# HG changeset patch # User cin # Date 1395942369 -14400 # Node ID f990fcb411a99bafd50a2ec7f7f064c4a5dee07b Копия текущей версии из github diff -r 000000000000 -r f990fcb411a9 .editorconfig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.editorconfig Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +; What is EditorConfig? http://editorconfig.org/ +; Extension for VS2010/2012 to support .editorconfig files: http://visualstudiogallery.msdn.microsoft.com/c8bccfe2-650c-4b42-bc5c-845e21f96328 + +root = true + +; use tabs identation for all files +[*] +indent_style = tab + diff -r 000000000000 -r f990fcb411a9 .gitignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.gitignore Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,50 @@ + +Binary file: E:\Projects\Git\BLToolkit\.gitignore (Detected) +#ignore thumbnails created by windows +Thumbs.db +#Ignore files build by Visual Studio +*.obj +*.exe +*.pdb +*.user +*.aps +*.pch +*.vspscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.cache +*.ilk +*.log +[Bb]in +[Dd]ebug*/ +*.lib +*.sbr +*.pidb +*.cache +*.userprefs +*.sdf +*.xap +obj/ +[Rr]elease*/ +_ReSharper*/ +[Tt]est[Rr]esult* +BLToolkit.2010.opensdf +BLToolkit.2010.sdf +BLToolkit.2010.userprefs +BLToolkit.2010.sdf +BLToolkit.2010.userprefs +Mono/_ReSharper.Mono/* +BLToolkit.2010.sln.docstates +*.csproj.user +UnitTests/BLToolkit.Linq.VisualState.xml +UnitTests/Linq/UserDataProviders.txt +!*.dll +!*.exe +!*.pdb +BLToolkit.2012.opensdf +ipch/examples.cpp-54293a33/examples.ipch diff -r 000000000000 -r f990fcb411a9 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +syntax: glob +Thumbs.db +*.obj +*.exe +*.pdb +*.user +*.aps +*.pch +*.vspscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.cache +*.ilk +*.log +bin +debug*/ +*.lib +*.sbr +*.pidb +*.cache +*.userprefs +*.sdf +*.xap +obj/ +release*/ +_ReSharper*/ +TestResult* +BLToolkit.2010.opensdf +BLToolkit.2010.sdf +BLToolkit.2010.userprefs +BLToolkit.2010.sdf +BLToolkit.2010.userprefs +Mono/_ReSharper.Mono/* +BLToolkit.2010.sln.docstates +*.csproj.user +UnitTests/BLToolkit.Linq.VisualState.xml +UnitTests/Linq/UserDataProviders.txt +!*.dll +!*.exe +!*.pdb +BLToolkit.2012.opensdf +ipch/examples.cpp-54293a33/examples.ipch diff -r 000000000000 -r f990fcb411a9 BLToolkit.2008.6.0.ReSharper --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BLToolkit.2008.6.0.ReSharper Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,97 @@ + + + + + SOLUTION + + + + + + + + public + protected + internal + private + new + abstract + virtual + override + sealed + static + readonly + extern + unsafe + volatile + + False + True + True + False + False + False + True + + + + System + + + System + + + + $object$_On$event$ + $event$Handler + + + + + + + + + + + + + + $object$_On$event$ + $event$Handler + + + + + + + + + + + + + + $object$_On$event$ + $event$Handler + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 BLToolkit.2008.6.1.ReSharper --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BLToolkit.2008.6.1.ReSharper Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,96 @@ + + + + SOLUTION + + + + + + + + public + protected + internal + private + new + abstract + virtual + override + sealed + static + readonly + extern + unsafe + volatile + + False + True + True + False + False + False + True + + + + System + + + System + + + + $object$_On$event$ + $event$Handler + + + + + + + + + + + + + + $object$_On$event$ + $event$Handler + + + + + + + + + + + + + + $object$_On$event$ + $event$Handler + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 BLToolkit.2008.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BLToolkit.2008.sln Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,249 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{92307E70-A839-4A76-9701-B5603B05BC08}" + ProjectSection(FolderStartupServices) = postProject + {B4F97281-0DBD-4835-9ED8-7DFB966E87FF} = {B4F97281-0DBD-4835-9ED8-7DFB966E87FF} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demo", "Demo", "{F45E2E57-2D88-49DF-8C97-9D8EE7A0A4B1}" + ProjectSection(FolderStartupServices) = postProject + {B4F97281-0DBD-4835-9ED8-7DFB966E87FF} = {B4F97281-0DBD-4835-9ED8-7DFB966E87FF} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.3", "Source\BLToolkit.3.csproj", "{0C325F5D-E50E-4340-8724-D29896CCC583}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExampleGenerator", "Tools\ExampleGenerator\ExampleGenerator.csproj", "{DE735B24-E20B-4440-BBBB-35AECC3F1124}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLTgen.2008", "Tools\BLTgen\BLTgen.2008.csproj", "{65FC918C-FF12-4C75-96F5-180B552989E5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Templates.2008", "Tools\Templates\Templates.2008.csproj", "{6E0C5565-F9A3-441C-9CB2-8B1878A800EF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linq", "Linq", "{4ABA64DA-8981-42F5-9144-DFD5350BEC2D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataProviders", "DataProviders", "{9F229425-A623-4066-9A92-84F31DD54FD2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.DB2.3", "DataProviders\DB2\BLToolkit.Data.DataProvider.DB2.3.csproj", "{86BF4F10-3606-4016-9919-84C3335813B6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Firebird.3", "DataProviders\Firebird\BLToolkit.Data.DataProvider.Firebird.3.csproj", "{C1F8C201-BBD9-44F4-884C-CFF8CC960B68}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Informix.3", "DataProviders\Informix\BLToolkit.Data.DataProvider.Informix.3.csproj", "{B1DEA25C-7667-471B-BBAD-64D017FDD104}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.MySql.3", "DataProviders\MySql\BLToolkit.Data.DataProvider.MySql.3.csproj", "{3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Oracle.3", "DataProviders\Oracle\BLToolkit.Data.DataProvider.Oracle.3.csproj", "{2B5287F2-A6AC-4D5A-B0A8-01C06144824D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.PostgreSQL.3", "DataProviders\PostgreSQL\BLToolkit.Data.DataProvider.PostgreSQL.3.csproj", "{5A556D57-0D68-433B-AD78-02849583582B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.SqlCe.3", "DataProviders\SqlCe\BLToolkit.Data.DataProvider.SqlCe.3.csproj", "{85E90F57-8DE1-4912-8414-28578F4D71CD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.SQLite.3", "DataProviders\SQLite\BLToolkit.Data.DataProvider.SQLite.3.csproj", "{3E414663-B673-47A8-AB59-0E08FE43DA86}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Sybase.3", "DataProviders\Sybase\BLToolkit.Data.DataProvider.Sybase.3.csproj", "{6CD8CC3D-643D-4D09-8660-A26085C44FBC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq.Demo.2008", "Demo\Linq\Demo\Linq.Demo.2008.csproj", "{57CE5505-44CB-42E4-A346-3471F68A5B60}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|.NET = Debug|.NET + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Release|.NET = Release|.NET + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|.NET.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Win32.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|.NET.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Any CPU.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Win32.ActiveCfg = Release|Any CPU + {DE735B24-E20B-4440-BBBB-35AECC3F1124}.Debug|.NET.ActiveCfg = Debug|Any CPU + {DE735B24-E20B-4440-BBBB-35AECC3F1124}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE735B24-E20B-4440-BBBB-35AECC3F1124}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE735B24-E20B-4440-BBBB-35AECC3F1124}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {DE735B24-E20B-4440-BBBB-35AECC3F1124}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {DE735B24-E20B-4440-BBBB-35AECC3F1124}.Debug|Win32.ActiveCfg = Debug|Any CPU + {DE735B24-E20B-4440-BBBB-35AECC3F1124}.Release|.NET.ActiveCfg = Release|Any CPU + {DE735B24-E20B-4440-BBBB-35AECC3F1124}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE735B24-E20B-4440-BBBB-35AECC3F1124}.Release|Any CPU.Build.0 = Release|Any CPU + {DE735B24-E20B-4440-BBBB-35AECC3F1124}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {DE735B24-E20B-4440-BBBB-35AECC3F1124}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {DE735B24-E20B-4440-BBBB-35AECC3F1124}.Release|Win32.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|.NET.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Win32.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|.NET.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Any CPU.Build.0 = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Win32.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|.NET.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Win32.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|.NET.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Any CPU.Build.0 = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Win32.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|.NET.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Win32.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|.NET.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Any CPU.Build.0 = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Win32.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|.NET.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Win32.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|.NET.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Any CPU.Build.0 = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Win32.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|.NET.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Win32.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|.NET.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Any CPU.Build.0 = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Win32.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|.NET.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Win32.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|.NET.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Any CPU.Build.0 = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Win32.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|.NET.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Win32.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|.NET.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Any CPU.Build.0 = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Win32.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|.NET.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|.NET.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Any CPU.Build.0 = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Win32.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|.NET.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Win32.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|.NET.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Any CPU.Build.0 = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Win32.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|.NET.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Win32.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|.NET.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Any CPU.Build.0 = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Win32.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|.NET.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Win32.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|.NET.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Any CPU.Build.0 = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Win32.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|.NET.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Win32.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|.NET.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Any CPU.Build.0 = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Win32.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {DE735B24-E20B-4440-BBBB-35AECC3F1124} = {92307E70-A839-4A76-9701-B5603B05BC08} + {65FC918C-FF12-4C75-96F5-180B552989E5} = {92307E70-A839-4A76-9701-B5603B05BC08} + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF} = {92307E70-A839-4A76-9701-B5603B05BC08} + {4ABA64DA-8981-42F5-9144-DFD5350BEC2D} = {F45E2E57-2D88-49DF-8C97-9D8EE7A0A4B1} + {57CE5505-44CB-42E4-A346-3471F68A5B60} = {4ABA64DA-8981-42F5-9144-DFD5350BEC2D} + {86BF4F10-3606-4016-9919-84C3335813B6} = {9F229425-A623-4066-9A92-84F31DD54FD2} + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68} = {9F229425-A623-4066-9A92-84F31DD54FD2} + {B1DEA25C-7667-471B-BBAD-64D017FDD104} = {9F229425-A623-4066-9A92-84F31DD54FD2} + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD} = {9F229425-A623-4066-9A92-84F31DD54FD2} + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D} = {9F229425-A623-4066-9A92-84F31DD54FD2} + {5A556D57-0D68-433B-AD78-02849583582B} = {9F229425-A623-4066-9A92-84F31DD54FD2} + {85E90F57-8DE1-4912-8414-28578F4D71CD} = {9F229425-A623-4066-9A92-84F31DD54FD2} + {3E414663-B673-47A8-AB59-0E08FE43DA86} = {9F229425-A623-4066-9A92-84F31DD54FD2} + {6CD8CC3D-643D-4D09-8660-A26085C44FBC} = {9F229425-A623-4066-9A92-84F31DD54FD2} + EndGlobalSection + GlobalSection(TextTemplating) = postSolution + TextTemplating = 1 + EndGlobalSection +EndGlobal diff -r 000000000000 -r f990fcb411a9 BLToolkit.2010.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BLToolkit.2010.sln Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2028 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.4", "Source\BLToolkit.4.csproj", "{0C325F5D-E50E-4340-8724-D29896CCC583}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{2CC0A340-512C-4F0D-A5E6-87C042EE13B9}" + ProjectSection(SolutionItems) = preProject + UnitTests\BLToolkit.Linq.nunit = UnitTests\BLToolkit.Linq.nunit + UnitTests\BLToolkit.nunit = UnitTests\BLToolkit.nunit + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.Linq.Interface", "UnitTests\Linq\UnitTests.Linq.Interface.csproj", "{D527524F-EC92-465E-9CAE-86278121675A}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "UnitTests.Linq.VisualBasic", "UnitTests\Linq\UnitTests.Linq.VisualBasic.vbproj", "{D11617AB-9F88-4C74-8ABD-F8580DB4B01B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.Linq", "UnitTests\Linq\UnitTests.Linq.csproj", "{07997A18-86D3-47AC-A514-AB1B03E6AEC8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{C0306556-68F4-4DD5-95F2-AAFEE8FACDFA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Templates", "Tools\Templates\Templates.csproj", "{6E0C5565-F9A3-441C-9CB2-8B1878A800EF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataProviders", "DataProviders", "{E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.DB2.4", "DataProviders\DB2\BLToolkit.Data.DataProvider.DB2.4.csproj", "{86BF4F10-3606-4016-9919-84C3335813B6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Firebird.4", "DataProviders\Firebird\BLToolkit.Data.DataProvider.Firebird.4.csproj", "{C1F8C201-BBD9-44F4-884C-CFF8CC960B68}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Informix.4", "DataProviders\Informix\BLToolkit.Data.DataProvider.Informix.4.csproj", "{B1DEA25C-7667-471B-BBAD-64D017FDD104}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.MySql.4", "DataProviders\MySql\BLToolkit.Data.DataProvider.MySql.4.csproj", "{3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Oracle.4", "DataProviders\Oracle\BLToolkit.Data.DataProvider.Oracle.4.csproj", "{2B5287F2-A6AC-4D5A-B0A8-01C06144824D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.PostgreSQL.4", "DataProviders\PostgreSQL\BLToolkit.Data.DataProvider.PostgreSQL.4.csproj", "{5A556D57-0D68-433B-AD78-02849583582B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.SqlCe.4", "DataProviders\SqlCe\BLToolkit.Data.DataProvider.SqlCe.4.csproj", "{85E90F57-8DE1-4912-8414-28578F4D71CD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.SQLite.4", "DataProviders\SQLite\BLToolkit.Data.DataProvider.SQLite.4.csproj", "{3E414663-B673-47A8-AB59-0E08FE43DA86}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Sybase.4", "DataProviders\Sybase\BLToolkit.Data.DataProvider.Sybase.4.csproj", "{6CD8CC3D-643D-4D09-8660-A26085C44FBC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.SL.4", "Source\BLToolkit.SL.4.csproj", "{663D4BFC-F565-41F7-9409-510B560CCEE8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demo", "Demo", "{B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Silverlight", "Silverlight", "{83C0070F-E639-4D65-B392-34F621165A1C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Demo\Silverlight\Client\Client.csproj", "{28693777-369C-4C0D-B076-38F7C0E5D06C}" + ProjectSection(ProjectDependencies) = postProject + {E796EF23-D63D-4EBD-A34D-5F243834933B} = {E796EF23-D63D-4EBD-A34D-5F243834933B} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client.Web", "Demo\Silverlight\Client.Web\Client.Web.csproj", "{E796EF23-D63D-4EBD-A34D-5F243834933B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Partial.Trust", "Partial.Trust", "{0F3F166F-9927-4BC0-855F-ADB0D20218F1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Partial.Trust.Components", "Demo\Partial.Trust\Components\Partial.Trust.Components.csproj", "{3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Partial.Trust.Asp.Net", "Demo\Partial.Trust\Asp.Net\Partial.Trust.Asp.Net.csproj", "{16272F10-9E3D-4C24-8761-8A43E9FB525F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLTgen.2010", "Tools\BLTgen\BLTgen.2010.csproj", "{65FC918C-FF12-4C75-96F5-180B552989E5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WinForms", "WinForms", "{35E61C2A-2B8C-4AF4-AD21-353936581EF5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Demo", "Demo\WinForms\BLToolkit.Demo.csproj", "{854749E5-9264-42FF-A576-3B5784C7C14C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linq", "Linq", "{9475B894-944A-47CF-855D-93A0C42136C9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq.Demo.2010", "Demo\Linq\Demo\Linq.Demo.2010.csproj", "{57CE5505-44CB-42E4-A346-3471F68A5B60}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq.OverWCF", "Demo\Linq\OverWCF\Linq.OverWCF.csproj", "{7ED3B518-7CEA-4991-98BD-9752E5F32F58}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Asp.Net", "Asp.Net", "{FC77CB0E-4DBF-4CDF-A1AD-C6F830A849B0}" + ProjectSection(SolutionItems) = preProject + Demo\Asp.Net\ReadMe.txt = Demo\Asp.Net\ReadMe.txt + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PetShop.ObjectModel", "Demo\Asp.Net\ObjectModel\PetShop.ObjectModel.csproj", "{BF0811CA-4663-4778-8331-9BEEBCAAC8C8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PetShop.BusinessLogic", "Demo\Asp.Net\BusinessLogic\PetShop.BusinessLogic.csproj", "{01C318D0-1CB1-4CB4-A5ED-D311665C76EE}" +EndProject +Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Web", "Demo\Asp.Net\Web\", "{7DAA2EBB-A724-498F-93BB-68966E2B738F}" + ProjectSection(WebsiteProperties) = preProject + SccProjectName = "" + SccAuxPath = "" + SccLocalPath = "" + SccProvider = "" + TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0" + ProjectReferences = "{0C325F5D-E50E-4340-8724-D29896CCC583}|BLToolkit.4.dll;{01C318D0-1CB1-4CB4-A5ED-D311665C76EE}|PetShop.BusinessLogic.dll;{BF0811CA-4663-4778-8331-9BEEBCAAC8C8}|PetShop.ObjectModel.dll;" + Debug.AspNetCompiler.VirtualPath = "/Web" + Debug.AspNetCompiler.PhysicalPath = "Demo\Asp.Net\Web\" + Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\Web\" + Debug.AspNetCompiler.Updateable = "true" + Debug.AspNetCompiler.ForceOverwrite = "true" + Debug.AspNetCompiler.FixedNames = "false" + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.VirtualPath = "/Web" + Release.AspNetCompiler.PhysicalPath = "Demo\Asp.Net\Web\" + Release.AspNetCompiler.TargetPath = "PrecompiledWeb\Web\" + Release.AspNetCompiler.Updateable = "true" + Release.AspNetCompiler.ForceOverwrite = "true" + Release.AspNetCompiler.FixedNames = "false" + Release.AspNetCompiler.Debug = "False" + VWDPort = "51456" + VWDDynamicPort = "false" + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebServices", "WebServices", "{2F6B63C4-295A-433C-91CB-CAE4CADE6B8B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObjectModel", "Demo\WebServices\ObjectModel\ObjectModel.csproj", "{8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Demo\WebServices\Server\Server.csproj", "{711A3803-4395-4E92-9B26-DC8DDDF80366}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Demo\WebServices\Client\Client.csproj", "{4EBBF9E9-53B2-493C-ABAB-E915C187558F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{8A7F38C5-EF9A-410B-8539-A58879F3AA22}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Examples.Cpp", "Examples\Cpp\Examples.Cpp.vcxproj", "{FF377109-1931-499F-9346-449D259977F2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.CS", "Examples\CS\Examples.CS.csproj", "{34989C73-F82A-4905-9349-D0CF1419CD1C}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Examples.VB", "Examples\VB\Examples.VB.vbproj", "{308A4189-53AB-460D-B2B1-0EB4B9219654}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HowTo", "HowTo\HowTo.csproj", "{8DA66999-005A-49AB-86A9-2C1F62905B50}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Templates.VB", "Tools\Templates.VB\Templates.VB.vbproj", "{F2B014F7-3807-4938-8F02-3CF8247C47DC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Create Scripts", "Create Scripts", "{4FDE7340-F60F-49BC-86CD-756CCD26C92A}" + ProjectSection(SolutionItems) = preProject + Data\Create Scripts\Access.sql = Data\Create Scripts\Access.sql + Data\Create Scripts\DB2.sql = Data\Create Scripts\DB2.sql + Data\Create Scripts\Firebird2.sql = Data\Create Scripts\Firebird2.sql + Data\Create Scripts\Informix.sql = Data\Create Scripts\Informix.sql + Data\Create Scripts\MsSql.sql = Data\Create Scripts\MsSql.sql + Data\Create Scripts\MsSql2000.sql = Data\Create Scripts\MsSql2000.sql + Data\Create Scripts\MySql.sql = Data\Create Scripts\MySql.sql + Data\Create Scripts\Oracle.sql = Data\Create Scripts\Oracle.sql + Data\Create Scripts\PostgreSQL.sql = Data\Create Scripts\PostgreSQL.sql + Data\Create Scripts\SqlCe.sql = Data\Create Scripts\SqlCe.sql + Data\Create Scripts\SQLite.sql = Data\Create Scripts\SQLite.sql + Data\Create Scripts\Sybase.sql = Data\Create Scripts\Sybase.sql + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.CS", "UnitTests\CS\UnitTests.CS.csproj", "{2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.All", "UnitTests\All\UnitTests.All.csproj", "{6AE74A35-B337-4B17-8092-E1B98DEF06AF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.4.JointureAddOn", "Extensions\JointureAddOn\BLToolkit.4.JointureAddOn.csproj", "{9FD2722C-1E6C-4061-8AC0-32EE28808FC0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{218E3584-CDC7-4A77-AD1A-CF9FBE90F67F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGet", "NuGet", "{4A9C0E31-8697-48BA-A46B-6A5EE78424D6}" + ProjectSection(SolutionItems) = preProject + NuGet\BLToolkit.DB2.nuspec = NuGet\BLToolkit.DB2.nuspec + NuGet\BLToolkit.DevartOraclePro.nuspec = NuGet\BLToolkit.DevartOraclePro.nuspec + NuGet\BLToolkit.Firebird.nuspec = NuGet\BLToolkit.Firebird.nuspec + NuGet\BLToolkit.Informix.nuspec = NuGet\BLToolkit.Informix.nuspec + NuGet\BLToolkit.MySql.nuspec = NuGet\BLToolkit.MySql.nuspec + NuGet\BLToolkit.nuspec = NuGet\BLToolkit.nuspec + NuGet\BLToolkit.Oracle.nuspec = NuGet\BLToolkit.Oracle.nuspec + NuGet\BLToolkit.PostgreSql.nuspec = NuGet\BLToolkit.PostgreSql.nuspec + NuGet\BLToolkit.SqlCe.nuspec = NuGet\BLToolkit.SqlCe.nuspec + NuGet\BLToolkit.SQLite.nuspec = NuGet\BLToolkit.SQLite.nuspec + NuGet\BLToolkit.Sybase.nuspec = NuGet\BLToolkit.Sybase.nuspec + NuGet\BLToolkit.symbols.nuspec = NuGet\BLToolkit.symbols.nuspec + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.4", "Source\BLToolkit.Data.4.csproj", "{0C325F5D-E50E-4340-8724-D29896CCC584}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.CP.4", "Source\BLToolkit.CP.4.csproj", "{0C325F5D-E50E-4340-8724-D29896CCC585}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NorthwindDataService", "Demo\WebServices\NorthwindDataService\NorthwindDataService.csproj", "{87FB4F28-5DCC-4F21-B83E-59C85E1A7423}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.OracleManaged.4", "DataProviders\Oracle\BLToolkit.Data.DataProvider.OracleManaged.4.csproj", "{785CE174-0A91-465F-9E41-65E6E05A0EC9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.DevartOracle.4", "DataProviders\DevartOraclePro\BLToolkit.Data.DataProvider.DevartOracle.4.csproj", "{CB303F0B-0AA3-4589-850A-95E985A09492}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug FW 3.5|Any CPU = Debug FW 3.5|Any CPU + Debug FW 3.5|Mixed Platforms = Debug FW 3.5|Mixed Platforms + Debug FW 3.5|Win32 = Debug FW 3.5|Win32 + Debug FW 3.5|x64 = Debug FW 3.5|x64 + Debug FW 3.5|x86 = Debug FW 3.5|x86 + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + DebugMono|Any CPU = DebugMono|Any CPU + DebugMono|Mixed Platforms = DebugMono|Mixed Platforms + DebugMono|Win32 = DebugMono|Win32 + DebugMono|x64 = DebugMono|x64 + DebugMono|x86 = DebugMono|x86 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + ReleaseMono|Any CPU = ReleaseMono|Any CPU + ReleaseMono|Mixed Platforms = ReleaseMono|Mixed Platforms + ReleaseMono|Win32 = ReleaseMono|Win32 + ReleaseMono|x64 = ReleaseMono|x64 + ReleaseMono|x86 = ReleaseMono|x86 + Template|Any CPU = Template|Any CPU + Template|Mixed Platforms = Template|Mixed Platforms + Template|Win32 = Template|Win32 + Template|x64 = Template|x64 + Template|x86 = Template|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|x64.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Win32.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|x64.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|x86.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Any CPU.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Win32.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|x64.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|x86.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|x64.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|x86.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|x64.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|Win32.ActiveCfg = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|x64.ActiveCfg = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|x86.ActiveCfg = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|Any CPU.Build.0 = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|Win32.ActiveCfg = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|x64.ActiveCfg = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|x86.ActiveCfg = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|x64.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|x86.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|x64.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|x64.ActiveCfg = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|x86.ActiveCfg = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|Any CPU.Build.0 = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|Win32.ActiveCfg = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|x64.ActiveCfg = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|x86.ActiveCfg = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|x64.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|x86.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|x64.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|Win32.ActiveCfg = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|x64.ActiveCfg = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|x86.ActiveCfg = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|Any CPU.Build.0 = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|Win32.ActiveCfg = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|x64.ActiveCfg = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|x86.ActiveCfg = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|x64.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|x86.ActiveCfg = Debug FW 3.5|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Win32.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|x64.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|x86.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Any CPU.Build.0 = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Win32.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|x64.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|x86.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|Any CPU.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|Any CPU.Build.0 = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|Win32.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|x64.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|x86.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Win32.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|x64.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|x86.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Any CPU.Build.0 = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Win32.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|x64.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|x86.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|Any CPU.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|Any CPU.Build.0 = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|Win32.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|x64.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|x86.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Win32.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|x64.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|x86.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Any CPU.Build.0 = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Win32.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|x64.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|x86.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|Any CPU.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|Any CPU.Build.0 = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|Win32.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|x64.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|x86.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Win32.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|x64.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|x86.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Any CPU.Build.0 = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Win32.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|x64.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|x86.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|Any CPU.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|Any CPU.Build.0 = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|Win32.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|x64.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|x86.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Win32.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|x64.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|x86.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Any CPU.Build.0 = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Win32.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|x64.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|x86.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|Any CPU.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|Any CPU.Build.0 = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|Win32.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|x64.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|x86.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Win32.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|x64.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|x86.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Any CPU.Build.0 = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Win32.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|x64.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|x86.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|Any CPU.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|Any CPU.Build.0 = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|Win32.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|x64.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|x86.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|x64.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|x86.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Any CPU.Build.0 = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Win32.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|x64.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|x86.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|Any CPU.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|Any CPU.Build.0 = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|Win32.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|x64.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|x86.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Win32.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|x64.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|x86.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Any CPU.Build.0 = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Win32.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|x64.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|x86.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|Any CPU.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|Any CPU.Build.0 = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|Win32.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|x64.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|x86.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Win32.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|x64.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|x86.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Any CPU.Build.0 = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Win32.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|x64.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|x86.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|Any CPU.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|Any CPU.Build.0 = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|Win32.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|x64.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|x86.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Win32.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|x64.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|x86.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Any CPU.Build.0 = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Win32.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|x64.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|x86.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|Any CPU.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|Any CPU.Build.0 = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|Win32.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|x64.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|x86.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|Win32.ActiveCfg = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|x64.ActiveCfg = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|x86.ActiveCfg = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|Any CPU.Build.0 = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|Win32.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|x64.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|x86.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|Any CPU.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|Any CPU.Build.0 = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|Win32.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|x64.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|x86.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|Win32.ActiveCfg = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|x64.ActiveCfg = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|x86.ActiveCfg = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|Any CPU.Build.0 = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|Win32.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|x64.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|x86.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|Any CPU.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|Any CPU.Build.0 = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|Win32.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|x64.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|x86.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|x64.ActiveCfg = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|x86.ActiveCfg = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|Any CPU.Build.0 = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|Win32.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|x64.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|x86.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|Any CPU.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|Any CPU.Build.0 = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|Win32.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|x64.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|x86.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|Win32.ActiveCfg = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|x64.ActiveCfg = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|x86.ActiveCfg = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|Any CPU.Build.0 = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|Win32.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|x64.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|x86.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|Any CPU.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|Any CPU.Build.0 = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|Win32.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|x64.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|x86.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|Win32.ActiveCfg = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|x64.ActiveCfg = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|x86.ActiveCfg = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|Any CPU.Build.0 = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|Win32.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|x64.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|x86.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|Any CPU.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|Any CPU.Build.0 = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|Win32.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|x64.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|x86.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Win32.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|x64.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|x86.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Any CPU.Build.0 = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Win32.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|x64.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|x86.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|Any CPU.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|Any CPU.Build.0 = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|Win32.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|x64.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|x86.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|Win32.ActiveCfg = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|x64.ActiveCfg = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|x86.ActiveCfg = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|Any CPU.Build.0 = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|Win32.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|x64.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|x86.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|Any CPU.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|Any CPU.Build.0 = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|Win32.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|x64.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|x86.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Win32.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|x64.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|x86.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Any CPU.Build.0 = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Win32.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|x64.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|x86.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|Any CPU.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|Any CPU.Build.0 = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|Win32.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|x64.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|x86.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|Win32.ActiveCfg = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|x64.ActiveCfg = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|x86.ActiveCfg = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|Any CPU.Build.0 = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|Win32.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|x64.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|x86.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|Any CPU.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|Any CPU.Build.0 = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|Win32.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|x64.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|x86.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|Win32.ActiveCfg = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|x64.ActiveCfg = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|x86.ActiveCfg = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|Any CPU.Build.0 = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|Win32.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|x64.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|x86.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|Any CPU.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|Any CPU.Build.0 = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|Win32.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|x64.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|x86.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|Win32.ActiveCfg = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|x64.ActiveCfg = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|x86.ActiveCfg = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|Any CPU.Build.0 = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|Win32.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|x64.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|x86.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|Any CPU.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|Any CPU.Build.0 = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|Win32.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|x64.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|x86.ActiveCfg = Release|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|Any CPU.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|Any CPU.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|Win32.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|x64.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|x86.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|Win32.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|x64.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|x86.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|Any CPU.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|Any CPU.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|Mixed Platforms.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|Win32.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|x64.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|x86.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|Any CPU.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|Any CPU.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|Mixed Platforms.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|Win32.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|x64.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|x86.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|Any CPU.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|Any CPU.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|Mixed Platforms.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|Win32.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|x64.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|x86.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|Any CPU.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|Any CPU.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|Mixed Platforms.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|Win32.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|x64.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|x86.ActiveCfg = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|Win32.ActiveCfg = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|x64.ActiveCfg = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|x86.ActiveCfg = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|Any CPU.Build.0 = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|Win32.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|x64.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|x86.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|Any CPU.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|Any CPU.Build.0 = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|Win32.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|x64.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|x86.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|Any CPU.Build.0 = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|Win32.ActiveCfg = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|x64.ActiveCfg = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|x86.ActiveCfg = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|Any CPU.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|Any CPU.Build.0 = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|Win32.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|x64.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|x86.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|Any CPU.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|Any CPU.Build.0 = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|Win32.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|x64.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|x86.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|Win32.ActiveCfg = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|x64.ActiveCfg = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|x86.ActiveCfg = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|Any CPU.Build.0 = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|Win32.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|x64.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|x86.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|Any CPU.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|Any CPU.Build.0 = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|Win32.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|x64.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|x86.ActiveCfg = Release|Any CPU + {FF377109-1931-499F-9346-449D259977F2}.Debug FW 3.5|Any CPU.ActiveCfg = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug FW 3.5|Win32.ActiveCfg = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug FW 3.5|Win32.Build.0 = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug FW 3.5|x64.ActiveCfg = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug FW 3.5|x86.ActiveCfg = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug|Any CPU.Build.0 = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug|Win32.ActiveCfg = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug|Win32.Build.0 = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug|x64.ActiveCfg = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Debug|x86.ActiveCfg = Debug|Win32 + {FF377109-1931-499F-9346-449D259977F2}.DebugMono|Any CPU.ActiveCfg = DebugMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.DebugMono|Win32.ActiveCfg = DebugMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.DebugMono|Win32.Build.0 = DebugMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.DebugMono|x64.ActiveCfg = DebugMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.DebugMono|x86.ActiveCfg = DebugMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Release|Any CPU.ActiveCfg = Release|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Release|Mixed Platforms.Build.0 = Release|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Release|Win32.ActiveCfg = Release|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Release|Win32.Build.0 = Release|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Release|x64.ActiveCfg = Release|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Release|x86.ActiveCfg = Release|Win32 + {FF377109-1931-499F-9346-449D259977F2}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.ReleaseMono|Win32.Build.0 = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Template|Any CPU.ActiveCfg = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Template|Mixed Platforms.ActiveCfg = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Template|Mixed Platforms.Build.0 = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Template|Win32.ActiveCfg = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Template|Win32.Build.0 = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Template|x64.ActiveCfg = ReleaseMono|Win32 + {FF377109-1931-499F-9346-449D259977F2}.Template|x86.ActiveCfg = ReleaseMono|Win32 + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|Win32.ActiveCfg = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|x64.ActiveCfg = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|x86.ActiveCfg = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|Any CPU.Build.0 = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|Win32.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|x64.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|x86.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|Any CPU.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|Any CPU.Build.0 = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|Win32.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|x64.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|x86.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|Any CPU.Build.0 = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|Win32.ActiveCfg = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|x64.ActiveCfg = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|x86.ActiveCfg = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|Any CPU.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|Any CPU.Build.0 = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|Win32.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|x64.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|x86.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|Any CPU.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|Any CPU.Build.0 = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|Win32.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|x64.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|x86.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|Win32.ActiveCfg = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|x64.ActiveCfg = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|x86.ActiveCfg = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|Any CPU.Build.0 = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|Win32.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|x64.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|x86.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|Any CPU.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|Any CPU.Build.0 = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|Win32.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|x64.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|x86.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|Win32.ActiveCfg = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|x64.ActiveCfg = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|x86.ActiveCfg = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|Any CPU.Build.0 = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|Win32.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|x64.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|x86.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|Any CPU.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|Any CPU.Build.0 = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|Win32.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|x64.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|x86.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|Win32.ActiveCfg = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|x64.ActiveCfg = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|x86.ActiveCfg = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|Any CPU.Build.0 = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|Win32.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|x64.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|x86.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|Any CPU.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|Any CPU.Build.0 = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|Win32.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|x64.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|x86.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|Win32.ActiveCfg = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|x64.ActiveCfg = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|x86.ActiveCfg = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|Any CPU.Build.0 = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|Win32.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|x64.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|x86.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|Any CPU.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|Any CPU.Build.0 = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|Win32.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|x64.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|x86.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|Any CPU.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|Any CPU.Build.0 = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|Win32.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|x64.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|x86.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|Win32.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|x64.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|x86.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|Any CPU.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|Any CPU.Build.0 = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|Mixed Platforms.Build.0 = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|Win32.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|x64.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|x86.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|Any CPU.Build.0 = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|Win32.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|x64.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|x86.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|Any CPU.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|Any CPU.Build.0 = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|Mixed Platforms.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|Mixed Platforms.Build.0 = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|Win32.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|x64.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|x86.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|Any CPU.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|Any CPU.Build.0 = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|Win32.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|x64.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|x86.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|x64.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|Win32.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|x64.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|x86.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|Any CPU.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|Win32.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|x64.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|x86.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|Any CPU.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|Win32.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|x64.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|x86.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|x64.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|Win32.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|x64.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|x86.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|Any CPU.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|Win32.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|x64.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|x86.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|Any CPU.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|Win32.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|x64.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|x86.ActiveCfg = ReleaseMono|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|Any CPU.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|Any CPU.Build.0 = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|Win32.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|x64.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|x86.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|Win32.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|x64.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|x86.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|Any CPU.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|Any CPU.Build.0 = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|Mixed Platforms.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|Mixed Platforms.Build.0 = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|Win32.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|x64.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|x86.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|Any CPU.Build.0 = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|Win32.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|x64.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|x86.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|Any CPU.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|Any CPU.Build.0 = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|Mixed Platforms.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|Mixed Platforms.Build.0 = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|Win32.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|x64.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|x86.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|Any CPU.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|Any CPU.Build.0 = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|Win32.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|x64.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|x86.ActiveCfg = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|Win32.ActiveCfg = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|x64.ActiveCfg = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|x86.ActiveCfg = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|Any CPU.Build.0 = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|Win32.ActiveCfg = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|x64.ActiveCfg = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|x86.ActiveCfg = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|Any CPU.Build.0 = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|Win32.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|x64.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|x86.ActiveCfg = ReleaseMono|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|Any CPU.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|Any CPU.Build.0 = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|Win32.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|x64.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|x86.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|Win32.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|x64.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|x86.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|Any CPU.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|Any CPU.Build.0 = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|Mixed Platforms.Build.0 = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|Win32.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|x64.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|x86.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|Any CPU.Build.0 = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|Win32.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|x64.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|x86.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|Any CPU.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|Any CPU.Build.0 = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|Mixed Platforms.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|Mixed Platforms.Build.0 = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|Win32.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|x64.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|x86.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|Any CPU.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|Any CPU.Build.0 = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|Win32.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|x64.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|x86.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {D527524F-EC92-465E-9CAE-86278121675A} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {07997A18-86D3-47AC-A514-AB1B03E6AEC8} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {4FDE7340-F60F-49BC-86CD-756CCD26C92A} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {6AE74A35-B337-4B17-8092-E1B98DEF06AF} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF} = {C0306556-68F4-4DD5-95F2-AAFEE8FACDFA} + {65FC918C-FF12-4C75-96F5-180B552989E5} = {C0306556-68F4-4DD5-95F2-AAFEE8FACDFA} + {F2B014F7-3807-4938-8F02-3CF8247C47DC} = {C0306556-68F4-4DD5-95F2-AAFEE8FACDFA} + {86BF4F10-3606-4016-9919-84C3335813B6} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {B1DEA25C-7667-471B-BBAD-64D017FDD104} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {5A556D57-0D68-433B-AD78-02849583582B} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {85E90F57-8DE1-4912-8414-28578F4D71CD} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {3E414663-B673-47A8-AB59-0E08FE43DA86} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {6CD8CC3D-643D-4D09-8660-A26085C44FBC} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {785CE174-0A91-465F-9E41-65E6E05A0EC9} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {CB303F0B-0AA3-4589-850A-95E985A09492} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {83C0070F-E639-4D65-B392-34F621165A1C} = {B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D} + {0F3F166F-9927-4BC0-855F-ADB0D20218F1} = {B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D} + {35E61C2A-2B8C-4AF4-AD21-353936581EF5} = {B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D} + {9475B894-944A-47CF-855D-93A0C42136C9} = {B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D} + {FC77CB0E-4DBF-4CDF-A1AD-C6F830A849B0} = {B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D} + {2F6B63C4-295A-433C-91CB-CAE4CADE6B8B} = {B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D} + {28693777-369C-4C0D-B076-38F7C0E5D06C} = {83C0070F-E639-4D65-B392-34F621165A1C} + {E796EF23-D63D-4EBD-A34D-5F243834933B} = {83C0070F-E639-4D65-B392-34F621165A1C} + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7} = {0F3F166F-9927-4BC0-855F-ADB0D20218F1} + {16272F10-9E3D-4C24-8761-8A43E9FB525F} = {0F3F166F-9927-4BC0-855F-ADB0D20218F1} + {854749E5-9264-42FF-A576-3B5784C7C14C} = {35E61C2A-2B8C-4AF4-AD21-353936581EF5} + {57CE5505-44CB-42E4-A346-3471F68A5B60} = {9475B894-944A-47CF-855D-93A0C42136C9} + {7ED3B518-7CEA-4991-98BD-9752E5F32F58} = {9475B894-944A-47CF-855D-93A0C42136C9} + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8} = {FC77CB0E-4DBF-4CDF-A1AD-C6F830A849B0} + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE} = {FC77CB0E-4DBF-4CDF-A1AD-C6F830A849B0} + {7DAA2EBB-A724-498F-93BB-68966E2B738F} = {FC77CB0E-4DBF-4CDF-A1AD-C6F830A849B0} + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6} = {2F6B63C4-295A-433C-91CB-CAE4CADE6B8B} + {711A3803-4395-4E92-9B26-DC8DDDF80366} = {2F6B63C4-295A-433C-91CB-CAE4CADE6B8B} + {4EBBF9E9-53B2-493C-ABAB-E915C187558F} = {2F6B63C4-295A-433C-91CB-CAE4CADE6B8B} + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423} = {2F6B63C4-295A-433C-91CB-CAE4CADE6B8B} + {FF377109-1931-499F-9346-449D259977F2} = {8A7F38C5-EF9A-410B-8539-A58879F3AA22} + {34989C73-F82A-4905-9349-D0CF1419CD1C} = {8A7F38C5-EF9A-410B-8539-A58879F3AA22} + {308A4189-53AB-460D-B2B1-0EB4B9219654} = {8A7F38C5-EF9A-410B-8539-A58879F3AA22} + {8DA66999-005A-49AB-86A9-2C1F62905B50} = {8A7F38C5-EF9A-410B-8539-A58879F3AA22} + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0} = {218E3584-CDC7-4A77-AD1A-CF9FBE90F67F} + EndGlobalSection +EndGlobal diff -r 000000000000 -r f990fcb411a9 BLToolkit.2012.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BLToolkit.2012.sln Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2071 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.4", "Source\BLToolkit.4.csproj", "{0C325F5D-E50E-4340-8724-D29896CCC583}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{2CC0A340-512C-4F0D-A5E6-87C042EE13B9}" + ProjectSection(SolutionItems) = preProject + UnitTests\BLToolkit.Linq.nunit = UnitTests\BLToolkit.Linq.nunit + UnitTests\BLToolkit.nunit = UnitTests\BLToolkit.nunit + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.Linq.Interface", "UnitTests\Linq\UnitTests.Linq.Interface.csproj", "{D527524F-EC92-465E-9CAE-86278121675A}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "UnitTests.Linq.VisualBasic", "UnitTests\Linq\UnitTests.Linq.VisualBasic.vbproj", "{D11617AB-9F88-4C74-8ABD-F8580DB4B01B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.Linq", "UnitTests\Linq\UnitTests.Linq.csproj", "{07997A18-86D3-47AC-A514-AB1B03E6AEC8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{C0306556-68F4-4DD5-95F2-AAFEE8FACDFA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Templates", "Tools\Templates\Templates.csproj", "{6E0C5565-F9A3-441C-9CB2-8B1878A800EF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataProviders", "DataProviders", "{E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.DB2.4", "DataProviders\DB2\BLToolkit.Data.DataProvider.DB2.4.csproj", "{86BF4F10-3606-4016-9919-84C3335813B6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Firebird.4", "DataProviders\Firebird\BLToolkit.Data.DataProvider.Firebird.4.csproj", "{C1F8C201-BBD9-44F4-884C-CFF8CC960B68}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Informix.4", "DataProviders\Informix\BLToolkit.Data.DataProvider.Informix.4.csproj", "{B1DEA25C-7667-471B-BBAD-64D017FDD104}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.MySql.4", "DataProviders\MySql\BLToolkit.Data.DataProvider.MySql.4.csproj", "{3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Oracle.4", "DataProviders\Oracle\BLToolkit.Data.DataProvider.Oracle.4.csproj", "{2B5287F2-A6AC-4D5A-B0A8-01C06144824D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.PostgreSQL.4", "DataProviders\PostgreSQL\BLToolkit.Data.DataProvider.PostgreSQL.4.csproj", "{5A556D57-0D68-433B-AD78-02849583582B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.SqlCe.4", "DataProviders\SqlCe\BLToolkit.Data.DataProvider.SqlCe.4.csproj", "{85E90F57-8DE1-4912-8414-28578F4D71CD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.SQLite.4", "DataProviders\SQLite\BLToolkit.Data.DataProvider.SQLite.4.csproj", "{3E414663-B673-47A8-AB59-0E08FE43DA86}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Sybase.4", "DataProviders\Sybase\BLToolkit.Data.DataProvider.Sybase.4.csproj", "{6CD8CC3D-643D-4D09-8660-A26085C44FBC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.SL.4", "Source\BLToolkit.SL.4.csproj", "{663D4BFC-F565-41F7-9409-510B560CCEE8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demo", "Demo", "{B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Silverlight", "Silverlight", "{83C0070F-E639-4D65-B392-34F621165A1C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Demo\Silverlight\Client\Client.csproj", "{28693777-369C-4C0D-B076-38F7C0E5D06C}" + ProjectSection(ProjectDependencies) = postProject + {E796EF23-D63D-4EBD-A34D-5F243834933B} = {E796EF23-D63D-4EBD-A34D-5F243834933B} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client.Web", "Demo\Silverlight\Client.Web\Client.Web.csproj", "{E796EF23-D63D-4EBD-A34D-5F243834933B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Partial.Trust", "Partial.Trust", "{0F3F166F-9927-4BC0-855F-ADB0D20218F1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Partial.Trust.Components", "Demo\Partial.Trust\Components\Partial.Trust.Components.csproj", "{3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Partial.Trust.Asp.Net", "Demo\Partial.Trust\Asp.Net\Partial.Trust.Asp.Net.csproj", "{16272F10-9E3D-4C24-8761-8A43E9FB525F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLTgen.2010", "Tools\BLTgen\BLTgen.2010.csproj", "{65FC918C-FF12-4C75-96F5-180B552989E5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WinForms", "WinForms", "{35E61C2A-2B8C-4AF4-AD21-353936581EF5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Demo", "Demo\WinForms\BLToolkit.Demo.csproj", "{854749E5-9264-42FF-A576-3B5784C7C14C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linq", "Linq", "{9475B894-944A-47CF-855D-93A0C42136C9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq.Demo.2010", "Demo\Linq\Demo\Linq.Demo.2010.csproj", "{57CE5505-44CB-42E4-A346-3471F68A5B60}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq.OverWCF", "Demo\Linq\OverWCF\Linq.OverWCF.csproj", "{7ED3B518-7CEA-4991-98BD-9752E5F32F58}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Asp.Net", "Asp.Net", "{FC77CB0E-4DBF-4CDF-A1AD-C6F830A849B0}" + ProjectSection(SolutionItems) = preProject + Demo\Asp.Net\ReadMe.txt = Demo\Asp.Net\ReadMe.txt + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PetShop.ObjectModel", "Demo\Asp.Net\ObjectModel\PetShop.ObjectModel.csproj", "{BF0811CA-4663-4778-8331-9BEEBCAAC8C8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PetShop.BusinessLogic", "Demo\Asp.Net\BusinessLogic\PetShop.BusinessLogic.csproj", "{01C318D0-1CB1-4CB4-A5ED-D311665C76EE}" +EndProject +Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Web", "Demo\Asp.Net\Web\", "{7DAA2EBB-A724-498F-93BB-68966E2B738F}" + ProjectSection(WebsiteProperties) = preProject + SccProjectName = "" + SccAuxPath = "" + SccLocalPath = "" + SccProvider = "" + TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0" + ProjectReferences = "{0C325F5D-E50E-4340-8724-D29896CCC583}|BLToolkit.4.dll;{01C318D0-1CB1-4CB4-A5ED-D311665C76EE}|PetShop.BusinessLogic.dll;{BF0811CA-4663-4778-8331-9BEEBCAAC8C8}|PetShop.ObjectModel.dll;" + Debug.AspNetCompiler.VirtualPath = "/Web" + Debug.AspNetCompiler.PhysicalPath = "Demo\Asp.Net\Web\" + Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\Web\" + Debug.AspNetCompiler.Updateable = "true" + Debug.AspNetCompiler.ForceOverwrite = "true" + Debug.AspNetCompiler.FixedNames = "false" + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.VirtualPath = "/Web" + Release.AspNetCompiler.PhysicalPath = "Demo\Asp.Net\Web\" + Release.AspNetCompiler.TargetPath = "PrecompiledWeb\Web\" + Release.AspNetCompiler.Updateable = "true" + Release.AspNetCompiler.ForceOverwrite = "true" + Release.AspNetCompiler.FixedNames = "false" + Release.AspNetCompiler.Debug = "False" + VWDPort = "51456" + VWDDynamicPort = "false" + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebServices", "WebServices", "{2F6B63C4-295A-433C-91CB-CAE4CADE6B8B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObjectModel", "Demo\WebServices\ObjectModel\ObjectModel.csproj", "{8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Demo\WebServices\Server\Server.csproj", "{711A3803-4395-4E92-9B26-DC8DDDF80366}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Demo\WebServices\Client\Client.csproj", "{4EBBF9E9-53B2-493C-ABAB-E915C187558F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{8A7F38C5-EF9A-410B-8539-A58879F3AA22}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.CS", "Examples\CS\Examples.CS.csproj", "{34989C73-F82A-4905-9349-D0CF1419CD1C}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Examples.VB", "Examples\VB\Examples.VB.vbproj", "{308A4189-53AB-460D-B2B1-0EB4B9219654}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HowTo", "HowTo\HowTo.csproj", "{8DA66999-005A-49AB-86A9-2C1F62905B50}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Templates.VB", "Tools\Templates.VB\Templates.VB.vbproj", "{F2B014F7-3807-4938-8F02-3CF8247C47DC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Create Scripts", "Create Scripts", "{4FDE7340-F60F-49BC-86CD-756CCD26C92A}" + ProjectSection(SolutionItems) = preProject + Data\Create Scripts\Access.sql = Data\Create Scripts\Access.sql + Data\Create Scripts\DB2.sql = Data\Create Scripts\DB2.sql + Data\Create Scripts\Firebird2.sql = Data\Create Scripts\Firebird2.sql + Data\Create Scripts\Informix.sql = Data\Create Scripts\Informix.sql + Data\Create Scripts\MsSql.sql = Data\Create Scripts\MsSql.sql + Data\Create Scripts\MySql.sql = Data\Create Scripts\MySql.sql + Data\Create Scripts\Oracle.sql = Data\Create Scripts\Oracle.sql + Data\Create Scripts\PostgreSQL.sql = Data\Create Scripts\PostgreSQL.sql + Data\Create Scripts\SqlCe.sql = Data\Create Scripts\SqlCe.sql + Data\Create Scripts\SQLite.sql = Data\Create Scripts\SQLite.sql + Data\Create Scripts\Sybase.sql = Data\Create Scripts\Sybase.sql + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.CS", "UnitTests\CS\UnitTests.CS.csproj", "{2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.All", "UnitTests\All\UnitTests.All.csproj", "{6AE74A35-B337-4B17-8092-E1B98DEF06AF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.4.JointureAddOn", "Extensions\JointureAddOn\BLToolkit.4.JointureAddOn.csproj", "{9FD2722C-1E6C-4061-8AC0-32EE28808FC0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{218E3584-CDC7-4A77-AD1A-CF9FBE90F67F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGet", "NuGet", "{4A9C0E31-8697-48BA-A46B-6A5EE78424D6}" + ProjectSection(SolutionItems) = preProject + NuGet\BLToolkit.DB2.nuspec = NuGet\BLToolkit.DB2.nuspec + NuGet\BLToolkit.DevartOraclePro.nuspec = NuGet\BLToolkit.DevartOraclePro.nuspec + NuGet\BLToolkit.Firebird.nuspec = NuGet\BLToolkit.Firebird.nuspec + NuGet\BLToolkit.Informix.nuspec = NuGet\BLToolkit.Informix.nuspec + NuGet\BLToolkit.MySql.nuspec = NuGet\BLToolkit.MySql.nuspec + NuGet\BLToolkit.nuspec = NuGet\BLToolkit.nuspec + NuGet\BLToolkit.Oracle.nuspec = NuGet\BLToolkit.Oracle.nuspec + NuGet\BLToolkit.PostgreSql.nuspec = NuGet\BLToolkit.PostgreSql.nuspec + NuGet\BLToolkit.SqlCe.nuspec = NuGet\BLToolkit.SqlCe.nuspec + NuGet\BLToolkit.SQLite.nuspec = NuGet\BLToolkit.SQLite.nuspec + NuGet\BLToolkit.Sybase.nuspec = NuGet\BLToolkit.Sybase.nuspec + NuGet\BLToolkit.symbols.nuspec = NuGet\BLToolkit.symbols.nuspec + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.4", "Source\BLToolkit.Data.4.csproj", "{0C325F5D-E50E-4340-8724-D29896CCC584}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.CP.4", "Source\BLToolkit.CP.4.csproj", "{0C325F5D-E50E-4340-8724-D29896CCC585}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NorthwindDataService", "Demo\WebServices\NorthwindDataService\NorthwindDataService.csproj", "{87FB4F28-5DCC-4F21-B83E-59C85E1A7423}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.OracleManaged.4", "DataProviders\Oracle\BLToolkit.Data.DataProvider.OracleManaged.4.csproj", "{785CE174-0A91-465F-9E41-65E6E05A0EC9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.DevartOracle.4", "DataProviders\DevartOraclePro\BLToolkit.Data.DataProvider.DevartOracle.4.csproj", "{CB303F0B-0AA3-4589-850A-95E985A09492}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.Fluent", "UnitTests\Fluent\UnitTests.Fluent.csproj", "{527300F8-9F04-434C-8239-4FE5E174FF6B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.Data.DataProvider.Generic.4", "DataProviders\Generic\BLToolkit.Data.DataProvider.Generic.4.csproj", "{6E7FE7FC-551F-4273-ACEB-72DC0D01120E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug FW 3.5|Any CPU = Debug FW 3.5|Any CPU + Debug FW 3.5|Mixed Platforms = Debug FW 3.5|Mixed Platforms + Debug FW 3.5|Win32 = Debug FW 3.5|Win32 + Debug FW 3.5|x64 = Debug FW 3.5|x64 + Debug FW 3.5|x86 = Debug FW 3.5|x86 + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + DebugMono|Any CPU = DebugMono|Any CPU + DebugMono|Mixed Platforms = DebugMono|Mixed Platforms + DebugMono|Win32 = DebugMono|Win32 + DebugMono|x64 = DebugMono|x64 + DebugMono|x86 = DebugMono|x86 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + ReleaseMono|Any CPU = ReleaseMono|Any CPU + ReleaseMono|Mixed Platforms = ReleaseMono|Mixed Platforms + ReleaseMono|Win32 = ReleaseMono|Win32 + ReleaseMono|x64 = ReleaseMono|x64 + ReleaseMono|x86 = ReleaseMono|x86 + Template|Any CPU = Template|Any CPU + Template|Mixed Platforms = Template|Mixed Platforms + Template|Win32 = Template|Win32 + Template|x64 = Template|x64 + Template|x86 = Template|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|x64.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Win32.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|x64.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|x86.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Any CPU.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Win32.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|x64.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|x86.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|x64.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Template|x86.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|x64.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|Win32.ActiveCfg = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|x64.ActiveCfg = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Debug|x86.ActiveCfg = Debug|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|Any CPU.Build.0 = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|Win32.ActiveCfg = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|x64.ActiveCfg = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Release|x86.ActiveCfg = Release|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|x64.ActiveCfg = Debug FW 3.5|Any CPU + {D527524F-EC92-465E-9CAE-86278121675A}.Template|x86.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|x64.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|x64.ActiveCfg = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Debug|x86.ActiveCfg = Debug|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|Any CPU.Build.0 = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|Win32.ActiveCfg = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|x64.ActiveCfg = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Release|x86.ActiveCfg = Release|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|x64.ActiveCfg = Debug FW 3.5|Any CPU + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B}.Template|x86.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|x64.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|Win32.ActiveCfg = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|x64.ActiveCfg = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Debug|x86.ActiveCfg = Debug|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|Any CPU.Build.0 = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|Win32.ActiveCfg = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|x64.ActiveCfg = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Release|x86.ActiveCfg = Release|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|x64.ActiveCfg = Debug FW 3.5|Any CPU + {07997A18-86D3-47AC-A514-AB1B03E6AEC8}.Template|x86.ActiveCfg = Debug FW 3.5|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|Win32.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|x64.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Debug|x86.ActiveCfg = Debug|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Any CPU.Build.0 = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|Win32.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|x64.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Release|x86.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|Any CPU.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|Any CPU.Build.0 = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|Win32.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|x64.ActiveCfg = Release|Any CPU + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF}.Template|x86.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|Win32.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|x64.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Debug|x86.ActiveCfg = Debug|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Any CPU.Build.0 = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|Win32.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|x64.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Release|x86.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|Any CPU.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|Any CPU.Build.0 = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|Win32.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|x64.ActiveCfg = Release|Any CPU + {86BF4F10-3606-4016-9919-84C3335813B6}.Template|x86.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|Win32.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|x64.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Debug|x86.ActiveCfg = Debug|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Any CPU.Build.0 = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|Win32.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|x64.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Release|x86.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|Any CPU.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|Any CPU.Build.0 = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|Win32.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|x64.ActiveCfg = Release|Any CPU + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68}.Template|x86.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|Win32.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|x64.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Debug|x86.ActiveCfg = Debug|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Any CPU.Build.0 = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|Win32.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|x64.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Release|x86.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|Any CPU.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|Any CPU.Build.0 = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|Win32.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|x64.ActiveCfg = Release|Any CPU + {B1DEA25C-7667-471B-BBAD-64D017FDD104}.Template|x86.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|Win32.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|x64.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Debug|x86.ActiveCfg = Debug|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Any CPU.Build.0 = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|Win32.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|x64.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Release|x86.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|Any CPU.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|Any CPU.Build.0 = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|Win32.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|x64.ActiveCfg = Release|Any CPU + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD}.Template|x86.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|Win32.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|x64.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Debug|x86.ActiveCfg = Debug|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Any CPU.Build.0 = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|Win32.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|x64.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Release|x86.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|Any CPU.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|Any CPU.Build.0 = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|Win32.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|x64.ActiveCfg = Release|Any CPU + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D}.Template|x86.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|x64.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Debug|x86.ActiveCfg = Debug|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Any CPU.Build.0 = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|Win32.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|x64.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Release|x86.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|Any CPU.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|Any CPU.Build.0 = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|Win32.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|x64.ActiveCfg = Release|Any CPU + {5A556D57-0D68-433B-AD78-02849583582B}.Template|x86.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|Win32.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|x64.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Debug|x86.ActiveCfg = Debug|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Any CPU.Build.0 = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|Win32.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|x64.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Release|x86.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|Any CPU.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|Any CPU.Build.0 = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|Win32.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|x64.ActiveCfg = Release|Any CPU + {85E90F57-8DE1-4912-8414-28578F4D71CD}.Template|x86.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|Win32.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|x64.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Debug|x86.ActiveCfg = Debug|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Any CPU.Build.0 = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|Win32.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|x64.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Release|x86.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|Any CPU.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|Any CPU.Build.0 = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|Win32.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|x64.ActiveCfg = Release|Any CPU + {3E414663-B673-47A8-AB59-0E08FE43DA86}.Template|x86.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|Win32.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|x64.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Debug|x86.ActiveCfg = Debug|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Any CPU.Build.0 = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|Win32.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|x64.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Release|x86.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|Any CPU.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|Any CPU.Build.0 = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|Win32.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|x64.ActiveCfg = Release|Any CPU + {6CD8CC3D-643D-4D09-8660-A26085C44FBC}.Template|x86.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|Win32.ActiveCfg = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|x64.ActiveCfg = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Debug|x86.ActiveCfg = Debug|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|Any CPU.Build.0 = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|Win32.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|x64.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Release|x86.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|Any CPU.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|Any CPU.Build.0 = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|Win32.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|x64.ActiveCfg = Release|Any CPU + {663D4BFC-F565-41F7-9409-510B560CCEE8}.Template|x86.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|Win32.ActiveCfg = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|x64.ActiveCfg = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Debug|x86.ActiveCfg = Debug|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|Any CPU.Build.0 = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|Win32.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|x64.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Release|x86.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|Any CPU.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|Any CPU.Build.0 = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|Win32.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|x64.ActiveCfg = Release|Any CPU + {28693777-369C-4C0D-B076-38F7C0E5D06C}.Template|x86.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|x64.ActiveCfg = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Debug|x86.ActiveCfg = Debug|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|Any CPU.Build.0 = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|Win32.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|x64.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Release|x86.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|Any CPU.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|Any CPU.Build.0 = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|Win32.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|x64.ActiveCfg = Release|Any CPU + {E796EF23-D63D-4EBD-A34D-5F243834933B}.Template|x86.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|Win32.ActiveCfg = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|x64.ActiveCfg = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Debug|x86.ActiveCfg = Debug|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|Any CPU.Build.0 = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|Win32.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|x64.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Release|x86.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|Any CPU.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|Any CPU.Build.0 = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|Win32.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|x64.ActiveCfg = Release|Any CPU + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7}.Template|x86.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|Win32.ActiveCfg = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|x64.ActiveCfg = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Debug|x86.ActiveCfg = Debug|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|Any CPU.Build.0 = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|Win32.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|x64.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Release|x86.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|Any CPU.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|Any CPU.Build.0 = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|Win32.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|x64.ActiveCfg = Release|Any CPU + {16272F10-9E3D-4C24-8761-8A43E9FB525F}.Template|x86.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|Win32.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|x64.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Debug|x86.ActiveCfg = Debug|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Any CPU.Build.0 = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|Win32.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|x64.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Release|x86.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|Any CPU.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|Any CPU.Build.0 = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|Win32.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|x64.ActiveCfg = Release|Any CPU + {65FC918C-FF12-4C75-96F5-180B552989E5}.Template|x86.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|Win32.ActiveCfg = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|x64.ActiveCfg = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Debug|x86.ActiveCfg = Debug|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|Any CPU.Build.0 = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|Win32.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|x64.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Release|x86.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|Any CPU.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|Any CPU.Build.0 = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|Win32.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|x64.ActiveCfg = Release|Any CPU + {854749E5-9264-42FF-A576-3B5784C7C14C}.Template|x86.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Win32.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|x64.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|x86.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Any CPU.Build.0 = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Win32.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|x64.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|x86.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|Any CPU.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|Any CPU.Build.0 = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|Win32.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|x64.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Template|x86.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|Win32.ActiveCfg = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|x64.ActiveCfg = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Debug|x86.ActiveCfg = Debug|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|Any CPU.Build.0 = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|Win32.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|x64.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Release|x86.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|Any CPU.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|Any CPU.Build.0 = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|Win32.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|x64.ActiveCfg = Release|Any CPU + {7ED3B518-7CEA-4991-98BD-9752E5F32F58}.Template|x86.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|Win32.ActiveCfg = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|x64.ActiveCfg = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Debug|x86.ActiveCfg = Debug|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|Any CPU.Build.0 = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|Win32.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|x64.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Release|x86.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|Any CPU.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|Any CPU.Build.0 = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|Win32.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|x64.ActiveCfg = Release|Any CPU + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8}.Template|x86.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|Win32.ActiveCfg = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|x64.ActiveCfg = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Debug|x86.ActiveCfg = Debug|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|Any CPU.Build.0 = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|Win32.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|x64.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Release|x86.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|Any CPU.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|Any CPU.Build.0 = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|Win32.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|x64.ActiveCfg = Release|Any CPU + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE}.Template|x86.ActiveCfg = Release|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|Any CPU.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|Any CPU.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|Win32.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|x64.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug FW 3.5|x86.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|Win32.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|x64.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Debug|x86.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|Any CPU.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|Any CPU.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|Mixed Platforms.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|Win32.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|x64.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.DebugMono|x86.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|Any CPU.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|Any CPU.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|Mixed Platforms.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|Win32.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|x64.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Release|x86.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|Any CPU.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|Any CPU.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|Mixed Platforms.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|Win32.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|x64.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.ReleaseMono|x86.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|Any CPU.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|Any CPU.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|Mixed Platforms.Build.0 = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|Win32.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|x64.ActiveCfg = Debug|Any CPU + {7DAA2EBB-A724-498F-93BB-68966E2B738F}.Template|x86.ActiveCfg = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|Win32.ActiveCfg = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|x64.ActiveCfg = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Debug|x86.ActiveCfg = Debug|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|Any CPU.Build.0 = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|Win32.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|x64.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Release|x86.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|Any CPU.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|Any CPU.Build.0 = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|Win32.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|x64.ActiveCfg = Release|Any CPU + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6}.Template|x86.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|Any CPU.Build.0 = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|Win32.ActiveCfg = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|x64.ActiveCfg = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Debug|x86.ActiveCfg = Debug|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|Any CPU.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|Any CPU.Build.0 = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|Win32.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|x64.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Release|x86.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|Any CPU.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|Any CPU.Build.0 = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|Win32.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|x64.ActiveCfg = Release|Any CPU + {711A3803-4395-4E92-9B26-DC8DDDF80366}.Template|x86.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|Win32.ActiveCfg = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|x64.ActiveCfg = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Debug|x86.ActiveCfg = Debug|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|Any CPU.Build.0 = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|Win32.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|x64.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Release|x86.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|Any CPU.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|Any CPU.Build.0 = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|Win32.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|x64.ActiveCfg = Release|Any CPU + {4EBBF9E9-53B2-493C-ABAB-E915C187558F}.Template|x86.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|Win32.ActiveCfg = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|x64.ActiveCfg = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Debug|x86.ActiveCfg = Debug|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|Any CPU.Build.0 = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|Win32.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|x64.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Release|x86.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|Any CPU.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|Any CPU.Build.0 = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|Win32.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|x64.ActiveCfg = Release|Any CPU + {34989C73-F82A-4905-9349-D0CF1419CD1C}.Template|x86.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|Any CPU.Build.0 = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|Win32.ActiveCfg = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|x64.ActiveCfg = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Debug|x86.ActiveCfg = Debug|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|Any CPU.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|Any CPU.Build.0 = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|Win32.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|x64.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Release|x86.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|Any CPU.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|Any CPU.Build.0 = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|Win32.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|x64.ActiveCfg = Release|Any CPU + {308A4189-53AB-460D-B2B1-0EB4B9219654}.Template|x86.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|Win32.ActiveCfg = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|x64.ActiveCfg = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Debug|x86.ActiveCfg = Debug|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|Any CPU.Build.0 = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|Win32.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|x64.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Release|x86.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|Any CPU.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|Any CPU.Build.0 = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|Win32.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|x64.ActiveCfg = Release|Any CPU + {8DA66999-005A-49AB-86A9-2C1F62905B50}.Template|x86.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|Win32.ActiveCfg = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|x64.ActiveCfg = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Debug|x86.ActiveCfg = Debug|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|Any CPU.Build.0 = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|Win32.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|x64.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Release|x86.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|Any CPU.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|Any CPU.Build.0 = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|Win32.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|x64.ActiveCfg = Release|Any CPU + {F2B014F7-3807-4938-8F02-3CF8247C47DC}.Template|x86.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|Win32.ActiveCfg = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|x64.ActiveCfg = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Debug|x86.ActiveCfg = Debug|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|Any CPU.Build.0 = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|Win32.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|x64.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Release|x86.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|Any CPU.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|Any CPU.Build.0 = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|Win32.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|x64.ActiveCfg = Release|Any CPU + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA}.Template|x86.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|Win32.ActiveCfg = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|x64.ActiveCfg = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Debug|x86.ActiveCfg = Debug|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|Any CPU.Build.0 = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|Win32.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|x64.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Release|x86.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|Any CPU.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|Any CPU.Build.0 = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|Win32.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|x64.ActiveCfg = Release|Any CPU + {6AE74A35-B337-4B17-8092-E1B98DEF06AF}.Template|x86.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|Any CPU.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|Any CPU.Build.0 = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|Win32.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|x64.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug FW 3.5|x86.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|Win32.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|x64.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Debug|x86.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|Any CPU.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|Any CPU.Build.0 = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|Mixed Platforms.Build.0 = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|Win32.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|x64.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.DebugMono|x86.ActiveCfg = Debug|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|Any CPU.Build.0 = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|Win32.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|x64.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Release|x86.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|Any CPU.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|Any CPU.Build.0 = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|Mixed Platforms.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|Mixed Platforms.Build.0 = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|Win32.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|x64.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.ReleaseMono|x86.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|Any CPU.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|Any CPU.Build.0 = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|Win32.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|x64.ActiveCfg = Release|Any CPU + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0}.Template|x86.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|x64.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|Win32.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|x64.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Debug|x86.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|Any CPU.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|Win32.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|x64.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Release|x86.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|Any CPU.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|Win32.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|x64.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC584}.Template|x86.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|Win32.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|x64.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|Win32.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|x64.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Debug|x86.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|Any CPU.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|Win32.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|x64.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Release|x86.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|Any CPU.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|Win32.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|x64.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC585}.Template|x86.ActiveCfg = ReleaseMono|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|Any CPU.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|Any CPU.Build.0 = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|Win32.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|x64.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug FW 3.5|x86.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|Win32.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|x64.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Debug|x86.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|Any CPU.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|Any CPU.Build.0 = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|Mixed Platforms.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|Mixed Platforms.Build.0 = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|Win32.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|x64.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.DebugMono|x86.ActiveCfg = Debug|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|Any CPU.Build.0 = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|Win32.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|x64.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Release|x86.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|Any CPU.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|Any CPU.Build.0 = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|Mixed Platforms.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|Mixed Platforms.Build.0 = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|Win32.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|x64.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.ReleaseMono|x86.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|Any CPU.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|Any CPU.Build.0 = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|Win32.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|x64.ActiveCfg = Release|Any CPU + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423}.Template|x86.ActiveCfg = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|Any CPU.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|Any CPU.Build.0 = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|Mixed Platforms.Build.0 = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|Win32.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|x64.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug FW 3.5|x86.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|Win32.ActiveCfg = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|x64.ActiveCfg = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Debug|x86.ActiveCfg = Debug|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|Win32.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|Any CPU.Build.0 = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|Win32.ActiveCfg = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|x64.ActiveCfg = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Release|x86.ActiveCfg = Release|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|Win32.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|Any CPU.Build.0 = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|Win32.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|x64.ActiveCfg = ReleaseMono|Any CPU + {785CE174-0A91-465F-9E41-65E6E05A0EC9}.Template|x86.ActiveCfg = ReleaseMono|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|Any CPU.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|Any CPU.Build.0 = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|Win32.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|x64.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug FW 3.5|x86.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|Win32.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|x64.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Debug|x86.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|Any CPU.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|Any CPU.Build.0 = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|Mixed Platforms.Build.0 = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|Win32.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|x64.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.DebugMono|x86.ActiveCfg = Debug|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|Any CPU.Build.0 = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|Win32.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|x64.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Release|x86.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|Any CPU.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|Any CPU.Build.0 = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|Mixed Platforms.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|Mixed Platforms.Build.0 = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|Win32.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|x64.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.ReleaseMono|x86.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|Any CPU.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|Any CPU.Build.0 = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|Win32.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|x64.ActiveCfg = Release|Any CPU + {CB303F0B-0AA3-4589-850A-95E985A09492}.Template|x86.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug FW 3.5|Any CPU.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug FW 3.5|Any CPU.Build.0 = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug FW 3.5|Win32.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug FW 3.5|x64.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug FW 3.5|x86.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug|x64.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Debug|x86.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.DebugMono|Any CPU.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.DebugMono|Any CPU.Build.0 = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.DebugMono|Mixed Platforms.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.DebugMono|Mixed Platforms.Build.0 = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.DebugMono|Win32.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.DebugMono|x64.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.DebugMono|x86.ActiveCfg = Debug|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Release|Any CPU.Build.0 = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Release|Win32.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Release|x64.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Release|x86.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.ReleaseMono|Any CPU.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.ReleaseMono|Any CPU.Build.0 = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.ReleaseMono|Mixed Platforms.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.ReleaseMono|Mixed Platforms.Build.0 = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.ReleaseMono|Win32.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.ReleaseMono|x64.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.ReleaseMono|x86.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Template|Any CPU.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Template|Any CPU.Build.0 = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Template|Win32.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Template|x64.ActiveCfg = Release|Any CPU + {527300F8-9F04-434C-8239-4FE5E174FF6B}.Template|x86.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug FW 3.5|Any CPU.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug FW 3.5|Any CPU.Build.0 = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug FW 3.5|Win32.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug FW 3.5|x64.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug FW 3.5|x86.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug|Win32.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug|x64.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Debug|x86.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.DebugMono|Any CPU.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.DebugMono|Any CPU.Build.0 = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.DebugMono|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.DebugMono|Mixed Platforms.Build.0 = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.DebugMono|Win32.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.DebugMono|x64.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.DebugMono|x86.ActiveCfg = Debug|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Release|Any CPU.Build.0 = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Release|Win32.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Release|x64.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Release|x86.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.ReleaseMono|Any CPU.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.ReleaseMono|Any CPU.Build.0 = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.ReleaseMono|Mixed Platforms.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.ReleaseMono|Mixed Platforms.Build.0 = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.ReleaseMono|Win32.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.ReleaseMono|x64.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.ReleaseMono|x86.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Template|Any CPU.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Template|Any CPU.Build.0 = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Template|Win32.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Template|x64.ActiveCfg = Release|Any CPU + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E}.Template|x86.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {D527524F-EC92-465E-9CAE-86278121675A} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {D11617AB-9F88-4C74-8ABD-F8580DB4B01B} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {07997A18-86D3-47AC-A514-AB1B03E6AEC8} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {4FDE7340-F60F-49BC-86CD-756CCD26C92A} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {2BB4AD77-190F-4D7E-A83E-7B254A0A1FCA} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {6AE74A35-B337-4B17-8092-E1B98DEF06AF} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {527300F8-9F04-434C-8239-4FE5E174FF6B} = {2CC0A340-512C-4F0D-A5E6-87C042EE13B9} + {6E0C5565-F9A3-441C-9CB2-8B1878A800EF} = {C0306556-68F4-4DD5-95F2-AAFEE8FACDFA} + {65FC918C-FF12-4C75-96F5-180B552989E5} = {C0306556-68F4-4DD5-95F2-AAFEE8FACDFA} + {F2B014F7-3807-4938-8F02-3CF8247C47DC} = {C0306556-68F4-4DD5-95F2-AAFEE8FACDFA} + {86BF4F10-3606-4016-9919-84C3335813B6} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {B1DEA25C-7667-471B-BBAD-64D017FDD104} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {5A556D57-0D68-433B-AD78-02849583582B} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {85E90F57-8DE1-4912-8414-28578F4D71CD} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {3E414663-B673-47A8-AB59-0E08FE43DA86} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {6CD8CC3D-643D-4D09-8660-A26085C44FBC} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {785CE174-0A91-465F-9E41-65E6E05A0EC9} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {CB303F0B-0AA3-4589-850A-95E985A09492} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E} = {E6CE0ECB-3373-4DC0-98CB-F4E9DC2293C4} + {83C0070F-E639-4D65-B392-34F621165A1C} = {B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D} + {0F3F166F-9927-4BC0-855F-ADB0D20218F1} = {B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D} + {35E61C2A-2B8C-4AF4-AD21-353936581EF5} = {B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D} + {9475B894-944A-47CF-855D-93A0C42136C9} = {B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D} + {FC77CB0E-4DBF-4CDF-A1AD-C6F830A849B0} = {B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D} + {2F6B63C4-295A-433C-91CB-CAE4CADE6B8B} = {B75C60BF-F5B7-472E-A0A8-8A12DDDDAA7D} + {28693777-369C-4C0D-B076-38F7C0E5D06C} = {83C0070F-E639-4D65-B392-34F621165A1C} + {E796EF23-D63D-4EBD-A34D-5F243834933B} = {83C0070F-E639-4D65-B392-34F621165A1C} + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7} = {0F3F166F-9927-4BC0-855F-ADB0D20218F1} + {16272F10-9E3D-4C24-8761-8A43E9FB525F} = {0F3F166F-9927-4BC0-855F-ADB0D20218F1} + {854749E5-9264-42FF-A576-3B5784C7C14C} = {35E61C2A-2B8C-4AF4-AD21-353936581EF5} + {57CE5505-44CB-42E4-A346-3471F68A5B60} = {9475B894-944A-47CF-855D-93A0C42136C9} + {7ED3B518-7CEA-4991-98BD-9752E5F32F58} = {9475B894-944A-47CF-855D-93A0C42136C9} + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8} = {FC77CB0E-4DBF-4CDF-A1AD-C6F830A849B0} + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE} = {FC77CB0E-4DBF-4CDF-A1AD-C6F830A849B0} + {7DAA2EBB-A724-498F-93BB-68966E2B738F} = {FC77CB0E-4DBF-4CDF-A1AD-C6F830A849B0} + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6} = {2F6B63C4-295A-433C-91CB-CAE4CADE6B8B} + {711A3803-4395-4E92-9B26-DC8DDDF80366} = {2F6B63C4-295A-433C-91CB-CAE4CADE6B8B} + {4EBBF9E9-53B2-493C-ABAB-E915C187558F} = {2F6B63C4-295A-433C-91CB-CAE4CADE6B8B} + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423} = {2F6B63C4-295A-433C-91CB-CAE4CADE6B8B} + {34989C73-F82A-4905-9349-D0CF1419CD1C} = {8A7F38C5-EF9A-410B-8539-A58879F3AA22} + {308A4189-53AB-460D-B2B1-0EB4B9219654} = {8A7F38C5-EF9A-410B-8539-A58879F3AA22} + {8DA66999-005A-49AB-86A9-2C1F62905B50} = {8A7F38C5-EF9A-410B-8539-A58879F3AA22} + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0} = {218E3584-CDC7-4A77-AD1A-CF9FBE90F67F} + EndGlobalSection +EndGlobal diff -r 000000000000 -r f990fcb411a9 Data/BLToolkitData.mdb Binary file Data/BLToolkitData.mdb has changed diff -r 000000000000 -r f990fcb411a9 Data/BLToolkitData.sqlite Binary file Data/BLToolkitData.sqlite has changed diff -r 000000000000 -r f990fcb411a9 Data/Create Scripts/Access.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Create Scripts/Access.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,281 @@ +DROP Procedure Person_SelectByKey +GO +DROP Procedure Person_SelectAll +GO +DROP Procedure Person_SelectByName +GO +DROP Procedure Person_SelectListByName +GO +DROP Procedure Person_Insert +GO +DROP Procedure Person_Update +GO +DROP Procedure Person_Delete +GO +DROP Procedure Patient_SelectAll +GO +DROP Procedure Patient_SelectByName +GO +DROP Procedure Scalar_DataReader +GO +DROP TABLE Dual +GO +DROP TABLE BinaryData +GO +DROP TABLE DataTypeTest +GO +DROP TABLE Doctor +GO +DROP TABLE Patient +GO +DROP TABLE Person +GO + +CREATE TABLE Person ( + PersonID Int IDENTITY, + FirstName Text(50) NOT NULL, + LastName Text(50) NOT NULL, + MiddleName Text(50), + Gender Text(1) NOT NULL, + + CONSTRAINT PK_Peson PRIMARY KEY (PersonID) +) +GO + +CREATE TABLE Doctor ( + PersonID Int NOT NULL, + Taxonomy Text(50) NOT NULL, + + CONSTRAINT OK_Doctor PRIMARY KEY (PersonID) +) +GO + +CREATE TABLE Patient ( + PersonID Int NOT NULL, + Diagnosis Text(255) NOT NULL, + + CONSTRAINT PK_Patient PRIMARY KEY (PersonID) +) +GO + +ALTER TABLE Doctor + ADD CONSTRAINT PersonDoctor FOREIGN KEY (PersonID) REFERENCES Person ON UPDATE CASCADE ON DELETE CASCADE; +GO + +ALTER TABLE Patient + ADD CONSTRAINT PersonPatient FOREIGN KEY (PersonID) REFERENCES Person ON UPDATE CASCADE ON DELETE CASCADE; +GO + +CREATE TABLE BinaryData ( + BinaryDataID AutoIncrement, + Data Image NOT NULL, + + CONSTRAINT PrimaryKey PRIMARY KEY (BinaryDataID) +); +GO + +CREATE TABLE DataTypeTest ( + DataTypeID AutoIncrement, + Binary_ Image, + Boolean_ Long, + Byte_ Byte DEFAULT 0, + Bytes_ Image, + Char_ Text(1), + DateTime_ DateTime, + Decimal_ Currency DEFAULT 0, + Double_ Double DEFAULT 0, + Guid_ Uniqueidentifier, + Int16_ SmallInt DEFAULT 0, + Int32_ Long DEFAULT 0, + Int64_ Long DEFAULT 0, + Money_ Currency DEFAULT 0, + SByte_ Byte DEFAULT 0, + Single_ Single DEFAULT 0, + Stream_ Image, + String_ Text(50) WITH COMP, + UInt16_ SmallInt DEFAULT 0, + UInt32_ Long DEFAULT 0, + UInt64_ Long DEFAULT 0, + Xml_ Text WITH COMP, + + CONSTRAINT PrimaryKey PRIMARY KEY (DataTypeID) +); +GO + +CREATE TABLE Dual (Dummy Text(10)); +GO + +INSERT INTO Person (FirstName, LastName, Gender) VALUES ("John", "Pupkin", "M") +GO +INSERT INTO Person (FirstName, LastName, Gender) VALUES ("Tester", "Testerson", "M") +GO +INSERT INTO Doctor (PersonID, Taxonomy) VALUES (1, "Psychiatry") +GO +INSERT INTO Patient (PersonID, Diagnosis) VALUES (2, "Hallucination with Paranoid Bugs' Delirium of Persecution") +GO + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, Xml_) +VALUES + ( NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL) +GO + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, + Xml_) +VALUES + (1, True, 255, 1, "B", Now(), 12345.67, + 1234.567, 1, 32767, 32768, 1000000, 12.3456, 127, + 1234.123, "12345678", "string", 32767, 32768, 2000000000, + "") +GO + +INSERT INTO Dual (Dummy) VALUES ('X') +GO + +CREATE Procedure Person_SelectByKey( + [@id] Long) +AS +SELECT * FROM Person WHERE PersonID = [@id]; +GO + +CREATE Procedure Person_SelectAll +AS +SELECT * FROM Person; +GO + +CREATE Procedure Person_SelectByName( + [@firstName] Text(50), + [@lastName] Text(50)) +AS +SELECT + * +FROM + Person +WHERE + FirstName = [@firstName] AND LastName = [@lastName]; +GO + +CREATE Procedure Person_SelectListByName( + [@firstName] Text(50), + [@lastName] Text(50)) +AS +SELECT + * +FROM + Person +WHERE + FirstName like [@firstName] AND LastName like [@lastName]; +GO + +CREATE Procedure Person_Insert( + [@FirstName] Text(50), + [@MiddleName] Text(50), + [@LastName] Text(50), + [@Gender] Text(1)) +AS +INSERT INTO Person + (FirstName, MiddleName, LastName, Gender) +VALUES + ([@FirstName], [@MiddleName], [@LastName], [@Gender]); +GO + +CREATE Procedure Person_Update( + [@id] Long, + [@PersonID] Long, + [@FirstName] Text(50), + [@MiddleName] Text(50), + [@LastName] Text(50), + [@Gender] Text(1)) +AS +UPDATE + Person +SET + LastName = [@LastName], + FirstName = [@FirstName], + MiddleName = [@MiddleName], + Gender = [@Gender] +WHERE + PersonID = [@id]; +GO + +CREATE Procedure Person_Delete( + [@PersonID] Long) +AS +DELETE FROM Person WHERE PersonID = [@PersonID]; +GO + +CREATE Procedure Patient_SelectAll +AS +SELECT + Person.*, Patient.Diagnosis +FROM + Patient, Person +WHERE + Patient.PersonID = Person.PersonID; +GO + +CREATE Procedure Patient_SelectByName( + [@firstName] Text(50), + [@lastName] Text(50)) +AS +SELECT + Person.*, Patient.Diagnosis +FROM + Patient, Person +WHERE + Patient.PersonID = Person.PersonID + AND FirstName = [@firstName] AND LastName = [@lastName]; +GO + +CREATE Procedure Scalar_DataReader +AS +SELECT 12345 AS intField, "54321" AS stringField; +GO + + +DROP TABLE Parent +GO +DROP TABLE Child +GO +DROP TABLE GrandChild +GO + +CREATE TABLE Parent (ParentID int, Value1 int NULL) +GO +CREATE TABLE Child (ParentID int, ChildID int) +GO +CREATE TABLE GrandChild (ParentID int, ChildID int, GrandChildID int) +GO +DROP TABLE LinqDataTypes +GO + +CREATE TABLE LinqDataTypes +( + ID int, + MoneyValue decimal(10,4), + DateTimeValue datetime, + DateTimeValue2 datetime, + BoolValue bit, + GuidValue uniqueidentifier, + BinaryValue OleObject NULL, + SmallIntValue smallint, + IntValue int NULL, + BigIntValue long NULL +) +GO + +DROP TABLE TestIdentity +GO + +CREATE TABLE TestIdentity ( + ID Int IDENTITY, + CONSTRAINT PK_TestIdentity PRIMARY KEY (ID) +) +GO diff -r 000000000000 -r f990fcb411a9 Data/Create Scripts/DB2.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Create Scripts/DB2.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,89 @@ +DROP TABLE "Doctor" +GO + +DROP TABLE "Patient" +GO + +DROP TABLE "Person" +GO + +CREATE TABLE "Person" +( + "PersonID" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY NOT NULL, + "FirstName" VARCHAR(50) NOT NULL, + "LastName" VARCHAR(50) NOT NULL, + "MiddleName" VARCHAR(50), + "Gender" CHAR(1) NOT NULL +) +GO + +INSERT INTO "Person" ("FirstName", "LastName", "Gender") VALUES ('John', 'Pupkin', 'M') +GO +INSERT INTO "Person" ("FirstName", "LastName", "Gender") VALUES ('Tester', 'Testerson', 'M') +GO + +-- Doctor Table Extension + +CREATE TABLE "Doctor" +( + "PersonID" INTEGER NOT NULL, + "Taxonomy" VARCHAR(50) NOT NULL +) +GO + +INSERT INTO "Doctor" ("PersonID", "Taxonomy") VALUES (1, 'Psychiatry') +GO + +-- Patient Table Extension + +CREATE TABLE "Patient" +( + "PersonID" INTEGER NOT NULL, + "Diagnosis" VARCHAR(256) NOT NULL +) +GO + +INSERT INTO "Patient" ("PersonID", "Diagnosis") VALUES (2, 'Hallucination with Paranoid Bugs'' Delirium of Persecution') +GO + + +DROP TABLE "Parent" +GO +DROP TABLE "Child" +GO +DROP TABLE "GrandChild" +GO + +CREATE TABLE "Parent" ("ParentID" int, "Value1" int) +GO +CREATE TABLE "Child" ("ParentID" int, "ChildID" int) +GO +CREATE TABLE "GrandChild" ("ParentID" int, "ChildID" int, "GrandChildID" int) +GO + + +DROP TABLE "LinqDataTypes" +GO + +CREATE TABLE "LinqDataTypes" +( + "ID" int, + "MoneyValue" decimal(10,4), + "DateTimeValue" timestamp, + "DateTimeValue2" timestamp NULL, + "BoolValue" smallint, + "GuidValue" char(16) for bit DATA, + "BinaryValue" blob(5000) NULL, + "SmallIntValue" smallint, + "IntValue" int NULL, + "BigIntValue" bigint NULL +) +GO + +DROP TABLE "TestIdentity" +GO + +CREATE TABLE "TestIdentity" ( + "ID" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY NOT NULL +) +GO diff -r 000000000000 -r f990fcb411a9 Data/Create Scripts/Firebird2.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Create Scripts/Firebird2.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,598 @@ +DROP PROCEDURE Person_SelectByKey; COMMIT; +DROP PROCEDURE Person_SelectAll; COMMIT; +DROP PROCEDURE Person_SelectByName; COMMIT; +DROP PROCEDURE Person_Insert; COMMIT; +DROP PROCEDURE Person_Insert_OutputParameter; COMMIT; +DROP PROCEDURE Person_Update; COMMIT; +DROP PROCEDURE Person_Delete; COMMIT; +DROP PROCEDURE Patient_SelectAll; COMMIT; +DROP PROCEDURE Patient_SelectByName; COMMIT; +DROP PROCEDURE OutRefTest; COMMIT; +DROP PROCEDURE OutRefEnumTest; COMMIT; +DROP PROCEDURE Scalar_DataReader; COMMIT; +DROP PROCEDURE Scalar_OutputParameter; COMMIT; +DROP PROCEDURE Scalar_ReturnParameter; COMMIT; + +DROP TRIGGER CREATE_BinaryDataID; COMMIT; +DROP TRIGGER CHANGE_BinaryData; COMMIT; +DROP TRIGGER CREATE_PersonID; COMMIT; +DROP TRIGGER CREATE_DataTypeTest; COMMIT; + +DROP GENERATOR DataTypeID; COMMIT; +DROP GENERATOR PersonID; COMMIT; +DROP GENERATOR TimestampGen; COMMIT; + +DROP VIEW PersonView; COMMIT; + +DROP TABLE Dual; COMMIT; +DROP TABLE DataTypeTest; COMMIT; +DROP TABLE BinaryData; COMMIT; +DROP TABLE Doctor; COMMIT; +DROP TABLE Patient; COMMIT; +DROP TABLE Person; COMMIT; + +DROP EXTERNAL FUNCTION rtrim; COMMIT; +DROP EXTERNAL FUNCTION ltrim; COMMIT; + + +DECLARE EXTERNAL FUNCTION ltrim + CSTRING(255) NULL + RETURNS CSTRING(255) FREE_IT + ENTRY_POINT 'IB_UDF_ltrim' MODULE_NAME 'ib_udf'; +COMMIT; + +DECLARE EXTERNAL FUNCTION rtrim + CSTRING(255) NULL + RETURNS CSTRING(255) FREE_IT + ENTRY_POINT 'IB_UDF_rtrim' MODULE_NAME 'ib_udf'; +COMMIT; + + +/* +Dual table FOR supporting queryies LIKE: +SELECT 1 AS id => SELECT 1 AS "id" *FROM Dual* +*/ +CREATE TABLE Dual (Dummy VARCHAR(10)); +COMMIT; +INSERT INTO Dual (Dummy) VALUES ('X'); +COMMIT; + +-- Person Table + +CREATE TABLE Person +( + PersonID INTEGER NOT NULL PRIMARY KEY, + FirstName VARCHAR(50) CHARACTER SET UNICODE_FSS NOT NULL, + LastName VARCHAR(50) CHARACTER SET UNICODE_FSS NOT NULL, + MiddleName VARCHAR(50), + Gender CHAR(1) NOT NULL CHECK (Gender in ('M', 'F', 'U', 'O')) +); +COMMIT; + +CREATE GENERATOR PersonID; +COMMIT; + +CREATE GENERATOR TimestampGen; +COMMIT; + +CREATE TRIGGER CREATE_PersonID FOR Person +BEFORE INSERT POSITION 0 +AS BEGIN + NEW.PersonID = GEN_ID(PersonID, 1); +END +COMMIT; + +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('John', 'Pupkin', 'M'); +COMMIT; +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('Tester', 'Testerson', 'M'); +COMMIT; + +-- Doctor Table Extension + +CREATE TABLE Doctor +( + PersonID INTEGER NOT NULL, + Taxonomy VARCHAR(50) NOT NULL, + FOREIGN KEY (PersonID) REFERENCES Person (PersonID) + ON DELETE CASCADE +) +COMMIT; + +INSERT INTO Doctor (PersonID, Taxonomy) VALUES (1, 'Psychiatry'); +COMMIT; + +-- Patient Table Extension + +CREATE TABLE Patient +( + PersonID int NOT NULL, + Diagnosis VARCHAR(256) NOT NULL, + FOREIGN KEY (PersonID) REFERENCES Person (PersonID) + ON DELETE CASCADE +); +COMMIT; + +INSERT INTO Patient (PersonID, Diagnosis) VALUES (2, 'Hallucination with Paranoid Bugs'' Delirium of Persecution'); +COMMIT; + +-- Person_SelectByKey + +CREATE PROCEDURE Person_SelectByKey(id INTEGER) +RETURNS ( + PersonID INTEGER, + FirstName VARCHAR(50), + LastName VARCHAR(50), + MiddleName VARCHAR(50), + Gender CHAR(1) + ) +AS +BEGIN + SELECT PersonID, FirstName, LastName, MiddleName, Gender FROM Person + WHERE PersonID = :id + INTO + :PersonID, + :FirstName, + :LastName, + :MiddleName, + :Gender; + SUSPEND; +END +COMMIT; + +-- Person_SelectAll + +CREATE PROCEDURE Person_SelectAll +RETURNS ( + PersonID INTEGER, + FirstName VARCHAR(50), + LastName VARCHAR(50), + MiddleName VARCHAR(50), + Gender CHAR(1) + ) +AS +BEGIN + FOR + SELECT PersonID, FirstName, LastName, MiddleName, Gender FROM Person + INTO + :PersonID, + :FirstName, + :LastName, + :MiddleName, + :Gender + DO SUSPEND; +END +COMMIT; + +-- Person_SelectByName + +CREATE PROCEDURE Person_SelectByName ( + in_FirstName VARCHAR(50), + in_LastName VARCHAR(50) + ) +RETURNS ( + PersonID int, + FirstName VARCHAR(50), + LastName VARCHAR(50), + MiddleName VARCHAR(50), + Gender CHAR(1) + ) +AS +BEGIN + + FOR SELECT PersonID, FirstName, LastName, MiddleName, Gender FROM Person + WHERE FirstName LIKE :in_FirstName and LastName LIKE :in_LastName + INTO + :PersonID, + :FirstName, + :LastName, + :MiddleName, + :Gender + DO SUSPEND; +END +COMMIT; + +-- Person_Insert + +CREATE PROCEDURE Person_Insert( + FirstName VARCHAR(50), + LastName VARCHAR(50), + MiddleName VARCHAR(50), + Gender CHAR(1) + ) +RETURNS (PersonID INTEGER) +AS +BEGIN + INSERT INTO Person + ( LastName, FirstName, MiddleName, Gender) + VALUES + (:LastName, :FirstName, :MiddleName, :Gender); + + SELECT MAX(PersonID) FROM person + INTO :PersonID; + SUSPEND; +END +COMMIT; + +-- Person_Insert_OutputParameter + +CREATE PROCEDURE Person_Insert_OutputParameter( + FirstName VARCHAR(50), + LastName VARCHAR(50), + MiddleName VARCHAR(50), + Gender CHAR(1) + ) +RETURNS (PersonID INTEGER) +AS +BEGIN + INSERT INTO Person + ( LastName, FirstName, MiddleName, Gender) + VALUES + (:LastName, :FirstName, :MiddleName, :Gender); + + SELECT max(PersonID) FROM person + INTO :PersonID; + SUSPEND; +END +COMMIT; + +-- Person_Update + +CREATE PROCEDURE Person_Update( + PersonID INTEGER, + FirstName VARCHAR(50), + LastName VARCHAR(50), + MiddleName VARCHAR(50), + Gender CHAR(1) + ) +AS +BEGIN + UPDATE + Person + SET + LastName = :LastName, + FirstName = :FirstName, + MiddleName = :MiddleName, + Gender = :Gender + WHERE + PersonID = :PersonID; +END +COMMIT; + +-- Person_Delete + +CREATE PROCEDURE Person_Delete( + PersonID INTEGER + ) +AS +BEGIN + DELETE FROM Person WHERE PersonID = :PersonID; +END +COMMIT; + +-- Patient_SelectAll + +CREATE PROCEDURE Patient_SelectAll +RETURNS ( + PersonID int, + FirstName VARCHAR(50), + LastName VARCHAR(50), + MiddleName VARCHAR(50), + Gender CHAR(1), + Diagnosis VARCHAR(256) + ) +AS +BEGIN + FOR + SELECT + Person.PersonID, + FirstName, + LastName, + MiddleName, + Gender, + Patient.Diagnosis + FROM + Patient, Person + WHERE + Patient.PersonID = Person.PersonID + INTO + :PersonID, + :FirstName, + :LastName, + :MiddleName, + :Gender, + :Diagnosis + DO SUSPEND; +END +COMMIT; + +-- Patient_SelectByName + +CREATE PROCEDURE Patient_SelectByName( + FirstName VARCHAR(50), + LastName VARCHAR(50) + ) +RETURNS ( + PersonID int, + MiddleName VARCHAR(50), + Gender CHAR(1), + Diagnosis VARCHAR(256) + ) +AS +BEGIN + FOR + SELECT + Person.PersonID, + MiddleName, + Gender, + Patient.Diagnosis + FROM + Patient, Person + WHERE + Patient.PersonID = Person.PersonID + and FirstName = :FirstName and LastName = :LastName + INTO + :PersonID, + :MiddleName, + :Gender, + :Diagnosis + DO SUSPEND; +END +COMMIT; + +-- BinaryData Table + +CREATE TABLE BinaryData +( + BinaryDataID INTEGER NOT NULL PRIMARY KEY, + Stamp INTEGER NOT NULL, + Data BLOB NOT NULL +); +COMMIT; + +CREATE TRIGGER CREATE_BinaryDataID FOR BinaryData +BEFORE INSERT POSITION 0 +AS BEGIN + NEW.BinaryDataID = GEN_ID(PersonID, 1); + NEW.Stamp = GEN_ID(TimestampGen, 1); +END +COMMIT; + +CREATE TRIGGER CHANGE_BinaryData FOR BinaryData +beFORe update +AS BEGIN + NEW.Stamp = GEN_ID(TimestampGen, 1); +END +COMMIT; + +-- OutRefTest + +/* +Fake input parameters are used to "emulate" input/output parameters. +Each inout parameter should be defined in RETURNS(...) section +and allso have a "mirror" in input section, mirror name shoul be: +FdpDataProvider.InOutInputParameterPrefix + [parameter name] +ex: +in_inputOutputID is input mirror FOR inout parameter inputOutputID +*/ +CREATE PROCEDURE OutRefTest( + ID INTEGER, + in_inputOutputID INTEGER, + str VARCHAR(50), + in_inputOutputStr VARCHAR(50) + ) +RETURNS( + inputOutputID INTEGER, + inputOutputStr VARCHAR(50), + outputID INTEGER, + outputStr VARCHAR(50) + ) +AS +BEGIN + outputID = ID; + inputOutputID = ID + in_inputOutputID; + outputStr = str; + inputOutputStr = str || in_inputOutputStr; + SUSPEND; +END +COMMIT; + +-- OutRefEnumTest + +CREATE PROCEDURE OutRefEnumTest( + str VARCHAR(50), + in_inputOutputStr VARCHAR(50) + ) +RETURNS ( + inputOutputStr VARCHAR(50), + outputStr VARCHAR(50) + ) +AS +BEGIN + outputStr = str; + inputOutputStr = str || in_inputOutputStr; + SUSPEND; +END +COMMIT; + +-- ExecuteScalarTest + +CREATE PROCEDURE Scalar_DataReader +RETURNS( + intField INTEGER, + stringField VARCHAR(50) + ) +AS +BEGIN + intField = 12345; + stringField = '54321'; + SUSPEND; +END +COMMIT; + +CREATE PROCEDURE Scalar_OutputParameter +RETURNS ( + outputInt INTEGER, + outputString VARCHAR(50) + ) +AS +BEGIN + outputInt = 12345; + outputString = '54321'; + SUSPEND; +END +COMMIT; + +/* +"Return_Value" is the name for ReturnValue "emulating" +may be changed: FdpDataProvider.ReturnParameterName +*/ +CREATE PROCEDURE Scalar_ReturnParameter +RETURNS (Return_Value INTEGER) +AS +BEGIN + Return_Value = 12345; + SUSPEND; +END +COMMIT; + +-- Data Types test + +/* +Data definitions according to: +http://www.firebirdsql.org/manual/migration-mssql-data-types.html + +BUT! BLOB is ised for BINARY data! not CHAR +*/ + +CREATE TABLE DataTypeTest +( + DataTypeID INTEGER NOT NULL PRIMARY KEY, + Binary_ BLOB, + Boolean_ CHAR(1), + Byte_ SMALLINT, + Bytes_ BLOB, + CHAR_ CHAR(1), + DateTime_ TIMESTAMP, + Decimal_ DECIMAL(10, 2), + Double_ DOUBLE PRECISION, + Guid_ CHAR(38), + Int16_ SMALLINT, + Int32_ INTEGER, + Int64_ NUMERIC(11), + Money_ DECIMAL(18, 4), + SByte_ SMALLINT, + Single_ FLOAT, + Stream_ BLOB, + String_ VARCHAR(50) CHARACTER SET UNICODE_FSS, + UInt16_ SMALLINT, + UInt32_ INTEGER, + UInt64_ NUMERIC(11), + Xml_ CHAR(1000) +) +COMMIT; + +CREATE GENERATOR DataTypeID; +COMMIT; + +CREATE TRIGGER CREATE_DataTypeTest FOR DataTypeTest +BEFORE INSERT POSITION 0 +AS BEGIN + NEW.DataTypeID = GEN_ID(DataTypeID, 1); +END +COMMIT; + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, CHAR_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, Xml_) +VALUES + ( NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL); +COMMIT; + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, CHAR_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, + Xml_) +VALUES + ('dddddddddddddddd', 1, 255,'dddddddddddddddd', 'B', 'NOW', 12345.67, + 1234.567, 'dddddddddddddddddddddddddddddddd', 32767, 32768, 1000000, 12.3456, 127, + 1234.123, 'dddddddddddddddd', 'string', 32767, 32768, 200000000, + ''); +COMMIT; + + + +DROP TABLE Parent COMMIT; +DROP TABLE Child COMMIT; +DROP TABLE GrandChild COMMIT; + +CREATE TABLE Parent (ParentID int, Value1 int) COMMIT; +CREATE TABLE Child (ParentID int, ChildID int) COMMIT; +CREATE TABLE GrandChild (ParentID int, ChildID int, GrandChildID int) COMMIT; + + +DROP TABLE LinqDataTypes COMMIT; + +CREATE TABLE LinqDataTypes +( + ID int, + MoneyValue decimal(10,4), + DateTimeValue timestamp, + DateTimeValue2 timestamp, + BoolValue char(1), + GuidValue char(38), + BinaryValue blob, + SmallIntValue smallint, + IntValue int, + BigIntValue bigint +) +COMMIT; + +DROP GENERATOR SequenceTestSeq +COMMIT; + +CREATE GENERATOR SequenceTestSeq +COMMIT; + +DROP TABLE SequenceTest COMMIT; + +CREATE TABLE SequenceTest +( + ID int NOT NULL PRIMARY KEY, + Value_ VARCHAR(50) NOT NULL +) +COMMIT; + + +DROP TRIGGER CREATE_ID +COMMIT; + +DROP GENERATOR TestIdentityID +COMMIT; + +DROP TABLE TestIdentity +COMMIT; + +CREATE TABLE TestIdentity ( + ID INTEGER NOT NULL PRIMARY KEY +) +COMMIT; + +CREATE GENERATOR TestIdentityID; +COMMIT; + +CREATE TRIGGER CREATE_ID FOR TestIdentity +BEFORE INSERT POSITION 0 +AS BEGIN + NEW.ID = GEN_ID(TestIdentityID, 1); +END +COMMIT; + + +CREATE VIEW PersonView +AS + SELECT * FROM Person +COMMIT; diff -r 000000000000 -r f990fcb411a9 Data/Create Scripts/Informix.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Create Scripts/Informix.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,92 @@ +DROP TABLE Doctor +GO + +DROP TABLE Patient +GO + +DROP TABLE Person +GO + +CREATE TABLE Person +( + PersonID SERIAL NOT NULL, + FirstName NVARCHAR(50) NOT NULL, + LastName NVARCHAR(50) NOT NULL, + MiddleName NVARCHAR(50), + Gender CHAR(1) NOT NULL, + + PRIMARY KEY(PersonID) +) +GO + +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('John', 'Pupkin', 'M') +GO +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('Tester', 'Testerson', 'M') +GO + +-- Doctor Table Extension + +CREATE TABLE Doctor +( + PersonID int NOT NULL, + Taxonomy nvarchar(50) NOT NULL +) +GO + +INSERT INTO Doctor (PersonID, Taxonomy) VALUES (1, 'Psychiatry') +GO + +-- Patient Table Extension + +CREATE TABLE Patient +( + PersonID int NOT NULL, + Diagnosis nvarchar(100) NOT NULL +) +GO + +INSERT INTO Patient (PersonID, Diagnosis) VALUES (2, 'Hallucination with Paranoid Bugs'' Delirium of Persecution') +GO + + +DROP TABLE Parent +GO +DROP TABLE Child +GO +DROP TABLE GrandChild +GO + +CREATE TABLE Parent (ParentID int, Value1 int) +GO +CREATE TABLE Child (ParentID int, ChildID int) +GO +CREATE TABLE GrandChild (ParentID int, ChildID int, GrandChildID int) +GO + + +DROP TABLE LinqDataTypes +GO + +CREATE TABLE LinqDataTypes +( + ID int, + MoneyValue decimal(10,4), + DateTimeValue datetime year to fraction(3), + DateTimeValue2 datetime year to fraction(3), + BoolValue boolean, + GuidValue char(36), + BinaryValue byte, + SmallIntValue smallint, + IntValue int, + BigIntValue bigint +) +GO + +DROP TABLE TestIdentity +GO + +CREATE TABLE TestIdentity ( + ID SERIAL NOT NULL, + PRIMARY KEY(ID) +) +GO diff -r 000000000000 -r f990fcb411a9 Data/Create Scripts/MsSql.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Create Scripts/MsSql.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,555 @@ +--CREATE DATABASE BLToolkitData ON PRIMARY +--(NAME=N'BLToolkitTest', FILENAME=N'C:\Data\MSSQL.1\MSSQL\DATA\BLToolkitData.mdf', SIZE=3072KB, FILEGROWTH=1024KB) +--LOG ON +--(NAME=N'BLToolkitTest_log', FILENAME=N'C:\Data\MSSQL.1\MSSQL\DATA\BLToolkitData_log.ldf', SIZE=1024KB, FILEGROWTH=10%) +--GO + +IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('Doctor') AND type in (N'U')) +BEGIN DROP TABLE Doctor END + +IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('Patient') AND type in (N'U')) +BEGIN DROP TABLE Patient END + +-- Person Table + +IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('Person') AND type in (N'U')) +BEGIN DROP TABLE Person END + +CREATE TABLE Person +( + PersonID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_Person PRIMARY KEY CLUSTERED, + FirstName nvarchar(50) NOT NULL, + LastName nvarchar(50) NOT NULL, + MiddleName nvarchar(50) NULL, + Gender char(1) NOT NULL CONSTRAINT CK_Person_Gender CHECK (Gender in ('M', 'F', 'U', 'O')) +) +ON [PRIMARY] +GO + +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('John', 'Pupkin', 'M') +GO +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('Tester', 'Testerson', 'M') +GO + +-- Doctor Table Extension + +CREATE TABLE Doctor +( + PersonID int NOT NULL + CONSTRAINT PK_Doctor PRIMARY KEY CLUSTERED + CONSTRAINT FK_Doctor_Person FOREIGN KEY + REFERENCES Person ([PersonID]) + ON UPDATE CASCADE + ON DELETE CASCADE, + Taxonomy nvarchar(50) NOT NULL +) +ON [PRIMARY] +GO + +INSERT INTO Doctor (PersonID, Taxonomy) VALUES (1, 'Psychiatry') +GO + +-- Patient Table Extension + +CREATE TABLE Patient +( + PersonID int NOT NULL + CONSTRAINT PK_Patient PRIMARY KEY CLUSTERED + CONSTRAINT FK_Patient_Person FOREIGN KEY + REFERENCES Person ([PersonID]) + ON UPDATE CASCADE + ON DELETE CASCADE, + Diagnosis nvarchar(256) NOT NULL +) +ON [PRIMARY] +GO + +INSERT INTO Patient (PersonID, Diagnosis) VALUES (2, 'Hallucination with Paranoid Bugs'' Delirium of Persecution') +GO + +-- Person_SelectByKey + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Person_SelectByKey') +BEGIN DROP Procedure Person_SelectByKey +END +GO + +CREATE Procedure Person_SelectByKey + @id int +AS + +SELECT * FROM Person WHERE PersonID = @id + +GO + +GRANT EXEC ON Person_SelectByKey TO PUBLIC +GO + +-- Person_SelectAll + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Person_SelectAll') +BEGIN DROP Procedure Person_SelectAll END +GO + +CREATE Procedure Person_SelectAll +AS + +SELECT * FROM Person + +GO + +GRANT EXEC ON Person_SelectAll TO PUBLIC +GO + +-- Person_SelectByName + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Person_SelectByName') +BEGIN DROP Procedure Person_SelectByName END +GO + +CREATE Procedure Person_SelectByName + @firstName nvarchar(50), + @lastName nvarchar(50) +AS + +SELECT + * +FROM + Person +WHERE + FirstName = @firstName AND LastName = @lastName + +GO + +GRANT EXEC ON Person_SelectByName TO PUBLIC +GO + +-- Person_SelectListByName + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Person_SelectListByName') +BEGIN DROP Procedure Person_SelectListByName +END +GO + +CREATE Procedure Person_SelectListByName + @firstName nvarchar(50), + @lastName nvarchar(50) +AS + +SELECT + * +FROM + Person +WHERE + FirstName like @firstName AND LastName like @lastName + +GO + +GRANT EXEC ON Person_SelectByName TO PUBLIC +GO + +-- Person_Insert + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Person_Insert') +BEGIN DROP Procedure Person_Insert END +GO + +CREATE Procedure Person_Insert + @FirstName nvarchar(50), + @LastName nvarchar(50), + @MiddleName nvarchar(50), + @Gender char(1) +AS + +INSERT INTO Person + ( LastName, FirstName, MiddleName, Gender) +VALUES + (@LastName, @FirstName, @MiddleName, @Gender) + +SELECT Cast(SCOPE_IDENTITY() as int) PersonID + +GO + +GRANT EXEC ON Person_Insert TO PUBLIC +GO + +-- Person_Insert_OutputParameter + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Person_Insert_OutputParameter') +BEGIN DROP Procedure Person_Insert_OutputParameter END +GO + +CREATE Procedure Person_Insert_OutputParameter + @FirstName nvarchar(50), + @LastName nvarchar(50), + @MiddleName nvarchar(50), + @Gender char(1), + @PersonID int output +AS + +INSERT INTO Person + ( LastName, FirstName, MiddleName, Gender) +VALUES + (@LastName, @FirstName, @MiddleName, @Gender) + +SET @PersonID = Cast(SCOPE_IDENTITY() as int) + +GO + +GRANT EXEC ON Person_Insert_OutputParameter TO PUBLIC +GO + +-- Person_Update + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Person_Update') +BEGIN DROP Procedure Person_Update END +GO + +CREATE Procedure Person_Update + @PersonID int, + @FirstName nvarchar(50), + @LastName nvarchar(50), + @MiddleName nvarchar(50), + @Gender char(1) +AS + +UPDATE + Person +SET + LastName = @LastName, + FirstName = @FirstName, + MiddleName = @MiddleName, + Gender = @Gender +WHERE + PersonID = @PersonID + +GO + +GRANT EXEC ON Person_Update TO PUBLIC +GO + +-- Person_Delete + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Person_Delete') +BEGIN DROP Procedure Person_Delete END +GO + +CREATE Procedure Person_Delete + @PersonID int +AS + +DELETE FROM Person WHERE PersonID = @PersonID + +GO + +GRANT EXEC ON Person_Delete TO PUBLIC +GO + +-- Patient_SelectAll + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Patient_SelectAll') +BEGIN DROP Procedure Patient_SelectAll END +GO + +CREATE Procedure Patient_SelectAll +AS + +SELECT + Person.*, Patient.Diagnosis +FROM + Patient, Person +WHERE + Patient.PersonID = Person.PersonID + +GO + +GRANT EXEC ON Patient_SelectAll TO PUBLIC +GO + +-- Patient_SelectByName + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Patient_SelectByName') +BEGIN DROP Procedure Patient_SelectByName END +GO + +CREATE Procedure Patient_SelectByName + @firstName nvarchar(50), + @lastName nvarchar(50) +AS + +SELECT + Person.*, Patient.Diagnosis +FROM + Patient, Person +WHERE + Patient.PersonID = Person.PersonID + AND FirstName = @firstName AND LastName = @lastName + +GO + +GRANT EXEC ON Person_SelectByName TO PUBLIC +GO + +-- BinaryData Table + +IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('BinaryData') AND type in (N'U')) +BEGIN DROP TABLE BinaryData END + +CREATE TABLE BinaryData +( + BinaryDataID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_BinaryData PRIMARY KEY CLUSTERED, + Stamp timestamp NOT NULL, + Data varbinary(1024) NOT NULL) +ON [PRIMARY] +GO + +-- OutRefTest + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'OutRefTest') +BEGIN DROP Procedure OutRefTest END +GO + +CREATE Procedure OutRefTest + @ID int, + @outputID int output, + @inputOutputID int output, + @str varchar(50), + @outputStr varchar(50) output, + @inputOutputStr varchar(50) output +AS + +SET @outputID = @ID +SET @inputOutputID = @ID + @inputOutputID +SET @outputStr = @str +SET @inputOutputStr = @str + @inputOutputStr + +GO + +-- OutRefEnumTest + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'OutRefEnumTest') +BEGIN DROP Procedure OutRefEnumTest END +GO + +CREATE Procedure OutRefEnumTest + @str varchar(50), + @outputStr varchar(50) output, + @inputOutputStr varchar(50) output +AS + +SET @outputStr = @str +SET @inputOutputStr = @str + @inputOutputStr + +GO + +-- ExecuteScalarTest + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Scalar_DataReader') +BEGIN DROP Procedure Scalar_DataReader END +GO + +CREATE Procedure Scalar_DataReader +AS +SELECT Cast(12345 as int) AS intField, Cast('54321' as varchar(50)) AS stringField + +GO + +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Scalar_OutputParameter') +BEGIN DROP Procedure Scalar_OutputParameter END +GO + +CREATE Procedure Scalar_OutputParameter + @outputInt int = 0 output, + @outputString varchar(50) = '' output +AS +BEGIN + SET @outputInt = 12345 + SET @outputString = '54321' +END + +GO + +IF EXISTS (SELECT * FROM sys.objects WHERE type in (N'FN', N'IF', N'TF', N'FS', N'FT') AND name = 'Scalar_ReturnParameter') +BEGIN DROP Function Scalar_ReturnParameter END +GO + +CREATE Function Scalar_ReturnParameter() +RETURNS int +AS +BEGIN + RETURN 12345 +END + +GO + +IF EXISTS (SELECT * FROM sys.objects WHERE type ='P' AND name = 'Scalar_ReturnParameterWithObject') +BEGIN DROP Procedure Scalar_ReturnParameterWithObject END +GO + +CREATE Procedure Scalar_ReturnParameterWithObject + @id int +AS +BEGIN + SELECT * FROM Person WHERE PersonID = @id + RETURN @id +END + +GO + +-- Data Types test + +IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('DataTypeTest') AND type in (N'U')) +BEGIN DROP TABLE DataTypeTest END +GO + +CREATE TABLE DataTypeTest +( + DataTypeID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_DataType PRIMARY KEY CLUSTERED, + Binary_ binary(50) NULL, + Boolean_ bit NULL, + Byte_ tinyint NULL, + Bytes_ varbinary(50) NULL, + Char_ char(1) NULL, + DateTime_ datetime NULL, + Decimal_ decimal(20,2) NULL, + Double_ float NULL, + Guid_ uniqueidentifier NULL, + Int16_ smallint NULL, + Int32_ int NULL, + Int64_ bigint NULL, + Money_ money NULL, + SByte_ tinyint NULL, + Single_ real NULL, + Stream_ varbinary(50) NULL, + String_ nvarchar(50) NULL, + UInt16_ smallint NULL, + UInt32_ int NULL, + UInt64_ bigint NULL, + Xml_ xml NULL +) ON [PRIMARY] +GO + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, Xml_) +VALUES + ( NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL) +GO + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, + Xml_) +VALUES + (NewID(), 1, 255, NewID(), 'B', GetDate(), 12345.67, + 1234.567, NewID(), 32767, 32768, 1000000, 12.3456, 127, + 1234.123, NewID(), 'string', 32767, 32768, 200000000, + '') +GO + +-- SKIP Sql2005 BEGIN +-- +-- Arrays +-- +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'ArrayTest') +BEGIN DROP PROCEDURE ArrayTest END +GO + +--IF EXISTS (SELECT * FROM sys.objects WHERE type = 'T' AND name = 'IntArray') +--BEGIN + DROP TYPE IntArray +--END +GO + +CREATE TYPE IntArray AS TABLE +( + Num int NULL +) +GO + +CREATE PROCEDURE ArrayTest + @InputIntArray IntArray READONLY +AS +BEGIN + SELECT Num * 2 FROM @InputIntArray; +END +GO +-- SKIP Sql2005 END + +DROP FUNCTION GetParentByID +GO + +DROP TABLE Parent +GO +DROP TABLE Child +GO +DROP TABLE GrandChild +GO + +CREATE TABLE Parent (ParentID int, Value1 int) +GO +CREATE TABLE Child (ParentID int, ChildID int) +GO +CREATE TABLE GrandChild (ParentID int, ChildID int, GrandChildID int) +GO + +CREATE FUNCTION GetParentByID(@id int) +RETURNS TABLE +AS +RETURN +( + SELECT * FROM Parent WHERE ParentID = @id +) +GO + +IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('LinqDataTypes') AND type in (N'U')) +BEGIN DROP TABLE LinqDataTypes END +GO + +-- SKIP Sql2005 BEGIN +CREATE TABLE LinqDataTypes +( + ID int, + MoneyValue decimal(10,4), + DateTimeValue datetime, + DateTimeValue2 datetime2, + BoolValue bit, + GuidValue uniqueidentifier, + BinaryValue varbinary(5000), + SmallIntValue smallint, + IntValue int NULL, + BigIntValue bigint NULL +) +GO +-- SKIP Sql2005 END + +-- SKIP Sql2008 BEGIN +-- SKIP Sql2012 BEGIN +CREATE TABLE LinqDataTypes +( + ID int, + MoneyValue decimal(10,4), + DateTimeValue datetime, + DateTimeValue2 datetime, + BoolValue bit, + GuidValue uniqueidentifier, + BinaryValue varbinary(5000) NULL, + SmallIntValue smallint, + IntValue int NULL, + BigIntValue bigint NULL +) +GO +-- SKIP Sql2012 END +-- SKIP Sql2008 END + +DROP TABLE TestIdentity +GO + +CREATE TABLE TestIdentity ( + ID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_TestIdentity PRIMARY KEY CLUSTERED +) +GO diff -r 000000000000 -r f990fcb411a9 Data/Create Scripts/MsSql2000.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Create Scripts/MsSql2000.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,472 @@ +DROP TABLE Doctor +DROP TABLE Patient +DROP TABLE Person + +CREATE TABLE Person +( + PersonID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_Person PRIMARY KEY CLUSTERED, + FirstName nvarchar(50) NOT NULL, + LastName nvarchar(50) NOT NULL, + MiddleName nvarchar(50) NULL, + Gender char(1) NOT NULL CONSTRAINT CK_Person_Gender CHECK (Gender in ('M', 'F', 'U', 'O')) +) +ON [PRIMARY] +GO + +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('John', 'Pupkin', 'M') +GO +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('Tester', 'Testerson', 'M') +GO + +-- Doctor Table Extension + +CREATE TABLE Doctor +( + PersonID int NOT NULL + CONSTRAINT PK_Doctor PRIMARY KEY CLUSTERED + CONSTRAINT FK_Doctor_Person FOREIGN KEY + REFERENCES Person ([PersonID]) + ON UPDATE CASCADE + ON DELETE CASCADE, + Taxonomy nvarchar(50) NOT NULL +) +ON [PRIMARY] +GO + +INSERT INTO Doctor (PersonID, Taxonomy) VALUES (1, 'Psychiatry') +GO + +-- Patient Table Extension + +CREATE TABLE Patient +( + PersonID int NOT NULL + CONSTRAINT PK_Patient PRIMARY KEY CLUSTERED + CONSTRAINT FK_Patient_Person FOREIGN KEY + REFERENCES Person ([PersonID]) + ON UPDATE CASCADE + ON DELETE CASCADE, + Diagnosis nvarchar(256) NOT NULL +) +ON [PRIMARY] +GO + +INSERT INTO Patient (PersonID, Diagnosis) VALUES (2, 'Hallucination with Paranoid Bugs'' Delirium of Persecution') +GO + +-- Person_SelectByKey + +DROP Procedure Person_SelectByKey +GO + +CREATE Procedure Person_SelectByKey + @id int +AS + +SELECT * FROM Person WHERE PersonID = @id + +GO + +GRANT EXEC ON Person_SelectByKey TO PUBLIC +GO + +-- Person_SelectAll + +DROP Procedure Person_SelectAll +GO + +CREATE Procedure Person_SelectAll +AS + +SELECT * FROM Person + +GO + +GRANT EXEC ON Person_SelectAll TO PUBLIC +GO + +-- Person_SelectByName + +DROP Procedure Person_SelectByName +GO + +CREATE Procedure Person_SelectByName + @firstName nvarchar(50), + @lastName nvarchar(50) +AS + +SELECT + * +FROM + Person +WHERE + FirstName = @firstName AND LastName = @lastName + +GO + +GRANT EXEC ON Person_SelectByName TO PUBLIC +GO + +-- Person_SelectListByName + +DROP Procedure Person_SelectListByName +GO + +CREATE Procedure Person_SelectListByName + @firstName nvarchar(50), + @lastName nvarchar(50) +AS + +SELECT + * +FROM + Person +WHERE + FirstName like @firstName AND LastName like @lastName + +GO + +GRANT EXEC ON Person_SelectByName TO PUBLIC +GO + +-- Person_Insert + +DROP Procedure Person_Insert +GO + +CREATE Procedure Person_Insert + @FirstName nvarchar(50), + @LastName nvarchar(50), + @MiddleName nvarchar(50), + @Gender char(1) +AS + +INSERT INTO Person + ( LastName, FirstName, MiddleName, Gender) +VALUES + (@LastName, @FirstName, @MiddleName, @Gender) + +SELECT Cast(SCOPE_IDENTITY() as int) PersonID + +GO + +GRANT EXEC ON Person_Insert TO PUBLIC +GO + +-- Person_Insert_OutputParameter + +DROP Procedure Person_Insert_OutputParameter +GO + +CREATE Procedure Person_Insert_OutputParameter + @FirstName nvarchar(50), + @LastName nvarchar(50), + @MiddleName nvarchar(50), + @Gender char(1), + @PersonID int output +AS + +INSERT INTO Person + ( LastName, FirstName, MiddleName, Gender) +VALUES + (@LastName, @FirstName, @MiddleName, @Gender) + +SET @PersonID = Cast(SCOPE_IDENTITY() as int) + +GO + +GRANT EXEC ON Person_Insert_OutputParameter TO PUBLIC +GO + +-- Person_Update + +DROP Procedure Person_Update +GO + +CREATE Procedure Person_Update + @PersonID int, + @FirstName nvarchar(50), + @LastName nvarchar(50), + @MiddleName nvarchar(50), + @Gender char(1) +AS + +UPDATE + Person +SET + LastName = @LastName, + FirstName = @FirstName, + MiddleName = @MiddleName, + Gender = @Gender +WHERE + PersonID = @PersonID + +GO + +GRANT EXEC ON Person_Update TO PUBLIC +GO + +-- Person_Delete + +DROP Procedure Person_Delete +GO + +CREATE Procedure Person_Delete + @PersonID int +AS + +DELETE FROM Person WHERE PersonID = @PersonID + +GO + +GRANT EXEC ON Person_Delete TO PUBLIC +GO + +-- Patient_SelectAll + +DROP Procedure Patient_SelectAll +GO + +CREATE Procedure Patient_SelectAll +AS + +SELECT + Person.*, Patient.Diagnosis +FROM + Patient, Person +WHERE + Patient.PersonID = Person.PersonID + +GO + +GRANT EXEC ON Patient_SelectAll TO PUBLIC +GO + +-- Patient_SelectByName + +DROP Procedure Patient_SelectByName +GO + +CREATE Procedure Patient_SelectByName + @firstName nvarchar(50), + @lastName nvarchar(50) +AS + +SELECT + Person.*, Patient.Diagnosis +FROM + Patient, Person +WHERE + Patient.PersonID = Person.PersonID + AND FirstName = @firstName AND LastName = @lastName + +GO + +GRANT EXEC ON Person_SelectByName TO PUBLIC +GO + +-- BinaryData Table + +DROP TABLE BinaryData + +CREATE TABLE BinaryData +( + BinaryDataID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_BinaryData PRIMARY KEY CLUSTERED, + Stamp timestamp NOT NULL, + Data varbinary(1024) NOT NULL) +ON [PRIMARY] +GO + +-- OutRefTest + +DROP Procedure OutRefTest +GO + +CREATE Procedure OutRefTest + @ID int, + @outputID int output, + @inputOutputID int output, + @str varchar(50), + @outputStr varchar(50) output, + @inputOutputStr varchar(50) output +AS + +SET @outputID = @ID +SET @inputOutputID = @ID + @inputOutputID +SET @outputStr = @str +SET @inputOutputStr = @str + @inputOutputStr + +GO + +-- OutRefEnumTest + +DROP Procedure OutRefEnumTest +GO + +CREATE Procedure OutRefEnumTest + @str varchar(50), + @outputStr varchar(50) output, + @inputOutputStr varchar(50) output +AS + +SET @outputStr = @str +SET @inputOutputStr = @str + @inputOutputStr + +GO + +-- ExecuteScalarTest + +DROP Procedure Scalar_DataReader +GO + +CREATE Procedure Scalar_DataReader +AS +SELECT Cast(12345 as int) AS intField, Cast('54321' as varchar(50)) AS stringField + +GO + +DROP Procedure Scalar_OutputParameter +GO + +CREATE Procedure Scalar_OutputParameter + @outputInt int = 0 output, + @outputString varchar(50) = '' output +AS +BEGIN + SET @outputInt = 12345 + SET @outputString = '54321' +END + +GO + +DROP Function Scalar_ReturnParameter +GO + +CREATE Function Scalar_ReturnParameter() +RETURNS int +AS +BEGIN + RETURN 12345 +END + +GO + +DROP Procedure Scalar_ReturnParameterWithObject +GO + +CREATE Procedure Scalar_ReturnParameterWithObject + @id int +AS +BEGIN + SELECT * FROM Person WHERE PersonID = @id + RETURN @id +END + +GO + +-- Data Types test + +DROP TABLE DataTypeTest +GO + +CREATE TABLE DataTypeTest +( + DataTypeID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_DataType PRIMARY KEY CLUSTERED, + Binary_ binary(50) NULL, + Boolean_ bit NULL, + Byte_ tinyint NULL, + Bytes_ varbinary(50) NULL, + Char_ char(1) NULL, + DateTime_ datetime NULL, + Decimal_ decimal(20,2) NULL, + Double_ float NULL, + Guid_ uniqueidentifier NULL, + Int16_ smallint NULL, + Int32_ int NULL, + Int64_ bigint NULL, + Money_ money NULL, + SByte_ tinyint NULL, + Single_ real NULL, + Stream_ varbinary(50) NULL, + String_ nvarchar(50) NULL, + UInt16_ smallint NULL, + UInt32_ int NULL, + UInt64_ bigint NULL, + Xml_ nvarchar(2000) NULL +) ON [PRIMARY] +GO + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, Xml_) +VALUES + ( NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL) +GO + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, + Xml_) +VALUES + (NewID(), 1, 255, NewID(), 'B', GetDate(), 12345.67, + 1234.567, NewID(), 32767, 32768, 1000000, 12.3456, 127, + 1234.123, NewID(), 'string', 32767, 32768, 200000000, + '') +GO + + +DROP FUNCTION GetParentByID +GO + +DROP TABLE Parent +GO +DROP TABLE Child +GO +DROP TABLE GrandChild +GO + +CREATE TABLE Parent (ParentID int, Value1 int) +GO +CREATE TABLE Child (ParentID int, ChildID int) +GO +CREATE TABLE GrandChild (ParentID int, ChildID int, GrandChildID int) +GO + +CREATE FUNCTION GetParentByID(@id int) +RETURNS TABLE +AS +RETURN +( + SELECT * FROM Parent WHERE ParentID = @id +) +GO + +DROP TABLE LinqDataTypes +GO + +CREATE TABLE LinqDataTypes +( + ID int, + MoneyValue decimal(10,4), + DateTimeValue datetime, + DateTimeValue2 datetime, + BoolValue bit, + GuidValue uniqueidentifier, + BinaryValue varbinary(5000) NULL, + SmallIntValue smallint, + IntValue int NULL, + BigIntValue bigint NULL +) +GO + +DROP TABLE TestIdentity +GO + +CREATE TABLE TestIdentity ( + ID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_TestIdentity PRIMARY KEY CLUSTERED +) +GO diff -r 000000000000 -r f990fcb411a9 Data/Create Scripts/MySql.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Create Scripts/MySql.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,478 @@ + +DROP TABLE Doctor +GO +DROP TABLE Patient +GO + +-- Person Table + +DROP TABLE Person +GO + +CREATE TABLE Person +( + PersonID int AUTO_INCREMENT NOT NULL, + FirstName varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + LastName varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + MiddleName varchar(50) NULL, + Gender char(1) NOT NULL, + CONSTRAINT PK_Person PRIMARY KEY CLUSTERED (PersonID) +) +GO + +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('John', 'Pupkin', 'M') +GO +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('Tester', 'Testerson', 'M') +GO + +-- Doctor Table Extension + +CREATE TABLE Doctor +( + PersonID int NOT NULL, + Taxonomy varchar(50) NOT NULL, + CONSTRAINT PK_Doctor PRIMARY KEY CLUSTERED (PersonID), + CONSTRAINT FK_Doctor_Person FOREIGN KEY (PersonID) + REFERENCES Person(PersonID) +) +GO + +INSERT INTO Doctor (PersonID, Taxonomy) VALUES (1, 'Psychiatry') +GO + +-- Patient Table Extension + +CREATE TABLE Patient +( + PersonID int NOT NULL, + Diagnosis varchar(256) NOT NULL, + CONSTRAINT PK_Patient PRIMARY KEY CLUSTERED (PersonID), + CONSTRAINT FK_Patient_Person FOREIGN KEY (PersonID) + REFERENCES Person (PersonID) +) +GO + +INSERT INTO Patient (PersonID, Diagnosis) VALUES (2, 'Hallucination with Paranoid Bugs'' Delirium of Persecution') +GO + + +-- GetPersonById + +DROP Procedure GetPersonById +GO + +CREATE Procedure GetPersonById(_ID INT) +BEGIN + + SELECT * FROM Person WHERE PersonID = _ID; + +END +GO + +-- GetPersonByName + +DROP Procedure GetPersonByName +GO + +CREATE Procedure GetPersonByName +( + _firstName varchar(50), + _lastName varchar(50) +) +BEGIN + + SELECT * FROM Person WHERE FirstName = _firstName AND LastName = _lastName; + +END +GO + +-- Person_SelectByKey + +DROP Procedure Person_SelectByKey +GO + +CREATE Procedure Person_SelectByKey(id int) +BEGIN + + SELECT * FROM Person WHERE PersonID = id; + +END +GO + +-- Person_SelectAll + +DROP Procedure Person_SelectAll +GO + +CREATE Procedure Person_SelectAll() +BEGIN + + SELECT * FROM Person; + +END +GO + +-- Person_SelectByName + +DROP Procedure Person_SelectByName +GO + +CREATE Procedure Person_SelectByName +( + firstName varchar(50), + lastName varchar(50) +) +BEGIN + + SELECT + * + FROM + Person + WHERE + FirstName = firstName AND LastName = lastName; + +END +GO + +-- Person_SelectListByName + +DROP Procedure Person_SelectListByName +GO + +CREATE Procedure Person_SelectListByName +( + firstName varchar(50), + lastName varchar(50) +) +BEGIN + + SELECT + * + FROM + Person + WHERE + FirstName like firstName AND LastName like lastName; + +END +GO + +-- Person_Insert + +DROP Procedure Person_Insert +GO + +CREATE Procedure Person_Insert +( + FirstName varchar(50), + LastName varchar(50), + MiddleName varchar(50), + Gender char(1) +) +BEGIN + + INSERT INTO Person + (LastName, FirstName, MiddleName, Gender) + VALUES + (LastName, FirstName, MiddleName, Gender); + + SELECT LAST_INSERT_ID() AS PersonID; + +END +GO + +-- Person_Insert_OutputParameter + +DROP Procedure Person_Insert_OutputParameter +GO + +CREATE Procedure Person_Insert_OutputParameter +( + FirstName varchar(50), + LastName varchar(50), + MiddleName varchar(50), + Gender char(1), + OUT PersonID int +) +BEGIN + + INSERT INTO Person + (LastName, FirstName, MiddleName, Gender) + VALUES + (LastName, FirstName, MiddleName, Gender); + + SET PersonID = LAST_INSERT_ID(); + +END +GO + +-- Person_Update + +DROP Procedure Person_Update +GO + +CREATE Procedure Person_Update +( + PersonID int, + FirstName varchar(50), + LastName varchar(50), + MiddleName varchar(50), + Gender char(1) +) +BEGIN + + UPDATE + Person + SET + LastName = LastName, + FirstName = FirstName, + MiddleName = MiddleName, + Gender = Gender + WHERE + PersonID = PersonID; + +END +GO + +-- Person_Delete + +DROP Procedure Person_Delete +GO + +CREATE Procedure Person_Delete +( + PersonID int +) +BEGIN + + DELETE FROM Person WHERE PersonID = PersonID; + +END +GO + +-- Patient_SelectAll + +DROP Procedure Patient_SelectAll +GO + +CREATE Procedure Patient_SelectAll() +BEGIN + + SELECT + Person.*, Patient.Diagnosis + FROM + Patient, Person + WHERE + Patient.PersonID = Person.PersonID; + +END +GO + +-- Patient_SelectByName + +DROP Procedure Patient_SelectByName +GO + +CREATE Procedure Patient_SelectByName +( + firstName varchar(50), + lastName varchar(50) +) +BEGIN + + SELECT + Person.*, Patient.Diagnosis + FROM + Patient, Person + WHERE + Patient.PersonID = Person.PersonID + AND FirstName = firstName AND LastName = lastName; + +END +GO + +-- BinaryData Table + +DROP TABLE BinaryData +GO + +CREATE TABLE BinaryData +( + BinaryDataID int AUTO_INCREMENT NOT NULL, + Stamp timestamp NOT NULL, + Data varbinary(1024) NOT NULL, + CONSTRAINT PK_BinaryData PRIMARY KEY CLUSTERED (BinaryDataID) +) +GO + +-- OutRefTest + +DROP Procedure OutRefTest +GO + +CREATE Procedure OutRefTest +( + ID int, + OUT outputID int, + OUT inputOutputID int, + str varchar(50), + OUT outputStr varchar(50), + OUT inputOutputStr varchar(50) +) +BEGIN + + SET outputID = ID; + SET inputOutputID = ID + inputOutputID; + SET outputStr = str; + SET inputOutputStr = str + inputOutputStr; + +END +GO + +-- OutRefEnumTest + +DROP Procedure OutRefEnumTest +GO + +CREATE Procedure OutRefEnumTest +( + str varchar(50), + OUT outputStr varchar(50), + OUT inputOutputStr varchar(50) +) +BEGIN + + SET outputStr = str; + SET inputOutputStr = str + inputOutputStr; + +END +GO + +-- ExecuteScalarTest + +DROP Procedure Scalar_DataReader +GO + +CREATE Procedure Scalar_DataReader() +BEGIN + + SELECT + 12345 AS intField, + '54321' AS stringField; + +END +GO + +DROP Procedure Scalar_OutputParameter +GO + +CREATE Procedure Scalar_OutputParameter +( + OUT outputInt int, + OUT outputString varchar(50) +) +BEGIN + + SET outputInt = 12345; + SET outputString = '54321'; + +END +GO + +-- Data Types test + +DROP TABLE DataTypeTest +GO + +CREATE TABLE DataTypeTest +( + DataTypeID int AUTO_INCREMENT NOT NULL, + Binary_ binary(50) NULL, + Boolean_ bit NOT NULL, + Byte_ tinyint NULL, + Bytes_ varbinary(50) NULL, + Char_ char(1) NULL, + DateTime_ datetime NULL, + Decimal_ decimal(20,2) NULL, + Double_ float NULL, + Guid_ varbinary(50) NULL, + Int16_ smallint NULL, + Int32_ int NULL, + Int64_ bigint NULL, + Money_ decimal(20,4) NULL, + SByte_ tinyint NULL, + Single_ real NULL, + Stream_ varbinary(50) NULL, + String_ varchar(50) NULL, + UInt16_ smallint NULL, + UInt32_ int NULL, + UInt64_ bigint NULL, + Xml_ varchar(1000) NULL, + CONSTRAINT PK_DataType PRIMARY KEY CLUSTERED (DataTypeID) +) +GO + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, Xml_) +VALUES + ( NULL, 0, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL) +GO + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, + Xml_) +VALUES + ( UUID(), 1, 127, UUID(), 'B', CurDate(), 12345.67, + 1234.567, UUID(), 32767, 32768, 1000000, 12.3456, 127, + 1234.123, UUID(), 'string', 32767, 32768, 200000000, + '') +GO + + + +DROP TABLE Parent +GO +DROP TABLE Child +GO +DROP TABLE GrandChild +GO + +CREATE TABLE Parent (ParentID int, Value1 int) +GO +CREATE TABLE Child (ParentID int, ChildID int) +GO +CREATE TABLE GrandChild (ParentID int, ChildID int, GrandChildID int) +GO + + +DROP TABLE LinqDataTypes +GO + +CREATE TABLE LinqDataTypes +( + ID int, + MoneyValue decimal(10,4), + DateTimeValue datetime, + DateTimeValue2 datetime NULL, + BoolValue boolean, + GuidValue char(36), + BinaryValue varbinary(5000) NULL, + SmallIntValue smallint, + IntValue int NULL, + BigIntValue bigint NULL +) +GO + +DROP TABLE TestIdentity +GO + +CREATE TABLE TestIdentity ( + ID int AUTO_INCREMENT NOT NULL, + CONSTRAINT PK_TestIdentity PRIMARY KEY CLUSTERED (ID) +) +GO diff -r 000000000000 -r f990fcb411a9 Data/Create Scripts/Oracle.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Create Scripts/Oracle.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,658 @@ +-- Person Table + +DROP SEQUENCE PersonSeq +/ +DROP TABLE Doctor +/ +DROP TABLE Patient +/ +DROP TABLE Person +/ +DROP SEQUENCE BinaryDataSeq +/ +DROP TABLE BinaryData +/ +DROP SEQUENCE DataTypeTestSeq +/ +DROP TABLE DataTypeTest +/ +DROP TABLE GrandChild +/ +DROP TABLE Child +/ +DROP TABLE Parent +/ +DROP TABLE LinqDataTypes +/ +DROP SEQUENCE SequenceTestSeq +/ +DROP TABLE SequenceTest +/ +DROP TABLE "STG_TRADE_INFORMATION" +/ +DROP table t_test_user_contract +/ +DROP table t_test_user +/ +DROP sequence sq_test_user +/ +DROP sequence sq_test_user_contract +/ + + +CREATE SEQUENCE PersonSeq +/ + +CREATE TABLE Person + ( PersonID NUMBER NOT NULL PRIMARY KEY + , Firstname VARCHAR2(50) NOT NULL + , Lastname VARCHAR2(50) NOT NULL + , Middlename VARCHAR2(50) + , Gender CHAR(1) NOT NULL + + , CONSTRAINT Ck_Person_Gender CHECK (Gender IN ('M', 'F', 'U', 'O')) + ) +/ + +-- Insert Trigger for Person + +CREATE OR REPLACE TRIGGER Person_Add +BEFORE INSERT +ON Person +FOR EACH ROW +BEGIN +SELECT + PersonSeq.NEXTVAL +INTO + :NEW.PersonID +FROM + dual; +END; +/ + +-- Doctor Table Extension + +CREATE TABLE Doctor + ( PersonID NUMBER NOT NULL PRIMARY KEY + , Taxonomy NVARCHAR2(50) NOT NULL + + , CONSTRAINT Fk_Doctor_Person FOREIGN KEY (PersonID) + REFERENCES Person (PersonID) ON DELETE CASCADE + ) +/ + +-- Patient Table Extension + +CREATE TABLE Patient + ( PersonID NUMBER NOT NULL PRIMARY KEY + , Diagnosis NVARCHAR2(256) NOT NULL + + , CONSTRAINT Fk_Patient_Person FOREIGN KEY (PersonID) + REFERENCES Person (PersonID) ON DELETE CASCADE + ) +/ + +-- Sample data for Person/Doctor/Patient + +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('John', 'Pupkin', 'M') +/ +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('Tester', 'Testerson', 'M') +/ +INSERT INTO Doctor (PersonID, Taxonomy) VALUES (PersonSeq.CURRVAL, 'Psychiatry') +/ +INSERT INTO Patient (PersonID, Diagnosis) VALUES (PersonSeq.CURRVAL, 'Hallucination with Paranoid Bugs'' Delirium of Persecution') +/ + +-- Person_Delete + +CREATE OR REPLACE +PROCEDURE Person_Delete(pPersonID IN NUMBER) IS +BEGIN +DELETE FROM + Person +WHERE + PersonID = pPersonID; +END; +/ + +-- Person_Insert + +CREATE OR REPLACE +PROCEDURE Person_Insert_OutputParameter + ( pFirstName IN NVARCHAR2 + , pLastName IN NVARCHAR2 + , pMiddleName IN NVARCHAR2 + , pGender IN CHAR + , pPersonID OUT NUMBER + ) IS +BEGIN +INSERT INTO Person + ( LastName, FirstName, MiddleName, Gender) +VALUES + (pLastName, pFirstName, pMiddleName, pGender) +RETURNING + PersonID +INTO + pPersonID; +END; +/ + +CREATE OR REPLACE +FUNCTION Person_Insert + ( pFirstName IN NVARCHAR2 + , pLastName IN NVARCHAR2 + , pMiddleName IN NVARCHAR2 + , pGender IN CHAR + ) +RETURN SYS_REFCURSOR IS + retCursor SYS_REFCURSOR; + lPersonID NUMBER; +BEGIN +INSERT INTO Person + ( LastName, FirstName, MiddleName, Gender) +VALUES + (pLastName, pFirstName, pMiddleName, pGender) +RETURNING + PersonID +INTO + lPersonID; + +OPEN retCursor FOR + SELECT + PersonID, Firstname, Lastname, Middlename, Gender + FROM + Person + WHERE + PersonID = lPersonID; +RETURN + retCursor; +END; +/ + +-- Person_SelectAll + +CREATE OR REPLACE +FUNCTION Person_SelectAll +RETURN SYS_REFCURSOR IS + retCursor SYS_REFCURSOR; +BEGIN +OPEN retCursor FOR + SELECT + PersonID, Firstname, Lastname, Middlename, Gender + FROM + Person; +RETURN + retCursor; +END; +/ + +-- Person_SelectAllByGender + +CREATE OR REPLACE +FUNCTION Person_SelectAllByGender(pGender IN CHAR) +RETURN SYS_REFCURSOR IS + retCursor SYS_REFCURSOR; +BEGIN +OPEN retCursor FOR + SELECT + PersonID, Firstname, Lastname, Middlename, Gender + FROM + Person + WHERE + Gender = pGender; +RETURN + retCursor; +END; +/ + +-- Person_SelectByKey + +CREATE OR REPLACE +FUNCTION Person_SelectByKey(pID IN NUMBER) +RETURN SYS_REFCURSOR IS + retCursor SYS_REFCURSOR; +BEGIN +OPEN retCursor FOR + SELECT + PersonID, Firstname, Lastname, Middlename, Gender + FROM + Person + WHERE + PersonID = pID; +RETURN + retCursor; +END; +/ + +-- Person_SelectByName + +CREATE OR REPLACE +FUNCTION Person_SelectByName + ( pFirstName IN NVARCHAR2 + , pLastName IN NVARCHAR2 + ) +RETURN SYS_REFCURSOR IS + retCursor SYS_REFCURSOR; +BEGIN +OPEN retCursor FOR + SELECT + PersonID, Firstname, Lastname, Middlename, Gender + FROM + Person + WHERE + FirstName = pFirstName AND LastName = pLastName; +RETURN + retCursor; +END; +/ + +-- Person_SelectListByName + +CREATE OR REPLACE +FUNCTION Person_SelectListByName + ( pFirstName IN NVARCHAR2 + , pLastName IN NVARCHAR2 + ) +RETURN SYS_REFCURSOR IS + retCursor SYS_REFCURSOR; +BEGIN +OPEN retCursor FOR + SELECT + PersonID, Firstname, Lastname, Middlename, Gender + FROM + Person + WHERE + FirstName LIKE pFirstName AND LastName LIKE pLastName; +RETURN + retCursor; +END; +/ + +CREATE OR REPLACE +PROCEDURE Person_Update + ( pPersonID IN NUMBER + , pFirstName IN NVARCHAR2 + , pLastName IN NVARCHAR2 + , pMiddleName IN NVARCHAR2 + , pGender IN CHAR + ) IS +BEGIN +UPDATE + Person +SET + LastName = pLastName, + FirstName = pFirstName, + MiddleName = pMiddleName, + Gender = pGender +WHERE + PersonID = pPersonID; +END; +/ + +-- Patient_SelectAll + +CREATE OR REPLACE +FUNCTION Patient_SelectAll +RETURN SYS_REFCURSOR IS + retCursor SYS_REFCURSOR; +BEGIN +OPEN retCursor FOR +SELECT + Person.*, Patient.Diagnosis +FROM + Patient, Person +WHERE + Patient.PersonID = Person.PersonID; +RETURN + retCursor; +END; +/ + + +-- Patient_SelectByName + +CREATE OR REPLACE +FUNCTION Patient_SelectByName + ( pFirstName IN NVARCHAR2 + , pLastName IN NVARCHAR2 + ) +RETURN SYS_REFCURSOR IS + retCursor SYS_REFCURSOR; +BEGIN +OPEN retCursor FOR +SELECT + Person.*, Patient.Diagnosis +FROM + Patient, Person +WHERE + Patient.PersonID = Person.PersonID + AND FirstName = pFirstName AND LastName = pLastName; +RETURN + retCursor; +END; +/ + +-- BinaryData Table + +CREATE SEQUENCE BinaryDataSeq +/ + +CREATE TABLE BinaryData + ( BinaryDataID NUMBER NOT NULL PRIMARY KEY + , Stamp TIMESTAMP DEFAULT SYSDATE NOT NULL + , Data BLOB NOT NULL + ) +/ + +-- Insert Trigger for Binarydata + +CREATE OR REPLACE TRIGGER BinaryData_Add +BEFORE INSERT +ON BinaryData +FOR EACH ROW +BEGIN +SELECT + BinaryDataSeq.NEXTVAL +INTO + :NEW.BinaryDataID +FROM + dual; +END; +/ + +-- OutRefTest + +CREATE OR REPLACE +PROCEDURE OutRefTest + ( pID IN NUMBER + , pOutputID OUT NUMBER + , pInputOutputID IN OUT NUMBER + , pStr IN NVARCHAR2 + , pOutputStr OUT NVARCHAR2 + , pInputOutputStr IN OUT NVARCHAR2 + ) IS +BEGIN + pOutputID := pID; + pInputOutputID := pID + pInputOutputID; + pOutputStr := pStr; + pInputOutputStr := pStr || pInputOutputStr; +END; +/ + +CREATE OR REPLACE +PROCEDURE OutRefEnumTest + ( pStr IN NVARCHAR2 + , pOutputStr OUT NVARCHAR2 + , pInputOutputStr IN OUT NVARCHAR2 + ) IS +BEGIN + pOutputStr := pStr; + pInputOutputStr := pStr || pInputOutputStr; +END; +/ + +-- ArrayTest + +CREATE OR REPLACE +PROCEDURE ArrayTest + ( pIntArray IN DBMS_UTILITY.NUMBER_ARRAY + , pOutputIntArray OUT DBMS_UTILITY.NUMBER_ARRAY + , pInputOutputIntArray IN OUT DBMS_UTILITY.NUMBER_ARRAY + , pStrArray IN DBMS_UTILITY.NAME_ARRAY + , pOutputStrArray OUT DBMS_UTILITY.NAME_ARRAY + , pInputOutputStrArray IN OUT DBMS_UTILITY.NAME_ARRAY + ) IS +BEGIN +pOutputIntArray := pIntArray; + +FOR i IN pIntArray.FIRST..pIntArray.LAST LOOP + pInputOutputIntArray(i) := pInputOutputIntArray(i) + pIntArray(i); +END LOOP; + +pOutputStrArray := pStrArray; + +FOR i IN pStrArray.FIRST..pStrArray.LAST LOOP + pInputOutputStrArray(i) := pInputOutputStrArray(i) || pStrArray(i); +END LOOP; +END; +/ + +CREATE OR REPLACE +PROCEDURE ScalarArray + ( pOutputIntArray OUT DBMS_UTILITY.NUMBER_ARRAY + ) IS +BEGIN +FOR i IN 1..5 LOOP + pOutputIntArray(i) := i; +END LOOP; +END; +/ + +-- ResultSetTest + +CREATE OR REPLACE +PROCEDURE RESULTSETTEST + ( mr OUT SYS_REFCURSOR + , sr OUT SYS_REFCURSOR + ) IS +BEGIN +OPEN mr FOR + SELECT 1 as MasterID FROM dual + UNION SELECT 2 as MasterID FROM dual; +OPEN sr FOR + SELECT 4 SlaveID, 1 as MasterID FROM dual + UNION SELECT 5 SlaveID, 2 as MasterID FROM dual + UNION SELECT 6 SlaveID, 2 as MasterID FROM dual + UNION SELECT 7 SlaveID, 1 as MasterID FROM dual; +END; +/ + +-- ExecuteScalarTest + +CREATE OR REPLACE +FUNCTION Scalar_DataReader +RETURN SYS_REFCURSOR +IS + retCursor SYS_REFCURSOR; +BEGIN +OPEN retCursor FOR + SELECT + 12345 intField, '54321' stringField + FROM + DUAL; +RETURN + retCursor; +END; +/ + +CREATE OR REPLACE +PROCEDURE Scalar_OutputParameter + ( pOutputInt OUT BINARY_INTEGER + , pOutputString OUT NVARCHAR2 + ) IS +BEGIN + pOutputInt := 12345; + pOutputString := '54321'; +END; +/ + +CREATE OR REPLACE +FUNCTION Scalar_ReturnParameter +RETURN BINARY_INTEGER IS +BEGIN +RETURN + 12345; +END; +/ + +-- Data Types test + +CREATE SEQUENCE DataTypeTestSeq +/ + +CREATE TABLE DataTypeTest +( + DataTypeID INTEGER NOT NULL PRIMARY KEY, + Binary_ RAW(50) NULL, + Boolean_ NUMBER(1,0) NULL, + Byte_ NUMBER(3,0) NULL, + Bytes_ BLOB NULL, + Char_ NCHAR NULL, + DateTime_ DATE NULL, + Decimal_ NUMBER(19,5) NULL, + Double_ DOUBLE PRECISION NULL, + Guid_ RAW(16) NULL, + Int16_ NUMBER(5,0) NULL, + Int32_ NUMBER(10,0) NULL, + Int64_ NUMBER(20,0) NULL, + Money_ NUMBER NULL, + SByte_ NUMBER(3,0) NULL, + Single_ FLOAT NULL, + Stream_ BLOB NULL, + String_ NVARCHAR2(50) NULL, + UInt16_ NUMBER(5,0) NULL, + UInt32_ NUMBER(10,0) NULL, + UInt64_ NUMBER(20,0) NULL, + Xml_ XMLTYPE NULL +) +/ + +-- Insert Trigger for DataTypeTest + +CREATE OR REPLACE TRIGGER DataTypeTest_Add +BEFORE INSERT +ON DataTypeTest +FOR EACH ROW +BEGIN +SELECT + DataTypeTestSeq.NEXTVAL +INTO + :NEW.DataTypeID +FROM + dual; +END; +/ + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, Xml_) +VALUES + ( NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL) +/ + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, + Xml_) +VALUES + (SYS_GUID(), 1, 255, SYS_GUID(), 'B', SYSDATE, 12345.67, + 1234.567, SYS_GUID(), 32767, 32768, 1000000, 12.3456, 127, + 1234.123, SYS_GUID(), 'string', 32767, 32768, 200000000, + XMLTYPE('')) +/ + + + +CREATE TABLE Parent (ParentID int, Value1 int) +/ +CREATE TABLE Child (ParentID int, ChildID int) +/ +CREATE TABLE GrandChild (ParentID int, ChildID int, GrandChildID int) +/ + + +CREATE TABLE LinqDataTypes +( + ID int, + MoneyValue decimal(10,4), + DateTimeValue timestamp, + DateTimeValue2 timestamp, + BoolValue smallint, + GuidValue raw(16), + BinaryValue blob NULL, + SmallIntValue smallint, + IntValue int NULL, + BigIntValue number(20,0) NULL +) +/ + +CREATE SEQUENCE SequenceTestSeq + MINVALUE 1 + START WITH 1 + INCREMENT BY 1 + CACHE 10 +/ + +CREATE TABLE SequenceTest +( + ID int NOT NULL PRIMARY KEY, + Value VARCHAR2(50) NOT NULL +) +/ + +CREATE TABLE "STG_TRADE_INFORMATION" +( + "STG_TRADE_ID" NUMBER NOT NULL ENABLE, + "STG_TRADE_VERSION" NUMBER NOT NULL ENABLE, + "INFORMATION_TYPE_ID" NUMBER NOT NULL ENABLE, + "INFORMATION_TYPE_NAME" VARCHAR2(50 BYTE), + "VALUE" VARCHAR2(4000 BYTE), + "VALUE_AS_INTEGER" NUMBER, + "VALUE_AS_DATE" DATE +) +/ + + +create table t_test_user +( + user_id number primary key, + name varchar2(255) not null unique +) +/ + +create table t_test_user_contract +( + user_contract_id number primary key, + user_id number not null references t_test_user on delete cascade, + contract_no number not null, + name varchar2(255) not null, + unique (user_id, contract_no) +) +/ + +create sequence sq_test_user +/ +create sequence sq_test_user_contract +/ + + +DROP SEQUENCE TestIdentitySeq +/ +DROP TABLE TestIdentity +/ + +CREATE TABLE TestIdentity ( + ID NUMBER NOT NULL PRIMARY KEY +) +/ + +CREATE SEQUENCE TestIdentitySeq +/ + +CREATE OR REPLACE TRIGGER TestIdentity_Add +BEFORE INSERT +ON TestIdentity +FOR EACH ROW +BEGIN +SELECT + TestIdentitySeq.NEXTVAL +INTO + :NEW.ID +FROM + dual; +END; +/ diff -r 000000000000 -r f990fcb411a9 Data/Create Scripts/PostgreSQL.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Create Scripts/PostgreSQL.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,182 @@ +DROP TABLE "Doctor" +GO + +DROP TABLE "Patient" +GO + +DROP TABLE "Person" +GO + +CREATE TABLE "Person" +( + --PersonID INTEGER PRIMARY KEY DEFAULT NEXTVAL('Seq'), + "PersonID" SERIAL PRIMARY KEY, + "FirstName" VARCHAR(50) NOT NULL, + "LastName" VARCHAR(50) NOT NULL, + "MiddleName" VARCHAR(50), + "Gender" CHAR(1) NOT NULL +) +GO + +INSERT INTO "Person" ("FirstName", "LastName", "Gender") VALUES ('John', 'Pupkin', 'M') +GO +INSERT INTO "Person" ("FirstName", "LastName", "Gender") VALUES ('Tester', 'Testerson', 'M') +GO + +-- Doctor Table Extension + +CREATE TABLE "Doctor" +( + "PersonID" INTEGER NOT NULL, + "Taxonomy" VARCHAR(50) NOT NULL +) +GO + +INSERT INTO "Doctor" ("PersonID", "Taxonomy") VALUES (1, 'Psychiatry') +GO + +-- Patient Table Extension + +CREATE TABLE "Patient" +( + "PersonID" INTEGER NOT NULL, + "Diagnosis" VARCHAR(256) NOT NULL +) +GO + +INSERT INTO "Patient" ("PersonID", "Diagnosis") VALUES (2, 'Hallucination with Paranoid Bugs'' Delirium of Persecution') +GO + + +CREATE OR REPLACE FUNCTION reverse(text) RETURNS text + AS $_$ +DECLARE +original alias for $1; + reverse_str text; + i int4; +BEGIN + reverse_str := ''; + FOR i IN REVERSE LENGTH(original)..1 LOOP + reverse_str := reverse_str || substr(original,i,1); + END LOOP; +RETURN reverse_str; +END;$_$ + LANGUAGE plpgsql IMMUTABLE; +GO + + +DROP TABLE "Parent" +GO +DROP TABLE "Child" +GO +DROP TABLE "GrandChild" +GO + +CREATE TABLE "Parent" ("ParentID" int, "Value1" int) +GO +CREATE TABLE "Child" ("ParentID" int, "ChildID" int) +GO +CREATE TABLE "GrandChild" ("ParentID" int, "ChildID" int, "GrandChildID" int) +GO + + +DROP TABLE "LinqDataTypes" +GO + +CREATE TABLE "LinqDataTypes" +( + "ID" int, + "MoneyValue" decimal(10,4), + "DateTimeValue" timestamp, + "DateTimeValue2" timestamp, + "BoolValue" boolean, + "GuidValue" uuid, + "BinaryValue" bytea NULL, + "SmallIntValue" smallint, + "IntValue" int NULL, + "BigIntValue" bigint NULL +) +GO + + +DROP TABLE entity +GO + +CREATE TABLE entity +( + the_name character varying(255) NOT NULL, + CONSTRAINT entity_name_key UNIQUE (the_name) +) +GO + +CREATE OR REPLACE FUNCTION add_if_not_exists(p_name character varying) + RETURNS void AS +$BODY$ +BEGIN + BEGIN + insert into entity(the_name) values(p_name); + EXCEPTION WHEN unique_violation THEN + -- is exists, do nothing + END; +END; +$BODY$ + LANGUAGE plpgsql; +GO + + +DROP TABLE "SequenceTest1" +GO + +DROP TABLE "SequenceTest2" +GO + +DROP TABLE "SequenceTest3" +GO + +DROP SEQUENCE SequenceTestSeq +GO + +CREATE SEQUENCE SequenceTestSeq INCREMENT 1 START 1 +GO + +DROP SEQUENCE "SequenceTest2_ID_seq" +GO + +CREATE SEQUENCE "SequenceTest2_ID_seq" INCREMENT 1 START 1 +GO + +CREATE TABLE "SequenceTest1" +( + "ID" INTEGER PRIMARY KEY, + "Value" VARCHAR(50) +) +GO + +CREATE TABLE "SequenceTest2" +( + "ID" INTEGER PRIMARY KEY DEFAULT NEXTVAL('"SequenceTest2_ID_seq"'), + "Value" VARCHAR(50) +) +GO + +CREATE TABLE "SequenceTest3" +( + "ID" INTEGER PRIMARY KEY DEFAULT NEXTVAL('SequenceTestSeq'), + "Value" VARCHAR(50) +) +GO + + +DROP TABLE "TestIdentity" +GO + +DROP SEQUENCE "TestIdentity_ID_seq" +GO + +CREATE SEQUENCE "TestIdentity_ID_seq" INCREMENT 1 START 1 +GO + +CREATE TABLE "TestIdentity" ( + "ID" INTEGER PRIMARY KEY DEFAULT NEXTVAL('"TestIdentity_ID_seq"') +) +GO diff -r 000000000000 -r f990fcb411a9 Data/Create Scripts/SQLite.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Create Scripts/SQLite.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,138 @@ +-- +-- Helper table +-- +DROP TABLE IF EXISTS Dual; +CREATE TABLE Dual (Dummy VARCHAR(10)); +INSERT INTO Dual (Dummy) VALUES ('X'); + +-- +-- Person Table +-- +DROP TABLE IF EXISTS Person; +CREATE TABLE Person +( + PersonID integer NOT NULL CONSTRAINT PK_Person PRIMARY KEY AUTOINCREMENT, + FirstName nvarchar(50) NOT NULL, + LastName nvarchar(50) NOT NULL, + MiddleName nvarchar(50) NULL, + Gender char(1) NOT NULL CONSTRAINT CK_Person_Gender CHECK (Gender in ('M', 'F', 'U', 'O')) +); + +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('John', 'Pupkin', 'M'); +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('Tester', 'Testerson', 'M'); + +-- +-- Doctor Table Extension +-- +DROP TABLE IF EXISTS Doctor; +CREATE TABLE Doctor +( + PersonID integer NOT NULL CONSTRAINT PK_Doctor PRIMARY KEY, + Taxonomy nvarchar(50) NOT NULL +); + +INSERT INTO Doctor (PersonID, Taxonomy) VALUES (1, 'Psychiatry'); + +-- +-- Patient Table Extension +-- +DROP TABLE IF EXISTS Patient; +CREATE TABLE Patient +( + PersonID integer NOT NULL CONSTRAINT PK_Patient PRIMARY KEY, + Diagnosis nvarchar(256) NOT NULL +); +INSERT INTO Patient (PersonID, Diagnosis) VALUES (2, 'Hallucination with Paranoid Bugs'' Delirium of Persecution'); + +-- +-- BinaryData Table +-- +DROP TABLE IF EXISTS BinaryData; +CREATE TABLE BinaryData +( + BinaryDataID integer NOT NULL CONSTRAINT PK_BinaryData PRIMARY KEY AUTOINCREMENT, + Stamp timestamp NOT NULL, + Data blob(1024) NOT NULL +); + +-- +-- Babylon test +-- +DROP TABLE IF EXISTS DataTypeTest; +CREATE TABLE DataTypeTest +( + DataTypeID integer NOT NULL CONSTRAINT PK_DataType PRIMARY KEY AUTOINCREMENT, + Binary_ binary(50) NULL, + Boolean_ bit NULL, + Byte_ tinyint NULL, + Bytes_ varbinary(50) NULL, + Char_ char(1) NULL, + DateTime_ datetime NULL, + Decimal_ decimal(20,2) NULL, + Double_ float NULL, + Guid_ uniqueidentifier NULL, + Int16_ smallint NULL, + Int32_ int NULL, + Int64_ bigint NULL, + Money_ money NULL, + SByte_ tinyint NULL, + Single_ real NULL, + Stream_ varbinary(50) NULL, + String_ nvarchar(50) NULL, + UInt16_ smallint NULL, + UInt32_ int NULL, + UInt64_ bigint NULL, + Xml_ text NULL +); + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, Xml_) +VALUES + ( NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL); + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, + Xml_) +VALUES + (randomblob(16), 1, 255, zeroblob(16), 'B', DATETIME('NOW'), 12345.67, + 1234.567, '{64e145a3-0077-4335-b2c6-ea19c9f464f8}', 32767, 32768, 1000000, 12.3456, 127, + 1234.123, randomblob(64), 'string', 32767, 32768, 200000000, + ''); + + +DROP TABLE IF EXISTS Parent; +DROP TABLE IF EXISTS Child; +DROP TABLE IF EXISTS GrandChild; + +CREATE TABLE Parent (ParentID int, Value1 int); +CREATE TABLE Child (ParentID int, ChildID int); +CREATE TABLE GrandChild (ParentID int, ChildID int, GrandChildID int); + +DROP TABLE IF EXISTS LinqDataTypes; +CREATE TABLE LinqDataTypes +( + ID int, + MoneyValue decimal(10,4), + DateTimeValue datetime, + DateTimeValue2 datetime2, + BoolValue boolean, + GuidValue uniqueidentifier, + BinaryValue binary(5000) NULL, + SmallIntValue smallint, + IntValue int NULL, + BigIntValue bigint NULL +); + +DROP TABLE TestIdentity +GO + +CREATE TABLE TestIdentity ( + ID integer NOT NULL CONSTRAINT PK_TestIdentity PRIMARY KEY AUTOINCREMENT +) +GO diff -r 000000000000 -r f990fcb411a9 Data/Create Scripts/SqlCe.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Create Scripts/SqlCe.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,162 @@ +DROP TABLE DataTypeTest +GO +DROP TABLE BinaryData +GO +DROP TABLE Patient +GO +DROP TABLE Doctor +GO +DROP TABLE Person +GO + +-- Person Table + +CREATE TABLE Person +( + PersonID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_Person PRIMARY KEY, + FirstName nvarchar(50) NOT NULL, + LastName nvarchar(50) NOT NULL, + MiddleName nvarchar(50) NULL, + Gender nchar(1) NOT NULL +) +GO + +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('John', 'Pupkin', 'M') +GO +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('Tester', 'Testerson', 'M') +GO + +-- Doctor Table Extension + +CREATE TABLE Doctor +( + PersonID int NOT NULL + CONSTRAINT PK_Doctor PRIMARY KEY + CONSTRAINT FK_Doctor_Person --FOREIGN KEY + REFERENCES Person ([PersonID]) + ON UPDATE CASCADE + ON DELETE CASCADE, + Taxonomy nvarchar(50) NOT NULL +) +GO + +INSERT INTO Doctor (PersonID, Taxonomy) VALUES (1, 'Psychiatry') +GO + +-- Patient Table Extension + +CREATE TABLE Patient +( + PersonID int NOT NULL + CONSTRAINT PK_Patient PRIMARY KEY + CONSTRAINT FK_Patient_Person --FOREIGN KEY + REFERENCES Person ([PersonID]) + ON UPDATE CASCADE + ON DELETE CASCADE, + Diagnosis nvarchar(256) NOT NULL +) +GO + +INSERT INTO Patient (PersonID, Diagnosis) VALUES (2, 'Hallucination with Paranoid Bugs'' Delirium of Persecution') +GO + +-- BinaryData Table + +CREATE TABLE BinaryData +( + BinaryDataID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_BinaryData PRIMARY KEY, + Data varbinary(1024) NOT NULL) +GO + +CREATE TABLE DataTypeTest +( + DataTypeID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_DataType PRIMARY KEY, + Binary_ binary(50) NULL, + Boolean_ bit NULL, + Byte_ tinyint NULL, + Bytes_ varbinary(50) NULL, + Char_ nchar(1) NULL, + DateTime_ datetime NULL, + Decimal_ numeric(20,2) NULL, + Double_ float NULL, + Guid_ uniqueidentifier NULL, + Int16_ smallint NULL, + Int32_ int NULL, + Int64_ bigint NULL, + Money_ money NULL, + SByte_ tinyint NULL, + Single_ real NULL, + Stream_ varbinary(50) NULL, + String_ nvarchar(50) NULL, + UInt16_ smallint NULL, + UInt32_ int NULL, + UInt64_ bigint NULL, + Xml_ ntext NULL +) +GO + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, Xml_) +VALUES + ( NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL) +GO + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, + Xml_) +VALUES + (NewID(), 1, 255, NewID(), 'B', GetDate(), 12345.67, + 1234.567, NewID(), 32767, 32768, 1000000, 12.3456, 127, + 1234.123, NewID(), 'string', 32767, 32768, 200000000, + '') +GO + + + +DROP TABLE Parent +GO +DROP TABLE Child +GO +DROP TABLE GrandChild +GO + +CREATE TABLE Parent (ParentID int, Value1 int) +GO +CREATE TABLE Child (ParentID int, ChildID int) +GO +CREATE TABLE GrandChild (ParentID int, ChildID int, GrandChildID int) +GO + + +DROP TABLE LinqDataTypes +GO + +CREATE TABLE LinqDataTypes +( + ID int, + MoneyValue decimal(10,4), + DateTimeValue datetime, + DateTimeValue2 datetime, + BoolValue bit, + GuidValue uniqueidentifier, + BinaryValue varbinary(5000) NULL, + SmallIntValue smallint, + IntValue int NULL, + BigIntValue bigint NULL +) +GO + + +DROP TABLE TestIdentity +GO + +CREATE TABLE TestIdentity ( + ID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_TestIdentity PRIMARY KEY +) +GO diff -r 000000000000 -r f990fcb411a9 Data/Create Scripts/Sybase.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Create Scripts/Sybase.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,475 @@ +IF OBJECT_ID('dbo.Doctor') IS NOT NULL +BEGIN DROP TABLE Doctor END +GO + +IF OBJECT_ID('dbo.Patient') IS NOT NULL +BEGIN DROP TABLE Patient END +GO + +-- Person Table + +IF OBJECT_ID('dbo.Person') IS NOT NULL +BEGIN DROP TABLE Person END +GO + +CREATE TABLE Person +( + PersonID int IDENTITY, + FirstName nvarchar(50) NOT NULL, + LastName nvarchar(50) NOT NULL, + MiddleName nvarchar(50) NULL, + Gender char(1) NOT NULL, + CONSTRAINT PK_Person PRIMARY KEY CLUSTERED (PersonID) +) +GO + +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('John', 'Pupkin', 'M') +GO +INSERT INTO Person (FirstName, LastName, Gender) VALUES ('Tester', 'Testerson', 'M') +GO + +-- Doctor Table Extension + +CREATE TABLE Doctor +( + PersonID int NOT NULL, + Taxonomy nvarchar(50) NOT NULL, + CONSTRAINT PK_Doctor PRIMARY KEY CLUSTERED (PersonID), + CONSTRAINT FK_Doctor_Person FOREIGN KEY (PersonID) + REFERENCES Person(PersonID) +) +GO + +INSERT INTO Doctor (PersonID, Taxonomy) VALUES (1, 'Psychiatry') +GO + +-- Patient Table Extension + +CREATE TABLE Patient +( + PersonID int NOT NULL, + Diagnosis nvarchar(256) NOT NULL, + CONSTRAINT PK_Patient PRIMARY KEY CLUSTERED (PersonID), + CONSTRAINT FK_Patient_Person FOREIGN KEY (PersonID) + REFERENCES Person (PersonID) +) +GO + +INSERT INTO Patient (PersonID, Diagnosis) VALUES (2, 'Hallucination with Paranoid Bugs'' Delirium of Persecution') +GO + +-- Person_SelectByKey + +IF OBJECT_ID('Person_SelectByKey') IS NOT NULL +BEGIN DROP Procedure Person_SelectByKey END +GO + +CREATE Procedure Person_SelectByKey + @id int +AS + +SELECT * FROM Person WHERE PersonID = @id + +GO + +GRANT EXEC ON Person_SelectByKey TO PUBLIC +GO + +-- Person_SelectAll + +IF OBJECT_ID('Person_SelectAll') IS NOT NULL +BEGIN DROP Procedure Person_SelectAll END +GO + +CREATE Procedure Person_SelectAll +AS + +SELECT * FROM Person + +GO + +GRANT EXEC ON Person_SelectAll TO PUBLIC +GO + +-- Person_SelectByName + +IF OBJECT_ID('Person_SelectByName') IS NOT NULL +BEGIN DROP Procedure Person_SelectByName END +GO + +CREATE Procedure Person_SelectByName + @firstName nvarchar(50), + @lastName nvarchar(50) +AS + +SELECT + * +FROM + Person +WHERE + FirstName = @firstName AND LastName = @lastName + +GO + +GRANT EXEC ON Person_SelectByName TO PUBLIC +GO + +-- Person_SelectListByName + +IF OBJECT_ID('Person_SelectListByName') IS NOT NULL +BEGIN DROP Procedure Person_SelectListByName END +GO + +CREATE Procedure Person_SelectListByName + @firstName nvarchar(50), + @lastName nvarchar(50) +AS + +SELECT + * +FROM + Person +WHERE + FirstName like @firstName AND LastName like @lastName + +GO + +GRANT EXEC ON Person_SelectByName TO PUBLIC +GO + +-- Person_Insert + +IF OBJECT_ID('Person_Insert') IS NOT NULL +BEGIN DROP Procedure Person_Insert END +GO + +CREATE Procedure Person_Insert + @FirstName nvarchar(50), + @LastName nvarchar(50), + @MiddleName nvarchar(50), + @Gender char(1) +AS + +INSERT INTO Person + ( LastName, FirstName, MiddleName, Gender) +VALUES + (@LastName, @FirstName, @MiddleName, @Gender) + +SELECT Cast(@@IDENTITY as int) PersonID + +GO + +GRANT EXEC ON Person_Insert TO PUBLIC +GO + +-- Person_Insert_OutputParameter + +IF OBJECT_ID('Person_Insert_OutputParameter') IS NOT NULL +BEGIN DROP Procedure Person_Insert_OutputParameter END +GO + +CREATE Procedure Person_Insert_OutputParameter + @FirstName nvarchar(50), + @LastName nvarchar(50), + @MiddleName nvarchar(50), + @Gender char(1), + @PersonID int output +AS + +INSERT INTO Person + ( LastName, FirstName, MiddleName, Gender) +VALUES + (@LastName, @FirstName, @MiddleName, @Gender) + +SET @PersonID = Cast(@@IDENTITY as int) + +GO + +GRANT EXEC ON Person_Insert_OutputParameter TO PUBLIC +GO + +-- Person_Update + +IF OBJECT_ID('Person_Update') IS NOT NULL +BEGIN DROP Procedure Person_Update END +GO + +CREATE Procedure Person_Update + @PersonID int, + @FirstName nvarchar(50), + @LastName nvarchar(50), + @MiddleName nvarchar(50), + @Gender char(1) +AS + +UPDATE + Person +SET + LastName = @LastName, + FirstName = @FirstName, + MiddleName = @MiddleName, + Gender = @Gender +WHERE + PersonID = @PersonID + +GO + +GRANT EXEC ON Person_Update TO PUBLIC +GO + +-- Person_Delete + +IF OBJECT_ID('Person_Delete') IS NOT NULL +BEGIN DROP Procedure Person_Delete END +GO + +CREATE Procedure Person_Delete + @PersonID int +AS + +DELETE FROM Person WHERE PersonID = @PersonID + +GO + +GRANT EXEC ON Person_Delete TO PUBLIC +GO + +-- Patient_SelectAll + +IF OBJECT_ID('Patient_SelectAll') IS NOT NULL +BEGIN DROP Procedure Patient_SelectAll END +GO + +CREATE Procedure Patient_SelectAll +AS + +SELECT + Person.*, Patient.Diagnosis +FROM + Patient, Person +WHERE + Patient.PersonID = Person.PersonID + +GO + +GRANT EXEC ON Patient_SelectAll TO PUBLIC +GO + +-- Patient_SelectByName + +IF OBJECT_ID('Patient_SelectByName') IS NOT NULL +BEGIN DROP Procedure Patient_SelectByName END +GO + +CREATE Procedure Patient_SelectByName + @firstName nvarchar(50), + @lastName nvarchar(50) +AS + +SELECT + Person.*, Patient.Diagnosis +FROM + Patient, Person +WHERE + Patient.PersonID = Person.PersonID + AND FirstName = @firstName AND LastName = @lastName + +GO + +GRANT EXEC ON Person_SelectByName TO PUBLIC +GO + +-- BinaryData Table + +IF OBJECT_ID('BinaryData') IS NOT NULL +BEGIN DROP TABLE BinaryData END +GO + +CREATE TABLE BinaryData +( + BinaryDataID int IDENTITY, + Stamp timestamp NOT NULL, + Data varbinary(1024) NOT NULL, + CONSTRAINT PK_BinaryData PRIMARY KEY CLUSTERED (BinaryDataID) +) +GO + +-- OutRefTest + +IF OBJECT_ID('OutRefTest') IS NOT NULL +BEGIN DROP Procedure OutRefTest END +GO + +CREATE Procedure OutRefTest + @ID int, + @outputID int output, + @inputOutputID int output, + @str varchar(50), + @outputStr varchar(50) output, + @inputOutputStr varchar(50) output +AS + +SET @outputID = @ID +SET @inputOutputID = @ID + @inputOutputID +SET @outputStr = @str +SET @inputOutputStr = @str + @inputOutputStr + +GO + +-- OutRefEnumTest + +IF OBJECT_ID('OutRefEnumTest') IS NOT NULL +BEGIN DROP Procedure OutRefEnumTest END +GO + +CREATE Procedure OutRefEnumTest + @str varchar(50), + @outputStr varchar(50) output, + @inputOutputStr varchar(50) output +AS + +SET @outputStr = @str +SET @inputOutputStr = @str + @inputOutputStr + +GO + +-- ExecuteScalarTest + +IF OBJECT_ID('Scalar_DataReader') IS NOT NULL +BEGIN DROP Procedure Scalar_DataReader END +GO + +CREATE Procedure Scalar_DataReader +AS +SELECT Cast(12345 as int) AS intField, Cast('54321' as varchar(50)) AS stringField + +GO + +IF OBJECT_ID('Scalar_OutputParameter') IS NOT NULL +BEGIN DROP Procedure Scalar_OutputParameter END +GO + +CREATE Procedure Scalar_OutputParameter + @outputInt int = 0 output, + @outputString varchar(50) = '' output +AS +BEGIN + SET @outputInt = 12345 + SET @outputString = '54321' +END + +GO + +IF OBJECT_ID('Scalar_ReturnParameterWithObject') IS NOT NULL +BEGIN DROP Procedure Scalar_ReturnParameterWithObject END +GO + +CREATE Procedure Scalar_ReturnParameterWithObject + @id int +AS +BEGIN + SELECT * FROM Person WHERE PersonID = @id + RETURN @id +END + +GO + +-- Data Types test + +IF OBJECT_ID('DataTypeTest') IS NOT NULL +BEGIN DROP TABLE DataTypeTest END +GO + +CREATE TABLE DataTypeTest +( + DataTypeID int IDENTITY, + Binary_ binary(50) NULL, + Boolean_ bit NOT NULL, + Byte_ tinyint NULL, + Bytes_ varbinary(50) NULL, + Char_ char(1) NULL, + DateTime_ datetime NULL, + Decimal_ decimal(20,2) NULL, + Double_ float NULL, + Guid_ varbinary(16) NULL, + Int16_ smallint NULL, + Int32_ int NULL, + Int64_ bigint NULL, + Money_ money NULL, + SByte_ tinyint NULL, + Single_ real NULL, + Stream_ varbinary(50) NULL, + String_ nvarchar(50) NULL, + UInt16_ smallint NULL, + UInt32_ int NULL, + UInt64_ bigint NULL, + Xml_ nvarchar(1000) NULL, + CONSTRAINT PK_DataType PRIMARY KEY CLUSTERED (DataTypeID) +) +GO + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, Xml_) +VALUES + ( NULL, 0, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL) +GO + +INSERT INTO DataTypeTest + (Binary_, Boolean_, Byte_, Bytes_, Char_, DateTime_, Decimal_, + Double_, Guid_, Int16_, Int32_, Int64_, Money_, SByte_, + Single_, Stream_, String_, UInt16_, UInt32_, UInt64_, + Xml_) +VALUES + (NewID(), 1, 255, NewID(), 'B', GetDate(), 12345.67, + 1234.567, NewID(), 32767, 32768, 1000000, 12.3456, 127, + 1234.123, NewID(), 'string', 32767, 32768, 200000000, + '') +GO + + + +DROP TABLE Parent +GO +DROP TABLE Child +GO +DROP TABLE GrandChild +GO + +CREATE TABLE Parent (ParentID int, Value1 int NULL) +GO +CREATE TABLE Child (ParentID int, ChildID int) +GO +CREATE TABLE GrandChild (ParentID int, ChildID int, GrandChildID int) +GO + + +DROP TABLE LinqDataTypes +GO + +CREATE TABLE LinqDataTypes +( + ID int, + MoneyValue decimal(10,4) NULL, + DateTimeValue datetime NULL, + DateTimeValue2 datetime NULL, + BoolValue bit default(0), + GuidValue char(36) NULL, + BinaryValue binary(500) NULL, + SmallIntValue smallint NULL, + IntValue int NULL, + BigIntValue bigint NULL +) +GO + +DROP TABLE TestIdentity +GO + +CREATE TABLE TestIdentity +( + ID int IDENTITY CONSTRAINT PK_TestIdentity PRIMARY KEY CLUSTERED +) +GO diff -r 000000000000 -r f990fcb411a9 Data/Data.dbp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Data.dbp Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,29 @@ +# Microsoft Developer Studio Project File - Database Project +Begin DataProject = "Data" + MSDTVersion = "80" + DefDBRef = "BLToolkitData.dbo" + Begin Folder = "Change Scripts" + End + Begin Folder = "Create Scripts" + Script = "Access.sql" + Script = "DB2.sql" + Script = "Firebird2.sql" + Script = "Informix.sql" + Script = "MsSql.sql" + Script = "MySql.sql" + Script = "Oracle.sql" + Script = "PostgreSQL.sql" + Script = "SqlCe.sql" + Script = "SQLite.sql" + Script = "Sybase.sql" + End + Begin DBRefFolder = "Database References" + Begin DBRefNode = "BLToolkitData.dbo" + ConnectStr = "Data Source=(local);Initial Catalog=BLToolkitData;Integrated Security=True" + Provider = "{91510608-8809-4020-8897-FBA057E22D54}" + Colorizer = 6 + End + End + Begin Folder = "Queries" + End +End diff -r 000000000000 -r f990fcb411a9 Data/Queries/Person_SelectAll.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Data/Queries/Person_SelectAll.sql Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,18 @@ +IF EXISTS (SELECT * FROM sysobjects WHERE type = 'P' AND name = 'Person_SelectAll') +BEGIN + DROP Procedure Person_SelectAll +END + +GO + +CREATE Procedure Person_SelectAll +AS + +SELECT * FROM Person + +GO + +GRANT EXEC ON Person_SelectAll TO PUBLIC + +GO + diff -r 000000000000 -r f990fcb411a9 DataProviders/Compile3.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Compile3.bat Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe DB2\BLToolkit.Data.DataProvider.DB2.3.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe Firebird\BLToolkit.Data.DataProvider.Firebird.3.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe Informix\BLToolkit.Data.DataProvider.Informix.3.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe MySql\BLToolkit.Data.DataProvider.MySql.3.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe Oracle\BLToolkit.Data.DataProvider.Oracle.3.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe PostgreSQL\BLToolkit.Data.DataProvider.PostgreSQL.3.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe SqlCe\BLToolkit.Data.DataProvider.SqlCe.3.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe SQLite\BLToolkit.Data.DataProvider.SQLite.3.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe Sybase\BLToolkit.Data.DataProvider.Sybase.3.csproj /property:Configuration=Debug + +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe DB2\BLToolkit.Data.DataProvider.DB2.3.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe Firebird\BLToolkit.Data.DataProvider.Firebird.3.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe Informix\BLToolkit.Data.DataProvider.Informix.3.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe MySql\BLToolkit.Data.DataProvider.MySql.3.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe Oracle\BLToolkit.Data.DataProvider.Oracle.3.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe PostgreSQL\BLToolkit.Data.DataProvider.PostgreSQL.3.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe SqlCe\BLToolkit.Data.DataProvider.SqlCe.3.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe SQLite\BLToolkit.Data.DataProvider.SQLite.3.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe Sybase\BLToolkit.Data.DataProvider.Sybase.3.csproj /property:Configuration=Release +pause \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Compile4.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Compile4.bat Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe DB2\BLToolkit.Data.DataProvider.DB2.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Firebird\BLToolkit.Data.DataProvider.Firebird.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Informix\BLToolkit.Data.DataProvider.Informix.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe MySql\BLToolkit.Data.DataProvider.MySql.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Oracle\BLToolkit.Data.DataProvider.Oracle.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Oracle\BLToolkit.Data.DataProvider.OracleManaged.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe DevartOraclePro\BLToolkit.Data.DataProvider.DevartOracle.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe PostgreSQL\BLToolkit.Data.DataProvider.PostgreSQL.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe SqlCe\BLToolkit.Data.DataProvider.SqlCe.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe SQLite\BLToolkit.Data.DataProvider.SQLite.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Sybase\BLToolkit.Data.DataProvider.Sybase.4.csproj /property:Configuration=Debug + +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe DB2\BLToolkit.Data.DataProvider.DB2.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Firebird\BLToolkit.Data.DataProvider.Firebird.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Informix\BLToolkit.Data.DataProvider.Informix.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe MySql\BLToolkit.Data.DataProvider.MySql.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Oracle\BLToolkit.Data.DataProvider.Oracle.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Oracle\BLToolkit.Data.DataProvider.OracleManaged.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe DevartOraclePro\BLToolkit.Data.DataProvider.DevartOracle.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe PostgreSQL\BLToolkit.Data.DataProvider.PostgreSQL.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe SqlCe\BLToolkit.Data.DataProvider.SqlCe.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe SQLite\BLToolkit.Data.DataProvider.SQLite.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Sybase\BLToolkit.Data.DataProvider.Sybase.4.csproj /property:Configuration=Release +pause \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/DB2/BLToolkit.Data.DataProvider.DB2.3.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/DB2/BLToolkit.Data.DataProvider.DB2.3.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,71 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {86BF4F10-3606-4016-9919-84C3335813B6} + Library + Properties + BLToolkit.Data.DataProvider.DB2 + BLToolkit.Data.DataProvider.DB2.3 + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\Redist\IBM\IBM.Data.DB2.dll + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + DB2DataProvider.cs + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.3 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/DB2/BLToolkit.Data.DataProvider.DB2.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/DB2/BLToolkit.Data.DataProvider.DB2.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,134 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {86BF4F10-3606-4016-9919-84C3335813B6} + Library + Properties + BLToolkit.Data.DataProvider.DB2 + BLToolkit.Data.DataProvider.DB2.4 + v4.0 + 512 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\BLToolkit.Data.DataProvider.DB2.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\BLToolkit.Data.DataProvider.DB2.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + + False + ..\..\Redist\IBM\IBM.Data.DB2.dll + + + + 3.5 + + + + + + DB2DataProvider.cs + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/DB2/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/DB2/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using System.Security; + +using BLToolkit; + +[assembly: AssemblyTitle (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyDescription (BLToolkitConstants.ProductDescription + " Data Provider")] +[assembly: AssemblyProduct (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyCopyright (BLToolkitConstants.Copyright)] +[assembly: AssemblyCulture ("")] +[assembly: ComVisible (false)] +[assembly: Guid ("6c3fb028-daf7-4134-8697-eedfe34d779e")] +[assembly: AssemblyVersion (BLToolkitConstants.FullVersionString)] +[assembly: AssemblyFileVersion (BLToolkitConstants.FullVersionString)] +[assembly: CLSCompliant (true)] +[assembly: NeutralResourcesLanguage("en-US")] +//[assembly: AllowPartiallyTrustedCallers] diff -r 000000000000 -r f990fcb411a9 DataProviders/DevartOraclePro/BLToolkit.Data.DataProvider.DevartOracle.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/DevartOraclePro/BLToolkit.Data.DataProvider.DevartOracle.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,71 @@ + + + + + Debug + AnyCPU + {CB303F0B-0AA3-4589-850A-95E985A09492} + Library + Properties + BLToolkit.Data.DataProvider + BLToolkit.Data.DataProvider.DevartOracle.4 + v4.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\packages\dotConnect.Express.for.Oracle.8.1.36\lib\Devart.Data.dll + + + False + ..\..\packages\dotConnect.Express.for.Oracle.8.1.36\lib\Devart.Data.Oracle.dll + + + + + + + + + + + + + + + + {0c325f5d-e50e-4340-8724-d29896ccc583} + BLToolkit.4 + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/DevartOraclePro/BLToolkit.Data.DataProvider.DevartOraclePro.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/DevartOraclePro/BLToolkit.Data.DataProvider.DevartOraclePro.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,72 @@ + + + + + Debug + AnyCPU + {CB303F0B-0AA3-4589-850A-95E985A09492} + Library + Properties + BLToolkit.Data.DataProvider + BLToolkit.Data.DataProvider.DevartOracle.4 + v4.0 + 512 + + + true + full + false + bin\Debug\ + TRACE;DEBUG;DEVART_PRO + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE;DEVART_PRO + prompt + 4 + + + + False + + + False + + + + + + + + + + + + + + + + {0c325f5d-e50e-4340-8724-d29896ccc583} + BLToolkit.4 + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/DevartOraclePro/DevartOracleDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/DevartOraclePro/DevartOracleDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,212 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text; + +using BLToolkit.Data.Sql.SqlProvider; +using BLToolkit.Mapping; + +using Devart.Data.Oracle; + +namespace BLToolkit.Data.DataProvider +{ + public class DevartOracleDataProvider : DataProviderBase + { + /// + /// Data provider name string. + /// + public const string NameString = "DevartOracle"; + + public override Type ConnectionType + { + get { return typeof(OracleConnection); } + } + + public override string Name + { + get { return NameString; } + } + + /// + /// Gets or sets the database activity monitor. + /// + private static Devart.Common.DbMonitor DbMonitor { get; set; } + + /// + /// Gets or sets value indicating whether the database activity monitor is enabled. + /// + /// + /// This feature requires Standard or Pro edition of Devart dotConnect for Oracle provider. + /// + public static bool DbMonitorActive + { + get { return DbMonitor == null ? false : DbMonitor.IsActive; } + set + { + // setting this property has no effect in Express edition +#if DEVART_PRO + if (DbMonitorActive != value) + { + DbMonitor = DbMonitor ?? new OracleMonitor(); + DbMonitor.IsActive = value; + } +#endif + } + } + + public override IDbConnection CreateConnectionObject() + { + return new OracleConnection(); + } + + public override DbDataAdapter CreateDataAdapterObject() + { + return new OracleDataAdapter(); + } + + public override bool DeriveParameters(IDbCommand command) + { + var oraCommand = command as OracleCommand; + + if (null != oraCommand) + { + try + { + OracleCommandBuilder.DeriveParameters(oraCommand); + } + catch (Exception ex) + { + // Make Oracle less laconic. + // + throw new DataException(string.Format("{0}\nCommandText: {1}", ex.Message, oraCommand.CommandText), ex); + } + + return true; + } + + return false; + } + + public override void AttachParameter(IDbCommand command, IDbDataParameter parameter) + { + var value = parameter.Value; + + if (value is DateTime) + { + parameter.Value = new OracleTimeStamp((DateTime)value); + } + else if (value is Guid) + { + parameter.Value = ((Guid)value).ToByteArray(); + parameter.DbType = DbType.Binary; + ((OracleParameter)parameter).OracleDbType = OracleDbType.Raw; + } +// else if (value is string) +// { +// ((OracleParameter)parameter).OracleDbType = OracleDbType.NVarChar; +// } + + base.AttachParameter(command, parameter); + } + + public override int ExecuteArray(IDbCommand command, int iterations) + { + var cmd = (OracleCommand)command; + return cmd.ExecuteArray(iterations); + } + + public override ISqlProvider CreateSqlProvider() + { + return new OracleSqlProvider(); + } + + + #region InsertBatch + + public override int InsertBatch( + DbManager db, + string insertText, + IEnumerable collection, + MemberMapper[] members, + int maxBatchSize, + DbManager.ParameterProvider getParameters) + { + var sb = new StringBuilder(); + var sp = new OracleSqlProvider(); + var n = 0; + var cnt = 0; + var str = "\t" + insertText + .Substring(0, insertText.IndexOf(") VALUES (")) + .Substring(7) + .Replace("\r", "") + .Replace("\n", "") + .Replace("\t", " ") + .Replace("( ", "(") + //.Replace(" ", " ") + + ") VALUES ("; + + foreach (var item in collection) + { + if (sb.Length == 0) + sb.AppendLine("INSERT ALL"); + + sb.Append(str); + + foreach (var member in members) + { + var value = member.GetValue(item); + + if (value is Nullable) + value = ((DateTime?)value).Value; + + if (value is DateTime) + { + var dt = (DateTime)value; + sb.Append(string.Format("to_timestamp('{0:dd.MM.yyyy HH:mm:ss.ffffff}', 'DD.MM.YYYY HH24:MI:SS.FF6')", dt)); + } + else + sp.BuildValue(sb, value); + + sb.Append(", "); + } + + sb.Length -= 2; + sb.AppendLine(")"); + + n++; + + if (n >= maxBatchSize) + { + sb.AppendLine("SELECT * FROM dual"); + + var sql = sb.ToString(); + + if (DbManager.TraceSwitch.TraceInfo) + DbManager.WriteTraceLine("\n" + sql.Replace("\r", ""), DbManager.TraceSwitch.DisplayName); + + cnt += db.SetCommand(sql).ExecuteNonQuery(); + + n = 0; + sb.Length = 0; + } + } + + if (n > 0) + { + sb.AppendLine("SELECT * FROM dual"); + + var sql = sb.ToString(); + + if (DbManager.TraceSwitch.TraceInfo) + DbManager.WriteTraceLine("\n" + sql.Replace("\r", ""), DbManager.TraceSwitch.DisplayName); + + cnt += db.SetCommand(sql).ExecuteNonQuery(); + } + + return cnt; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 DataProviders/DevartOraclePro/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/DevartOraclePro/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BLToolkit.Data.DataProvider.DevartOracle.4")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("BLToolkit.Data.DataProvider.DevartOracle.4")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3eccd100-83fa-4b39-af69-dffd7ba55edb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 DataProviders/DevartOraclePro/Properties/licenses.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/DevartOraclePro/Properties/licenses.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +mono.exe +nunit-console.exe +nunit-console-x86.exe +nunit.exe +nunit-x86.exe +ProcessInvocation.exe +ProcessInvocation86.exe +SilverlightExecute.TestRunner.exe +Demo.exe +Test.exe +Sample.exe +Server.exe +Demo.vshost.exe +Test.vshost.exe +Sample.vshost.exe +Server.vshost.exe +Demo.vshost32.exe +Test.vshost32.exe +Sample.vshost32.exe +Server.vshost32.exe diff -r 000000000000 -r f990fcb411a9 DataProviders/DevartOraclePro/Properties/licenses.licx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/DevartOraclePro/Properties/licenses.licx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1 @@ +Devart.Data.Oracle.OracleConnection, Devart.Data.Oracle, Version=6.10.121.0, Culture=neutral, PublicKeyToken=09af7300eec23701 diff -r 000000000000 -r f990fcb411a9 DataProviders/DevartOraclePro/app.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/DevartOraclePro/app.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/DevartOraclePro/packages.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/DevartOraclePro/packages.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Firebird/BLToolkit.Data.DataProvider.Firebird.3.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Firebird/BLToolkit.Data.DataProvider.Firebird.3.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,74 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68} + Library + Properties + BLToolkit.Data.DataProvider.Firebird + BLToolkit.Data.DataProvider.Firebird.3 + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\Redist\Firebird\FirebirdSql.Data.FirebirdClient.dll + + + + 3.5 + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + FdpDataProvider.cs + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.3 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Firebird/BLToolkit.Data.DataProvider.Firebird.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Firebird/BLToolkit.Data.DataProvider.Firebird.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,143 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {C1F8C201-BBD9-44F4-884C-CFF8CC960B68} + Library + Properties + BLToolkit.Data.DataProvider.Firebird + BLToolkit.Data.DataProvider.Firebird.4 + v4.0 + 512 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\BLToolkit.Data.DataProvider.Firebird.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\BLToolkit.Data.DataProvider.Firebird.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + False + ..\..\packages\FirebirdSql.Data.FirebirdClient.4.0.0.0\lib\net40-client\FirebirdSql.Data.FirebirdClient.dll + + + + 3.5 + + + 3.5 + + + + + + + FdpDataProvider.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Firebird/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Firebird/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using System.Security; + +using BLToolkit; + +[assembly: AssemblyTitle (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyDescription (BLToolkitConstants.ProductDescription + " Data Provider")] +[assembly: AssemblyProduct (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyCopyright (BLToolkitConstants.Copyright)] +[assembly: AssemblyCulture ("")] +[assembly: ComVisible (false)] +[assembly: Guid ("6c3fb028-daf7-4134-8697-eedfe34d779e")] +[assembly: AssemblyVersion (BLToolkitConstants.FullVersionString)] +[assembly: AssemblyFileVersion (BLToolkitConstants.FullVersionString)] +[assembly: CLSCompliant (true)] +[assembly: NeutralResourcesLanguage("en-US")] +//[assembly: AllowPartiallyTrustedCallers] diff -r 000000000000 -r f990fcb411a9 DataProviders/Firebird/packages.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Firebird/packages.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Generic/App.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Generic/App.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Generic/BLToolkit.Data.DataProvider.Generic.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Generic/BLToolkit.Data.DataProvider.Generic.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,66 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {6E7FE7FC-551F-4273-ACEB-72DC0D01120E} + Library + Properties + BLToolkit.Data.DataProvider.Generic + BLToolkit.Data.DataProvider.Generic.4 + v4.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + GenericDataProvider.cs + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Generic/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Generic/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using System.Security; + +using BLToolkit; + +[assembly: AssemblyTitle (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyDescription (BLToolkitConstants.ProductDescription + " Data Provider")] +[assembly: AssemblyProduct (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyCopyright (BLToolkitConstants.Copyright)] +[assembly: AssemblyCulture ("")] +[assembly: ComVisible (false)] +[assembly: Guid ("6c3fb028-daf7-4134-8697-eedfe34d779e")] +[assembly: AssemblyVersion (BLToolkitConstants.FullVersionString)] +[assembly: AssemblyFileVersion (BLToolkitConstants.FullVersionString)] +[assembly: CLSCompliant (true)] +[assembly: NeutralResourcesLanguage("en-US")] +//[assembly: AllowPartiallyTrustedCallers] diff -r 000000000000 -r f990fcb411a9 DataProviders/Informix/BLToolkit.Data.DataProvider.Informix.3.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Informix/BLToolkit.Data.DataProvider.Informix.3.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,71 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {B1DEA25C-7667-471B-BBAD-64D017FDD104} + Library + Properties + BLToolkit.Data.DataProvider.Informix + BLToolkit.Data.DataProvider.Informix.3 + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\Redist\IBM\IBM.Data.Informix.dll + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + InformixDataProvider.cs + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.3 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Informix/BLToolkit.Data.DataProvider.Informix.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Informix/BLToolkit.Data.DataProvider.Informix.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,136 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {B1DEA25C-7667-471B-BBAD-64D017FDD104} + Library + Properties + BLToolkit.Data.DataProvider.Informix + BLToolkit.Data.DataProvider.Informix.4 + v4.0 + 512 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\BLToolkit.Data.DataProvider.Informix.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\BLToolkit.Data.DataProvider.Informix.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + + False + ..\..\Redist\IBM\IBM.Data.Informix.dll + + + + 3.5 + + + + + + + InformixDataProvider.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Informix/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Informix/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using System.Security; + +using BLToolkit; + +[assembly: AssemblyTitle (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyDescription (BLToolkitConstants.ProductDescription + " Data Provider")] +[assembly: AssemblyProduct (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyCopyright (BLToolkitConstants.Copyright)] +[assembly: AssemblyCulture ("")] +[assembly: ComVisible (false)] +[assembly: Guid ("6c3fb028-daf7-4134-8697-eedfe34d779e")] +[assembly: AssemblyVersion (BLToolkitConstants.FullVersionString)] +[assembly: AssemblyFileVersion (BLToolkitConstants.FullVersionString)] +[assembly: CLSCompliant (true)] +[assembly: NeutralResourcesLanguage("en-US")] +//[assembly: AllowPartiallyTrustedCallers] diff -r 000000000000 -r f990fcb411a9 DataProviders/MySql/BLToolkit.Data.DataProvider.MySql.3.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/MySql/BLToolkit.Data.DataProvider.MySql.3.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,74 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD} + Library + Properties + BLToolkit.Data.DataProvider.MySql + BLToolkit.Data.DataProvider.MySql.3 + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\packages\MySql.Data.6.4.4\lib\net20\mysql.data.dll + + + + 3.5 + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + MySqlDataProvider.cs + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.3 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/MySql/BLToolkit.Data.DataProvider.MySql.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/MySql/BLToolkit.Data.DataProvider.MySql.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,146 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {3578AF4C-CBFF-4A38-88F5-E86AC990AFBD} + Library + Properties + BLToolkit.Data.DataProvider.MySql + BLToolkit.Data.DataProvider.MySql.4 + v4.0 + 512 + + + 3.5 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\BLToolkit.Data.DataProvider.MySql.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + 4 + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\BLToolkit.Data.DataProvider.MySql.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + 4 + + + + False + ..\..\packages\MySql.Data.6.8.3\lib\net40\MySql.Data.dll + + + + + + + + + + + + + + + MySqlDataProvider.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/MySql/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/MySql/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using System.Security; + +using BLToolkit; + +[assembly: AssemblyTitle (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyDescription (BLToolkitConstants.ProductDescription + " Data Provider")] +[assembly: AssemblyProduct (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyCopyright (BLToolkitConstants.Copyright)] +[assembly: AssemblyCulture ("")] +[assembly: ComVisible (false)] +[assembly: Guid ("6c3fb028-daf7-4134-8697-eedfe34d779e")] +[assembly: AssemblyVersion (BLToolkitConstants.FullVersionString)] +[assembly: AssemblyFileVersion (BLToolkitConstants.FullVersionString)] +[assembly: CLSCompliant (true)] +[assembly: NeutralResourcesLanguage("en-US")] +//[assembly: AllowPartiallyTrustedCallers] diff -r 000000000000 -r f990fcb411a9 DataProviders/MySql/packages.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/MySql/packages.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Oracle/BLToolkit.Data.DataProvider.Oracle.3.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Oracle/BLToolkit.Data.DataProvider.Oracle.3.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,74 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D} + Library + Properties + BLToolkit.Data.DataProvider.Oracle + BLToolkit.Data.DataProvider.Oracle.3 + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\Redist\Oracle\Oracle.DataAccess.dll + + + + 3.5 + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + OdpDataProvider.cs + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.3 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Oracle/BLToolkit.Data.DataProvider.Oracle.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Oracle/BLToolkit.Data.DataProvider.Oracle.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,144 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {2B5287F2-A6AC-4D5A-B0A8-01C06144824D} + Library + Properties + BLToolkit.Data.DataProvider.Oracle + BLToolkit.Data.DataProvider.Oracle.4 + v4.0 + 512 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\BLToolkit.Data.DataProvider.Oracle.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\BLToolkit.Data.DataProvider.Oracle.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + + ..\..\packages\odp.net.x86.112.3.20\lib\net40\Oracle.DataAccess.dll + + + False + ..\..\packages\odp.net.managed.121.1.1\lib\net40\Oracle.ManagedDataAccess.dll + + + + 3.5 + + + 3.5 + + + + + + + OdpDataProvider.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Oracle/BLToolkit.Data.DataProvider.OracleManaged.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Oracle/BLToolkit.Data.DataProvider.OracleManaged.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,138 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {785CE174-0A91-465F-9E41-65E6E05A0EC9} + Library + Properties + BLToolkit.Data.DataProvider.Oracle + BLToolkit.Data.DataProvider.OracleManaged.4 + v4.0 + 512 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + MANAGED;DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + MANAGED;TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\BLToolkit.Data.DataProvider.OracleManaged.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\BLToolkit.Data.DataProvider.OracleManaged.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + + False + ..\..\packages\odp.net.managed.121.1.0\lib\net40\Oracle.ManagedDataAccess.dll + + + + 3.5 + + + 3.5 + + + + + + + OdpDataProvider.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Oracle/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Oracle/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using System.Security; + +using BLToolkit; + +[assembly: AssemblyTitle (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyDescription (BLToolkitConstants.ProductDescription + " Data Provider")] +[assembly: AssemblyProduct (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyCopyright (BLToolkitConstants.Copyright)] +[assembly: AssemblyCulture ("")] +[assembly: ComVisible (false)] +[assembly: Guid ("6c3fb028-daf7-4134-8697-eedfe34d779e")] +[assembly: AssemblyVersion (BLToolkitConstants.FullVersionString)] +[assembly: AssemblyFileVersion (BLToolkitConstants.FullVersionString)] +[assembly: CLSCompliant (true)] +[assembly: NeutralResourcesLanguage("en-US")] +//[assembly: AllowPartiallyTrustedCallers] diff -r 000000000000 -r f990fcb411a9 DataProviders/Oracle/packages.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Oracle/packages.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/PostgreSQL/BLToolkit.Data.DataProvider.PostgreSQL.3.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/PostgreSQL/BLToolkit.Data.DataProvider.PostgreSQL.3.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,79 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {5A556D57-0D68-433B-AD78-02849583582B} + Library + Properties + BLToolkit.Data.DataProvider.PostgreSQL + BLToolkit.Data.DataProvider.PostgreSQL.3 + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\packages\Npgsql.2.0.12.1\lib\net20\Mono.Security.dll + + + False + ..\..\packages\Npgsql.2.0.12.1\lib\net20\Npgsql.dll + + + + 3.5 + + + + 3.5 + + + 3.5 + + + + + + + PostgreSQLDataProvider.cs + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.3 + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/PostgreSQL/BLToolkit.Data.DataProvider.PostgreSQL.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/PostgreSQL/BLToolkit.Data.DataProvider.PostgreSQL.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,145 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {5A556D57-0D68-433B-AD78-02849583582B} + Library + Properties + BLToolkit.Data.DataProvider.PostgreSQL + BLToolkit.Data.DataProvider.PostgreSQL.4 + v4.0 + 512 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\BLToolkit.Data.DataProvider.PostgreSQL.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\BLToolkit.Data.DataProvider.PostgreSQL.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + + False + ..\..\packages\Npgsql.2.0.14.3\lib\net40\Mono.Security.dll + + + False + ..\..\packages\Npgsql.2.0.14.3\lib\net40\Npgsql.dll + + + + 3.5 + + + + + + + + PostgreSQLDataProvider.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/PostgreSQL/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/PostgreSQL/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using System.Security; + +using BLToolkit; + +[assembly: AssemblyTitle (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyDescription (BLToolkitConstants.ProductDescription + " Data Provider")] +[assembly: AssemblyProduct (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyCopyright (BLToolkitConstants.Copyright)] +[assembly: AssemblyCulture ("")] +[assembly: ComVisible (false)] +[assembly: Guid ("6c3fb028-daf7-4134-8697-eedfe34d779e")] +[assembly: AssemblyVersion (BLToolkitConstants.FullVersionString)] +[assembly: AssemblyFileVersion (BLToolkitConstants.FullVersionString)] +[assembly: CLSCompliant (true)] +[assembly: NeutralResourcesLanguage("en-US")] +//[assembly: AllowPartiallyTrustedCallers] diff -r 000000000000 -r f990fcb411a9 DataProviders/PostgreSQL/packages.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/PostgreSQL/packages.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/SQLite/BLToolkit.Data.DataProvider.SQLite.3.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/SQLite/BLToolkit.Data.DataProvider.SQLite.3.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,72 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {3E414663-B673-47A8-AB59-0E08FE43DA86} + Library + Properties + BLToolkit.Data.DataProvider.SQLite + BLToolkit.Data.DataProvider.SQLite.3 + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + False + ..\..\Redist\SQLite\System.Data.SQLite.DLL + False + + + 3.5 + + + 3.5 + + + + + + + SQLiteDataProvider.cs + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.3 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/SQLite/BLToolkit.Data.DataProvider.SQLite.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/SQLite/BLToolkit.Data.DataProvider.SQLite.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,152 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {3E414663-B673-47A8-AB59-0E08FE43DA86} + Library + Properties + BLToolkit.Data.DataProvider.SQLite + BLToolkit.Data.DataProvider.SQLite.4 + v4.0 + 512 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\BLToolkit.Data.DataProvider.SQLite.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\BLToolkit.Data.DataProvider.SQLite.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + + 3.5 + + + + False + ..\..\packages\System.Data.SQLite.1.0.90.0\lib\net40\System.Data.SQLite.dll + + + False + ..\..\packages\System.Data.SQLite.1.0.90.0\lib\net40\System.Data.SQLite.Linq.dll + + + + + + SQLiteDataProvider.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + Always + + + Always + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/SQLite/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/SQLite/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using System.Security; + +using BLToolkit; + +[assembly: AssemblyTitle (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyDescription (BLToolkitConstants.ProductDescription + " Data Provider")] +[assembly: AssemblyProduct (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyCopyright (BLToolkitConstants.Copyright)] +[assembly: AssemblyCulture ("")] +[assembly: ComVisible (false)] +[assembly: Guid ("6c3fb028-daf7-4134-8697-eedfe34d779e")] +[assembly: AssemblyVersion (BLToolkitConstants.FullVersionString)] +[assembly: AssemblyFileVersion (BLToolkitConstants.FullVersionString)] +[assembly: CLSCompliant (true)] +[assembly: NeutralResourcesLanguage("en-US")] +//[assembly: AllowPartiallyTrustedCallers] diff -r 000000000000 -r f990fcb411a9 DataProviders/SQLite/packages.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/SQLite/packages.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/SQLite/x64/SQLite.Interop.dll Binary file DataProviders/SQLite/x64/SQLite.Interop.dll has changed diff -r 000000000000 -r f990fcb411a9 DataProviders/SQLite/x86/SQLite.Interop.dll Binary file DataProviders/SQLite/x86/SQLite.Interop.dll has changed diff -r 000000000000 -r f990fcb411a9 DataProviders/SqlCe/BLToolkit.Data.DataProvider.SqlCe.3.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/SqlCe/BLToolkit.Data.DataProvider.SqlCe.3.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,71 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {85E90F57-8DE1-4912-8414-28578F4D71CD} + Library + Properties + BLToolkit.Data.DataProvider.SqlCe + BLToolkit.Data.DataProvider.SqlCe.3 + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + False + ..\..\Redist\SqlCe\System.Data.SqlServerCe.dll + + + 3.5 + + + 3.5 + + + + + + + SqlCeDataProvider.cs + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.3 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/SqlCe/BLToolkit.Data.DataProvider.SqlCe.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/SqlCe/BLToolkit.Data.DataProvider.SqlCe.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,149 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {85E90F57-8DE1-4912-8414-28578F4D71CD} + Library + Properties + BLToolkit.Data.DataProvider.SqlCe + BLToolkit.Data.DataProvider.SqlCe.4 + v4.0 + 512 + + + 3.5 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\BLToolkit.Data.DataProvider.SqlCe.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\BLToolkit.Data.DataProvider.SqlCe.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + + 3.5 + + + + True + ..\..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll + + + + + + SqlCeDataProvider.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + + + + if not exist "$(TargetDir)x86" md "$(TargetDir)x86" + xcopy /s /y "$(ProjectDir)...\..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86" +if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64" + xcopy /s /y "$(ProjectDir)..\..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64" + 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 -r 000000000000 -r f990fcb411a9 DataProviders/SqlCe/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/SqlCe/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using System.Security; + +using BLToolkit; + +[assembly: AssemblyTitle (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyDescription (BLToolkitConstants.ProductDescription + " Data Provider")] +[assembly: AssemblyProduct (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyCopyright (BLToolkitConstants.Copyright)] +[assembly: AssemblyCulture ("")] +[assembly: ComVisible (false)] +[assembly: Guid ("6c3fb028-daf7-4134-8697-eedfe34d779e")] +[assembly: AssemblyVersion (BLToolkitConstants.FullVersionString)] +[assembly: AssemblyFileVersion (BLToolkitConstants.FullVersionString)] +[assembly: CLSCompliant (true)] +[assembly: NeutralResourcesLanguage("en-US")] +//[assembly: AllowPartiallyTrustedCallers] diff -r 000000000000 -r f990fcb411a9 DataProviders/SqlCe/packages.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/SqlCe/packages.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Sybase/BLToolkit.Data.DataProvider.Sybase.3.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Sybase/BLToolkit.Data.DataProvider.Sybase.3.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,72 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {6CD8CC3D-643D-4D09-8660-A26085C44FBC} + Library + Properties + BLToolkit.Data.DataProvider.Sybase + BLToolkit.Data.DataProvider.Sybase.3 + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\Redist\Sybase\Sybase.AdoNet2.AseClient.dll + False + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + SybaseDataProvider.cs + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.3 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Sybase/BLToolkit.Data.DataProvider.Sybase.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Sybase/BLToolkit.Data.DataProvider.Sybase.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,139 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {6CD8CC3D-643D-4D09-8660-A26085C44FBC} + Library + Properties + BLToolkit.Data.DataProvider.Sybase + BLToolkit.Data.DataProvider.Sybase.4 + v4.0 + 512 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\BLToolkit.Data.DataProvider.Sybase.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\BLToolkit.Data.DataProvider.Sybase.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + False + ..\..\Redist\Sybase\Sybase.AdoNet2.AseClient.dll + False + + + + 3.5 + + + + + + + SybaseDataProvider.cs + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 DataProviders/Sybase/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataProviders/Sybase/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using System.Security; + +using BLToolkit; + +[assembly: AssemblyTitle (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyDescription (BLToolkitConstants.ProductDescription + " Data Provider")] +[assembly: AssemblyProduct (BLToolkitConstants.ProductName + " Data Provider")] +[assembly: AssemblyCopyright (BLToolkitConstants.Copyright)] +[assembly: AssemblyCulture ("")] +[assembly: ComVisible (false)] +[assembly: Guid ("6c3fb028-daf7-4134-8697-eedfe34d779e")] +[assembly: AssemblyVersion (BLToolkitConstants.FullVersionString)] +[assembly: AssemblyFileVersion (BLToolkitConstants.FullVersionString)] +[assembly: CLSCompliant (true)] +[assembly: NeutralResourcesLanguage("en-US")] +//[assembly: AllowPartiallyTrustedCallers] diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/BusinessLogic/Cart.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/BusinessLogic/Cart.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; + +namespace PetShop.BusinessLogic +{ + using ObjectModel; + + [Serializable] + public class Cart + { + /// + /// Calculate the total for all the cartItems in the Cart + /// + public decimal Total + { + get + { + decimal total = 0; + + foreach (CartItem item in _items.Values) + total += item.Subtotal; + + return total; + } + } + + /// + /// Update the quantity for item that exists in the cart + /// + /// Item Id + /// Quantity + public void SetQuantity(string itemId, int qty) + { + _items[itemId].Quantity = qty; + } + + /// + /// Return the number of unique items in cart + /// + public int Count + { + get { return _items.Count; } + } + + /// + /// Add an item to the cart. + /// When ItemId to be added has already existed, this method will update the quantity instead. + /// + /// Item Id of item to add + public void Add(string itemId) + { + CartItem cartItem; + + if (!_items.TryGetValue(itemId, out cartItem)) + { + Item item = new ProductManager().GetItem(itemId); + + if (item != null) + { + cartItem = new CartItem(); + + cartItem.ItemID = itemId; + cartItem.Name = item.ProductName; + cartItem.Price = (decimal)item.Price; + cartItem.Type = item.Name; + cartItem.CategoryID = item.CategoryID; + cartItem.ProductID = item.ProductID; + + _items.Add(itemId, cartItem); + } + } + + cartItem.Quantity++; + } + + /// + /// Add an item to the cart. + /// When ItemId to be added has already existed, this method will update the quantity instead. + /// + /// Item to add + public void Add(CartItem item) + { + CartItem cartItem; + + if (!_items.TryGetValue(item.ItemID, out cartItem)) + _items.Add(item.ItemID, item); + else + cartItem.Quantity += item.Quantity; + } + + /// + /// Remove item from the cart based on + /// + /// ItemId of item to remove + public void Remove(string itemId) + { + _items.Remove(itemId); + } + + // Internal storage for a cart + private Dictionary _items = new Dictionary(); + + /// + /// Returns all items in the cart. Useful for looping through the cart. + /// + /// Collection of CartItemInfo + public ICollection Items + { + get { return _items.Values; } + } + + /// + /// Method to convert all cart items to order line items + /// + /// A new array of order line items + public OrderLineItem[] GetOrderLineItems() + { + OrderLineItem[] items = new OrderLineItem[_items.Count]; + + int lineNum = 0; + + foreach (CartItem item in _items.Values) + { + OrderLineItem line = new OrderLineItem(); + + items[lineNum] = line; + + line.ItemID = item.ItemID; + line.Line = ++lineNum; + line.Quantity = item.Quantity; + line.Price = item.Price; + } + + return items; + } + + /// + /// Clear the cart + /// + public void Clear() + { + _items.Clear(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/BusinessLogic/DataAccess/AccessorBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/BusinessLogic/DataAccess/AccessorBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; + +using BLToolkit.Aspects; +using BLToolkit.Data; +using BLToolkit.DataAccess; +using BLToolkit.Reflection; + +namespace PetShop.BusinessLogic.DataAccess +{ + [Log, Counter] + public abstract class AccessorBase : DataAccessor + where D : DbManager, new() + where A : AccessorBase + { + #region Overrides + + [NoInterception] + protected override DbManager CreateDbManager() + { + return new D(); + } + + #endregion + + #region CreateInstance + + public static A CreateInstance() + { + return TypeAccessor.CreateInstance(); + } + + #endregion + + #region Query + + [Log, Counter] + public abstract class PetShopQuery : SqlQuery + { + [NoInterception] + protected override DbManager CreateDbManager() + { + return new D(); + } + + #region SelectByKeyWords + + public virtual List SelectByKeyWords(string[] keyWords) + { + StringBuilder sql = new StringBuilder("SELECT * FROM "); + + sql.Append(GetTableName(typeof(T))); + sql.Append(" WHERE "); + + for (int i = 0; i < keyWords.Length; i++) + { + if (i > 0) + sql.Append(" OR "); + + sql.AppendFormat("LOWER(Name) LIKE @kw{0} OR LOWER(CategoryId) LIKE @kw{0}", i); + } + + using (DbManager db = GetDbManager()) + { + IDbDataParameter[] parms = new IDbDataParameter[keyWords.Length]; + + for (int i = 0; i < keyWords.Length; i++) + parms[i] = db.Parameter("@kw" + i, "%" + keyWords[i].ToLower() + "%"); + + return db.SetCommand(sql.ToString(), parms).ExecuteList(); + } + } + + #endregion + + #region InsertAndGetIdentity + + public virtual int InsertAndGetIdentity(DbManager db, object obj) + { + SqlQueryInfo query = GetSqlQueryInfo(db, obj.GetType(), "InsertAndGetIdentity"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, obj)) + .ExecuteScalar(); + } + + public virtual int InsertAndGetIdentity(object obj) + { + DbManager db = GetDbManager(); + + try + { + return InsertAndGetIdentity(db, obj); + } + finally + { + Dispose(db); + } + } + + [NoInterception] + protected override SqlQueryInfo CreateSqlText(DbManager db, Type type, string actionName) + { + switch (actionName) + { + case "InsertAndGetIdentity": + SqlQueryInfo qi = CreateInsertSqlText(db, type, -1); + + qi.QueryText += "\nSELECT Cast(SCOPE_IDENTITY() as int)"; + + return qi; + + default : + return base.CreateSqlText(db, type, actionName); + } + } + + #endregion + } + + public PetShopQuery Query + { + get { return TypeAccessor.CreateInstance(); } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/BusinessLogic/DataAccess/InventoryAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/BusinessLogic/DataAccess/InventoryAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,17 @@ +using System; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace PetShop.BusinessLogic.DataAccess +{ + using ObjectModel; + + public abstract class InventoryAccessor : AccessorBase + { + public class DB : DbManager { public DB() : base("InventoryDB") {} } + + [SqlQuery(@"UPDATE Inventory SET Qty = Qty - @qty WHERE ItemId = @itemId")] + public abstract void TakeInventory(DbManager db, int @qty, string @itemId); + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/BusinessLogic/DataAccess/OrderAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/BusinessLogic/DataAccess/OrderAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace PetShop.BusinessLogic.DataAccess +{ + using ObjectModel; + + public abstract class OrderAccessor : AccessorBase + { + public class DB : DbManager { public DB() : base("OrderDB") {} } + + [SqlQuery(@"INSERT INTO OrderStatus (OrderId, LineNum, Timestamp, Status) VALUES (@id, @id, GetDate(), 'P')")] + public abstract void InsertStatus(DbManager db, int @id); + + [SqlQuery(@" + SELECT + o.*, + os.Status + FROM + Orders o + JOIN OrderStatus os ON os.OrderId = o.OrderId + ORDER BY + o.OrderId DESC")] + public abstract List GetAllOrderList(); + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/BusinessLogic/DataAccess/ProductAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/BusinessLogic/DataAccess/ProductAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; + +using BLToolkit.Aspects; +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace PetShop.BusinessLogic.DataAccess +{ + using ObjectModel; + + public abstract class ProductAccessor : AccessorBase + { + public class DB : DbManager { public DB() : base("ProductDB") {} } + + #region Item + + const string _itemQuery = @" + SELECT + i.*, + n.Qty, + p.Name as ProductName, + p.CategoryId + FROM + Item i + JOIN Product p ON p.ProductId = i.ProductId + JOIN Inventory n ON n.ItemId = i.ItemId"; + + [SqlQuery(_itemQuery + @" WHERE i.ProductId = @id")] + public abstract IList GetItemListByProductID(string @id); + + [SqlQuery(_itemQuery + @" WHERE i.ItemId = @itemID")] + public abstract Item GetItem(string @itemID); + + [SqlQuery(_itemQuery + @" ORDER BY i.Name")] + public abstract List GetAllItemList(); + + #endregion + + #region Product + + [Cache(MaxMinutes = 60)] + [SqlQuery(@"SELECT * FROM Product WHERE CategoryId = @id")] + public abstract IList GetProductListByCategoryID(string @id); + + #endregion + + #region Categoty + + // This method needs to be cached, so we can't call Query.SelectByKey directly from the manager class. + // + [Cache(MaxMinutes=60)] + public virtual Category GetCategory(string id) + { + return Query.SelectByKey(id); + } + + #endregion + + #region Inventory + + [SqlQuery(@"SELECT Qty FROM Inventory WHERE ItemId = @itemId")] + public abstract int CurrentQtyInStock(string @itemId); + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/BusinessLogic/DataAccess/ProfileAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/BusinessLogic/DataAccess/ProfileAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace PetShop.BusinessLogic.DataAccess +{ + using ObjectModel; + + public abstract class ProfileAccessor : AccessorBase + { + public class DB : DbManager { public DB() : base("ProfileDB") {} } + + [SqlQuery(@" + SELECT + UniqueID + FROM + Profiles + WHERE + Username = @userName AND ApplicationName = @appName")] + public abstract int? GetUniqueID(string @userName, string @appName); + + [SqlQuery(@" + SELECT + UniqueID + FROM + Profiles + WHERE + Username = @userName AND ApplicationName = @appName AND IsAnonymous != @isAuthenticated")] + public abstract int? GetUniqueIDAuth(string @userName, string @appName, bool @isAuthenticated); + + [SqlQuery(@" + INSERT INTO Profiles ( + Username, ApplicationName, LastActivityDate, LastUpdatedDate, IsAnonymous + ) Values ( + @userName, @appName, getdate(), getdate(), CASE WHEN @isAuthenticated = 1 THEN 0 ELSE 1 END + ) + + SELECT SCOPE_IDENTITY()")] + public abstract int CreateProfile(string @userName, string @appName, bool @isAuthenticated); + + [SqlQuery(@" + SELECT + a.FirstName as ToFirstName, + a.LastName as ToLastName, + a.Address1 as Addr1, + a.Address2 as Addr2, + a.City, + a.State, + a.Zip, + a.Country, + a.Email, + a.Phone + FROM + Account a + JOIN Profiles p ON p.UniqueID = a.UniqueID + WHERE + p.Username = @userName AND p.ApplicationName = @appName;")] + public abstract Address GetAccountInfo(string @userName, string @appName); + + [SqlQuery(@" + SELECT + c.ItemId, + c.Name, + c.Type, + c.Price, + c.CategoryId, + c.ProductId, + c.Quantity + FROM + Profiles p + JOIN Cart c ON c.UniqueID = p.UniqueID + WHERE + p.Username = @userName AND + p.ApplicationName = @appName AND + c.IsShoppingCart = @isShoppingCart")] + public abstract IList GetCartItems(string @userName, string @appName, bool @isShoppingCart); + + [SqlQuery(@" + DELETE FROM Account WHERE UniqueID = @uniqueID + + INSERT INTO Account ( + UniqueID, Email, FirstName, LastName, Address1, Address2, City, State, Zip, Country, Phone + ) VALUES ( + @uniqueID, @Email, @ToFirstName, @ToLastName, @Addr1, @Addr2, @City, @State, @Zip, @Country, @Phone + )")] + public abstract void SetAccountInfo(int @uniqueID, Address address); + + // This method is not abstract as BLToolkit does not generate methods for the ExecuteForEach method. + // It's virtual as we want to get statistic info for this method. + // Counter and Log aspects wrap all abstract, virtual, and override members. + // + public virtual void SetCartItems(int uniqueID, ICollection cartItems, bool isShoppingCart) + { + using (DbManager db = GetDbManager()) + { + db.BeginTransaction(); + + db + .SetCommand(@" + DELETE FROM + Cart + WHERE + UniqueID = @uniqueID AND IsShoppingCart = @isShoppingCart", + db.Parameter("@uniqueID", uniqueID), + db.Parameter("@isShoppingCart", isShoppingCart)) + .ExecuteNonQuery(); + + if (cartItems.Count > 0) + { + db + .SetCommand(@" + INSERT INTO Cart ( + UniqueID, ItemId, Name, Type, Price, CategoryId, ProductId, IsShoppingCart, Quantity + ) VALUES ( + @uniqueID, @ItemId, @Name, @Type, @Price, @CategoryId, @ProductId, @isShoppingCart, @Quantity + )", + db.CreateParameters(typeof(CartItem), + db.Parameter("@uniqueID", uniqueID), + db.Parameter("@isShoppingCart", isShoppingCart))) + .ExecuteForEach(cartItems); + } + + db.CommitTransaction(); + } + } + + [SqlQuery(@" + UPDATE + Profiles + SET + LastActivityDate = getdate() + WHERE + Username = @userName AND ApplicationName = @appName")] + public abstract void UpdateActivityDate(string @userName, string @appName); + + [SqlQuery(@" + UPDATE + Profiles + SET + LastActivityDate = getdate(), + LastUpdatedDate = getdate() + WHERE + Username = @userName AND ApplicationName = @appName")] + public abstract void UpdateActivityAndUdpateDates(string @userName, string @appName); + + [SqlQuery(@"DELETE FROM Profiles WHERE UniqueID = @uniqueID")] + [ScalarSource(ScalarSourceType.AffectedRows)] + public abstract int DeleteProfile(int @uniqueID); + + [SqlQuery(@" + SELECT + Username + FROM + Profiles + WHERE ApplicationName = @appName AND LastActivityDate <= @userInactiveSinceDate")] + public abstract IList GetInactiveProfiles(DateTime userInactiveSinceDate, string appName); + + [SqlQuery(@" + SELECT + Username + FROM + Profiles + WHERE ApplicationName = @appName AND LastActivityDate <= @userInactiveSinceDate AND IsAnonymous = @isAnonymous")] + public abstract IList GetInactiveProfiles(DateTime @userInactiveSinceDate, string @appName, bool @isAnonymous); + + const string _profileQuery = @" + FROM + Profiles + WHERE + ApplicationName = @appName AND + (@isAnonymous IS NULL OR IsAnonymous = @isAnonymous) AND + (@userName IS NULL OR Username LIKE @userName) AND + (@userInactiveSinceDate IS NULL OR LastActivityDate >= @userInactiveSinceDate)"; + + [SqlQuery(@" + SELECT @totalRecords = Count(*)" + _profileQuery + @" + SELECT *" + _profileQuery)] + public abstract IList GetProfile( + bool? @isAnonymous, string @userName, DateTime? @userInactiveSinceDate, string @appName, out int @totalRecords); + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/BusinessLogic/OrderManager.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/BusinessLogic/OrderManager.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Transactions; + +using BLToolkit.Data; + +namespace PetShop.BusinessLogic +{ + using DataAccess; + using ObjectModel; + + public class OrderManager + { + #region Order + + /// + /// Inserts the order and updates the inventory stock within a transaction. + /// + /// All information about the order + public void InsertOrder(Order order) + { + using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required)) + { + OrderAccessor accessor = Accessor; + + using (DbManager db = accessor.GetDbManager()) + { + order.Courier = "UPS"; + order.Locale = "US_en"; + order.ID = accessor.Query.InsertAndGetIdentity(db, order); + + accessor.InsertStatus(db, order.ID); + + for (int i = 0; i < order.Lines.Length; i++) + { + OrderLineItem line = order.Lines[i]; + + line.OrderID = order.ID; + + accessor.Query.Insert(line); + } + } + + InventoryAccessor inv = InventoryAccessor.CreateInstance(); + + using (DbManager db = inv.GetDbManager()) + foreach (OrderLineItem line in order.Lines) + inv.TakeInventory(db, line.Quantity, line.ItemID); + + ts.Complete(); + } + } + + public List GetAllOrderList() + { + return Accessor.GetAllOrderList(); + } + + #endregion + + #region Accessor + + OrderAccessor Accessor + { + [System.Diagnostics.DebuggerStepThrough] + get { return OrderAccessor.CreateInstance(); } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/BusinessLogic/PetShop.BusinessLogic.2005.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/BusinessLogic/PetShop.BusinessLogic.2005.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,71 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE} + Library + Properties + PetShop.BusinessLogic + PetShop.BusinessLogic + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + {F4DF7358-8EE6-49FD-AB13-EA5145058D79} + BLToolkit.2 + + + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8} + PetShop.ObjectModel.2005 + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/BusinessLogic/PetShop.BusinessLogic.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/BusinessLogic/PetShop.BusinessLogic.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,157 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {01C318D0-1CB1-4CB4-A5ED-D311665C76EE} + Library + Properties + PetShop.BusinessLogic + PetShop.BusinessLogic + + + 3.5 + + + false + v4.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\PetShop.BusinessLogic.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\PetShop.BusinessLogic.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8} + PetShop.ObjectModel + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/BusinessLogic/ProductManager.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/BusinessLogic/ProductManager.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace PetShop.BusinessLogic +{ + using DataAccess; + using ObjectModel; + + public class ProductManager + { + #region Product + + public Product GetProduct(string id) + { + return Accessor.Query.SelectByKey(id) ?? new Product(); + } + + public IList GetProductListByCategoryID(string id) + { + return Accessor.GetProductListByCategoryID(id); + } + + public IList SearchProducts(string[] keyWords) + { + return Accessor.Query.SelectByKeyWords(keyWords); + } + + #endregion + + #region Item + + public IList GetItemListByProductID(string id) + { + return Accessor.GetItemListByProductID(id); + } + + public Item GetItem(string itemId) + { + return Accessor.GetItem(itemId); + } + + public List GetAllItemList() + { + return Accessor.GetAllItemList(); + } + + #endregion + + #region Category + + public IList GetCategoryList() + { + return Accessor.Query.SelectAll(); + } + + public Category GetCategory(string id) + { + return Accessor.GetCategory(id); + } + + public List SearchCategories(string[] keyWords) + { + return Accessor.Query.SelectByKeyWords(keyWords); + } + + #endregion + + #region Accessor + + ProductAccessor Accessor + { + [System.Diagnostics.DebuggerStepThrough] + get { return ProductAccessor.CreateInstance(); } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/BusinessLogic/ProfileProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/BusinessLogic/ProfileProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,419 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Configuration; +using System.Web.Profile; + +namespace PetShop.BusinessLogic +{ + using DataAccess; + using ObjectModel; + + public sealed class ProfileProvider : System.Web.Profile.ProfileProvider + { + private static string _applicationName = ".NET Pet Shop 4.0"; + + /// + /// The name of the application using the custom profile provider. + /// + public override string ApplicationName + { + get { return _applicationName; } + set { _applicationName = value; } + } + + /// + /// Initializes the provider. + /// + /// The friendly name of the provider. + /// A collection of the name/value pairs representing the provider-specific attributes specified in the configuration for this provider. + public override void Initialize(string name, NameValueCollection config) + { + if (config == null) + throw new ArgumentNullException("config"); + + if (string.IsNullOrEmpty(config["description"])) + { + config.Remove("description"); + config.Add("description", "Pet Shop Custom Profile Provider"); + } + + if (string.IsNullOrEmpty(name)) + name = "PetShopProfileProvider"; + + if (config["applicationName"] != null && !string.IsNullOrEmpty(config["applicationName"].Trim())) + _applicationName = config["applicationName"]; + + base.Initialize(name, config); + } + + private const string ERR_INVALID_PARAMETER = "Invalid Profile parameter:"; + private const string PROFILE_SHOPPINGCART = "ShoppingCart"; + private const string PROFILE_WISHLIST = "WishList"; + private const string PROFILE_ACCOUNT = "AccountInfo"; + + /// + /// Returns the collection of settings property values for the specified application instance and settings property group. + /// + /// A System.Configuration.SettingsContext describing the current application use. + /// A System.Configuration.SettingsPropertyCollection containing the settings property group whose values are to be retrieved. + /// A System.Configuration.SettingsPropertyValueCollection containing the values for the specified settings property group. + public override SettingsPropertyValueCollection GetPropertyValues( + SettingsContext context, SettingsPropertyCollection collection) + { + string username = (string)context["UserName"]; + bool isAuthenticated = (bool) context["IsAuthenticated"]; + + SettingsPropertyValueCollection svc = new SettingsPropertyValueCollection(); + + foreach (SettingsProperty prop in collection) + { + SettingsPropertyValue pv = new SettingsPropertyValue(prop); + + switch (pv.Property.Name) + { + case PROFILE_SHOPPINGCART: pv.PropertyValue = GetCartItems(username, true); break; + case PROFILE_WISHLIST: pv.PropertyValue = GetCartItems(username, false); break; + case PROFILE_ACCOUNT: + if (isAuthenticated) + pv.PropertyValue = GetAccountInfo(username); + break; + + default: + throw new ApplicationException(ERR_INVALID_PARAMETER + " name."); + } + + svc.Add(pv); + } + + return svc; + } + + /// + /// Sets the values of the specified group of property settings. + /// + /// A System.Configuration.SettingsContext describing the current application usage. + /// A System.Configuration.SettingsPropertyValueCollection representing the group of property settings to set. + public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) + { + string username = (string)context["UserName"]; + + CheckUserName(username); + + bool isAuthenticated = (bool)context["IsAuthenticated"]; + int uniqueID = GetUniqueID(username, isAuthenticated, false, ApplicationName); + + foreach (SettingsPropertyValue pv in collection) + { + if (pv.PropertyValue != null) + { + switch (pv.Property.Name) + { + case PROFILE_SHOPPINGCART: SetCartItems(uniqueID, (Cart)pv.PropertyValue, true); break; + case PROFILE_WISHLIST: SetCartItems(uniqueID, (Cart)pv.PropertyValue, false); break; + case PROFILE_ACCOUNT: + if (isAuthenticated) + SetAccountInfo(uniqueID, (Address)pv.PropertyValue); + break; + + default: + throw new ApplicationException(ERR_INVALID_PARAMETER + " name."); + } + } + } + + UpdateActivityDates(username, false); + } + + private int GetUniqueID(string userName, bool isAuthenticated, bool ignoreAuthenticationType, string appName) + { + int? uniqueID = ignoreAuthenticationType ? + Accessor.GetUniqueID (userName, appName) : + Accessor.GetUniqueIDAuth(userName, appName, isAuthenticated); + + return uniqueID ?? Accessor.CreateProfile(userName, appName, isAuthenticated); + } + + private Address GetAccountInfo(string username) + { + return Accessor.GetAccountInfo(username, _applicationName); + } + + private Cart GetCartItems(string username, bool isShoppingCart) + { + Cart cart = new Cart(); + + foreach (CartItem cartItem in Accessor.GetCartItems(username, _applicationName, isShoppingCart)) + cart.Add(cartItem); + + return cart; + } + + private void SetAccountInfo(int uniqueID, Address address) + { + Accessor.SetAccountInfo(uniqueID, address); + } + + private void SetCartItems(int uniqueID, Cart cart, bool isShoppingCart) + { + Accessor.SetCartItems(uniqueID, cart.Items, isShoppingCart); + } + + // UpdateActivityDates + // Updates the LastActivityDate and LastUpdatedDate values + // when profile properties are accessed by the + // GetPropertyValues and SetPropertyValues methods. + // Passing true as the activityOnly parameter will update + // only the LastActivityDate. + private void UpdateActivityDates(string username, bool activityOnly) + { + if (activityOnly) + Accessor.UpdateActivityDate(username, _applicationName); + else + Accessor.UpdateActivityAndUdpateDates(username, _applicationName); + } + + /// + /// Deletes profile properties and information for the supplied list of profiles. + /// + /// A System.Web.Profile.ProfileInfoCollection of information about profiles that are to be deleted. + /// The number of profiles deleted from the data source. + public override int DeleteProfiles(ProfileInfoCollection profiles) + { + int deleteCount = 0; + + foreach (ProfileInfo p in profiles) + if (DeleteProfile(p.UserName)) + deleteCount++; + + return deleteCount; + } + + /// + /// Deletes profile properties and information for profiles that match the supplied list of user names. + /// + /// A string array of user names for profiles to be deleted. + /// The number of profiles deleted from the data source. + public override int DeleteProfiles(string[] usernames) + { + int deleteCount = 0; + + foreach (string user in usernames) + if (DeleteProfile(user)) + deleteCount++; + + return deleteCount; + } + + // DeleteProfile + // Deletes profile data from the database for the specified user name. + private bool DeleteProfile(string username) + { + CheckUserName(username); + + int? uniqueID = Accessor.GetUniqueID(username, _applicationName); + + return uniqueID != null && Accessor.DeleteProfile(uniqueID.Value) > 0; + } + + // Verifies user name for sise and comma + private static void CheckUserName(string userName) + { + if (string.IsNullOrEmpty(userName) || userName.Length > 256 || userName.IndexOf(",") > 0) + throw new ApplicationException(ERR_INVALID_PARAMETER + " user name."); + } + + /// + /// Deletes all user-profile data for profiles in which the last activity date occurred before the specified date. + /// + /// One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are deleted. + /// A System.DateTime that identifies which user profiles are considered inactive. If the System.Web.Profile.ProfileInfo.LastActivityDate value of a user profile occurs on or before this date and time, the profile is considered inactive. + /// The number of profiles deleted from the data source. + public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) + { + IList list; + + switch (authenticationOption) + { + case ProfileAuthenticationOption.Anonymous: + list = Accessor.GetInactiveProfiles(userInactiveSinceDate, ApplicationName, true); + break; + + case ProfileAuthenticationOption.Authenticated: + list = Accessor.GetInactiveProfiles(userInactiveSinceDate, ApplicationName, false); + break; + + default: + list = Accessor.GetInactiveProfiles(userInactiveSinceDate, ApplicationName); + break; + } + + string[] userArray = new string[list.Count]; + + list.CopyTo(userArray, 0); + + return DeleteProfiles(userArray); + } + + /// + /// Retrieves profile information for profiles in which the user name matches the specified user names. + /// + /// One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned. + /// The user name to search for. + /// The index of the page of results to return. + /// The size of the page of results to return. + /// When this method returns, contains the total number of profiles. + /// A System.Web.Profile.ProfileInfoCollection containing user-profile information + /// for profiles where the user name matches the supplied usernameToMatch parameter. + public override ProfileInfoCollection FindProfilesByUserName( + ProfileAuthenticationOption authenticationOption, string usernameToMatch, + int pageIndex, int pageSize, out int totalRecords) + { + CheckParameters(pageIndex, pageSize); + + return GetProfileInfo(authenticationOption, usernameToMatch, null, pageIndex, pageSize, out totalRecords); + } + + /// + /// Retrieves profile information for profiles in which the last activity date occurred on or before the specified date and the user name matches the specified user name. + /// + /// One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned. + /// The user name to search for. + /// A System.DateTime that identifies which user profiles are considered inactive. If the System.Web.Profile.ProfileInfo.LastActivityDate value of a user profile occurs on or before this date and time, the profile is considered inactive. + /// The index of the page of results to return. + /// The size of the page of results to return. + /// When this method returns, contains the total number of profiles. + /// A System.Web.Profile.ProfileInfoCollection containing user profile information for inactive profiles where the user name matches the supplied usernameToMatch parameter. + public override ProfileInfoCollection FindInactiveProfilesByUserName( + ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, + int pageIndex, int pageSize, out int totalRecords) + { + CheckParameters(pageIndex, pageSize); + + return GetProfileInfo(authenticationOption, usernameToMatch, userInactiveSinceDate, pageIndex, pageSize, out totalRecords); + } + + /// + /// Retrieves user profile data for all profiles in the data source. + /// + /// One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned. + /// The index of the page of results to return. + /// The size of the page of results to return. + /// When this method returns, contains the total number of profiles. + /// A System.Web.Profile.ProfileInfoCollection containing user-profile information for all profiles in the data source. + public override ProfileInfoCollection GetAllProfiles( + ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords) + { + CheckParameters(pageIndex, pageSize); + + return GetProfileInfo(authenticationOption, null, null, pageIndex, pageSize, out totalRecords); + } + + /// + /// Retrieves user-profile data from the data source for profiles in which the last activity date occurred on or before the specified date. + /// + /// One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned. + /// A System.DateTime that identifies which user profiles are considered inactive. If the System.Web.Profile.ProfileInfo.LastActivityDate of a user profile occurs on or before this date and time, the profile is considered inactive. + /// The index of the page of results to return. + /// The size of the page of results to return. + /// When this method returns, contains the total number of profiles. + /// A System.Web.Profile.ProfileInfoCollection containing user-profile information about the inactive profiles. + public override ProfileInfoCollection GetAllInactiveProfiles( + ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, + int pageIndex, int pageSize, out int totalRecords) + { + CheckParameters(pageIndex, pageSize); + + return GetProfileInfo(authenticationOption, null, userInactiveSinceDate, pageIndex, pageSize, out totalRecords); + } + + /// + /// Returns the number of profiles in which the last activity date occurred on or before the specified date. + /// + /// One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned. + /// A System.DateTime that identifies which user profiles are considered inactive. If the System.Web.Profile.ProfileInfo.LastActivityDate of a user profile occurs on or before this date and time, the profile is considered inactive. + /// The number of profiles in which the last activity date occurred on or before the specified date. + public override int GetNumberOfInactiveProfiles( + ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) + { + int inactiveProfiles = 0; + + ProfileInfoCollection profiles = GetProfileInfo(authenticationOption, null, userInactiveSinceDate, 0, 0, out inactiveProfiles); + + return inactiveProfiles; + } + + private static void CheckParameters(int pageIndex, int pageSize) + { + if (pageIndex < 1 || pageSize < 1) + throw new ApplicationException(ERR_INVALID_PARAMETER + " page index."); + } + + // GetProfileInfo + // Retrieves a count of profiles and creates a + // ProfileInfoCollection from the profile data in the + // database. Called by GetAllProfiles, GetAllInactiveProfiles, + // FindProfilesByUserName, FindInactiveProfilesByUserName, + // and GetNumberOfInactiveProfiles. + // Specifying a pageIndex of 0 retrieves a count of the results only. + private ProfileInfoCollection GetProfileInfo( + ProfileAuthenticationOption authenticationOption, + string usernameToMatch, + DateTime? userInactiveSinceDate, + int pageIndex, + int pageSize, + out int totalRecords) + { + totalRecords = 0; + + ProfileInfoCollection profiles = new ProfileInfoCollection(); + + // Count profiles only. + if (pageSize == 0) + return profiles; + + int counter = 0; + int startIndex = pageSize * (pageIndex - 1); + int endIndex = startIndex + pageSize - 1; + + bool? isAnonymous = null; + + if (authenticationOption == ProfileAuthenticationOption.Anonymous) + isAnonymous = true; + else if (authenticationOption == ProfileAuthenticationOption.Authenticated) + isAnonymous = false; + + foreach (CustomProfile profile in Accessor.GetProfile( + isAnonymous, usernameToMatch, userInactiveSinceDate, _applicationName, out totalRecords)) + { + if (counter >= startIndex) + { + ProfileInfo p = new ProfileInfo( + profile.UserName, + profile.IsAnonymous ?? true, + profile.LastActivityDate ?? DateTime.MinValue, + profile.LastUpdatedDate ?? DateTime.MinValue, 0); + + profiles.Add(p); + } + + if (counter >= endIndex) + break; + + counter++; + } + + return profiles; + } + + #region Accessor + + ProfileAccessor Accessor + { + [System.Diagnostics.DebuggerStepThrough] + get { return ProfileAccessor.CreateInstance(); } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/BusinessLogic/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/BusinessLogic/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("PetShop.BusinessLogic")] +[assembly: AssemblyProduct("PetShop.BusinessLogic")] +[assembly: AssemblyCopyright("\xA9 2002-2012 www.bltoolkit.net")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1b814eca-adcd-4780-bdaa-f335a66f5030")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion ("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/Address.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/Address.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ +using System; + +using BLToolkit.Common; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace PetShop.ObjectModel +{ + public class Address : EntityBase + { + [MapField("ToFirstName")] public string FirstName; + [MapField("ToLastName")] public string LastName; + [MapField("Addr1")] public string Line1; + [MapField("Addr2")] public string Line2; + public string City; + public string State; + public string Zip; + public string Country; + + [NonUpdatable] public string Phone; + [NonUpdatable] public string Email; + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/CartItem.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/CartItem.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +using System; + +using BLToolkit.Common; +using BLToolkit.Mapping; + +namespace PetShop.ObjectModel +{ + [Serializable] + public class CartItem : EntityBase + { + [MapField("ItemId")] public string ItemID; + public string Name; + public int Quantity; + public decimal Price; + public string Type; + [MapField("CategoryId")] public string CategoryID; + [MapField("ProductId")] public string ProductID; + + [MapIgnore] public decimal Subtotal { get { return Price * Quantity; } } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/Category.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/Category.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +using System; + +using BLToolkit.Common; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace PetShop.ObjectModel +{ + public class Category : EntityBase + { + [PrimaryKey] + [MapField("CategoryId")] public string ID; + public string Name; + [MapField("Descn")] public string Description; + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/CreditCard.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/CreditCard.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; + +using BLToolkit.Common; + +namespace PetShop.ObjectModel +{ + public class CreditCard : EntityBase + { + public string Type; + public string Number; + public string Expiration; + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/CustomProfile.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/CustomProfile.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,18 @@ +using System; + +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace PetShop.ObjectModel +{ + public class CustomProfile + { + [PrimaryKey] + [MapField("UniqueID")] public int ID; + [MapField("Username")] public string UserName; + public string ApplicationName; + public bool? IsAnonymous; + public DateTime? LastActivityDate; + public DateTime? LastUpdatedDate; + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/Item.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/Item.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; + +using BLToolkit.Common; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace PetShop.ObjectModel +{ + public class Item : EntityBase + { + [MapField("ItemId"), PrimaryKey] public string ID; + + [MapField("ProductId")] public string ProductID; + [MapField("Supplier")] public int? SupplierID; + + [MapField("ListPrice")] public decimal? Price; + public decimal? UnitCost; + public ItemStatus Status; + public string Name; + public string Image; + + [MapField("ProductName"), NonUpdatable] public string ProductName; + [MapField("Qty"), NonUpdatable] public int Quantity; + [MapField("CategoryId"), NonUpdatable] public string CategoryID; + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/ItemStatus.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/ItemStatus.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using System; + +using BLToolkit.Mapping; + +namespace PetShop.ObjectModel +{ + public enum ItemStatus + { + [NullValue] Null, + [MapValue("P")] PStatus + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/Order.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/Order.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ +using System; + +using BLToolkit.Common; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace PetShop.ObjectModel +{ + [TableName("Orders")] + public class Order : EntityBase + { + [PrimaryKey, NonUpdatable] + [MapField("OrderId")] public int ID; + + [MapField("UserId")] public string UserID; + public DateTime OrderDate; + public string Courier; + public decimal TotalPrice; + public int AuthorizationNumber; + public string Locale; + + [MapField(Format="Ship{0}")] public Address ShippingAddress = new Address(); + [MapField(Format="Bill{0}")] public Address BillingAddress = new Address(); + + [NonUpdatable] public string Status; + + public OrderLineItem[] Lines; + public CreditCard CreditCard; + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/OrderLineItem.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/OrderLineItem.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ +using System; + +using BLToolkit.Common; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace PetShop.ObjectModel +{ + [Serializable] + [TableName("LineItem")] + public class OrderLineItem : EntityBase + { + [MapField("OrderId"), PrimaryKey(1)] public int OrderID; + [MapField("LineNum"), PrimaryKey(2)] public int Line; + + [MapField("ItemId")] public string ItemID; + public int Quantity; + [MapField("UnitPrice")] public decimal Price; + + [MapIgnore] public decimal Subtotal { get { return Quantity * Price; } } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/PetShop.ObjectModel.2005.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/PetShop.ObjectModel.2005.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,65 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8} + Library + Properties + PetShop.ObjectModel + PetShop.ObjectModel + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + {F4DF7358-8EE6-49FD-AB13-EA5145058D79} + BLToolkit.2 + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/PetShop.ObjectModel.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/PetShop.ObjectModel.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,147 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {BF0811CA-4663-4778-8331-9BEEBCAAC8C8} + Library + Properties + PetShop.ObjectModel + PetShop.ObjectModel + + + 3.5 + + + false + v4.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\PetShop.ObjectModel.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\PetShop.ObjectModel.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + + + + + + + + + + + + + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/Product.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/Product.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; + +using BLToolkit.Common; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace PetShop.ObjectModel +{ + public class Product : EntityBase + { + [PrimaryKey] + [MapField("ProductId")] public string ID; + + [MapField("CategoryId")] public string CategoryID; + public string Name; + [MapField("Descn")] public string Description; + public string Image; + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ObjectModel/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ObjectModel/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,31 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("PetShop.ObjectModel")] +[assembly: AssemblyProduct("PetShop.ObjectModel")] +[assembly: AssemblyCopyright("\xA9 2002-2012 www.bltoolkit.net")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("fadc05ac-5ae2-4342-a79d-bd39f666dc2a")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/ReadMe.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/ReadMe.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,14 @@ +This version of the PetShop application is simplified as much as possible and +has the following limitations: + +- It does not provide database creation script. + You should download the original version of Microsoft .NET Pet Shop 4.0 + from MSDN (http://msdn2.microsoft.com/en-us/library/aa479071.aspx) + and install it instead. +- MSMQ order processing has been removed. +- Support for Oracle has been removed. + +If you install the database on the different from local machine, +please modify the web.config file accordingly. + +Try the "Off-Limits to Guests" link on the main page. diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Admin/Counters.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Admin/Counters.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,53 @@ +<%@ Page Language="C#" MasterPageFile="~/Admin/MasterPage.master" AutoEventWireup="true" CodeFile="Counters.aspx.cs" Inherits="Admin_Counters" Title="Counters" %> +<%@ Import Namespace="BLToolkit.Aspects" %> + + + + + + + + + + + + + + + +
GC.CollectionCount:<%= GC.CollectionCount(GC.MaxGeneration) %>Cache Cleanup Times:<%= CacheAspect.CleanupThread.WorkTimes %>Objects in Cache:<%= CacheAspect.CleanupThread.ObjectsInCache %>
GC.TotalMemory:<%= GC.GetTotalMemory(false)/(1024*1024) %>MTotal Cleanup Time:<%= CacheAspect.CleanupThread.WorkTime %>Objects Expired:<%= CacheAspect.CleanupThread.ObjectsExpired %>
+
+ + + + + + + + + + + + + + + + + + + + + + +<%# GetCurrent((MethodCallCounter)Container.DataItem) %> + + +
TypeMethodCallsCacheCall Time
CountExInFromMinAverageMaxTotal
<%# GetName(((MethodCallCounter)Container.DataItem).MethodInfo.DeclaringType) %><%# ((MethodCallCounter)Container.DataItem).MethodInfo.Name %><%# ((MethodCallCounter)Container.DataItem).TotalCount %><%# ((MethodCallCounter)Container.DataItem).ExceptionCount == 0? "": ((MethodCallCounter)Container.DataItem).ExceptionCount.ToString() %><%# ((MethodCallCounter)Container.DataItem).CallMethodInfo.CacheAspect != null? ((MethodCallCounter)Container.DataItem).CallMethodInfo.CacheAspect.Cache.Count: 0 %><%# ((MethodCallCounter)Container.DataItem).CachedCount %><%# GetTime(((MethodCallCounter)Container.DataItem).MinTime) %><%# GetTime(((MethodCallCounter)Container.DataItem).AverageTime) %><%# GetTime(((MethodCallCounter)Container.DataItem).MaxTime) %><%# GetTime(((MethodCallCounter)Container.DataItem).TotalTime) %>
+
+ +
+ +
cache cleanup + + + diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Admin/Counters.aspx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Admin/Counters.aspx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using System.Web.UI; + +using BLToolkit.Aspects; + +public partial class Admin_Counters : Page +{ + protected void Page_Load(object sender, EventArgs e) + { + if (Request["cleanup"] == "1") + { + CacheAspect.ClearCache(); + Response.Redirect("Counters.aspx"); + } + + List counters = new List(); + + lock (CounterAspect.Counters.SyncRoot) + foreach (MethodCallCounter c in CounterAspect.Counters) + lock (c.CurrentCalls.SyncRoot) + if (c.TotalCount > 0 || c.CachedCount > 0 | c.CurrentCalls.Count > 0) + counters.Add(c); + + counters.Sort(delegate(MethodCallCounter x, MethodCallCounter y) + { + int c = string.Compare( + x.MethodInfo.DeclaringType.Name, + y.MethodInfo.DeclaringType.Name); + + if (c != 0) + return c; + + return string.Compare(x.MethodInfo.Name, y.MethodInfo.Name); + }); + + counterRepeater.DataSource = counters; + + DataBind(); + } + + protected string GetName(Type type) + { + string name = type.Name; + + if (type.IsGenericType || type.Name.IndexOf('_') > 0 && type.BaseType.IsGenericType) + { + if (!type.IsGenericType) + type = type.BaseType; + + name = type.Name.Split('`')[0] + "<"; + + foreach (Type t in type.GetGenericArguments()) + name += GetName(t) + ","; + + name = name.TrimEnd(',') + ">"; + } + + return name; + } + + protected string GetTime(TimeSpan time) + { + if (time == TimeSpan.MinValue || time == TimeSpan.MaxValue) + return ""; + + string s = time.ToString(); + + if (s.Length > 12) + s = s.Substring(0, 12); + + if (time.TotalSeconds <= 1) + s = string.Format("{0}", s); + + return s; + } + + protected string GetCurrent(MethodCallCounter counter) + { + List info = new List(); + + lock (counter.CurrentCalls.SyncRoot) + { + if (counter.CurrentCalls.Count == 0) + return ""; + + foreach (InterceptCallInfo c in counter.CurrentCalls) + info.Add(c); + } + + StringBuilder sb = new StringBuilder(); + + sb.Append(""); + + sb.Append(""); + sb.Append(""); + sb.Append(""); + + foreach (ParameterInfo pi in counter.MethodInfo.GetParameters()) + sb.AppendFormat("", pi.Name); + + sb.Append(""); + + foreach (InterceptCallInfo c in counter.CurrentCalls) + { + sb.AppendFormat(""); + + sb.AppendFormat("", DateTime.Now - c.BeginCallTime); + sb.AppendFormat("", c.CurrentPrincipal.Identity.Name); + + foreach (object value in c.ParameterValues) + { + sb.AppendFormat(""); + } + + sb.AppendFormat(""); + } + + sb.Append("
TimeLogin{0}
{0}{0}"); + + sb.Append( + value == null ? "" : + value is string ? "\"" + value.ToString().Replace("\n", "
\n") + "\"" : + value is char ? "'" + value + "'" : + value.ToString()); + + sb.AppendFormat("
"); + + return sb.ToString(); + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Admin/Items.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Admin/Items.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ +<%@ Page Language="C#" MasterPageFile="~/Admin/MasterPage.master" AutoEventWireup="true" CodeFile="Items.aspx.cs" Inherits="Admin_Items" Title="Items" %> + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Admin/Items.aspx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Admin/Items.aspx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +using System; + +using PetShop.BusinessLogic; + +public partial class Admin_Items : System.Web.UI.Page +{ + protected void Page_Load(object sender, EventArgs e) + { + binder.List = new ProductManager().GetAllItemList(); + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Admin/MasterPage.master --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Admin/MasterPage.master Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,74 @@ +<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="Admin_MasterPage" %> +<%@ Register Src="~/Controls/BreadCrumbControl.ascx" TagName="BreadCrumbControl" TagPrefix="PetShopControl" %> +<%@ Register Src="~/Controls/NavigationControl.ascx" TagName="NavigationControl" TagPrefix="PetShopControl" %> + + + + The .NET Pet Shop Admin Interface + + +
+ + + + + + +
 .NET Pet Shop 4.0 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  + + +
+
 
  
 
+ +
+ +
+ + diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Admin/MasterPage.master.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Admin/MasterPage.master.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +using System; + +public partial class Admin_MasterPage : System.Web.UI.MasterPage +{ + protected void Page_Load(object sender, EventArgs e) + { + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Admin/Orders.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Admin/Orders.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +<%@ Page Language="C#" MasterPageFile="~/Admin/MasterPage.master" AutoEventWireup="true" CodeFile="Orders.aspx.cs" Inherits="Admin_Orders" Title="Orders" %> +<%@ Import Namespace="PetShop.ObjectModel" %> + + + + + + + + + <%# FormatAddress(((Order)Container.DataItem).ShippingAddress) %> + + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Admin/Orders.aspx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Admin/Orders.aspx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; + +using PetShop.BusinessLogic; +using PetShop.ObjectModel; + +public partial class Admin_Orders : System.Web.UI.Page +{ + protected void Page_Load(object sender, EventArgs e) + { + binder.List = new OrderManager().GetAllOrderList(); + } + + protected static string FormatAddress(Address addr) + { + return string.Format( + "{0} {1}
{2} {3}
{4}, {5} {6}, {7}", + addr.FirstName, + addr.LastName, + addr.Line1, + addr.Line2, + addr.City, + addr.State, + addr.Zip, + addr.Country); + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/App_Code/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/App_Code/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; +using System.Reflection; + +[assembly: AssemblyVersion("4.0.4.50")] + +[assembly: AssemblyTitle(".NET Pet Shop Web")] +[assembly: AssemblyDescription(".NET Pet Shop Web Components")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft Corporation")] +[assembly: AssemblyProduct(".NET Pet Shop 4.0")] +[assembly: AssemblyCopyright("Copyright \xA9 2005 Microsoft Corporation")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/App_Code/CustomGrid.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/App_Code/CustomGrid.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,139 @@ +using System; +using System.Collections; +using System.Text.RegularExpressions; +using System.Web.UI; +using System.Web.UI.WebControls; + +namespace PetShop.Web +{ + public class CustomGrid : Repeater + { + private static readonly Regex RX = new Regex(@"^&page=\d+", RegexOptions.Compiled); + + protected string _emptyText; + private IList _dataSource; + private int _pageSize = 10; + private int _currentPageIndex; + private int _itemCount; + + public override object DataSource + { + set + { + // This try catch block is to avoid issues with the VS.NET designer + // The designer will try and bind a datasource which does not derive from ILIST + try + { + _dataSource = (IList)value; + ItemCount = _dataSource.Count; + } + catch + { + _dataSource = null; + ItemCount = 0; + } + } + } + + public int PageSize { get { return _pageSize; } set { _pageSize = value; } } + protected virtual int ItemCount { get { return _itemCount; } set { _itemCount = value; } } + public virtual int CurrentPageIndex { get { return _currentPageIndex; } set { _currentPageIndex = value; } } + + protected int PageCount { get { return (ItemCount - 1) / _pageSize; } } + public string EmptyText { set { _emptyText = value; } } + + public void SetPage(int index) + { + OnPageIndexChanged(new DataGridPageChangedEventArgs(null, index)); + } + + protected override void OnLoad(EventArgs e) + { + if (Visible) + { + string page = Context.Request["page"]; + int index = page != null ? int.Parse(page) : 0; + + SetPage(index); + } + } + + /// + /// Overridden method to control how the page is rendered + /// + /// + protected override void Render(HtmlTextWriter writer) + { + // Check there is some data attached + // + if (ItemCount == 0) + { + writer.Write(_emptyText); + return; + } + + // Mask the query + // + string query = Context.Request.Url.Query.Replace("?", "&"); + query = RX.Replace(query, string.Empty); + + // Write out the first part of the control, the table header + // + writer.Write("
"); + + // Call the inherited method + // + base.Render(writer); + + // Write out a table row closure + // + writer.Write("
"); + + // Determin whether next and previous buttons are required Previous button? + // + if (_currentPageIndex > 0) + writer.Write(string.Format("< Previous", _currentPageIndex - 1 + query)); + + // Close the table data tag + // + writer.Write(""); + + // Next button? + // + if (_currentPageIndex < PageCount) + writer.Write(string.Format("More >", _currentPageIndex + 1 + query)); + + // Close the table + // + writer.Write("
"); + } + + protected override void OnDataBinding(EventArgs e) + { + // Work out which items we want to render to the page + // + int start = CurrentPageIndex * _pageSize; + int size = Math.Min(_pageSize, ItemCount - start); + + IList page = new ArrayList(); + + // Add the relevant items from the datasource + // + for (int i = 0; i < size; i++) + page.Add(_dataSource[start + i]); + + // Set the base objects datasource + // + base.DataSource = page; + base.OnDataBinding(e); + } + + public event DataGridPageChangedEventHandler PageIndexChanged; + + protected virtual void OnPageIndexChanged(DataGridPageChangedEventArgs e) + { + if (PageIndexChanged != null) + PageIndexChanged(this, e); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/App_Code/CustomList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/App_Code/CustomList.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,140 @@ +using System; +using System.Collections; +using System.Text.RegularExpressions; +using System.Web.UI; +using System.Web.UI.WebControls; + +namespace PetShop.Web +{ + public class CustomList : DataList + { + private static readonly Regex RX = new Regex(@"^&page=\d+", RegexOptions.Compiled); + + protected string _emptyText; + private IList _dataSource; + private int _pageSize = 10; + private int _currentPageIndex; + private int _itemCount; + + public override object DataSource + { + set + { + //This try catch block is to avoid issues with the VS.NET designer + //The designer will try and bind a datasource which does not derive from ILIST + try + { + _dataSource = (IList)value; + ItemCount = _dataSource.Count; + } + catch + { + _dataSource = null; + ItemCount = 0; + } + } + } + + public int PageSize { get { return _pageSize; } set { _pageSize = value; } } + protected virtual int ItemCount { get { return _itemCount; } set { _itemCount = value; } } + public virtual int CurrentPageIndex { get { return _currentPageIndex; } set { _currentPageIndex = value; } } + + protected int PageCount { get { return (ItemCount - 1) / _pageSize; } } + public string EmptyText { set { _emptyText = value; } } + + public void SetPage(int index) + { + OnPageIndexChanged(new DataGridPageChangedEventArgs(null, index)); + } + + protected override void OnLoad(EventArgs e) + { + if (Visible) + { + string page = Context.Request["page"]; + int index = page != null ? int.Parse(page) : 0; + + SetPage(index); + } + } + + /// + /// Overridden method to control how the page is rendered + /// + /// + protected override void Render(HtmlTextWriter writer) + { + // Check there is some data attached + // + if (ItemCount == 0) + { + writer.Write(_emptyText); + return; + } + + // Mask the query + // + string query = Context.Request.Url.Query.Replace("?", "&"); + + query = RX.Replace(query, string.Empty); + + // Write out the first part of the control, the table header + // + writer.Write("
"); + + // Call the inherited method + // + base.Render(writer); + + // Write out a table row closure + // + writer.Write("
"); + + // Determin whether next and previous buttons are required Previous button? + // + if (_currentPageIndex > 0) + writer.Write(string.Format("< Previous", _currentPageIndex - 1 + query)); + + // Close the table data tag + // + writer.Write(""); + + // Next button? + // + if (_currentPageIndex < PageCount) + writer.Write(string.Format("More >", _currentPageIndex + 1 + query)); + + // Close the table + // + writer.Write("
"); + } + + protected override void OnDataBinding(EventArgs e) + { + // Work out which items we want to render to the page + // + int start = CurrentPageIndex * _pageSize; + int size = Math.Min(_pageSize, ItemCount - start); + + IList page = new ArrayList(); + + // Add the relevant items from the datasource + // + for (int i = 0; i < size; i++) + page.Add(_dataSource[start + i]); + + // set the base objects datasource + // + base.DataSource = page; + base.OnDataBinding(e); + } + + public event DataGridPageChangedEventHandler PageIndexChanged; + + virtual protected void OnPageIndexChanged(DataGridPageChangedEventArgs e) + { + if (PageIndexChanged != null) + PageIndexChanged(this, e); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/App_Code/PageBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/App_Code/PageBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; +using System.Web.UI; + +namespace PetShop.Web +{ + public class PageBase : Page + { + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/App_Code/WebUtility.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/App_Code/WebUtility.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,59 @@ +using System; +using System.Text.RegularExpressions; +using System.Web; +using System.Web.Caching; +using System.Configuration; + +using PetShop.BusinessLogic; + +namespace PetShop.Web +{ + /// + /// Collection of utility methods for web tier + /// + public static class WebUtility + { + /// + /// Method to make sure that user's inputs are not malicious + /// + /// User's Input + /// Maximum length of input + /// The cleaned up version of the input + public static string InputText(string text, int maxLength) + { + text = text.Trim(); + + if (string.IsNullOrEmpty(text)) + return string.Empty; + + text = Regex.Replace(text, "[\\s]{2,}", " "); // two or more spaces + text = Regex.Replace(text, "(<[b|B][r|R]/*>)+|(<[p|P](.|\\n)*?>)", "\n"); //
+ text = Regex.Replace(text, "(\\s*&[n|N][b|B][s|S][p|P];\\s*)+", " "); //   + text = Regex.Replace(text, "<(.|\\n)*?>", string.Empty); // any other tags + text = text.Replace("'", "''"); + + if (text.Length > maxLength) + text = text.Substring(0, maxLength); + + return text; + } + + /// + /// Method to check whether input has other characters than numbers + /// + public static string CleanNonWord(string text) + { + return Regex.Replace(text, "\\W", ""); + } + + /// + /// Method to redirect user to search page + /// + /// Search keyword + public static void SearchRedirect(string key) + { + HttpContext.Current.Response.Redirect( + string.Format("~/Search.aspx?keywords={0}", InputText(key, 255))); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/App_Themes/PetShop/SkinFile.skin --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/App_Themes/PetShop/SkinFile.skin Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + <%--Uncomment for using with default layout of wizard control + --%> + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/App_Themes/PetShop/StyleSheet.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/App_Themes/PetShop/StyleSheet.css Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,630 @@ +body { + background-color: #E3E5DC; + margin-left: 0px; + margin-top: 0px; + margin-right: 0px; + margin-bottom: 0px; + background-image: url(../../Comm_Images/bg-body.gif); + background-repeat: repeat-x; +} +a:visited { + color: #333; + text-decoration: none; +} +a:hover { + color: #1639A9; + text-decoration: underline; +} +a:link { + color: #333; + text-decoration: none; +} +.link { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.65em; + text-transform: uppercase; + color: #333333; + text-indent: 10px; +} +.disabledLink +{ + font-family: Arial, Helvetica, sans-serif; + font-size: 0.65em; + text-transform: uppercase; + color: #999999; + text-indent: 10px; +} +.signIn { + background-color: #E9EED8; + background-image: url(../../Comm_Images/bg-sign-in.gif); + background-repeat: repeat-x; + height: 60px; + margin-top: 20px; +} +.checkOut { + background-color: #ABAF94; + /*cursor: hand;*/ +} +.linkCheckOut { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.65em; + text-transform: uppercase; + color: #333333; + text-indent: 7px; +} +.welcomeName { + font-size: 0.7em; + font-weight: bold; + white-space: nowrap; + text-indent: 37px; + color: #555; + font-family: Arial, Helvetica, sans-serif; +} +.textboxSearch { + font-size: 0.8em; + color: #000; + text-indent: 3px; + background-color: #FFF; + border-width: 1px; + border-style: solid; + border-top-color: #E9EED8; + border-right-color: #C6C3B3; + border-bottom-color: #ABAF94; + border-left-color: #C6C3B3; + height: 14px; +} +.breadcrumb { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.7em; + text-transform: uppercase; + color: #333333; + font-weight: bold; +} +.bgBreadcrumb { + padding-top: 12px; + padding-bottom: 9px; +} +.mainNavigation { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.7em; + text-transform: uppercase; + padding-left: 2px; + color: #333333; + font-weight: bold; + line-height: 20px; + padding-right: 5px; + display:block; + height:100%; +} +.pageHeader { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.9em; + font-weight: bold; + text-transform: uppercase; + color: #FFFFFF; + background-color: #0A1B50; + text-indent:16px; +} +.dottedLine { + background-image: url(../../Comm_Images/dotten-line.gif); + background-repeat: repeat-x; + background-position: bottom; + height: 8px; +} +input { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.8em; + color: #333333; + padding-left: 3px; + padding-right: 3px; +} +.footer td { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.65em; + text-transform: uppercase; + color: #FFF; + background-color: #ABAF94; + padding-left: 18px; + line-height: 16px; +} +.homeBody { + background-color: #FFF; + margin-left: 0px; + margin-top: 0px; + margin-right: 0px; + margin-bottom: 0px; + background-image: url(../../Comm_Images/home-bg-body.gif); + background-repeat: repeat-x; +} +.homeBgSearch { + background-image: url(../../Comm_Images/bg-search.gif); + background-repeat: repeat-x; + background-position: top; + padding-top: 20px; +} +.fishPosition { + position: relative; + left: -60px; + top: 0px; + width: 241px; + height: 300px; +} +.footerHome { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.65em; + text-transform: uppercase; + color: #FFF; + background-color: #122E87; + padding-left: 18px; + line-height: 16px; +} +.homeLink { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.65em; + text-transform: uppercase; + color: #333; + vertical-align: middle; +} +.homeSearchBox { + font-size: 0.8em; + color: #404040; + text-indent: 3px; + background-color: #FFF; + border-width: 1px; + border-style: solid; + border-top-color: #E9EED8; + border-right-color: #C6C3B3; + border-bottom-color: #ABAF94; + border-left-color: #C6C3B3; + height: 14px; + padding-right: 5px; +} +.paddingSearchicon { + padding-top:3px; + padding-left:5px; +} +.welcome { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.9em; + font-weight: bold; + color: #FFFFFF; + padding-left: 20px; + height: 27px; + text-transform: uppercase; + background-color: #ABAF94; + vertical-align: middle; +} +.intro { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.9em; + font-weight: bold; + color: #555555; + padding-top: 20px; + line-height: 18px; + padding-left: 20px; + padding-bottom: 20px; + display: block; + width: 300px; +} +.navigationLinks { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.9em; + text-transform: uppercase; + color: #333; + line-height: 1.8em; + font-weight: bold; + vertical-align:top; + background-image: url(../../Comm_Images/dotten-line.gif); + background-repeat: repeat-x; + background-position: bottom; + width:320px; +} +.navigationLabel { + color: #98A839; + font-size: 0.9em; + font-weight: bold; + line-height:25px; + font-family: Arial, Helvetica, sans-serif; + padding-left: 20px; +} +.bgControl { + background-color: #E3E5DC; +} +.productDescription { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.7em; + font-weight: normal; + color: #333333; +} +.productName { + font-family: Arial, Helvetica, sans-serif; + font-size: 1em; + font-weight: bold; + color: #333333; + padding-bottom: 12px; +} +.paging { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.85em; + color:#98A839; + font-weight: bold; + text-decoration: none; + padding-top: 16px; + padding-bottom: 16px; + padding-left: 16px; + padding-right: 16px; +} +.productsPosition { + padding-top: 37px; + padding-bottom: 33px; +} +.productsLine { + padding-top: 16px; + padding-bottom: 3px; + border-bottom: solid 1px #E8EADD; +} +.itemsPosition { + padding-top: 5px; + padding-bottom: 33px; +} +.itemText { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.7em; + font-weight: normal; + color: #333333; + padding-bottom: 5px; + text-indent: 3px; + line-height: 1.3em; +} +.itemName { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.7em; + font-weight: bold; + color: #333333; + padding-bottom: 5px; + text-indent: 3px; + line-height: 1.3em; +} +.linkCart { + text-transform: uppercase; + font-size: 1em; + font-weight: bold; + padding-top: 16px; + padding-bottom: 10px; + padding-left: 21px; + cursor: hand; + background-image: url(../../Comm_Images/button-cart.gif); + background-repeat: no-repeat; + background-position: 0px; + line-height:35px; +} +.linkWishlist { + text-transform: uppercase; + font-size: 1em; + font-weight: bold; + padding-top: 4px; + padding-left: 21px; + cursor: hand; + background-image: url(../../Comm_Images/button-wishlist.gif); + background-repeat: no-repeat; + } +.cartPosition { + padding-top: 50px; + padding-bottom: 33px; +} +.label { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.7em; + color: #333333; + margin-left: 20px; + margin-bottom: 10px; + text-align: left; +} +.cart { + background-color:#E8EADD; +} +.labelLists { + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 0.7em; + font-weight: bold; + color: #747C6D; + vertical-align: bottom; + background-image: url(../../Comm_Images/bg-labelLists.gif); + text-align:left; + line-height: 21px; + padding-left: 5px; + text-indent: 2px; + padding-right: 5px; + padding-top: 8px; + padding-bottom: 1px; + border-bottom-width: 1px; + border-bottom-color: #FFF; + border-bottom-style: solid; +} +.listItem { + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 0.7em; + color: #333333; + text-decoration: none; + line-height: 15px; + padding-left: 5px; + padding-right: 5px; + padding-bottom: 2px; + padding-top: 2px; + white-space: nowrap; + text-align: left; +} +.dottedLineCentered { + background-image: url(../../Comm_Images/dotten-line.gif); + background-repeat: repeat-x; + background-position: center; + height: 8px; +} +.total { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.7em; + font-weight: bold; + color: #000000; + padding-right: 2px; + line-height: 1.5em; +} +.signinButton { + font-family : Tahoma, Arial, Helvetica, sans-serif; + background-color:#FB9D00; + font-size: 0.85em; + color: #FFF; + text-decoration: none; + font-weight: bold; + cursor: hand; + border: 1px solid; + border-bottom-color:#F07C00; + border-top-color: #FFCC00; + border-right-color:#F07C00; + border-left-color:#FFCC00; + padding-right: 5px; + padding-left: 5px; + margin-bottom: 15px; + margin-right: 10px; +} +.signinHeader { + font-family: Arial, Helvetica, sans-serif; + font-size: 1.1em; + font-weight: bold; + text-align: left; + white-space: nowrap; + color: #333333; + padding-top: 5px; + padding-bottom: 5px; + line-height:30px; + +} +.signinTextbox { + font-size: 0.9em; + color: #000; + text-indent: 3px; + background-color: #EAE9E4; + border-width: 1px; + border-style: solid; + border-top-color: #C6C3B3; + border-right-color: #7C7D6A; + border-bottom-color: #000; + border-left-color: #7C7D6A; + height: 16px; + margin-right: 2px; +} +.signinLabel { + font-family: Arial, Helvetica, sans-serif; + font-weight:normal; + color: #333333; +} +.signinNewUser { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.8em; + text-transform: uppercase; + color: #333333; + text-indent: 3px; +} +.asterisk { + color: #333333; + vertical-align: top; +} +.signInContent { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.8em; + background-color: #FFFFFF; + white-space: nowrap; + color: #333333; + padding-top: 10px; + padding-bottom: 10px; +} +.checkoutPosition { + padding-top: 40px; + padding-bottom: 33px; +} +.checkoutContent { + font-family: Arial, Helvetica, sans-serif; + background-color: #FFFFFF; + white-space: nowrap; + color: #333333; + padding-left: 15px; +} +.checkoutHeaders{ + font-family: Arial, Helvetica, sans-serif; + font-size: 0.9em; + font-weight: bold; + color: #333333; + text-transform: capitalize; + white-space: nowrap; + height: 30px; + padding-top: 3px; + padding-bottom: 5px; +} +.checkoutLabel { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.95em; + color: #333333; + margin-left: 20px; + margin-bottom: 10px; + text-align: left; +} +.checkoutTextbox { + font-size: 1em; + color: #000; + text-indent: 3px; + background-color: #EAE9E4; + border-width: 1px; + border-style: solid; + border-top-color: #C6C3B3; + border-right-color: #7C7D6A; + border-bottom-color: #000; + border-left-color: #7C7D6A; + height: 16px; + margin-top: 1px; +} +.checkoutDropdown { + font-size: 1em; + color: #000; + text-indent: 3px; + background-color: #EAE9E4; + border-width: 1px; + border-style: solid; + border-top-color: #C6C3B3; + border-right-color: #7C7D6A; + border-bottom-color: #000; + height: 16px; + margin-top: 2px; +} +.checkoutButtonBg { + background-image: url(../../Comm_Images/dotten-line.gif); + background-repeat: repeat-x; + background-position: top; +} +.back { + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 0.7em; + color: #000; + text-decoration: none; + font-weight: bold; + background-image: url(../../Comm_Images/button-back.gif); + background-repeat: no-repeat; + background-position: left 7px; + padding-left: 22px; + padding-top: 9px; + margin-left: 7px; + cursor: hand; + line-height: 40px; +} +.continue { + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 0.7em; + color: #000; + text-decoration: none; + font-weight: bold; + background-image: url(../../Comm_Images/button-continue.gif); + background-repeat: no-repeat; + background-position: right 7px; + padding-right: 22px; + padding-top: 9px; + margin-right: 7px; + cursor: hand; + line-height: 40px; +} +.submit { + font-family: Tahoma, Arial, Helvetica, sans-serif; + background-color:#FB9D00; + font-size: 0.7em; + color: #FFF; + text-decoration: none; + font-weight: bold; + cursor: hand; + line-height: 30px; + border: 1px solid; + border-bottom-color:#F07C00; + border-top-color: #FFCC00; + border-right-color:#F07C00; + border-left-color:#FFCC00; + padding-right: 10px; + padding-left: 10px; + padding-top: 1px; + padding-bottom: 1px; +} +.checkOutLabel { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.7em; + color: #333333; + margin-left: 3px; + margin-bottom: 10px; + text-align: left; +} +.info { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.7em; + color: #333333; + margin-bottom: 15px; + text-align: left; +} +.profilePosition { + padding-top: 50px; + padding-bottom: 33px; +} +.tableContent { + font-family: Arial, Helvetica, sans-serif; + background-color: #FFFFFF; + text-align: center; + font-weight:bold; + white-space: nowrap; + color: #333333; + padding-left: 25px; + padding-top: 12px; + padding-bottom: 3px; +} +.searchPosition { + font-family: Arial, Helvetica, sans-serif; + padding-top: 12px; + padding-bottom: 33px; +} +.linkNewUser { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.8em; + text-transform: uppercase; + color: #333333; + text-indent: 3px; +} +.cartHeader { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.9em; + font-weight: bold; + text-align: left; + white-space: nowrap; + color: #333333; + width: 387px; + padding-bottom: 16px; +} +.signinPosition { + padding-top: 22px; + padding-bottom: 33px; +} +.adminContent { + font-family: Verdana; + font-size: .8em; +} +.infoTable td { + padding: 4 5 0 0; + font-size: 0.7em; + text-align: right; +} +.grid th { + padding: 1 5 2 5; + font-size: .8em; +} +.grid td { + padding: 1 5 2 5; + font-size: .8em; +} +.pageHeader a:link, .pageHeader a:hover, .pageHeader a:visited { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.9em; + font-weight: bold; + color: #FFFFFF; + text-transform: uppercase; +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/CheckOut.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/CheckOut.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,206 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="CheckOut.aspx.cs" Inherits="PetShop.Web.CheckOut" Title="Check Out" %> +<%@ Register Src="Controls/CartList.ascx" TagName="CartList" TagPrefix="PetShopControl" %> +<%@ Register Src="Controls/AddressConfirm.ascx" TagName="AddressConfirm" TagPrefix="PetShopControl" %> +<%@ Register Src="Controls/AddressForm.ascx" TagName="AddressForm" TagPrefix="PetShopControl" %> + + +
+ + + + + + + +
+
+ +
+ + + + + + + + + + +
+ +
+
+
+ + +
+ +
+ + + + + + +
+ + + +
+
+
+ + + + + + + + + + + + + +
Credit Card Number
+ 4444123412341234
+ +  
Expiration Date (MM/YYYY)
+ 12/2009
+ + +   +
Credit card Type
+ + Visa + Master Card + American Express + Discovery + +
 
+

 

+ + + + + +
+ + + +
+
+
+ + +
+ Your order will not be processed until you select "Submit Order" below.

+ Billing address:
+
+ Shipping address:
+ +
+
+ A total of + will be charged to your credit card, ending with + . +
+ + + + + +
+ + + +
+
+
+ +
+ Thank you for your order!

+ +
+

+ A total of + is being charged to your credit card, ending with + . +

+

If you have any questions regarding this order, please contact our customer service at anytime.

+

The .NET Pet Shop Team

+
+
+
+ + <%= wzdCheckOut.ActiveStep.Title %> + + + +
+
+ +
+
+ diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/CheckOut.aspx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/CheckOut.aspx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,111 @@ +using System; +using System.Web.UI.WebControls; + +using PetShop.BusinessLogic; +using PetShop.ObjectModel; + +namespace PetShop.Web +{ + public partial class CheckOut : System.Web.UI.Page + { + protected void Page_Load(object sender, EventArgs e) + { + if (billingForm.Address == null) + billingForm.Address = Profile.AccountInfo; + } + + /// + /// Process the order + /// + protected void wzdCheckOut_FinishButtonClick(object sender, WizardNavigationEventArgs e) + { + if (Profile.ShoppingCart.Items.Count > 0) + { + if (Profile.ShoppingCart.Count > 0) + { + // display ordered items + CartListOrdered.Bind(Profile.ShoppingCart.Items); + + // display total and credit card information + ltlTotalComplete.Text = ltlTotal.Text; + ltlCreditCardComplete.Text = ltlCreditCard.Text; + + // create order + Order order = new Order(); + + order.UserID = User.Identity.Name; + order.OrderDate = DateTime.Now; + order.TotalPrice = Profile.ShoppingCart.Total; + order.ShippingAddress = shippingForm.Address; + order.BillingAddress = billingForm.Address; + order.Lines = Profile.ShoppingCart.GetOrderLineItems(); + order.CreditCard = GetCreditCardInfo(); + + new OrderManager().InsertOrder(order); + + // destroy cart + Profile.ShoppingCart.Clear(); + Profile.Save(); + } + } + else + { + lblMsg.Text = "


Can not process the order. Your cart is empty.

Continue shopping

"; + wzdCheckOut.Visible = false; + } + } + + /// + /// Create CreditCardInfo object from user input + /// + private CreditCard GetCreditCardInfo() + { + CreditCard cc = new CreditCard(); + + cc.Type = WebUtility.InputText(listCCType.SelectedValue, 40); + cc.Expiration = WebUtility.InputText(txtExpDate.Text, 7); + cc.Number = WebUtility.InputText(txtCCNumber.Text, 20); + + return cc; + } + + /// + /// Changing Wiszard steps + /// + protected void wzdCheckOut_ActiveStepChanged(object sender, EventArgs e) + { + if (wzdCheckOut.ActiveStepIndex == 3) + { + billingConfirm. Address = billingForm.Address; + shippingConfirm.Address = shippingForm.Address; + ltlTotal.Text = Profile.ShoppingCart.Total.ToString("c"); + + if (txtCCNumber.Text.Length > 4) + ltlCreditCard.Text = txtCCNumber.Text.Substring(txtCCNumber.Text.Length - 4, 4); + } + } + + /// + /// Handler for "Ship to Billing Addredd" checkbox. + /// Prefill/Clear shipping address form. + /// + protected void chkShipToBilling_CheckedChanged(object sender, EventArgs e) + { + if (chkShipToBilling.Checked) + shippingForm.Address = billingForm.Address; + } + + /// + /// Custom validator to check CC expiration date + /// + protected void ServerValidate(object source, ServerValidateEventArgs value) + { + DateTime dt; + + if (DateTime.TryParse(value.Value, out dt)) + value.IsValid = dt > DateTime.Now; + else + value.IsValid = false; + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/Logo-home.gif Binary file Demo/Asp.Net/Web/Comm_Images/Logo-home.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/Logo.gif Binary file Demo/Asp.Net/Web/Comm_Images/Logo.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/bg-body.gif Binary file Demo/Asp.Net/Web/Comm_Images/bg-body.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/bg-labelLists.gif Binary file Demo/Asp.Net/Web/Comm_Images/bg-labelLists.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/bg-search.gif Binary file Demo/Asp.Net/Web/Comm_Images/bg-search.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/bg-sign-in.gif Binary file Demo/Asp.Net/Web/Comm_Images/bg-sign-in.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/button-back.gif Binary file Demo/Asp.Net/Web/Comm_Images/button-back.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/button-calculate.gif Binary file Demo/Asp.Net/Web/Comm_Images/button-calculate.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/button-cart-grey.gif Binary file Demo/Asp.Net/Web/Comm_Images/button-cart-grey.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/button-cart.gif Binary file Demo/Asp.Net/Web/Comm_Images/button-cart.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/button-checkout.gif Binary file Demo/Asp.Net/Web/Comm_Images/button-checkout.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/button-continue.gif Binary file Demo/Asp.Net/Web/Comm_Images/button-continue.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/button-delete.gif Binary file Demo/Asp.Net/Web/Comm_Images/button-delete.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/button-home.gif Binary file Demo/Asp.Net/Web/Comm_Images/button-home.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/button-search.gif Binary file Demo/Asp.Net/Web/Comm_Images/button-search.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/button-wishlist-grey.gif Binary file Demo/Asp.Net/Web/Comm_Images/button-wishlist-grey.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/button-wishlist.gif Binary file Demo/Asp.Net/Web/Comm_Images/button-wishlist.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/dotten-line.gif Binary file Demo/Asp.Net/Web/Comm_Images/dotten-line.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/home-bg-body.gif Binary file Demo/Asp.Net/Web/Comm_Images/home-bg-body.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/home-fish.gif Binary file Demo/Asp.Net/Web/Comm_Images/home-fish.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/seahorse.gif Binary file Demo/Asp.Net/Web/Comm_Images/seahorse.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/spacer.gif Binary file Demo/Asp.Net/Web/Comm_Images/spacer.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Comm_Images/vertigo-icon.gif Binary file Demo/Asp.Net/Web/Comm_Images/vertigo-icon.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/AddressConfirm.ascx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/AddressConfirm.ascx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="AddressConfirm.ascx.cs" Inherits="PetShop.Web.AddressConfirm" %> + + +
+  
+
+
+  
+
+
+ +
diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/AddressConfirm.ascx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/AddressConfirm.ascx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,32 @@ +using System; + +using PetShop.ObjectModel; + +namespace PetShop.Web +{ + public partial class AddressConfirm : System.Web.UI.UserControl + { + /// + /// Control property to set the address + /// + public Address Address + { + set + { + if (value != null) + { + ltlFirstName.Text = value.FirstName; + ltlLastName. Text = value.LastName; + ltlAddress1. Text = value.Line1; + ltlAddress2. Text = value.Line2; + ltlCity. Text = value.City; + ltlZip. Text = value.Zip; + ltlState. Text = value.State; + ltlCountry. Text = value.Country; + ltlPhone. Text = value.Phone; + ltlEmail. Text = value.Email; + } + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/AddressForm.ascx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/AddressForm.ascx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,77 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="AddressForm.ascx.cs" Inherits="PetShop.Web.AddressForm" %> + + + + + + + + + + + + + + + + + + + + +
First Name
+
+    +
Last Name
+
+    +
Address
+
+   +
+ +
City
+
+    +
State
+ + CA + NY + TX +
+
Postal Code
+
+ +
Country
+ + USA + Canada + Japan +
+  
Phone Number
+
+   
Email
+
+    +
diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/AddressForm.ascx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/AddressForm.ascx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,75 @@ +using System; +using System.Text.RegularExpressions; + +using PetShop.ObjectModel; + +namespace PetShop.Web +{ + public partial class AddressForm : System.Web.UI.UserControl + { + /// + /// Control property to set or get the address + /// + public Address Address + { + get + { + // Return null if control is empty. + // + if (string.IsNullOrEmpty(txtFirstName.Text) && + string.IsNullOrEmpty(txtLastName. Text) && + string.IsNullOrEmpty(txtAddress1. Text) && + string.IsNullOrEmpty(txtAddress2. Text) && + string.IsNullOrEmpty(txtCity. Text) && + string.IsNullOrEmpty(txtZip. Text) && + string.IsNullOrEmpty(txtEmail. Text) && + string.IsNullOrEmpty(txtPhone. Text)) + return null; + + Address addr = new Address(); + + // Make sure we clean the input. + // + addr.FirstName = WebUtility.InputText(txtFirstName.Text, 50); + addr.LastName = WebUtility.InputText(txtLastName. Text, 50); + addr.Line1 = WebUtility.InputText(txtAddress1. Text, 50); + addr.Line2 = WebUtility.InputText(txtAddress2. Text, 50); + addr.City = WebUtility.InputText(txtCity. Text, 50); + addr.Zip = WebUtility.InputText(txtZip. Text, 10); + addr.Phone = WebUtility.InputText(WebUtility.CleanNonWord(txtPhone.Text), 10); + addr.Email = WebUtility.InputText(txtEmail.Text, 80); + addr.State = WebUtility.InputText(listState. SelectedItem.Value, 2); + addr.Country = WebUtility.InputText(listCountry.SelectedItem.Value, 50); + + return addr; + } + + set + { + if (value != null) + { + txtFirstName.Text = value.FirstName; + txtLastName. Text = value.LastName; + txtAddress1. Text = value.Line1; + txtAddress2. Text = value.Line2; + txtCity. Text = value.City; + txtZip. Text = value.Zip; + txtPhone. Text = value.Phone; + txtEmail. Text = value.Email; + + if (!string.IsNullOrEmpty(value.State)) + { + listState.ClearSelection(); + listState.SelectedValue = value.State; + } + + if (!string.IsNullOrEmpty(value.Country)) + { + listCountry.ClearSelection(); + listCountry.SelectedValue = value.Country; + } + } + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/BreadCrumbControl.ascx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/BreadCrumbControl.ascx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="BreadCrumbControl.ascx.cs" Inherits="PetShop.Web.BreadCrumbControl" %> +  \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/BreadCrumbControl.ascx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/BreadCrumbControl.ascx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,86 @@ +using System; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using PetShop.BusinessLogic; + +namespace PetShop.Web +{ + public partial class BreadCrumbControl : System.Web.UI.UserControl + { + protected void Page_Load(object sender, EventArgs e) + { + string categoryId = Request.QueryString["categoryId"]; + + if (!string.IsNullOrEmpty(categoryId)) + { + ProcessHomePageLink(); + + // Process Product page link + // + HtmlAnchor lnkProducts = new HtmlAnchor(); + + lnkProducts.InnerText = new ProductManager().GetCategory(categoryId).Name; + lnkProducts.HRef = string.Format("~/Products.aspx?page=0&categoryId={0}", categoryId); + + plhControl.Controls.Add(lnkProducts); + + string productId = Request.QueryString["productId"]; + + if (!string.IsNullOrEmpty(productId)) + { + // Process Item page link + // + plhControl.Controls.Add(GetDivider()); + + HtmlAnchor lnkItemDetails = new HtmlAnchor(); + + lnkItemDetails.InnerText = new ProductManager().GetProduct(productId).Name; + lnkItemDetails.HRef = string.Format("~/Items.aspx?categoryId={0}&productId={1}", categoryId, productId); + + plhControl.Controls.Add(lnkItemDetails); + } + } + else + { + int len = Request.Url.Segments.Length; + + if (len >= 2 && Request.Url.Segments[len-2].TrimEnd('/', '\\').ToLower() == "admin") + { + ProcessHomePageLink(); + + HtmlAnchor a = new HtmlAnchor(); + + a.InnerText = Request.Url.Segments[len - 1].Split('.')[0]; + a.HRef = Request.Url.PathAndQuery; + + plhControl.Controls.Add(a); + } + } + } + + private void ProcessHomePageLink() + { + HtmlAnchor lnkHome = new HtmlAnchor(); + + lnkHome.InnerText = "Home"; + lnkHome.HRef = "~/Default.aspx"; + + plhControl.Controls.Add(lnkHome); + plhControl.Controls.Add(GetDivider()); + } + + /// + /// Create a breadcrumb nodes divider + /// + /// Literal control containing formatted divider + private Literal GetDivider() + { + Literal ltlDivider = new Literal(); + + ltlDivider.Text = " > "; + + return ltlDivider; + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/CartList.ascx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/CartList.ascx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CartList.ascx.cs" Inherits="PetShop.Web.CartList" %> + + + + + + + + + +
NameQty
<%# Eval("Name") + " " + Eval("Type")%><%# Eval("Quantity") %>
+
diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/CartList.ascx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/CartList.ascx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Web.UI; + +using PetShop.ObjectModel; + +namespace PetShop.Web +{ + public partial class CartList : UserControl + { + public void Bind(ICollection cart) + { + if (cart != null) + { + repOrdered.DataSource = cart; + repOrdered.DataBind(); + } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/CreditCardForm.ascx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/CreditCardForm.ascx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,75 @@ +<%@ Control AutoEventWireup="true" CodeFile="CreditCardForm.ascx.cs" Inherits="PetShop.Web.CreditCardForm" Language="C#" %> + + + + + + + + + +
 
+
+ Credit Card Type
+ + Visa + Master Card + American Express + Discovery + +

+
+
+
+ Card Number +
+ + *
+ +   +
+
+
+
+ Expiration Date (MM/YYYY) +
+ + *
+ + +   +
+
+
diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/CreditCardForm.ascx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/CreditCardForm.ascx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,50 @@ +using System; +using System.Web.UI.WebControls; + +using PetShop.ObjectModel; + +namespace PetShop.Web +{ + public partial class CreditCardForm : System.Web.UI.UserControl + { + /// + /// Custom validator to check the expiration date + /// + protected void ServerValidate(object source, ServerValidateEventArgs value) + { + DateTime dt; + + if (DateTime.TryParse(value.Value, out dt)) + value.IsValid = dt > DateTime.Now; + else + value.IsValid = false; + } + + /// + /// Property to set/get credit card info + /// + public CreditCard CreditCard + { + get + { + CreditCard cc = new CreditCard(); + + cc.Type = WebUtility.InputText(listCctype.SelectedValue, 40); + cc.Expiration = WebUtility.InputText(txtExpdate. Text, 7); + cc.Number = WebUtility.InputText(txtCcnumber.Text, 20); + + return cc; + } + + set + { + if (value != null) + { + if (!string.IsNullOrEmpty(value.Number)) txtCcnumber.Text = value.Number; + if (!string.IsNullOrEmpty(value.Expiration)) txtExpdate. Text = value.Expiration; + if (!string.IsNullOrEmpty(value.Type)) listCctype.Items.FindByValue(value.Type).Selected = true; + } + } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/ItemsControl.ascx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/ItemsControl.ascx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,46 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ItemsControl.ascx.cs" Inherits="PetShop.Web.ItemsControl" %> +<%@ Register TagPrefix="PetShopControl" Namespace="PetShop.Web" %> + + +
+ + + + + + + + + + + + + + + +
+ <%# Eval("Name") %>  + + + + + + + + + + + + + + + + + + + +
Name:<%# string.Format("{0} {1}", Eval("ProductName"), Eval("Name")) %>
Quantity:<%# Eval("Quantity") %>
Price:<%# Eval("Price", "{0:c}") %>
+
 
+
+ +
diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/ItemsControl.ascx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/ItemsControl.ascx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +using System; +using System.Web.UI; +using System.Web.UI.WebControls; + +using PetShop.BusinessLogic; + +namespace PetShop.Web +{ + public partial class ItemsControl : UserControl + { + protected void PageChanged(object sender, DataGridPageChangedEventArgs e) + { + itemsGrid.CurrentPageIndex = e.NewPageIndex; + + string id = Request.QueryString["productId"]; + + itemsGrid.DataSource = new ProductManager().GetItemListByProductID(id); + itemsGrid.DataBind(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/NavigationControl.ascx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/NavigationControl.ascx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="NavigationControl.ascx.cs" Inherits="PetShop.Web.NavigationControl" %> +<%@ OutputCache Duration="100000" VaryByParam="*" %> + + + + + + + + + + + +
+ +
diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/NavigationControl.ascx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/NavigationControl.ascx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,69 @@ +using System; +using System.Web.UI; +using System.Web.UI.WebControls; + +using PetShop.BusinessLogic; + +namespace PetShop.Web +{ + public partial class NavigationControl : UserControl + { + // Control layout property. + // + private string _controlStyle; + protected string ControlStyle + { + get { return _controlStyle; } + } + + // Get properties based on control consumer. + // + protected void GetControlStyle() + { + if (Request.ServerVariables["SCRIPT_NAME"].ToLower().IndexOf("default.aspx") > 0) + _controlStyle = "navigationLinks"; + else + _controlStyle = "mainNavigation"; + } + + protected void Page_Load(object sender, EventArgs e) + { + GetControlStyle(); + BindCategories(); + + // Select current category. + // + string categoryId = Request.QueryString["categoryId"]; + + if (!string.IsNullOrEmpty(categoryId)) + SelectCategory(categoryId); + } + + // Select current category. + // + private void SelectCategory(string categoryId) + { + foreach (RepeaterItem item in repCategories.Items) + { + HiddenField hidCategoryId = (HiddenField)item.FindControl("hidCategoryId"); + + if (hidCategoryId.Value.ToLower() == categoryId.ToLower()) + { + HyperLink lnkCategory = (HyperLink)item.FindControl("lnkCategory"); + + lnkCategory.ForeColor = System.Drawing.Color.FromArgb(199, 116, 3); + + break; + } + } + } + + // Bind categories. + // + private void BindCategories() + { + repCategories.DataSource = new ProductManager().GetCategoryList(); + repCategories.DataBind(); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/ProductsControl.ascx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/ProductsControl.ascx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,18 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ProductsControl.ascx.cs" Inherits="PetShop.Web.ProductsControl" EnableViewState="false" %> +<%@ Register TagPrefix="PetShopControl" Namespace="PetShop.Web" %> +<%@ OutputCache Duration="100000" VaryByParam="page;categoryId" %> + +
+ + + + + + + + +
<%# Eval("Name") %> 
<%# Eval("Name") %>
<%# Eval("Description") %>
+
+ +
+
\ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/ProductsControl.ascx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/ProductsControl.ascx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +using System; +using System.Web; +using System.Web.UI.WebControls; + +using PetShop.BusinessLogic; + +namespace PetShop.Web +{ + public partial class ProductsControl : System.Web.UI.UserControl + { + protected void PageChanged(object sender, DataGridPageChangedEventArgs e) + { + productsList.CurrentPageIndex = e.NewPageIndex; + + string id = Request.QueryString["categoryId"]; + + productsList.DataSource = new ProductManager().GetProductListByCategoryID(id); + productsList.DataBind(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/SearchControl.ascx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/SearchControl.ascx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="SearchControl.ascx.cs" Inherits="PetShop.Web.SearchControl" %> +<%@ OutputCache Duration="100000" VaryByParam="page;keywords" Shared="true" %> +<%@ Register TagPrefix="PetShopControl" Namespace="PetShop.Web" %> + +
+
Search results for <%= Request.QueryString["keywords"] %>:
+ + + + + + + + +
<%# Eval("Name") %> 
<%# Eval("Name") %>
<%# Eval("Description") %>
+
+ +
+
diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/SearchControl.ascx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/SearchControl.ascx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +using System; +using System.Web.UI; +using System.Web.UI.WebControls; + +using PetShop.BusinessLogic; + +namespace PetShop.Web +{ + public partial class SearchControl : UserControl + { + protected void PageChanged(object sender, DataGridPageChangedEventArgs e) + { + searchList.CurrentPageIndex = e.NewPageIndex; + + string keywordKey = Request.QueryString["keywords"]; + + searchList.DataSource = new ProductManager().SearchProducts(keywordKey.Split()); + searchList.DataBind(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/ShoppingCartControl.ascx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/ShoppingCartControl.ascx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,55 @@ +<%@ Control AutoEventWireup="true" CodeFile="ShoppingCartControl.ascx.cs" Inherits="PetShop.Web.ShoppingCartControl" Language="C#" %> + + +
Items in your Shopping Cart
+ + + + + + + + + + + + + + + + + + + + + + +
 NameQtyPrice 
+ + + <%# string.Format("{0} {1}", Eval("Name"), Eval("Type")) %> + + + <%# Eval("Price", "{0:c}")%> + +
+ + +
+ + + + + + + + + +
 
Total + +  
+
+
diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/ShoppingCartControl.ascx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/ShoppingCartControl.ascx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Web.UI.WebControls; + +using PetShop.ObjectModel; + +namespace PetShop.Web +{ + public partial class ShoppingCartControl : System.Web.UI.UserControl + { + protected void Page_PreRender(object sender, EventArgs e) + { + if (!IsPostBack) + BindCart(); + } + + /// + /// Bind repeater to Cart object in Profile + /// + private void BindCart() + { + ICollection cart = Profile.ShoppingCart.Items; + + if (cart.Count > 0) + { + repShoppingCart.DataSource = cart; + repShoppingCart.DataBind(); + + PrintTotal(); + + plhTotal.Visible = true; + } + else + { + repShoppingCart.Visible = false; + plhTotal. Visible = false; + lblMsg. Text = "Your cart is empty."; + } + } + + /// + /// Recalculate the total + /// + private void PrintTotal() + { + if (Profile.ShoppingCart.Items.Count > 0) + ltlTotal.Text = Profile.ShoppingCart.Total.ToString("c"); + } + + /// + /// Calculate total + /// + protected void BtnTotal_Click(object sender, System.Web.UI.ImageClickEventArgs e) + { + TextBox txtQuantity; + ImageButton btnDelete; + int qty = 0; + + foreach (RepeaterItem row in repShoppingCart.Items) + { + txtQuantity = (TextBox) row.FindControl("txtQuantity"); + btnDelete = (ImageButton)row.FindControl("btnDelete"); + + if (int.TryParse(WebUtility.InputText(txtQuantity.Text, 10), out qty)) + { + if (qty > 0) + Profile.ShoppingCart.SetQuantity(btnDelete.CommandArgument, qty); + else if (qty == 0) + Profile.ShoppingCart.Remove(btnDelete.CommandArgument); + } + } + + Profile.Save(); + BindCart(); + } + + /// + /// Handler for Delete/Move buttons + /// + protected void CartItem_Command(object sender, CommandEventArgs e) + { + switch (e.CommandName.ToString()) + { + case "Del": + Profile.ShoppingCart.Remove(e.CommandArgument.ToString()); + break; + + case "Move": + Profile.ShoppingCart.Remove(e.CommandArgument.ToString()); + Profile.WishList.Add(e.CommandArgument.ToString()); + break; + } + + Profile.Save(); + BindCart(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/WishListControl.ascx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/WishListControl.ascx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WishListControl.ascx.cs" Inherits="PetShop.Web.WishListControl"%> +
Items in your Wish List
+ + + + + + + + + + + + + + + + + + + + +
 NamePrice 
+ + + <%# string.Format("{0} {1}", Eval("Name"), Eval("Type")) %> + <%# Eval("Price", "{0:c}")%> + +
+ +
diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Controls/WishListControl.ascx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Controls/WishListControl.ascx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Web.UI.WebControls; + +using PetShop.ObjectModel; + +namespace PetShop.Web +{ + public partial class WishListControl : System.Web.UI.UserControl + { + /// + /// Handle Page load event + /// + protected void Page_PreRender(object sender, EventArgs e) + { + if (!IsPostBack) + BindCart(); + } + + /// + /// Bind repeater to Cart object in Profile + /// + private void BindCart() + { + ICollection wishList = Profile.WishList.Items; + + if (wishList.Count > 0) + { + repWishList.DataSource = wishList; + repWishList.DataBind(); + } + else + { + repWishList.Visible = false; + lblMsg.Text = "Your wish list is empty."; + } + } + + /// + /// Handler for Delete/Move buttons + /// + protected void CartItem_Command(object sender, CommandEventArgs e) + { + switch (e.CommandName.ToString()) + { + case "Del": + Profile.WishList.Remove(e.CommandArgument.ToString()); + break; + + case "Move": + Profile.WishList.Remove(e.CommandArgument.ToString()); + Profile.ShoppingCart.Add(e.CommandArgument.ToString()); + break; + } + + Profile.Save(); + BindCart(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Default.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Default.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,90 @@ +<%@ Page AutoEventWireup="true" CodeFile="~/Default.aspx.cs" EnableViewState="false" Inherits="PetShop.Web.Default" Language="C#" %> +<%@ Register Src="Controls/NavigationControl.ascx" TagName="NavigationControl" TagPrefix="PetShopControl" %> + + + + + + Welcome to .NET Pet Shop + + + + +
+ + + + + + + + + + +
home + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  Welcome to the world of animals  
Sea Horse  + + + + + + + + + + +
Explore our wide selection of what could be your future pet.
+ +

 

+
+
+
  + Created by Vertigo Software, Inc. +
  Based on Pet Shop Version 4.0 - Powered by bltoolkit for .NET  Off-Limits to Guests
+ + + Vertigo Software + +
+ + + diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Default.aspx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Default.aspx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +using System; +using System.Web.UI; + +namespace PetShop.Web +{ + public partial class Default : Page + { + /// + /// Redirect to Search page + /// + protected void btnSearch_Click(object sender, EventArgs e) + { + WebUtility.SearchRedirect(txtSearch.Text); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Error.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Error.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +<%@ Page AutoEventWireup="true" Language="C#" MasterPageFile="~/MasterPage.master" Title="Error" %> + + + + + + + + + +

 

An error occurred!
+

 

+

The system administrator will be checking the web server's event log for details.

+

+ If you have any concerns about a pending transactions please contact the Microsoft + .NET Pet Shop on (555) 555-1234.

+

 

+

 

+
+ +
diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Global.asax --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Global.asax Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,45 @@ +<%@ Application Language="C#" %> +<%@ Import Namespace="System.Diagnostics" %> +<%@ Import Namespace="System.Web" %> +<%@ Import Namespace="PetShop.ObjectModel" %> + + diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Items.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Items.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ +<%@ Page AutoEventWireup="true" CodeFile="Items.aspx.cs" Inherits="PetShop.Web.Items" Language="C#" MasterPageFile="~/MasterPage.master" Title="Items" %> +<%@ Register Src="Controls/ItemsControl.ascx" TagName="ItemsControl" TagPrefix="PetShopControl" %> + + + + diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Items.aspx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Items.aspx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +using System; +using System.Web.UI; + +using PetShop.BusinessLogic; + +namespace PetShop.Web +{ + public partial class Items : PageBase + { + protected void Page_Load(object sender, EventArgs e) + { + Page.Title = new ProductManager().GetProduct(Request.QueryString["productId"]).Name; + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/MasterPage.master --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/MasterPage.master Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,133 @@ +<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="PetShop.Web.MasterPage" %> +<%@ Register Src="Controls/BreadCrumbControl.ascx" TagName="BreadCrumbControl" TagPrefix="PetShopControl" %> +<%@ Register Src="Controls/NavigationControl.ascx" TagName="NavigationControl" TagPrefix="PetShopControl" %> + + + + + + The .NET Pet Shop + + + +
+ + + + + + + +
 .NET Pet Shop 4.0 + + + + + + + + + + + + + +
+ + + + + + + + +
check out wish list
+
+
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
   + + + + + +
+
 
   
 
  + + + + + + 
   
+ +
+ + diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/MasterPage.master.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/MasterPage.master.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Web; +using System.Web.UI.WebControls; + +namespace PetShop.Web +{ + public partial class MasterPage : System.Web.UI.MasterPage + { + protected void Page_PreRender(object sender, EventArgs e) + { + ltlHeader.Text = Page.Header.Title; + Page.Header.Title = string.Format(".NET Pet Shop :: {0}", Page.Header.Title); + } + + protected void btnSearch_Click(object sender, EventArgs e) + { + WebUtility.SearchRedirect(txtSearch.Text); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/NewUser.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/NewUser.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,91 @@ +<%@ Page AutoEventWireup="true" Language="C#" MasterPageFile="~/MasterPage.master" Title="New User" %> + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sign Up for Your New Account
+ + + * +
+ + + * +
+ + + * +
+ +
+ +
+ + + + + +
+ +  
+
+
+
+ + +


Thank you for signing up.

+

Your account has been created. Now you can:

+

Continue shopping

+

Check out

+

Update your profile

+

 

+
+
+
+
+
+
+ diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/icon-cat.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/icon-cat.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/icon-crab.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/icon-crab.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/icon-goose.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/icon-goose.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/icon-raccoon.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/icon-raccoon.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/icon-sheep.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/icon-sheep.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/icon-skunk.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/icon-skunk.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/icon-zebra.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/icon-zebra.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-cat-patterned.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-cat-patterned.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-cat-transparent.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-cat-transparent.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-cat-uncolored.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-cat-uncolored.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-crab-dotted.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-crab-dotted.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-crab-orange.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-crab-orange.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-crab-red.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-crab-red.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-goose-feathered.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-goose-feathered.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-goose-plucked.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-goose-plucked.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-raccoon-hairy-tongue.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-raccoon-hairy-tongue.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-raccoon-long-tongue.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-raccoon-long-tongue.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-raccoon-rough-tongue.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-raccoon-rough-tongue.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-sheep-fuzzy.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-sheep-fuzzy.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-sheep-ironed.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-sheep-ironed.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-skunk-bad-smell.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-skunk-bad-smell.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-skunk-really-bad-smell.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-skunk-really-bad-smell.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-skunk-worst-smell.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-skunk-worst-smell.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-zebra-large.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-zebra-large.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-zebra-medium.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-zebra-medium.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-zebra-small.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-zebra-small.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Backyard/item-zebra-tiny.gif Binary file Demo/Asp.Net/Web/Prod_Images/Backyard/item-zebra-tiny.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/icon-Duck.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/icon-Duck.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/icon-Owl.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/icon-Owl.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/icon-Pelican.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/icon-Pelican.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/icon-Penguin.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/icon-Penguin.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/icon-Pteranodon.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/icon-Pteranodon.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/item-duck-domestic.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/item-duck-domestic.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/item-duck-wild.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/item-duck-wild.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/item-owl-day.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/item-owl-day.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/item-owl-night.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/item-owl-night.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/item-pelican-flowerloving.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/item-pelican-flowerloving.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/item-pelican-grassloving.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/item-pelican-grassloving.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/item-penguine-adventurous.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/item-penguine-adventurous.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/item-penguine-homey.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/item-penguine-homey.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/item-pteranodon-ancient.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/item-pteranodon-ancient.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Birds/item-pteranodon-old.gif Binary file Demo/Asp.Net/Web/Prod_Images/Birds/item-pteranodon-old.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/icon-ant.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/icon-ant.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/icon-butterfly.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/icon-butterfly.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/icon-dragonfly.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/icon-dragonfly.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/icon-frog.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/icon-frog.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/icon-slug.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/icon-slug.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/icon-spider.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/icon-spider.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-ant-queen.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-ant-queen.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-ant-soldier.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-ant-soldier.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-ant-worker.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-ant-worker.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-butterfly-adult.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-butterfly-adult.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-butterfly-larva.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-butterfly-larva.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-butterfly-pupa.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-butterfly-pupa.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-dragonfly-omnivore.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-dragonfly-omnivore.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-dragonfly-vegan.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-dragonfly-vegan.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-dragonfly-vegetarian.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-dragonfly-vegetarian.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-frog-false.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-frog-false.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-frog-true.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-frog-true.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-slug-habitat.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-slug-habitat.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-slug-naked.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-slug-naked.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-spider-Aranielladisplicata.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-spider-Aranielladisplicata.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Bugs/item-spider-Dysderacrocata.gif Binary file Demo/Asp.Net/Web/Prod_Images/Bugs/item-spider-Dysderacrocata.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/icon-dino.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/icon-dino.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/icon-fish.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/icon-fish.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/icon-panda.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/icon-panda.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/icon-pet.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/icon-pet.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/icon-skeleton.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/icon-skeleton.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-dino-pointy.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-dino-pointy.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-dino-shaved.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-dino-shaved.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-dino-spiky.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-dino-spiky.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-fish-caught.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-fish-caught.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-fish-drunk.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-fish-drunk.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-fish-lost.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-fish-lost.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-panda-exclusive.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-panda-exclusive.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-pet-kitty.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-pet-kitty.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-pet-rover.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-pet-rover.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-pet-thumper.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-pet-thumper.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-skeleton-aphrodite.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-skeleton-aphrodite.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-skeleton-female.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-skeleton-female.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-skeleton-hermaphrodite.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-skeleton-hermaphrodite.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Endangered/item-skeleton-male.gif Binary file Demo/Asp.Net/Web/Prod_Images/Endangered/item-skeleton-male.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/icon-Ballonfish.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/icon-Ballonfish.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/icon-Blindfish.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/icon-Blindfish.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/icon-crabfish.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/icon-crabfish.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/icon-eucalyptus.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/icon-eucalyptus.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/icon-meno.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/icon-meno.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/icon-misterno.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/icon-misterno.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/icon-nosyfish.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/icon-nosyfish.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/icon-toothferry.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/icon-toothferry.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-MisterNo-black.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-MisterNo-black.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-MisterNo-sable.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-MisterNo-sable.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-MisterNo-sepia.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-MisterNo-sepia.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-balloon-extra-stretch.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-balloon-extra-stretch.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-balloon-flammable.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-balloon-flammable.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-balloon-natural.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-balloon-natural.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-blindfish-blind.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-blindfish-blind.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-blindfish-farsighted.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-blindfish-farsighted.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-blindfish-shortsighted.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-blindfish-shortsighted.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-crabfish-ballet.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-crabfish-ballet.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-crabfish-ballroom.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-crabfish-ballroom.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-crabfish-tabdance.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-crabfish-tabdance.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-eucalyptus-longarms.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-eucalyptus-longarms.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-eucalyptus-shortarms.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-eucalyptus-shortarms.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-meno-camouflage.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-meno-camouflage.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-meno-happy.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-meno-happy.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-meno-worried.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-meno-worried.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-nosyfish-beastly.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-nosyfish-beastly.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-nosyfish-invidious.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-nosyfish-invidious.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-nosyfish-mean.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-nosyfish-mean.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-nosyfish-sneaky.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-nosyfish-sneaky.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-toothferry-toothless.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-toothferry-toothless.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Prod_Images/Fish/item-toothferry-withteeth.gif Binary file Demo/Asp.Net/Web/Prod_Images/Fish/item-toothferry-withteeth.gif has changed diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Products.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Products.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ +<%@ Page AutoEventWireup="true" Language="C#" MasterPageFile="~/MasterPage.master" Title="Products" Inherits="PetShop.Web.Products" CodeFile="~/Products.aspx.cs" %> +<%@ Register Src="Controls/ProductsControl.ascx" TagName="ProductsControl" TagPrefix="PetShopControl" %> + + + + diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Products.aspx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Products.aspx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +using System; +using System.Web.UI; + +using PetShop.BusinessLogic; + +namespace PetShop.Web +{ + public partial class Products : Page + { + protected void Page_Load(object sender, EventArgs e) + { + Page.Title = new ProductManager().GetCategory(Request.QueryString["categoryId"]).Name; + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Search.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Search.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ +<%@ Page AutoEventWireup="true" Language="C#" MasterPageFile="~/MasterPage.master" Title="Search" %> +<%@ Register Src="Controls/SearchControl.ascx" TagName="SearchControl" TagPrefix="uc1" %> +<%@ Register TagPrefix="PetShopControl" Namespace="PetShop.Web" %> + + + + diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/ShoppingCart.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/ShoppingCart.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ShoppingCart.aspx.cs" Inherits="ShoppingCart" Title="Shopping Cart" %> +<%@ Register Src="Controls/ShoppingCartControl.ascx" TagName="ShoppingCartControl" TagPrefix="PetShopControl" %> + + +
+ + + + + + + + + + + + +
 
Continue Shopping
 
Check Out
+
+
+ diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/ShoppingCart.aspx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/ShoppingCart.aspx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ +using System; + +public partial class ShoppingCart : System.Web.UI.Page +{ + protected void Page_PreInit(object sender, EventArgs e) + { + if (!IsPostBack) + { + string itemId = Request.QueryString["addItem"]; + + if (!string.IsNullOrEmpty(itemId)) + { + Profile.ShoppingCart.Add(itemId); + Profile.Save(); + + // Redirect to prevent duplictations in the cart if user hits "Refresh" + // + Response.Redirect("~/ShoppingCart.aspx", true); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/SignIn.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/SignIn.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,61 @@ +<%@ Page AutoEventWireup="true" Language="C#" MasterPageFile="~/MasterPage.master" Title="Sign In" %> + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
Please Sign In
+ User Name: + + * +
+ Password: + + * +
+   +
+ +
+ +
+ Not registered yet? +
+
+
+
+
+
+
+ diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/UserProfile.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/UserProfile.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +<%@ Page AutoEventWireup="true" CodeFile="UserProfile.aspx.cs" Inherits="PetShop.Web.UserProfile" Language="C#" MasterPageFile="~/MasterPage.master" Title="User Profile" %> +<%@ Register Src="Controls/AddressForm.ascx" TagName="AddressForm" TagPrefix="PetShopControl" %> + + +
+ + + + +
+
Billing Information
+
+ User Name: + +
+
+ + + +
+ +
+
+
+
+
diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/UserProfile.aspx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/UserProfile.aspx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; + +namespace PetShop.Web +{ + public partial class UserProfile : System.Web.UI.Page + { + protected void Page_Load(object sender, EventArgs e) + { + if (!IsPostBack) + BindUser(); + } + + protected void btnSubmit_Click(object sender, EventArgs e) + { + Profile.AccountInfo = AddressForm.Address; + Profile.Save(); + + lblMessage.Text = "Your profile information has been successfully updated.
 "; + } + + private void BindUser() + { + AddressForm.Address = Profile.AccountInfo; + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/Web.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/Web.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/WishList.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/WishList.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="WishList.aspx.cs" Inherits="WishList" Title="Wish List" %> + +<%@ Register Src="Controls/WishListControl.ascx" TagName="WishListControl" TagPrefix="PetShopControl" %> + +
+ + + + + + + + + + + + +
 
Continue Shopping
 
Check Out
+
+
+ diff -r 000000000000 -r f990fcb411a9 Demo/Asp.Net/Web/WishList.aspx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Asp.Net/Web/WishList.aspx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ +using System; + +public partial class WishList : System.Web.UI.Page +{ + protected void Page_PreInit(object sender, EventArgs e) + { + if (!IsPostBack) + { + string itemId = Request.QueryString["addItem"]; + + if (!string.IsNullOrEmpty(itemId)) + { + Profile.WishList.Add(itemId); + Profile.Save(); + + // Redirect to prevent duplictations in the wish list if user hits "Refresh" + // + Response.Redirect("~/WishList.aspx", true); + } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/App.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/Demo/App.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/BLToolkit/BLToolkit.3.dll Binary file Demo/Linq/Demo/BLToolkit/BLToolkit.3.dll has changed diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/DataModel/BLToolkit.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/Demo/DataModel/BLToolkit.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,495 @@ +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Data" #> +<#@ import namespace="System.Linq" #> +<# + AppDomain.CurrentDomain.AssemblyResolve += (_,args) => + { + if (DataProviderAssembly != null) + return System.Reflection.Assembly.LoadFile(DataProviderAssembly); + else + return null; + }; +#><#+ + +static Action WriteComment = (tt,s) => tt.WriteLine("//{0}", s); +static Action WriteUsing = (tt,s) => tt.WriteLine("using {0};", s); +static Action WriteBeginNamespace = (tt,s) => { tt.WriteLine("namespace {0}", s); tt.WriteLine("{"); }; +static Action WriteEndNamespace = tt => tt.WriteLine("}"); +static Action WriteBeginClass = (tt,cl,bc) => +{ + tt.Write("public partial class {0}", cl); + if (!string.IsNullOrEmpty(bc)) + tt.Write(" : {0}", bc); + tt.WriteLine(""); + tt.WriteLine("{"); +}; +static Action WriteEndClass = tt => tt.WriteLine("}"); +static Func MakeGenericType = (c,t) => string.Format("{0}<{1}>", c, t); +static Func MakeType = t => t; +static Action WriteTableProperty = (tt,name,maxlen) => +{ + tt.WriteLine("public Table<{0}>{1} {0}{1} {{ get {{ return GetTable<{0}>();{1} }} }}", name, tt.LenDiff(maxlen, name)); +}; +static Action WriteAttribute = (tt,a) => tt.Write("[{0}]", a); +static Action WriteAttributeLine = tt => tt.WriteLine(""); + +string ConnectionString; +string ConnectionType; +string DataProviderAssembly = null; + +string DatabaseName = null; +string DataContextName = "DataContext"; +string Namespace = "DataModel"; +string BaseDataContextClass = "DbManager"; +string BaseEntityClass = null; +string OneToManyAssociationType = "IEnumerable<{0}>"; + +bool RenderField = false; + +bool IsMetadataLoaded; + +int MaxColumnTypeLen; +int MaxColumnMemberLen; + +static Action RenderColumn = (tt,c,maxLens,attrs) => +{ + if (maxLens.Sum() > 0) + { + if (attrs.Any(_ => _ != null)) + { + tt.Write("["); + + for (var i = 0; i < attrs.Length; i++) + { + if (attrs[i] != null) + { + tt.Write(attrs[i]); + tt.WriteSpace(maxLens[i] - attrs[i].Length); + + if (attrs.Skip(i + 1).Any(_ => _ != null)) + tt.Write(", "); + else if (maxLens.Skip(i + 1).Any(_ => _ > 0)) + tt.WriteSpace(2); + } + else if (maxLens[i] > 0) + { + tt.WriteSpace(maxLens[i]); + + if (maxLens.Skip(i + 1).Any(_ => _ > 0)) + tt.WriteSpace(2); + } + } + + tt.Write("] "); + } + else + { + tt.WriteSpace(maxLens.Sum() + (maxLens.Where(_ => _ > 0).Count() - 1) * 2 + 3); + } + } + + tt.Write("public {0}{1} {2}", c.Type, tt.LenDiff(tt.MaxColumnTypeLen, c.Type), c.MemberName); + + if (tt.RenderField) + tt.WriteLine(";"); + else + tt.WriteLine("{0} {{ get; set; }}", tt.LenDiff(tt.MaxColumnMemberLen, c.MemberName)); +}; + +static Action RenderForeignKey = (tt,key) => +{ + WriteComment(tt, " " + key.KeyName); + tt.WriteLine("[Association(ThisKey=\"{0}\", OtherKey=\"{1}\")]", + string.Join(", ", (from c in key.ThisColumns select c.MemberName).ToArray()), + string.Join(", ", (from c in key.OtherColumns select c.MemberName).ToArray())); + + tt.Write("public "); + + if (key.AssociationType == AssociationType.OneToMany) + tt.Write(tt.OneToManyAssociationType, key.OtherTable.ClassName); + else + tt.Write(key.OtherTable.ClassName); + + tt.Write(" "); + tt.Write(key.MemberName); + + if (tt.RenderField) + tt.WriteLine(";"); + else + tt.WriteLine(" { get; set; }"); +}; + +static Action RenderTable = (tt,t) => +{ + RenderTableAttributes(tt, t); + + WriteBeginClass(tt, t.ClassName, t.BaseClassName); + + tt.PushIndent("\t"); + + tt.MaxColumnTypeLen = t.Columns.Values.Max(_ => _.Type.Length); + tt.MaxColumnMemberLen = t.Columns.Values.Max(_ => _.MemberName.Length); + + var maxLens = new int[] + { + t.Columns.Values.Max(_ => _.MemberName == _.ColumnName ? 0 : "MapField('')".Length + _.ColumnName.Length), + t.Columns.Values.Max(_ => _.IsNullable ? "Nullable".Length : _.IsIdentity ? "Identity".Length : 0), + t.Columns.Values.Max(_ => _.IsIdentity && _.IsNullable ? "Identity".Length : 0), + t.Columns.Values.Max(_ => _.IsPrimaryKey ? string.Format("PrimaryKey({0})", _.PKIndex).Length : 0), + t.Columns.Values.Max(_ => _.Attributes.Count == 0 ? 0 : string.Join(", ", _.Attributes.Distinct().ToArray()).Length), + }; + + foreach (var c in from c in t.Columns.Values orderby c.ID select c) + { + var attrs = new string[] + { + c.MemberName == c.ColumnName ? null : string.Format("MapField(\"{0}\")", c.ColumnName), + c.IsNullable ? "Nullable" : c.IsIdentity ? "Identity" : null, + c.IsIdentity && c.IsNullable ? "Identity" : null, + c.IsPrimaryKey ? string.Format("PrimaryKey({0})", c.PKIndex) : null, + c.Attributes.Count == 0 ? null : string.Join(", ", c.Attributes.Distinct().ToArray()), + }; + + RenderColumn(tt, c, maxLens, attrs); + } + + if (t.ForeignKeys.Count > 0) + { + foreach (var key in t.ForeignKeys.Values) + { + tt.WriteLine(""); + RenderForeignKey(tt, key); + } + } + + tt.PopIndent(); + WriteEndClass(tt); +}; + +static Action RenderTableAttributes = (tt,t) => +{ + if (t.Attributes.Count > 0) + { + WriteAttribute(tt, string.Join(", ", t.Attributes.Distinct().ToArray())); + WriteAttributeLine(tt); + } + + string tbl = "TableName("; + + if (!string.IsNullOrEmpty(tt.DatabaseName)) + tbl += string.Format("Database=\"{0}\", ", tt.DatabaseName); + + if (!string.IsNullOrEmpty(t.Owner)) + tbl += string.Format("Owner=\"{0}\", ", t.Owner); + + tbl += string.Format("Name=\"{0}\")", t.TableName); + + WriteAttribute(tt, tbl); + WriteAttributeLine(tt); +}; + +List Usings = new List() +{ + "System", + "BLToolkit.Data", + "BLToolkit.Data.Linq", + "BLToolkit.DataAccess", + "BLToolkit.Mapping", +}; + +static Action RenderUsing = tt => +{ + var q = + from ns in tt.Usings.Distinct() + group ns by ns.Split('.')[0]; + + var groups = + (from ns in q where ns.Key == "System" select ns).Concat + (from ns in q where ns.Key != "System" orderby ns.Key select ns); + + foreach (var gr in groups) + { + foreach (var ns in from s in gr orderby s select s) + WriteUsing(tt, ns); + + tt.WriteLine(""); + } +}; + +Action BeforeGenerateModel = _ => {}; +Action AfterGenerateModel = _ => {}; + +void GenerateModel() +{ + BeforeGenerateModel(this); + + if (ConnectionString != null) ConnectionString = ConnectionString.Trim(); + if (DataContextName != null) DataContextName = DataContextName. Trim(); + + if (string.IsNullOrEmpty(ConnectionString)) { Error("ConnectionString cannot be empty."); return; } + if (string.IsNullOrEmpty(DataContextName)) { Error("DataContextName cannot be empty."); return; } + + LoadMetadata(); + + WriteComment(this, "---------------------------------------------------------------------------------------------------"); + WriteComment(this, " "); + WriteComment(this, " This code was generated by BLToolkit template for T4."); + WriteComment(this, " Changes to this file may cause incorrect behavior and will be lost if the code is regenerated."); + WriteComment(this, " "); + WriteComment(this, "---------------------------------------------------------------------------------------------------"); + + RenderUsing(this); + + WriteBeginNamespace(this, Namespace); + PushIndent("\t"); + + WriteBeginClass(this, DataContextName, BaseDataContextClass); + + var tlist = (from t in Tables.Values orderby t.TableName select t).ToList(); + var maxlen = tlist.Max(_ => _.ClassName.Length); + + PushIndent("\t"); + + foreach (var t in tlist) + WriteTableProperty(this, t.ClassName, maxlen); + + PopIndent(); + + WriteEndClass(this); + + foreach (var t in tlist) + { + WriteLine(""); + RenderTable(this, t); + } + + PopIndent(); + WriteEndNamespace(this); + + AfterGenerateModel(this); +} + +string LenDiff(int max, string str) +{ + var s = ""; + + while (max-- > str.Length) + s += " "; + + return s; +} + +void WriteSpace(int len) +{ + while (len-- > 0) + Write(" "); +} + +List CreateList(T item) +{ + return new List(); +} + +System.Data.IDbConnection GetConnection() +{ + Type connType = null; + + if (DataProviderAssembly != null) + { + try + { + var assembly = System.Reflection.Assembly.LoadFile(DataProviderAssembly); + connType = assembly.GetType(ConnectionType); + } + catch + { + } + } + + if (connType == null) + connType = Type.GetType(ConnectionType); + + var conn = (System.Data.IDbConnection)Activator.CreateInstance(connType); + + conn.ConnectionString = ConnectionString; + conn.Open(); + + return conn; +} + +void LoadMetadata() +{ + if (IsMetadataLoaded) + return; + + IsMetadataLoaded = true; + + BeforeLoadMetadata(this); + LoadServerMetadata(); + + foreach (var t in Tables.Values) + { + if (t.ClassName.Contains(" ")) + { + var ss = t.ClassName.Split(' ').Where(_ => _.Trim().Length > 0).Select(_ => char.ToUpper(_[0]) + _.Substring(1)); + t.ClassName = string.Join("", ss.ToArray()); + } + } + + foreach (var t in Tables.Values) + foreach (var key in t.ForeignKeys.Values.ToList()) + if (!key.KeyName.EndsWith("_BackReference")) + key.OtherTable.ForeignKeys.Add(key.KeyName + "_BackReference", key.BackReference = new ForeignKey + { + KeyName = key.KeyName + "_BackReference", + MemberName = key.MemberName + "_BackReference", + AssociationType = AssociationType.Auto, + OtherTable = t, + ThisColumns = key.OtherColumns, + OtherColumns = key.ThisColumns + }); + + foreach (var t in Tables.Values) + { + foreach (var key in t.ForeignKeys.Values) + { + if (key.BackReference != null && key.AssociationType == AssociationType.Auto) + { + if (key.ThisColumns.All(_ => _.IsPrimaryKey)) + { + if (t.Columns.Values.Count(_ => _.IsPrimaryKey) == key.ThisColumns.Count) + key.AssociationType = AssociationType.OneToOne; + else + key.AssociationType = AssociationType.ManyToOne; + } + else + key.AssociationType = AssociationType.ManyToOne; + } + } + } + + foreach (var t in Tables.Values) + { + foreach (var key in t.ForeignKeys.Values) + { + var name = key.MemberName; + + if (key.BackReference != null && key.ThisColumns.Count == 1 && key.ThisColumns[0].MemberName.ToLower().EndsWith("id")) + { + name = key.ThisColumns[0].MemberName; + name = name.Substring(0, name.Length - "id".Length); + + if (!t.ForeignKeys.Values.Select(_ => _.MemberName).Concat( + t.Columns. Values.Select(_ => _.MemberName)).Concat( + new[] { t.ClassName }).Any(_ => _ == name)) + { + name = key.MemberName;; + } + } + + if (name == key.MemberName) + { + if (name.StartsWith("FK_")) + name = name.Substring(3); + + if (name.EndsWith("_BackReference")) + name = name.Substring(0, name.Length - "_BackReference".Length); + + name = string.Join("", name.Split('_').Where(_ => _.Length > 0 && _ != t.TableName).ToArray()); + + if (key.AssociationType == AssociationType.OneToMany) + name += "s"; + } + + if (name.Length != 0 && + !t.ForeignKeys.Values.Select(_ => _.MemberName).Concat( + t.Columns. Values.Select(_ => _.MemberName)).Concat( + new[] { t.ClassName }).Any(_ => _ == name)) + { + key.MemberName = name; + } + } + } + + if (Tables.Values.SelectMany(_ => _.ForeignKeys.Values).Any(_ => _.AssociationType == AssociationType.OneToMany)) + Usings.Add("System.Collections.Generic"); + + AfterLoadMetadata(this); +} + +Action BeforeLoadMetadata = _ => {}; +Action AfterLoadMetadata = _ => {}; + +Dictionary Tables = new Dictionary(); + +partial class Table +{ + public string Owner; + public string TableName; + public string ClassName; + public string BaseClassName; + public bool IsView; + public List Attributes = new List(); + + public Dictionary Columns = new Dictionary(); + public Dictionary ForeignKeys = new Dictionary(); +} + +partial class Column +{ + public int ID; + public string ColumnName; + public string MemberName; + public bool IsNullable; + public bool IsIdentity; + public string Type; + public bool IsClass; + public DbType DbType; + public SqlDbType SqlDbType; + public int PKIndex = -1; + public List Attributes = new List(); + + public bool IsPrimaryKey { get { return PKIndex >= 0; } } +} + +enum AssociationType +{ + Auto, + OneToOne, + OneToMany, + ManyToOne, +} + +partial class ForeignKey +{ + public string KeyName; + public string MemberName; + public Table OtherTable; + public List ThisColumns = new List(); + public List OtherColumns = new List(); + public ForeignKey BackReference; + + private AssociationType _associationType = AssociationType.Auto; + public AssociationType AssociationType + { + get { return _associationType; } + set + { + _associationType = value; + + if (BackReference != null) + { + switch (value) + { + case AssociationType.Auto : BackReference.AssociationType = AssociationType.Auto; break; + case AssociationType.OneToOne : BackReference.AssociationType = AssociationType.OneToOne; break; + case AssociationType.OneToMany : BackReference.AssociationType = AssociationType.ManyToOne; break; + case AssociationType.ManyToOne : BackReference.AssociationType = AssociationType.OneToMany; break; + } + } + } + } +} +#> diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/DataModel/MSSQL.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/Demo/DataModel/MSSQL.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,252 @@ +<# + ConnectionType = typeof(System.Data.SqlClient.SqlConnection).AssemblyQualifiedName; +#><#+ +private void LoadServerMetadata() +{ + var tables = CreateList(new { ID = "", Table = new Table() }); + var columns = CreateList(new { ID = "", Column = new Column() }); + + using (var conn = GetConnection()) + using (var cmd = conn.CreateCommand()) + { + // Load tables & vies. + // + cmd.CommandText = @" + SELECT + TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME, + TABLE_SCHEMA, + TABLE_NAME, + TABLE_TYPE + FROM + INFORMATION_SCHEMA.TABLES s + LEFT JOIN sys.tables t ON OBJECT_ID(TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME) = t.object_id + WHERE + t.object_id IS NULL OR + t.is_ms_shipped <> 1 AND + ( + SELECT + major_id + FROM + sys.extended_properties + WHERE + major_id = t.object_id and + minor_id = 0 and + class = 1 and + name = N'microsoft_database_tools_support' + ) IS NULL"; + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var t = new + { + ID = Convert.ToString(rd[0]), + Table = new Table + { + Owner = rd[1].ToString(), + TableName = rd[2].ToString(), + ClassName = rd[2].ToString(), + IsView = rd[3].ToString() == "VIEW", + BaseClassName = BaseEntityClass, + } + }; + + tables.Add(t); + } + } + + // Load columns. + // + cmd.CommandText = @" + SELECT + (TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME) as id, + CASE WHEN IS_NULLABLE = 'YES' THEN 1 ELSE 0 END as isNullable, + ORDINAL_POSITION as colid, + COLUMN_NAME as name, + c.DATA_TYPE as dataType, + CHARACTER_MAXIMUM_LENGTH as length, + ISNULL(NUMERIC_PRECISION, DATETIME_PRECISION) AS prec, + NUMERIC_SCALE as scale, + COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') as isIdentity + FROM + INFORMATION_SCHEMA.COLUMNS c"; + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var col = new + { + ID = Convert.ToString(rd["id"]), + Column = new Column + { + ID = Convert.ToInt16 (rd["colid"]), + ColumnName = Convert.ToString (rd["name"]), + MemberName = Convert.ToString (rd["name"]), + IsNullable = Convert.ToBoolean(rd["isNullable"]), + IsIdentity = Convert.ToBoolean(rd["isIdentity"]), + } + }; + + var c = col.Column; + + switch (Convert.ToString(rd["dataType"])) + { + case "image" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Image; break; + case "text" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.Text; break; + case "binary" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Binary; break; + case "tinyint" : c.Type = "byte"; c.DbType = DbType.Byte; c.SqlDbType = SqlDbType.TinyInt; break; + case "date" : c.Type = "DateTime"; c.DbType = DbType.Date; c.SqlDbType = SqlDbType.Date; break; + case "time" : c.Type = "DateTime"; c.DbType = DbType.Time; c.SqlDbType = SqlDbType.Time; break; + case "bit" : c.Type = "bool"; c.DbType = DbType.Boolean; c.SqlDbType = SqlDbType.Bit; break; + case "smallint" : c.Type = "short"; c.DbType = DbType.Int16; c.SqlDbType = SqlDbType.SmallInt; break; + case "decimal" : c.Type = "decimal"; c.DbType = DbType.Decimal; c.SqlDbType = SqlDbType.Decimal; break; + case "int" : c.Type = "int"; c.DbType = DbType.Int32; c.SqlDbType = SqlDbType.Int; break; + case "smalldatetime" : c.Type = "DateTime"; c.DbType = DbType.DateTime; c.SqlDbType = SqlDbType.SmallDateTime; break; + case "real" : c.Type = "float"; c.DbType = DbType.Single; c.SqlDbType = SqlDbType.Real; break; + case "money" : c.Type = "decimal"; c.DbType = DbType.Currency; c.SqlDbType = SqlDbType.Money; break; + case "datetime" : c.Type = "DateTime"; c.DbType = DbType.DateTime; c.SqlDbType = SqlDbType.DateTime; break; + case "float" : c.Type = "double"; c.DbType = DbType.Double; c.SqlDbType = SqlDbType.Float; break; + case "numeric" : c.Type = "decimal"; c.DbType = DbType.Decimal; c.SqlDbType = SqlDbType.Decimal; break; + case "smallmoney" : c.Type = "decimal"; c.DbType = DbType.Currency; c.SqlDbType = SqlDbType.SmallMoney; break; + case "datetime2" : c.Type = "DateTime"; c.DbType = DbType.DateTime2; c.SqlDbType = SqlDbType.DateTime2; break; + case "bigint" : c.Type = "long"; c.DbType = DbType.Int64; c.SqlDbType = SqlDbType.BigInt; break; + case "varbinary" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.VarBinary; break; + case "timestamp" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Timestamp; break; + case "sysname" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.NVarChar; break; + case "nvarchar" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.NVarChar; break; + case "varchar" : c.Type = "string"; c.DbType = DbType.AnsiString; c.SqlDbType = SqlDbType.VarChar; break; + case "ntext" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.NText; break; + case "uniqueidentifier" : c.Type = "Guid"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.UniqueIdentifier; break; + case "datetimeoffset" : c.Type = "DateTimeOffset"; c.DbType = DbType.DateTimeOffset; c.SqlDbType = SqlDbType.DateTimeOffset; break; + case "sql_variant" : c.Type = "object"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Variant; break; + case "xml" : c.Type = "string"; c.DbType = DbType.Xml; c.SqlDbType = SqlDbType.Xml; break; + +//hierarchyid +//geometry +//geography + + case "char" : + c.Type = Convert.ToInt32 (rd["length"]) == 1 ? "char" : "string"; + c.DbType = DbType.AnsiStringFixedLength; + c.SqlDbType = SqlDbType.Char; + break; + + case "nchar" : + c.Type = Convert.ToInt32 (rd["length"]) == 1 ? "char" : "string"; + c.DbType = DbType.StringFixedLength; + c.SqlDbType = SqlDbType.NChar; + break; + } + + switch (c.Type) + { + case "string" : + case "byte[]" : c.IsClass = true; break; + } + + if (c.IsNullable && !c.IsClass) + c.Type += "?"; + + columns.Add(col); + } + } + + // Load PKs. + // + cmd.CommandText = @" + SELECT + (k.TABLE_CATALOG + '.' + k.TABLE_SCHEMA + '.' + k.TABLE_NAME) as id, + k.CONSTRAINT_NAME as name, + k.COLUMN_NAME as colname, + k.ORDINAL_POSITION as colid + FROM + INFORMATION_SCHEMA.KEY_COLUMN_USAGE k + JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS c ON k.CONSTRAINT_NAME = c.CONSTRAINT_NAME + WHERE + c.CONSTRAINT_TYPE='PRIMARY KEY'"; + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var id = Convert.ToString(rd["id"]); + var colid = Convert.ToInt32 (rd["colid"]); + var colname = Convert.ToString(rd["colname"]); + + columns.Single(_ => _.ID == id && _.Column.ColumnName == colname).Column.PKIndex = colid; + } + } + + // Load FKs. + // + cmd.CommandText = @" + SELECT + rc.CONSTRAINT_NAME as Name, + fk.TABLE_CATALOG + '.' + fk.TABLE_SCHEMA + '.' + fk.TABLE_NAME as ThisTable, + fk.COLUMN_NAME as ThisColumn, + pk.TABLE_CATALOG + '.' + pk.TABLE_SCHEMA + '.' + pk.TABLE_NAME as OtherTable, + pk.COLUMN_NAME as OtherColumn, + cu.ORDINAL_POSITION as Ordinal + FROM + INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc + JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE fk + ON + rc.CONSTRAINT_CATALOG = fk.CONSTRAINT_CATALOG AND + rc.CONSTRAINT_NAME = fk.CONSTRAINT_NAME + JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE pk + ON + rc.UNIQUE_CONSTRAINT_CATALOG = pk.CONSTRAINT_CATALOG AND + rc.UNIQUE_CONSTRAINT_NAME = pk.CONSTRAINT_NAME + JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE cu + ON + rc.CONSTRAINT_NAME = cu.CONSTRAINT_NAME + ORDER BY + ThisTable, + Ordinal"; + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var name = Convert.ToString(rd["Name"]); + var thisTableID = Convert.ToString(rd["ThisTable"]); + var otherTableID = Convert.ToString(rd["OtherTable"]); + var thisColumnName = Convert.ToString(rd["ThisColumn"]); + var otherColumnName = Convert.ToString(rd["OtherColumn"]); + + var thisTable = (from t in tables where t.ID == thisTableID select t.Table).Single(); + var otherTable = (from t in tables where t.ID == otherTableID select t.Table).Single(); + var thisColumn = (from c in columns where c.ID == thisTableID && c.Column.ColumnName == thisColumnName select c.Column).Single(); + var otherColumn = (from c in columns where c.ID == otherTableID && c.Column.ColumnName == otherColumnName select c.Column).Single(); + + if (thisTable.ForeignKeys.ContainsKey(name) == false) + thisTable.ForeignKeys.Add(name, new ForeignKey { KeyName = name, MemberName = name, OtherTable = otherTable }); + + var key = thisTable.ForeignKeys[name]; + + key.ThisColumns. Add(thisColumn); + key.OtherColumns.Add(otherColumn); + } + } + } + + var qc = + from c in columns + group c by c.ID into gr + join t in tables on gr.Key equals t.ID + select new { t.Table, gr }; + + foreach (var c in qc) + { + foreach (var col in from col in c.gr orderby col.Column.ID select col.Column) + c.Table.Columns.Add(col.ColumnName, col); + + if (c.Table.Owner == "dbo") + c.Table.Owner = null; + + Tables.Add(c.Table.TableName, c.Table); + } +} +#> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/DataModel/Northwind.sql Binary file Demo/Linq/Demo/DataModel/Northwind.sql has changed diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/DataModel/NorthwindDB.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/Demo/DataModel/NorthwindDB.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +using System; +using BLToolkit.Data.Linq; +using BLToolkit.Mapping; + +namespace Linq.Demo.DataModel +{ + partial class NorthwindDB + { + public Table DiscontinuedProduct { get { return GetTable(); } } + public Table ActiveProduct { get { return GetTable(); } } + } + + [InheritanceMapping(Code="True", Type=typeof(DiscontinuedProduct))] + [InheritanceMapping(Code="False", Type=typeof(ActiveProduct))] + abstract partial class Product + { + } + + public class ActiveProduct : Product {} + public class DiscontinuedProduct : Product {} +} diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/DataModel/NorthwindDB.generated.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/Demo/DataModel/NorthwindDB.generated.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,488 @@ +//--------------------------------------------------------------------------------------------------- +// +// This code was generated by BLToolkit template for T4. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// +//--------------------------------------------------------------------------------------------------- +using System; +using System.Collections.Generic; + +using BLToolkit.Data; +using BLToolkit.Data.Linq; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace Linq.Demo.DataModel +{ + public partial class NorthwindDB : DbManager + { + public Table AlphabeticalListOfProduct { get { return GetTable(); } } + public Table Category { get { return GetTable(); } } + public Table CategorySalesFor1997 { get { return GetTable(); } } + public Table CurrentProductList { get { return GetTable(); } } + public Table CustomerAndSuppliersByCity { get { return GetTable(); } } + public Table CustomerCustomerDemo { get { return GetTable(); } } + public Table CustomerDemographic { get { return GetTable(); } } + public Table Customer { get { return GetTable(); } } + public Table Employee { get { return GetTable(); } } + public Table EmployeeTerritory { get { return GetTable(); } } + public Table Invoice { get { return GetTable(); } } + public Table OrderDetail { get { return GetTable(); } } + public Table OrderDetailsExtended { get { return GetTable(); } } + public Table OrderSubtotal { get { return GetTable(); } } + public Table Order { get { return GetTable(); } } + public Table OrdersQry { get { return GetTable(); } } + public Table ProductSalesFor1997 { get { return GetTable(); } } + public Table Product { get { return GetTable(); } } + public Table ProductsAboveAveragePrice { get { return GetTable(); } } + public Table ProductsByCategory { get { return GetTable(); } } + public Table QuarterlyOrder { get { return GetTable(); } } + public Table Region { get { return GetTable(); } } + public Table SalesByCategory { get { return GetTable(); } } + public Table SalesTotalsByAmount { get { return GetTable(); } } + public Table Shipper { get { return GetTable(); } } + public Table SummaryOfSalesByQuarter { get { return GetTable(); } } + public Table SummaryOfSalesByYear { get { return GetTable(); } } + public Table Supplier { get { return GetTable(); } } + public Table Territory { get { return GetTable(); } } + } + + [TableName(Name="Alphabetical list of products")] + public partial class AlphabeticalListOfProduct + { + public int ProductID { get; set; } + public string ProductName { get; set; } + [Nullable] public int? SupplierID { get; set; } + [Nullable] public int? CategoryID { get; set; } + [Nullable] public string QuantityPerUnit { get; set; } + [Nullable] public decimal? UnitPrice { get; set; } + [Nullable] public short? UnitsInStock { get; set; } + [Nullable] public short? UnitsOnOrder { get; set; } + [Nullable] public short? ReorderLevel { get; set; } + public bool Discontinued { get; set; } + public string CategoryName { get; set; } + } + + [TableName(Name="Categories")] + public partial class Category + { + [Identity, PrimaryKey(1)] public int CategoryID { get; set; } + public string CategoryName { get; set; } + [Nullable ] public string Description { get; set; } + [Nullable ] public byte[] Picture { get; set; } + + // FK_Products_Categories_BackReference + [Association(ThisKey="CategoryID", OtherKey="CategoryID")] + public List Products { get; set; } + } + + [TableName(Name="Category Sales for 1997")] + public partial class CategorySalesFor1997 + { + public string CategoryName { get; set; } + [Nullable] public decimal? CategorySales { get; set; } + } + + [TableName(Name="Current Product List")] + public partial class CurrentProductList + { + [Identity] public int ProductID { get; set; } + public string ProductName { get; set; } + } + + [TableName(Name="Customer and Suppliers by City")] + public partial class CustomerAndSuppliersByCity + { + [Nullable] public string City { get; set; } + public string CompanyName { get; set; } + [Nullable] public string ContactName { get; set; } + public string Relationship { get; set; } + } + + [TableName(Name="CustomerCustomerDemo")] + public partial class CustomerCustomerDemo + { + [PrimaryKey(1)] public string CustomerID { get; set; } + [PrimaryKey(2)] public string CustomerTypeID { get; set; } + + // FK_CustomerCustomerDemo + [Association(ThisKey="CustomerTypeID", OtherKey="CustomerTypeID")] + public CustomerDemographic FK_CustomerCustomerDemo { get; set; } + + // FK_CustomerCustomerDemo_Customers + [Association(ThisKey="CustomerID", OtherKey="CustomerID")] + public Customer Customer { get; set; } + } + + [TableName(Name="CustomerDemographics")] + public partial class CustomerDemographic + { + [ PrimaryKey(1)] public string CustomerTypeID { get; set; } + [Nullable ] public string CustomerDesc { get; set; } + + // FK_CustomerCustomerDemo_BackReference + [Association(ThisKey="CustomerTypeID", OtherKey="CustomerTypeID")] + public List CustomerCustomerDemo { get; set; } + } + + [TableName(Name="Customers")] + public partial class Customer + { + [ PrimaryKey(1)] public string CustomerID { get; set; } + public string CompanyName { get; set; } + [Nullable ] public string ContactName { get; set; } + [Nullable ] public string ContactTitle { get; set; } + [Nullable ] public string Address { get; set; } + [Nullable ] public string City { get; set; } + [Nullable ] public string Region { get; set; } + [Nullable ] public string PostalCode { get; set; } + [Nullable ] public string Country { get; set; } + [Nullable ] public string Phone { get; set; } + [Nullable ] public string Fax { get; set; } + + // FK_Orders_Customers_BackReference + [Association(ThisKey="CustomerID", OtherKey="CustomerID")] + public List Orders { get; set; } + + // FK_CustomerCustomerDemo_Customers_BackReference + [Association(ThisKey="CustomerID", OtherKey="CustomerID")] + public List CustomerCustomerDemo { get; set; } + } + + [TableName(Name="Employees")] + public partial class Employee + { + [Identity, PrimaryKey(1)] public int EmployeeID { get; set; } + public string LastName { get; set; } + public string FirstName { get; set; } + [Nullable ] public string Title { get; set; } + [Nullable ] public string TitleOfCourtesy { get; set; } + [Nullable ] public DateTime? BirthDate { get; set; } + [Nullable ] public DateTime? HireDate { get; set; } + [Nullable ] public string Address { get; set; } + [Nullable ] public string City { get; set; } + [Nullable ] public string Region { get; set; } + [Nullable ] public string PostalCode { get; set; } + [Nullable ] public string Country { get; set; } + [Nullable ] public string HomePhone { get; set; } + [Nullable ] public string Extension { get; set; } + [Nullable ] public byte[] Photo { get; set; } + [Nullable ] public string Notes { get; set; } + [Nullable ] public int? ReportsTo { get; set; } + [Nullable ] public string PhotoPath { get; set; } + + // FK_Employees_Employees + [Association(ThisKey="ReportsTo", OtherKey="EmployeeID")] + public Employee ReportsToEmployee { get; set; } + + // FK_Orders_Employees_BackReference + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID")] + public List Orders { get; set; } + + // FK_EmployeeTerritories_Employees_BackReference + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID")] + public List EmployeeTerritories { get; set; } + + // FK_Employees_Employees_BackReference + [Association(ThisKey="EmployeeID", OtherKey="ReportsTo")] + public List Reporters { get; set; } + } + + [TableName(Name="EmployeeTerritories")] + public partial class EmployeeTerritory + { + [PrimaryKey(1)] public int EmployeeID { get; set; } + [PrimaryKey(2)] public string TerritoryID { get; set; } + + // FK_EmployeeTerritories_Employees + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID")] + public Employee Employee { get; set; } + + // FK_EmployeeTerritories_Territories + [Association(ThisKey="TerritoryID", OtherKey="TerritoryID")] + public Territory Territory { get; set; } + } + + [TableName(Name="Invoices")] + public partial class Invoice + { + [Nullable] public string ShipName { get; set; } + [Nullable] public string ShipAddress { get; set; } + [Nullable] public string ShipCity { get; set; } + [Nullable] public string ShipRegion { get; set; } + [Nullable] public string ShipPostalCode { get; set; } + [Nullable] public string ShipCountry { get; set; } + [Nullable] public string CustomerID { get; set; } + public string CustomerName { get; set; } + [Nullable] public string Address { get; set; } + [Nullable] public string City { get; set; } + [Nullable] public string Region { get; set; } + [Nullable] public string PostalCode { get; set; } + [Nullable] public string Country { get; set; } + public string Salesperson { get; set; } + public int OrderID { get; set; } + [Nullable] public DateTime? OrderDate { get; set; } + [Nullable] public DateTime? RequiredDate { get; set; } + [Nullable] public DateTime? ShippedDate { get; set; } + public string ShipperName { get; set; } + public int ProductID { get; set; } + public string ProductName { get; set; } + public decimal UnitPrice { get; set; } + public short Quantity { get; set; } + public float Discount { get; set; } + [Nullable] public decimal? ExtendedPrice { get; set; } + [Nullable] public decimal? Freight { get; set; } + } + + [TableName(Name="Order Details")] + public partial class OrderDetail + { + [PrimaryKey(1)] public int OrderID { get; set; } + [PrimaryKey(2)] public int ProductID { get; set; } + public decimal UnitPrice { get; set; } + public short Quantity { get; set; } + public float Discount { get; set; } + + // FK_Order_Details_Orders + [Association(ThisKey="OrderID", OtherKey="OrderID")] + public Order Order { get; set; } + + // FK_Order_Details_Products + [Association(ThisKey="ProductID", OtherKey="ProductID")] + public Product Product { get; set; } + } + + [TableName(Name="Order Details Extended")] + public partial class OrderDetailsExtended + { + public int OrderID { get; set; } + public int ProductID { get; set; } + public string ProductName { get; set; } + public decimal UnitPrice { get; set; } + public short Quantity { get; set; } + public float Discount { get; set; } + [Nullable] public decimal? ExtendedPrice { get; set; } + } + + [TableName(Name="Order Subtotals")] + public partial class OrderSubtotal + { + public int OrderID { get; set; } + [Nullable] public decimal? Subtotal { get; set; } + } + + [TableName(Name="Orders")] + public partial class Order + { + [Identity, PrimaryKey(1)] public int OrderID { get; set; } + [Nullable ] public string CustomerID { get; set; } + [Nullable ] public int? EmployeeID { get; set; } + [Nullable ] public DateTime? OrderDate { get; set; } + [Nullable ] public DateTime? RequiredDate { get; set; } + [Nullable ] public DateTime? ShippedDate { get; set; } + [Nullable ] public int? ShipVia { get; set; } + [Nullable ] public decimal? Freight { get; set; } + [Nullable ] public string ShipName { get; set; } + [Nullable ] public string ShipAddress { get; set; } + [Nullable ] public string ShipCity { get; set; } + [Nullable ] public string ShipRegion { get; set; } + [Nullable ] public string ShipPostalCode { get; set; } + [Nullable ] public string ShipCountry { get; set; } + + // FK_Orders_Customers + [Association(ThisKey="CustomerID", OtherKey="CustomerID")] + public Customer Customer { get; set; } + + // FK_Orders_Employees + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID")] + public Employee Employee { get; set; } + + // FK_Orders_Shippers + [Association(ThisKey="ShipVia", OtherKey="ShipperID")] + public Shipper Shipper { get; set; } + + // FK_Order_Details_Orders_BackReference + [Association(ThisKey="OrderID", OtherKey="OrderID")] + public List OrderDetails { get; set; } + } + + [TableName(Name="Orders Qry")] + public partial class OrdersQry + { + public int OrderID { get; set; } + [Nullable] public string CustomerID { get; set; } + [Nullable] public int? EmployeeID { get; set; } + [Nullable] public DateTime? OrderDate { get; set; } + [Nullable] public DateTime? RequiredDate { get; set; } + [Nullable] public DateTime? ShippedDate { get; set; } + [Nullable] public int? ShipVia { get; set; } + [Nullable] public decimal? Freight { get; set; } + [Nullable] public string ShipName { get; set; } + [Nullable] public string ShipAddress { get; set; } + [Nullable] public string ShipCity { get; set; } + [Nullable] public string ShipRegion { get; set; } + [Nullable] public string ShipPostalCode { get; set; } + [Nullable] public string ShipCountry { get; set; } + public string CompanyName { get; set; } + [Nullable] public string Address { get; set; } + [Nullable] public string City { get; set; } + [Nullable] public string Region { get; set; } + [Nullable] public string PostalCode { get; set; } + [Nullable] public string Country { get; set; } + } + + [TableName(Name="Product Sales for 1997")] + public partial class ProductSalesFor1997 + { + public string CategoryName { get; set; } + public string ProductName { get; set; } + [Nullable] public decimal? ProductSales { get; set; } + } + + [TableName(Name="Products")] + public partial class Product + { + [Identity, PrimaryKey(1) ] public int ProductID { get; set; } + public string ProductName { get; set; } + [Nullable ] public int? SupplierID { get; set; } + [Nullable ] public int? CategoryID { get; set; } + [Nullable ] public string QuantityPerUnit { get; set; } + [Nullable ] public decimal? UnitPrice { get; set; } + [Nullable ] public short? UnitsInStock { get; set; } + [Nullable ] public short? UnitsOnOrder { get; set; } + [Nullable ] public short? ReorderLevel { get; set; } + [ MapField(IsInheritanceDiscriminator=true)] public bool Discontinued { get; set; } + + // FK_Products_Categories + [Association(ThisKey="CategoryID", OtherKey="CategoryID")] + public Category Category { get; set; } + + // FK_Products_Suppliers + [Association(ThisKey="SupplierID", OtherKey="SupplierID")] + public Supplier Supplier { get; set; } + + // FK_Order_Details_Products_BackReference + [Association(ThisKey="ProductID", OtherKey="ProductID")] + public List OrderDetails { get; set; } + } + + [TableName(Name="Products Above Average Price")] + public partial class ProductsAboveAveragePrice + { + public string ProductName { get; set; } + [Nullable] public decimal? UnitPrice { get; set; } + } + + [TableName(Name="Products by Category")] + public partial class ProductsByCategory + { + public string CategoryName { get; set; } + public string ProductName { get; set; } + [Nullable] public string QuantityPerUnit { get; set; } + [Nullable] public short? UnitsInStock { get; set; } + public bool Discontinued { get; set; } + } + + [TableName(Name="Quarterly Orders")] + public partial class QuarterlyOrder + { + [Nullable] public string CustomerID { get; set; } + [Nullable] public string CompanyName { get; set; } + [Nullable] public string City { get; set; } + [Nullable] public string Country { get; set; } + } + + [TableName(Name="Region")] + public partial class Region + { + [PrimaryKey(1)] public int RegionID { get; set; } + public string RegionDescription { get; set; } + + // FK_Territories_Region_BackReference + [Association(ThisKey="RegionID", OtherKey="RegionID")] + public List Territories { get; set; } + } + + [TableName(Name="Sales by Category")] + public partial class SalesByCategory + { + public int CategoryID { get; set; } + public string CategoryName { get; set; } + public string ProductName { get; set; } + [Nullable] public decimal? ProductSales { get; set; } + } + + [TableName(Name="Sales Totals by Amount")] + public partial class SalesTotalsByAmount + { + [Nullable] public decimal? SaleAmount { get; set; } + public int OrderID { get; set; } + public string CompanyName { get; set; } + [Nullable] public DateTime? ShippedDate { get; set; } + } + + [TableName(Name="Shippers")] + public partial class Shipper + { + [Identity, PrimaryKey(1)] public int ShipperID { get; set; } + public string CompanyName { get; set; } + [Nullable ] public string Phone { get; set; } + + // FK_Orders_Shippers_BackReference + [Association(ThisKey="ShipperID", OtherKey="ShipVia")] + public List Orders { get; set; } + } + + [TableName(Name="Summary of Sales by Quarter")] + public partial class SummaryOfSalesByQuarter + { + [Nullable] public DateTime? ShippedDate { get; set; } + public int OrderID { get; set; } + [Nullable] public decimal? Subtotal { get; set; } + } + + [TableName(Name="Summary of Sales by Year")] + public partial class SummaryOfSalesByYear + { + [Nullable] public DateTime? ShippedDate { get; set; } + public int OrderID { get; set; } + [Nullable] public decimal? Subtotal { get; set; } + } + + [TableName(Name="Suppliers")] + public partial class Supplier + { + [Identity, PrimaryKey(1)] public int SupplierID { get; set; } + public string CompanyName { get; set; } + [Nullable ] public string ContactName { get; set; } + [Nullable ] public string ContactTitle { get; set; } + [Nullable ] public string Address { get; set; } + [Nullable ] public string City { get; set; } + [Nullable ] public string Region { get; set; } + [Nullable ] public string PostalCode { get; set; } + [Nullable ] public string Country { get; set; } + [Nullable ] public string Phone { get; set; } + [Nullable ] public string Fax { get; set; } + [Nullable ] public string HomePage { get; set; } + + // FK_Products_Suppliers_BackReference + [Association(ThisKey="SupplierID", OtherKey="SupplierID")] + public List Products { get; set; } + } + + [TableName(Name="Territories")] + public partial class Territory + { + [PrimaryKey(1)] public string TerritoryID { get; set; } + public string TerritoryDescription { get; set; } + public int RegionID { get; set; } + + // FK_Territories_Region + [Association(ThisKey="RegionID", OtherKey="RegionID")] + public Region Region { get; set; } + + // FK_EmployeeTerritories_Territories_BackReference + [Association(ThisKey="TerritoryID", OtherKey="TerritoryID")] + public List EmployeeTerritories { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/DataModel/NorthwindDB.tt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/Demo/DataModel/NorthwindDB.tt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,38 @@ +<#@ template language="C#v3.5" debug="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="BLToolkit.ttinclude" #> +<#@ include file="MSSQL.ttinclude" #> +<# + ConnectionString = "Data Source=.;Database=Northwind;Integrated Security=SSPI"; + Namespace = "Linq.Demo.DataModel"; + DataContextName = "NorthwindDB"; + + OneToManyAssociationType = "List<{0}>"; + + LoadMetadata(); + + foreach (var t in Tables.Values) + { + if (t.ClassName.EndsWith("ies")) + t.ClassName = t.ClassName.Substring(0, t.ClassName.Length - 3) + "y"; + else if (t.ClassName.EndsWith("s")) + t.ClassName = t.ClassName.Substring(0, t.ClassName.Length - 1); + + foreach (var a in t.ForeignKeys.Values) + { + if (a.MemberName.EndsWith("ies")) + a.MemberName = a.MemberName.Substring(0, a.MemberName.Length - 3) + "y"; + else if (a.MemberName.EndsWith("s")) + a.MemberName = a.MemberName.Substring(0, a.MemberName.Length - 1); + } + } + + Tables["Employees"]. ForeignKeys["FK_Employees_Employees"]. MemberName = "ReportsToEmployee"; + Tables["Employees"]. ForeignKeys["FK_Employees_Employees_BackReference"].MemberName = "Reporters"; + Tables["Order Details"].ForeignKeys["FK_Order_Details_Orders"]. MemberName = "Order"; + Tables["Order Details"].ForeignKeys["FK_Order_Details_Products"]. MemberName = "Product"; + + Tables["Products"].Columns["Discontinued"].Attributes.Add("MapField(IsInheritanceDiscriminator=true)"); + + GenerateModel(); +#> diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/Linq.Demo.2008.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/Demo/Linq.Demo.2008.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,85 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {57CE5505-44CB-42E4-A346-3471F68A5B60} + Exe + Properties + Linq.Demo + Linq.Demo + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + BLToolkit\BLToolkit.3.dll + + + + 3.5 + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + True + True + NorthwindDB.tt + + + + + + + + + TextTemplatingFileGenerator + NorthwindDB.generated.cs + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/Linq.Demo.2008.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/Demo/Linq.Demo.2008.sln Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq.Demo.2008", "Linq.Demo.2008.csproj", "{57CE5505-44CB-42E4-A346-3471F68A5B60}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/Linq.Demo.2010.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/Demo/Linq.Demo.2010.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,160 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {57CE5505-44CB-42E4-A346-3471F68A5B60} + Exe + Properties + Linq.Demo + Linq.Demo + v4.0 + 512 + + + 3.5 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\Linq.Demo.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\Linq.Demo.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + + + 3.5 + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + Component + + + True + True + NorthwindDB.tt + Component + + + + + + + + + + TextTemplatingFileGenerator + NorthwindDB.generated.cs + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/Linq.Demo.2010.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/Demo/Linq.Demo.2010.sln Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq.Demo.2010", "Linq.Demo.2010.csproj", "{57CE5505-44CB-42E4-A346-3471F68A5B60}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.4", "..\..\..\Source\BLToolkit.4.csproj", "{0C325F5D-E50E-4340-8724-D29896CCC583}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57CE5505-44CB-42E4-A346-3471F68A5B60}.Release|Any CPU.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/Program.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/Demo/Program.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,740 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Linq.Expressions; + +using BLToolkit.Data; +using BLToolkit.Data.Linq; + +namespace Linq.Demo +{ + using DataModel; + + static class Program + { + static void Main() + { + DbManager.TraceSwitch = new TraceSwitch("DbManager", "DbManager trace switch", "Info"); + + FirstTest(); + CountTest(); + SingleTableTest(); + SelectManyTest(); + InnerJoinTest(); + LeftJoinTest(); + AssociationInnerJoinTest(); + AssociationCountTest(); + AssociationObjectTest(); + MultiLevelAssociationTest(); + CompareAssociationTest(); + GroupByAssociationTest(); + InheritanceTest1(); + InheritanceTest2(); + StringLengthTest(); + StringCompareTest(); + MathRoundCompare1Test(); + MathRoundCompare2Test(); + MathRoundCompare3Test(); + SimpleSelectTest(); + InsertTest1(); + InsertTest2(); + MultipleInsertTest1(); + MultipleInsertTest2(); + InsertWithIdentityTest1(); + InsertWithIdentityTest2(); + UpdateTest1(); + UpdateTest2(); + UpdateTest3(); + SelfUpdateTest(); + DeleteTest1(); + DeleteTest2(); + SqlLengthTest(); + SqlRoundCompare1Test(); + SqlSelectLengthTest(); + SqlSelectLengthAsSqlTest(); + RoundToEvenTest(); + MethodExpressionTest(); + CompiledQueryTest(); + } + + static void FirstTest() + { + using (var db = new NorthwindDB()) + { + var query = db.Employee; + + foreach (var employee in query) + { + Console.WriteLine("{0} {1}", employee.EmployeeID, employee.FirstName); + } + } + } + + static void CountTest() + { + using (var db = new NorthwindDB()) + { + int count = db.Employee.Count(); + + Console.WriteLine(count); + } + } + + static void SingleTableTest() + { + using (var db = new NorthwindDB()) + { + var query = + from e in db.Employee + where e.EmployeeID > 5 + orderby e.LastName, e.FirstName + select e; + + foreach (var employee in query) + { + Console.WriteLine("{0} {1}, {2}", employee.EmployeeID, employee.LastName, employee.FirstName); + } + } + } + + static void SelectManyTest() + { + using (var db = new NorthwindDB()) + { + var query = + from c in db.Category + from p in db.Product + where p.CategoryID == c.CategoryID + select new + { + c.CategoryName, + p.ProductName + }; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void InnerJoinTest() + { + using (var db = new NorthwindDB()) + { + var query = + from p in db.Product + join c in db.Category on p.CategoryID equals c.CategoryID + select new + { + c.CategoryName, + p.ProductName + }; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void LeftJoinTest() + { + using (var db = new NorthwindDB()) + { + var query = + from p in db.Product + join c in db.Category on p.CategoryID equals c.CategoryID into g + from c in g.DefaultIfEmpty() + select new + { + c.CategoryName, + p.ProductName + }; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void AssociationInnerJoinTest() + { + using (var db = new NorthwindDB()) + { + var query = + from p in db.Product + select new + { + p.Category.CategoryName, + p.ProductName + }; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void AssociationCountTest() + { + using (var db = new NorthwindDB()) + { + var query = + from p in db.Product + select new + { + p.OrderDetails.Count, + p.ProductName + }; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void AssociationObjectTest() + { + using (var db = new NorthwindDB()) + { + var query = + from o in db.Order + select new Order + { + OrderID = o.OrderID, + Customer = o.Customer + }; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void MultiLevelAssociationTest() + { + using (var db = new NorthwindDB()) + { + var query = + from o in db.OrderDetail + select new + { + o.Product.ProductName, + o.Order.OrderID, + o.Order.Employee.ReportsToEmployee.Region + }; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void CompareAssociationTest() + { + using (var db = new NorthwindDB()) + { + var query = + from o in db.Order + from t in db.EmployeeTerritory + where o.Employee == t.Employee + select new + { + o.OrderID, + o.EmployeeID, + t.TerritoryID + }; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void GroupByAssociationTest() + { + using (var db = new NorthwindDB()) + { + var query = + from p in db.Product + group p by p.Category into g + where g.Count() == 12 + select g.Key.CategoryName; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void InheritanceTest1() + { + using (var db = new NorthwindDB()) + { + var query = from p in db.DiscontinuedProduct select p; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void InheritanceTest2() + { + using (var db = new NorthwindDB()) + { + var query = + from p in db.Product + where p is DiscontinuedProduct + select p; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void StringLengthTest() + { + using (var db = new NorthwindDB()) + { + var query = + from c in db.Customer + where c.ContactName.Length > 5 + select c.ContactName; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void StringCompareTest() + { + using (var db = new NorthwindDB()) + { + var query = + from c in db.Customer + where c.ContactName.CompareTo("John") > 0 + select c.ContactName; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void MathRoundCompare1Test() + { + using (var db = new NorthwindDB()) + { + var query = + from o in db.Order + where Math.Round(o.Freight.Value) >= 10 + select o.Freight; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void MathRoundCompare2Test() + { + using (var db = new NorthwindDB()) + { + var query = + from o in db.Order + where Math.Round(o.OrderDetails.Sum(d => d.Quantity * d.UnitPrice)) >= 10 + select o.Freight; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void MathRoundCompare3Test() + { + using (var db = new NorthwindDB()) + { + var query = + from o in db.Order + let sum = o.OrderDetails.Sum(d => d.Quantity * d.UnitPrice) + where Math.Round(sum) >= 10 + select o.Freight; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void SimpleSelectTest() + { + using (var db = new NorthwindDB()) + { + var value = db.Select(() => Sql.CurrentTimestamp); + + Console.WriteLine(value); + } + } + + static void InsertTest1() + { + using (var db = new NorthwindDB()) + { + var value = db.Employee.Insert(() => new Employee + { + FirstName = "John", + LastName = "Shepard", + Title = "Spectre", + HireDate = Sql.CurrentTimestamp + }); + + Console.WriteLine(value); + + db.Employee.Delete(e => e.LastName == "Shepard"); + } + } + + static void InsertTest2() + { + using (var db = new NorthwindDB()) + { + var value = + db + .Into(db.Employee) + .Value(e => e.FirstName, "John") + .Value(e => e.LastName, "Shepard") + .Value(e => e.Title, "Spectre") + .Value(e => e.HireDate, () => Sql.CurrentTimestamp) + .Insert(); + + Console.WriteLine(value); + + db.Employee.Delete(e => e.LastName == "Shepard"); + } + } + + static void MultipleInsertTest1() + { + using (var db = new NorthwindDB()) + { + var value = + db.Region + .Where(r => r.RegionID > 2) + .Insert(db.Region, r => new Region() + { + RegionID = r.RegionID + 100, + RegionDescription = "Copy Of " + r.RegionDescription + }); + + Console.WriteLine(value); + + db.Region.Delete(r => r.RegionDescription.StartsWith("Copy Of ")); + } + } + + static void MultipleInsertTest2() + { + using (var db = new NorthwindDB()) + { + var value = + db.Region + .Where(r => r.RegionID > 2) + .Into(db.Region) + .Value(r => r.RegionID, r => r.RegionID + 100) + .Value(r => r.RegionDescription, r => "Copy Of " + r.RegionDescription) + .Insert(); + + Console.WriteLine(value); + + db.Region.Delete(r => r.RegionDescription.StartsWith("Copy Of ")); + } + } + + static void InsertWithIdentityTest1() + { + using (var db = new NorthwindDB()) + { + var value = db.Employee.InsertWithIdentity(() => new Employee + { + FirstName = "John", + LastName = "Shepard", + Title = "Spectre", + HireDate = Sql.CurrentTimestamp + }); + + Console.WriteLine(value); + + db.Employee.Delete(e => e.EmployeeID == Convert.ToInt32(value)); + } + } + + static void InsertWithIdentityTest2() + { + using (var db = new NorthwindDB()) + { + var value = + db + .Into(db.Employee) + .Value(e => e.FirstName, "John") + .Value(e => e.LastName, "Shepard") + .Value(e => e.Title, () => "Spectre") + .Value(e => e.HireDate, () => Sql.CurrentTimestamp) + .InsertWithIdentity(); + + Console.WriteLine(value); + + db.Employee.Delete(e => e.EmployeeID == Convert.ToInt32(value)); + } + } + + static void UpdateTest1() + { + using (var db = new NorthwindDB()) + { + var value = + db.Employee + .Update( + e => e.Title == "Spectre", + e => new Employee + { + Title = "Commander" + }); + + Console.WriteLine(value); + } + } + + static void UpdateTest2() + { + using (var db = new NorthwindDB()) + { + var value = + db.Employee + .Where(e => e.Title == "Spectre") + .Update(e => new Employee + { + Title = "Commander" + }); + + Console.WriteLine(value); + } + } + + static void UpdateTest3() + { + using (var db = new NorthwindDB()) + { + var value = + db.Employee + .Where(e => e.Title == "Spectre") + .Set(e => e.Title, "Commander") + .Update(); + + Console.WriteLine(value); + } + } + + static void SelfUpdateTest() + { + using (var db = new NorthwindDB()) + { + var value = + db.Employee + .Where(e => e.Title == "Spectre") + .Set(e => e.HireDate, e => e.HireDate.Value.AddDays(10)) + .Update(); + + Console.WriteLine(value); + } + } + + static void DeleteTest1() + { + using (var db = new NorthwindDB()) + { + var value = db.Employee.Delete(e => e.Title == "Spectre"); + + Console.WriteLine(value); + } + } + + static void DeleteTest2() + { + using (var db = new NorthwindDB()) + { + var value = + db.Employee + .Where(e => e.Title == "Spectre") + .Delete(); + + Console.WriteLine(value); + } + } + + static void SqlLengthTest() + { + using (var db = new NorthwindDB()) + { + var query = + from c in db.Customer + where Sql.Length(c.ContactName) > 5 + select c.ContactName; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void SqlRoundCompare1Test() + { + using (var db = new NorthwindDB()) + { + var query = + from o in db.Order + where Sql.Round(o.Freight) >= 10 + select o.Freight; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void SqlSelectLengthTest() + { + using (var db = new NorthwindDB()) + { + var query = + from c in db.Customer + select Sql.Length(c.ContactName); + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static void SqlSelectLengthAsSqlTest() + { + using (var db = new NorthwindDB()) + { + var query = + from c in db.Customer + select Sql.AsSql(Sql.Length(c.ContactName)); + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static decimal? RoundToEven(decimal? value) + { + return + value - Sql.Floor(value) == 0.5m && Sql.Floor(value) % 2 == 0? + Sql.Floor(value) : + Sql.Round(value); + } + + static void RoundToEvenTest() + { + Expressions.MapMember( + value => RoundToEven(value), + value => + value - Sql.Floor(value) == 0.5m && Sql.Floor(value) % 2 == 0? + Sql.Floor(value) : + Sql.Round(value)); + + using (var db = new NorthwindDB()) + { + var query = + from o in db.Order + let sum = o.OrderDetails.Sum(d => d.Quantity * d.UnitPrice) + where RoundToEven(sum) >= 10 + select o.Freight; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + [MethodExpression("OrderCountExpression")] + static int OrderCount(Customer customer, string region) + { + throw new InvalidOperationException(); + } + + static Expression> OrderCountExpression() + { + return (customer, region) => customer.Orders.Count(o => o.ShipRegion == region); + } + + static void MethodExpressionTest() + { + using (var db = new NorthwindDB()) + { + var query = + from c in db.Customer + select new + { + sum1 = OrderCount(c, "SP"), + sum2 = OrderCount(c, "NM") + }; + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + + static Func> _query = + CompiledQuery.Compile>((db, n) => + from e in db.Employee + where e.EmployeeID > n + orderby e.LastName, e.FirstName + select e + ); + + static void CompiledQueryTest() + { + using (var db = new NorthwindDB()) + { + var query = _query(db, 5); + + foreach (var item in query) + { + Console.WriteLine(item); + } + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 Demo/Linq/Demo/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/Demo/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Linq.Demo")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Linq.Demo")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("db69ad10-383d-486e-8c3d-bff41f384a1c")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Demo/Linq/OverWCF/App.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/OverWCF/App.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Demo/Linq/OverWCF/Client.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/OverWCF/Client.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ServiceModel; + +namespace Linq.OverWCF +{ + class Client : ClientBase, IDemoService + { + public Client() : base( + new NetTcpBinding(SecurityMode.None) + { + MaxReceivedMessageSize = 10000000, + MaxBufferPoolSize = 10000000, + MaxBufferSize = 10000000, + }, + new EndpointAddress("net.tcp://localhost:1234/LinqOverWCF")) + { + } + + public IEnumerable DemoMethod(string str) + { + return Channel.DemoMethod(str); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Linq/OverWCF/DataModel.generated.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/OverWCF/DataModel.generated.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,261 @@ +//--------------------------------------------------------------------------------------------------- +// +// This code was generated by BLToolkit template for T4. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// +//--------------------------------------------------------------------------------------------------- +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.ServiceModel; +using System.Text; + +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; +using BLToolkit.Data.Linq; +using BLToolkit.Data.Sql; +using BLToolkit.Data.Sql.SqlProvider; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; +using BLToolkit.ServiceModel; + +namespace Linq.OverWCF +{ + public partial class DataModel : ServiceModelDataContext + { + public Table BinaryData { get { return this.GetTable(); } } + public Table Child { get { return this.GetTable(); } } + public Table DataTypes { get { return this.GetTable(); } } + public Table DataTypeTest { get { return this.GetTable(); } } + public Table Doctor { get { return this.GetTable(); } } + public Table GrandChild { get { return this.GetTable(); } } + public Table LinqDataTypes { get { return this.GetTable(); } } + public Table Parent { get { return this.GetTable(); } } + public Table Patient { get { return this.GetTable(); } } + public Table Person { get { return this.GetTable(); } } + + #region FreeTextTable + + public class FreeTextKey + { + public T Key; + public int Rank; + } + + class FreeTextTableExpressionAttribute : TableExpressionAttribute + { + public FreeTextTableExpressionAttribute() + : base("") + { + } + + public override void SetTable(SqlTable table, MemberInfo member, IEnumerable expArgs, IEnumerable sqlArgs) + { + var aargs = sqlArgs.ToArray(); + var arr = ConvertArgs(member, aargs).ToList(); + var method = (MethodInfo)member; + var sp = new MsSql2008SqlProvider(); + + { + var ttype = method.GetGenericArguments()[0]; + var tbl = new SqlTable(ttype); + + var database = tbl.Database == null ? null : sp.Convert(tbl.Database, ConvertType.NameToDatabase). ToString(); + var owner = tbl.Owner == null ? null : sp.Convert(tbl.Owner, ConvertType.NameToOwner). ToString(); + var physicalName = tbl.PhysicalName == null ? null : sp.Convert(tbl.PhysicalName, ConvertType.NameToQueryTable).ToString(); + + var name = sp.BuildTableName(new StringBuilder(), database, owner, physicalName); + + arr.Add(new SqlExpression(name.ToString(), Precedence.Primary)); + } + + { + var field = ((ConstantExpression)expArgs.First()).Value; + + if (field is string) + { + arr[0] = new SqlExpression(field.ToString(), Precedence.Primary); + } + else if (field is LambdaExpression) + { + var body = ((LambdaExpression)field).Body; + + if (body is MemberExpression) + { + var name = ((MemberExpression)body).Member.Name; + + name = sp.Convert(name, ConvertType.NameToQueryField).ToString(); + + arr[0] = new SqlExpression(name, Precedence.Primary); + } + } + } + + table.SqlTableType = SqlTableType.Expression; + table.Name = "FREETEXTTABLE({6}, {2}, {3}) {1}"; + table.TableArguments = arr.ToArray(); + } + } + + [FreeTextTableExpressionAttribute] + public Table> FreeTextTable(string field, string text) + { + return this.GetTable>( + this, + ((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)), + field, + text); + } + + [FreeTextTableExpressionAttribute] + public Table> FreeTextTable(Expression> fieldSelector, string text) + { + return this.GetTable>( + this, + ((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)), + fieldSelector, + text); + } + + #endregion + } + + [TableName(Name="BinaryData")] + public partial class BinaryData + { + [Identity, PrimaryKey(1)] public int BinaryDataID { get; set; } // int(10) + public byte[] Stamp { get; set; } // timestamp + public byte[] Data { get; set; } // varbinary(1024) + } + + [TableName(Name="Child")] + public partial class Child + { + [Nullable] public int? ParentID { get; set; } // int(10) + [Nullable] public int? ChildID { get; set; } // int(10) + } + + [TableName(Name="DataTypes")] + public partial class DataTypes + { + [Nullable] public int? ID { get; set; } // int(10) + [Nullable] public decimal? MoneyValue { get; set; } // decimal(10,4) + } + + [TableName(Name="DataTypeTest")] + public partial class DataTypeTest + { + [Identity, PrimaryKey(1)] public int DataTypeID { get; set; } // int(10) + [Nullable ] public byte[] Binary_ { get; set; } // binary(50) + [Nullable ] public bool? Boolean_ { get; set; } // bit + [Nullable ] public byte? Byte_ { get; set; } // tinyint(3) + [Nullable ] public byte[] Bytes_ { get; set; } // varbinary(50) + [Nullable ] public char? Char_ { get; set; } // char(1) + [Nullable ] public DateTime? DateTime_ { get; set; } // datetime(3) + [Nullable ] public decimal? Decimal_ { get; set; } // decimal(20,2) + [Nullable ] public double? Double_ { get; set; } // float(53) + [Nullable ] public Guid? Guid_ { get; set; } // uniqueidentifier + [Nullable ] public short? Int16_ { get; set; } // smallint(5) + [Nullable ] public int? Int32_ { get; set; } // int(10) + [Nullable ] public long? Int64_ { get; set; } // bigint(19) + [Nullable ] public decimal? Money_ { get; set; } // money(19,4) + [Nullable ] public byte? SByte_ { get; set; } // tinyint(3) + [Nullable ] public float? Single_ { get; set; } // real(24) + [Nullable ] public byte[] Stream_ { get; set; } // varbinary(50) + [Nullable ] public string String_ { get; set; } // nvarchar(50) + [Nullable ] public short? UInt16_ { get; set; } // smallint(5) + [Nullable ] public int? UInt32_ { get; set; } // int(10) + [Nullable ] public long? UInt64_ { get; set; } // bigint(19) + [Nullable ] public string Xml_ { get; set; } // xml(-1) + } + + [TableName(Name="Doctor")] + public partial class Doctor + { + [PrimaryKey(1)] public int PersonID { get; set; } // int(10) + public string Taxonomy { get; set; } // nvarchar(50) + + // FK_Doctor_Person + [Association(ThisKey="PersonID", OtherKey="PersonID", CanBeNull=false)] + public Person Person { get; set; } + } + + [TableName(Name="GrandChild")] + public partial class GrandChild + { + [Nullable] public int? ParentID { get; set; } // int(10) + [Nullable] public int? ChildID { get; set; } // int(10) + [Nullable] public int? GrandChildID { get; set; } // int(10) + } + + [TableName(Name="LinqDataTypes")] + public partial class LinqDataTypes + { + [Nullable] public int? ID { get; set; } // int(10) + [Nullable] public decimal? MoneyValue { get; set; } // decimal(10,4) + [Nullable] public DateTime? DateTimeValue { get; set; } // datetime(3) + [Nullable] public bool? BoolValue { get; set; } // bit + [Nullable] public Guid? GuidValue { get; set; } // uniqueidentifier + [Nullable] public byte[] BinaryValue { get; set; } // varbinary(5000) + [Nullable] public short? SmallIntValue { get; set; } // smallint(5) + } + + [TableName(Name="Parent")] + public partial class Parent + { + [Nullable] public int? ParentID { get; set; } // int(10) + [Nullable] public int? Value1 { get; set; } // int(10) + } + + [TableName(Name="Patient")] + public partial class Patient + { + [PrimaryKey(1)] public int PersonID { get; set; } // int(10) + public string Diagnosis { get; set; } // nvarchar(256) + + // FK_Patient_Person + [Association(ThisKey="PersonID", OtherKey="PersonID", CanBeNull=false)] + public Person Person { get; set; } + } + + [TableName(Name="Person")] + public partial class Person + { + [Identity, PrimaryKey(1)] public int PersonID { get; set; } // int(10) + public string FirstName { get; set; } // nvarchar(50) + public string LastName { get; set; } // nvarchar(50) + [Nullable ] public string MiddleName { get; set; } // nvarchar(50) + public char Gender { get; set; } // char(1) + + // FK_Doctor_Person_BackReference + [Association(ThisKey="PersonID", OtherKey="PersonID", CanBeNull=true)] + public Doctor Doctor { get; set; } + + // FK_Patient_Person_BackReference + [Association(ThisKey="PersonID", OtherKey="PersonID", CanBeNull=true)] + public Patient Patient { get; set; } + } +} + +namespace Linq.OverWCF +{ + public partial class DataModel + { + public DataModel() : base( + new NetTcpBinding(SecurityMode.None) + { + MaxReceivedMessageSize = 10000000, + MaxBufferPoolSize = 10000000, + MaxBufferSize = 10000000, + CloseTimeout = new TimeSpan(00, 01, 00), + OpenTimeout = new TimeSpan(00, 01, 00), + ReceiveTimeout = new TimeSpan(00, 10, 00), + SendTimeout = new TimeSpan(00, 10, 00), + }, + new EndpointAddress("net.tcp://localhost:1234/LinqOverWCF")) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Linq/OverWCF/DataModel.tt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/OverWCF/DataModel.tt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +<#@ template language="C#" debug="True" hostspecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(SolutionDir)\Source\Templates\BLToolkit.ttinclude" #> +<#@ include file="$(SolutionDir)\Source\Templates\BLT4Toolkit.ttinclude" #> +<#@ include file="$(SolutionDir)\Source\Templates\MSSQL.ttinclude" #> +<# + ConnectionString = "Server=.;Database=BLToolkitData;Integrated Security=SSPI"; + + BaseDataContextClass = "ServiceModelDataContext"; + + Usings.Add("BLToolkit.ServiceModel"); + Usings.Add("System.ServiceModel"); + + GenerateModel(); +#> + +namespace Linq.OverWCF +{ + public partial class DataModel + { + public DataModel() : base( + new NetTcpBinding(SecurityMode.None) + { + MaxReceivedMessageSize = 10000000, + MaxBufferPoolSize = 10000000, + MaxBufferSize = 10000000, + CloseTimeout = new TimeSpan(00, 01, 00), + OpenTimeout = new TimeSpan(00, 01, 00), + ReceiveTimeout = new TimeSpan(00, 10, 00), + SendTimeout = new TimeSpan(00, 10, 00), + }, + new EndpointAddress("net.tcp://localhost:1234/LinqOverWCF")) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Linq/OverWCF/DemoService.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/OverWCF/DemoService.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.ServiceModel; + +namespace Linq.OverWCF +{ + [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] + public class DemoService : IDemoService + { + public IEnumerable DemoMethod(string str) + { + foreach (var ch in str) + { + yield return ch.ToString(); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Linq/OverWCF/IDemoService.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/OverWCF/IDemoService.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.ServiceModel; + +namespace Linq.OverWCF +{ + [ServiceContract] + public interface IDemoService + { + [OperationContract] + IEnumerable DemoMethod(string str); + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Linq/OverWCF/Linq.OverWCF.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/OverWCF/Linq.OverWCF.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,163 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {7ED3B518-7CEA-4991-98BD-9752E5F32F58} + Exe + Properties + Linq.OverWCF + Linq.OverWCF + v4.0 + 512 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\Linq.OverWCF.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\Linq.OverWCF.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + + 3.5 + + + 3.0 + + + 3.0 + + + 3.5 + + + 3.5 + + + + + + + + True + True + DataModel.tt + + + + + + + + + + TextTemplatingFileGenerator + DataModel.generated.cs + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Linq/OverWCF/Program.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/OverWCF/Program.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,60 @@ +using System; +using System.Linq; +using System.ServiceModel; +using System.ServiceModel.Description; + +using BLToolkit.Data; +using BLToolkit.ServiceModel; + +namespace Linq.OverWCF +{ + class Program + { + static void Main() + { + DbManager.TurnTraceSwitchOn(); + + using (var host = new ServiceHost(new LinqService("Sql2008"), new Uri("net.tcp://localhost:1234"))) + { + host.Description.Behaviors.Add(new ServiceMetadataBehavior()); + host.Description.Behaviors.Find().IncludeExceptionDetailInFaults = true; + host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex"); + host.AddServiceEndpoint( + typeof(ILinqService), + new NetTcpBinding(SecurityMode.None) + { + MaxReceivedMessageSize = 10000000, + MaxBufferPoolSize = 10000000, + MaxBufferSize = 10000000, + CloseTimeout = new TimeSpan(00, 01, 00), + OpenTimeout = new TimeSpan(00, 01, 00), + ReceiveTimeout = new TimeSpan(00, 10, 00), + SendTimeout = new TimeSpan(00, 10, 00), + }, + "LinqOverWCF"); + + host.Open(); + + var client = new DataModel(); + + var q = + from p in client.Person + select new + { + p.PersonID, + p.FirstName, + p.MiddleName, + p.LastName, + p.Gender + }; + + foreach (var p in q) + Console.WriteLine(p); + + Console.ReadLine(); + + host.Close(); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Linq/OverWCF/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Linq/OverWCF/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Linq.OverWCF")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Linq.OverWCF")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e2dbeea8-fc86-40b1-b63d-0abad6ffafb4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Asp.Net/Default.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/Asp.Net/Default.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,81 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Partial.Trust.Asp.Net._Default" %> + + + + + + Partial Trust Demo + + +
+ +
+To use BLToolkit in Partial Trust Environment you should perform the following steps: + +
+ For all assemblies containing classes for which BLToolkit generates new types such as Partial.Trust.Components.dll in this demo: + +
+
    +
  • + Sign the assembly. +
  • +
  • + Add the AllowPartiallyTrustedCallers attribute: +
    [assembly: AllowPartiallyTrustedCallers]
    +
  • + +
  • + Use BLTgen.exe to generate BLToolkit extensions at the post-build step. For example:

    + + $(ProjectDir)..\..\..\Tools\BLTgen\bin\$(ConfigurationName)\BLTgen.4.exe $(TargetPath) /O:$(ProjectDir)..\Asp.Net\bin /K:$(ProjectDir)Partial.Trust.snk /D

    + + Extension assembly must be signed as well (use /K flag). +
  • +
+
+ + Turn the TypeFactory.LoadTypes flag on. + +
+ Add the following section in the Web.config file: + +
+<configSections>
+	<section name="bltoolkit" type="BLToolkit.Configuration.BLToolkitSection, BLToolkit.4" requirePermission="false"/>
+</configSections>
+<bltoolkit>
+	<typeFactory loadTypes="true" />
+</bltoolkit>
+
+ + - or

+ + set + +
TypeFactory.LoadTypes = true;
+ + somewhere before the first use of BLToolkit (Global.asax for Web applications). + +
+
+ +
+
+ +Sample output: +
+
+ +
+ + + + +
DataAccessor:
Linq query:
Compiled Linq query:
+
+ +
+
+ + diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Asp.Net/Default.aspx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/Asp.Net/Default.aspx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,38 @@ +using System; +using System.Linq; +using System.Web.UI; + +using BLToolkit.Data; +using BLToolkit.Data.Linq; + +namespace Partial.Trust.Asp.Net +{ + using Components; + + public partial class _Default : Page + { + protected void Page_Load(object sender, EventArgs e) + { + var da = PersonDataAccessor.CreateInstance(); + var list = da.GetPersonList(); + + Label1.Text = list[0].ContactName; + + var q = + from c in new Table() + where c.CustomerID == list[0].CustomerID + select c.ContactName; + + Label2.Text = q.First(); + + using (var db = new DbManager()) + Label3.Text = _compiledQuery(db, list[0].CustomerID).ToList().First(); + } + + static readonly Func> _compiledQuery = + CompiledQuery.Compile((DbManager db, string id) => + from c in db.GetTable() + where c.CustomerID == id + select c.ContactName); + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Asp.Net/Default.aspx.designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/Asp.Net/Default.aspx.designer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,51 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Partial.Trust.Asp.Net { + + + public partial class _Default { + + /// + /// form1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlForm form1; + + /// + /// Label1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label Label1; + + /// + /// Label2 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label Label2; + + /// + /// Label3 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label Label3; + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Asp.Net/Partial.Trust.Asp.Net.2008.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/Asp.Net/Partial.Trust.Asp.Net.2008.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,110 @@ + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {16272F10-9E3D-4C24-8761-8A43E9FB525F} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Partial.Trust.Asp.Net + Partial.Trust.Asp.Net + v3.5 + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + + 3.5 + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + + + + + + ASPXCodeBehind + Default.aspx + + + Default.aspx + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.3 + + + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7} + Partial.Trust.Components.2008 + + + + + + + + + + + + + False + True + 61649 + / + + + False + False + + + False + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Asp.Net/Partial.Trust.Asp.Net.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/Asp.Net/Partial.Trust.Asp.Net.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,153 @@ + + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {16272F10-9E3D-4C24-8761-8A43E9FB525F} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Partial.Trust.Asp.Net + Partial.Trust.Asp.Net + v4.0 + + + 4.0 + + + false + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\ + DEBUG;TRACE + full + AnyCPU + bin\Partial.Trust.Asp.Net.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ + TRACE + true + pdbonly + AnyCPU + bin\Partial.Trust.Asp.Net.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + + + + + + + + + + + + + + + + + + + Designer + + + + + ASPXCodeBehind + Default.aspx + + + Default.aspx + + + + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7} + Partial.Trust.Components + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + + False + True + 59174 + / + + + False + False + + + False + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Asp.Net/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/Asp.Net/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Partial.Trust.Asp.Net")] +[assembly: AssemblyProduct("Partial.Trust.Asp.Net")] +[assembly: AssemblyCopyright("\xA9 2002-2012 www.bltoolkit.net")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3d5900ae-111a-45be-96b3-d9e4606ca793")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Asp.Net/Web.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/Asp.Net/Web.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,17 @@ + + + +
+ + + + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Components/Customer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/Components/Customer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; + +namespace Partial.Trust.Components +{ + public class Customers + { + public string CustomerID; + public string CompanyName; + public string ContactName; + public string ContactTitle; + public string Address; + public string City; + public string Region; + public string PostalCode; + public string Country; + public string Phone; + public string Fax; + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Components/Partial.Trust.Components.2008.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/Components/Partial.Trust.Components.2008.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,75 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7} + Library + Properties + Partial.Trust.Components + Partial.Trust.Components + v3.5 + 512 + true + Partial.Trust.snk + OnOutputUpdated + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.3 + + + + + + + + + $(ProjectDir)..\..\..\Tools\BLTgen\bin\$(ConfigurationName)\BLTgen.exe $(TargetPath) /O:$(ProjectDir)..\Asp.Net\bin /K:$(ProjectDir)Partial.Trust.snk /D + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Components/Partial.Trust.Components.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/Components/Partial.Trust.Components.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,148 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {3BCB17AC-9941-4460-858B-2B7BC3BEDDE7} + Library + Properties + Partial.Trust.Components + Partial.Trust.Components + v4.0 + 512 + true + Partial.Trust.snk + OnOutputUpdated + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\Partial.Trust.Components.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\Partial.Trust.Components.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + $(ProjectDir)..\..\..\Tools\BLTgen\bin\$(ConfigurationName)\BLTgen.4.exe $(TargetPath) /O:$(ProjectDir)..\Asp.Net\bin /K:$(ProjectDir)Partial.Trust.snk /D + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Components/Partial.Trust.snk Binary file Demo/Partial.Trust/Components/Partial.Trust.snk has changed diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Components/PersonDataAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/Components/PersonDataAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +using BLToolkit.DataAccess; + +namespace Partial.Trust.Components +{ + public abstract class PersonDataAccessor : DataAccessor + { + [SqlQuery("SELECT * FROM Customers")] + public abstract List GetPersonList(); + + public static PersonDataAccessor CreateInstance() + { + return CreateInstance(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/Components/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/Components/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ +using System; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Partial.Trust.Components")] +[assembly: AssemblyProduct("Partial.Trust.Components")] +[assembly: AssemblyCopyright("\xA9 2002-2012 www.bltoolkit.net")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c9109767-494e-4994-ac1a-2458efc3765c")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + +[assembly: AllowPartiallyTrustedCallers] diff -r 000000000000 -r f990fcb411a9 Demo/Partial.Trust/ReadMe.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Partial.Trust/ReadMe.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +To use BLToolkit in Partial Trust Environment you should perform the following steps: + + For all assemblies containing classes for which BLToolkit generates + new types such as Partial.Trust.Components.dll in this demo: + + - Sign the assembly. + + - Add the AllowPartiallyTrustedCallers attribute: + + [assembly: AllowPartiallyTrustedCallers] + + - Use BLTgen.exe to generate BLToolkit extensions at the post-build step. + For example: + + $(ProjectDir)..\..\..\Tools\BLTgen\bin\$(ConfigurationName)\BLTgen.exe $(TargetPath) /O:$(ProjectDir)..\Asp.Net\bin /K:$(ProjectDir)Partial.Trust.snk /D + + Extension assembly must be signed as well (use /K flag). + + Turn the TypeFactory.LoadTypes flag on. + + Add the following section in the Web.config file: + + +
+ + + + + + - or + + set + + TypeFactory.LoadTypes = true; + + somewhere before the first use of BLToolkit (Global.asax for Web applications). diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client.Web/Client.Web.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client.Web/Client.Web.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,175 @@ + + + + + Debug + AnyCPU + + + 2.0 + {E796EF23-D63D-4EBD-A34D-5F243834933B} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Client.Web + Client.Web + v4.0 + {28693777-369C-4C0D-B076-38F7C0E5D06C}|..\Client\Client.csproj|ClientBin|False + false + + + 4.0 + + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + true + bin\ + DEBUG;TRACE + full + AnyCPU + bin\Client.Web.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + + + bin\ + TRACE + true + pdbonly + AnyCPU + bin\Client.Web.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Web.config + + + Web.config + + + + + DataModel.tt + True + True + Component + + + + LinqWebService.asmx + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + TextTemplatingFileGenerator + DataModel.generated.cs + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + False + False + 31020 + / + + + False + False + + + False + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client.Web/ClientTestPage.aspx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client.Web/ClientTestPage.aspx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,74 @@ +<%@ Page Language="C#" AutoEventWireup="true" %> + + + + + Client + + + + + +
+
+ + + + + + + + Get Microsoft Silverlight + +
+
+ + diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client.Web/ClientTestPage.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client.Web/ClientTestPage.html Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,73 @@ + + + + + Client + + + + + +
+
+ + + + + + + + Get Microsoft Silverlight + +
+
+ + diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client.Web/DataModel.generated.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client.Web/DataModel.generated.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,619 @@ +//--------------------------------------------------------------------------------------------------- +// +// This code was generated by BLToolkit template for T4. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// +//--------------------------------------------------------------------------------------------------- +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.ServiceModel; +using System.Text; + +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; +using BLToolkit.Data.Linq; +using BLToolkit.Data.Sql; +using BLToolkit.Data.Sql.SqlProvider; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; +using BLToolkit.ServiceModel; + +namespace Client +{ + public partial class DataModel : DbManager + { + public Table AlphabeticalListOfProducts { get { return this.GetTable(); } } + /// + /// Description for Categories table. + /// + public Table Categories { get { return this.GetTable(); } } + public Table CategorySalesFor1997 { get { return this.GetTable(); } } + public Table CurrentProductList { get { return this.GetTable(); } } + public Table CustomerAndSuppliersByCity { get { return this.GetTable(); } } + public Table CustomerCustomerDemo { get { return this.GetTable(); } } + public Table CustomerDemographics { get { return this.GetTable(); } } + /// + /// Description of Customers table. + /// + public Table Customers { get { return this.GetTable(); } } + public Table Employees { get { return this.GetTable(); } } + public Table EmployeeTerritories { get { return this.GetTable(); } } + public Table Invoices { get { return this.GetTable(); } } + public Table OrderDetails { get { return this.GetTable(); } } + public Table OrderDetailsExtended { get { return this.GetTable(); } } + public Table OrderSubtotals { get { return this.GetTable(); } } + public Table Orders { get { return this.GetTable(); } } + public Table OrdersQry { get { return this.GetTable(); } } + public Table ProductSalesFor1997 { get { return this.GetTable(); } } + public Table Products { get { return this.GetTable(); } } + public Table ProductsAboveAveragePrice { get { return this.GetTable(); } } + public Table ProductsByCategory { get { return this.GetTable(); } } + public Table QuarterlyOrders { get { return this.GetTable(); } } + public Table Region { get { return this.GetTable(); } } + public Table SalesByCategory { get { return this.GetTable(); } } + public Table SalesTotalsByAmount { get { return this.GetTable(); } } + public Table Shippers { get { return this.GetTable(); } } + public Table SummaryOfSalesByQuarter { get { return this.GetTable(); } } + public Table SummaryOfSalesByYear { get { return this.GetTable(); } } + public Table Suppliers { get { return this.GetTable(); } } + public Table Territories { get { return this.GetTable(); } } + + #region FreeTextTable + + public class FreeTextKey + { + public T Key; + public int Rank; + } + + class FreeTextTableExpressionAttribute : TableExpressionAttribute + { + public FreeTextTableExpressionAttribute() + : base("") + { + } + + public override void SetTable(SqlTable table, MemberInfo member, IEnumerable expArgs, IEnumerable sqlArgs) + { + var aargs = sqlArgs.ToArray(); + var arr = ConvertArgs(member, aargs).ToList(); + var method = (MethodInfo)member; + var sp = new MsSql2008SqlProvider(); + + { + var ttype = method.GetGenericArguments()[0]; + var tbl = new SqlTable(ttype); + + var database = tbl.Database == null ? null : sp.Convert(tbl.Database, ConvertType.NameToDatabase). ToString(); + var owner = tbl.Owner == null ? null : sp.Convert(tbl.Owner, ConvertType.NameToOwner). ToString(); + var physicalName = tbl.PhysicalName == null ? null : sp.Convert(tbl.PhysicalName, ConvertType.NameToQueryTable).ToString(); + + var name = sp.BuildTableName(new StringBuilder(), database, owner, physicalName); + + arr.Add(new SqlExpression(name.ToString(), Precedence.Primary)); + } + + { + var field = ((ConstantExpression)expArgs.First()).Value; + + if (field is string) + { + arr[0] = new SqlExpression(field.ToString(), Precedence.Primary); + } + else if (field is LambdaExpression) + { + var body = ((LambdaExpression)field).Body; + + if (body is MemberExpression) + { + var name = ((MemberExpression)body).Member.Name; + + name = sp.Convert(name, ConvertType.NameToQueryField).ToString(); + + arr[0] = new SqlExpression(name, Precedence.Primary); + } + } + } + + table.SqlTableType = SqlTableType.Expression; + table.Name = "FREETEXTTABLE({6}, {2}, {3}) {1}"; + table.TableArguments = arr.ToArray(); + } + } + + [FreeTextTableExpressionAttribute] + public Table> FreeTextTable(string field, string text) + { + return this.GetTable>( + this, + ((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)), + field, + text); + } + + [FreeTextTableExpressionAttribute] + public Table> FreeTextTable(Expression> fieldSelector, string text) + { + return this.GetTable>( + this, + ((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)), + fieldSelector, + text); + } + + #endregion + } + + // View + [TableName(Name="Alphabetical list of products")] + public partial class AlphabeticalListOfProducts + { + public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public int? SupplierID { get; set; } // int(10) + [Nullable] public int? CategoryID { get; set; } // int(10) + [Nullable] public string QuantityPerUnit { get; set; } // nvarchar(20) + [Nullable] public decimal? UnitPrice { get; set; } // money(19,4) + [Nullable] public short? UnitsInStock { get; set; } // smallint(5) + [Nullable] public short? UnitsOnOrder { get; set; } // smallint(5) + [Nullable] public short? ReorderLevel { get; set; } // smallint(5) + public bool Discontinued { get; set; } // bit + public string CategoryName { get; set; } // nvarchar(15) + } + + /// + /// Description for Categories table. + /// + [TableName(Name="Categories")] + public partial class Categories + { + /// + /// Description of Categories.CategoryID field. + /// + [Identity, PrimaryKey(1)] public int CategoryID { get; set; } // int(10) + public string CategoryName { get; set; } // nvarchar(15) + [Nullable ] public string Description { get; set; } // ntext(1073741823) + [Nullable ] public byte[] Picture { get; set; } // image(2147483647) + + // FK_Products_Categories_BackReference + [Association(ThisKey="CategoryID", OtherKey="CategoryID", CanBeNull=true)] + public IEnumerable Productss { get; set; } + } + + // View + [TableName(Name="Category Sales for 1997")] + public partial class CategorySalesFor1997 + { + public string CategoryName { get; set; } // nvarchar(15) + [Nullable] public decimal? CategorySales { get; set; } // money(19,4) + } + + // View + [TableName(Name="Current Product List")] + public partial class CurrentProductList + { + [Identity] public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + } + + // View + [TableName(Name="Customer and Suppliers by City")] + public partial class CustomerAndSuppliersByCity + { + [Nullable] public string City { get; set; } // nvarchar(15) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable] public string ContactName { get; set; } // nvarchar(30) + public string Relationship { get; set; } // varchar(9) + } + + [TableName(Name="CustomerCustomerDemo")] + public partial class CustomerCustomerDemo + { + [PrimaryKey(1)] public string CustomerID { get; set; } // nchar(5) + [PrimaryKey(2)] public string CustomerTypeID { get; set; } // nchar(10) + + // FK_CustomerCustomerDemo + [Association(ThisKey="CustomerTypeID", OtherKey="CustomerTypeID", CanBeNull=false)] + public CustomerDemographics FK_CustomerCustomerDemo { get; set; } + + // FK_CustomerCustomerDemo_Customers + [Association(ThisKey="CustomerID", OtherKey="CustomerID", CanBeNull=false)] + public Customers Customers { get; set; } + } + + [TableName(Name="CustomerDemographics")] + public partial class CustomerDemographics + { + [ PrimaryKey(1)] public string CustomerTypeID { get; set; } // nchar(10) + [Nullable ] public string CustomerDesc { get; set; } // ntext(1073741823) + + // FK_CustomerCustomerDemo_BackReference + [Association(ThisKey="CustomerTypeID", OtherKey="CustomerTypeID", CanBeNull=true)] + public IEnumerable CustomerCustomerDemos { get; set; } + } + + /// + /// Description of Customers table. + /// + [TableName(Name="Customers")] + public partial class Customers + { + /// + /// Just ID. + /// + [ PrimaryKey(1)] public string CustomerID { get; set; } // nchar(5) + /// + /// Name of the Company. + /// + public string CompanyName { get; set; } // nvarchar(40) + [Nullable ] public string ContactName { get; set; } // nvarchar(30) + [Nullable ] public string ContactTitle { get; set; } // nvarchar(30) + [Nullable ] public string Address { get; set; } // nvarchar(60) + [Nullable ] public string City { get; set; } // nvarchar(15) + [Nullable ] public string Region { get; set; } // nvarchar(15) + [Nullable ] public string PostalCode { get; set; } // nvarchar(10) + [Nullable ] public string Country { get; set; } // nvarchar(15) + [Nullable ] public string Phone { get; set; } // nvarchar(24) + [Nullable ] public string Fax { get; set; } // nvarchar(24) + + // FK_Orders_Customers_BackReference + [Association(ThisKey="CustomerID", OtherKey="CustomerID", CanBeNull=true)] + public IEnumerable Orderss { get; set; } + + // FK_CustomerCustomerDemo_Customers_BackReference + [Association(ThisKey="CustomerID", OtherKey="CustomerID", CanBeNull=true)] + public IEnumerable CustomerCustomerDemos { get; set; } + } + + [TableName(Name="Employees")] + public partial class Employees + { + [Identity, PrimaryKey(1)] public int EmployeeID { get; set; } // int(10) + public string LastName { get; set; } // nvarchar(20) + public string FirstName { get; set; } // nvarchar(10) + [Nullable ] public string Title { get; set; } // nvarchar(30) + [Nullable ] public string TitleOfCourtesy { get; set; } // nvarchar(25) + [Nullable ] public DateTime? BirthDate { get; set; } // datetime(3) + [Nullable ] public DateTime? HireDate { get; set; } // datetime(3) + [Nullable ] public string Address { get; set; } // nvarchar(60) + [Nullable ] public string City { get; set; } // nvarchar(15) + [Nullable ] public string Region { get; set; } // nvarchar(15) + [Nullable ] public string PostalCode { get; set; } // nvarchar(10) + [Nullable ] public string Country { get; set; } // nvarchar(15) + [Nullable ] public string HomePhone { get; set; } // nvarchar(24) + [Nullable ] public string Extension { get; set; } // nvarchar(4) + [Nullable ] public byte[] Photo { get; set; } // image(2147483647) + [Nullable ] public string Notes { get; set; } // ntext(1073741823) + [Nullable ] public int? ReportsTo { get; set; } // int(10) + [Nullable ] public string PhotoPath { get; set; } // nvarchar(255) + + // FK_Employees_Employees + [Association(ThisKey="ReportsTo", OtherKey="EmployeeID", CanBeNull=true)] + public Employees FK_Employees_Employees { get; set; } + + // FK_Orders_Employees_BackReference + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID", CanBeNull=true)] + public IEnumerable Orderss { get; set; } + + // FK_EmployeeTerritories_Employees_BackReference + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID", CanBeNull=true)] + public IEnumerable EmployeeTerritoriess { get; set; } + + // FK_Employees_Employees_BackReference + [Association(ThisKey="EmployeeID", OtherKey="ReportsTo", CanBeNull=true)] + public IEnumerable FK_Employees_Employees_BackReference { get; set; } + } + + [TableName(Name="EmployeeTerritories")] + public partial class EmployeeTerritories + { + [PrimaryKey(1)] public int EmployeeID { get; set; } // int(10) + [PrimaryKey(2)] public string TerritoryID { get; set; } // nvarchar(20) + + // FK_EmployeeTerritories_Employees + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID", CanBeNull=false)] + public Employees Employees { get; set; } + + // FK_EmployeeTerritories_Territories + [Association(ThisKey="TerritoryID", OtherKey="TerritoryID", CanBeNull=false)] + public Territories Territories { get; set; } + } + + // View + [TableName(Name="Invoices")] + public partial class Invoices + { + [Nullable] public string ShipName { get; set; } // nvarchar(40) + [Nullable] public string ShipAddress { get; set; } // nvarchar(60) + [Nullable] public string ShipCity { get; set; } // nvarchar(15) + [Nullable] public string ShipRegion { get; set; } // nvarchar(15) + [Nullable] public string ShipPostalCode { get; set; } // nvarchar(10) + [Nullable] public string ShipCountry { get; set; } // nvarchar(15) + [Nullable] public string CustomerID { get; set; } // nchar(5) + public string CustomerName { get; set; } // nvarchar(40) + [Nullable] public string Address { get; set; } // nvarchar(60) + [Nullable] public string City { get; set; } // nvarchar(15) + [Nullable] public string Region { get; set; } // nvarchar(15) + [Nullable] public string PostalCode { get; set; } // nvarchar(10) + [Nullable] public string Country { get; set; } // nvarchar(15) + public string Salesperson { get; set; } // nvarchar(31) + public int OrderID { get; set; } // int(10) + [Nullable] public DateTime? OrderDate { get; set; } // datetime(3) + [Nullable] public DateTime? RequiredDate { get; set; } // datetime(3) + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + public string ShipperName { get; set; } // nvarchar(40) + public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + public decimal UnitPrice { get; set; } // money(19,4) + public short Quantity { get; set; } // smallint(5) + public float Discount { get; set; } // real(24) + [Nullable] public decimal? ExtendedPrice { get; set; } // money(19,4) + [Nullable] public decimal? Freight { get; set; } // money(19,4) + } + + [TableName(Name="Order Details")] + public partial class OrderDetails + { + [PrimaryKey(1)] public int OrderID { get; set; } // int(10) + [PrimaryKey(2)] public int ProductID { get; set; } // int(10) + public decimal UnitPrice { get; set; } // money(19,4) + public short Quantity { get; set; } // smallint(5) + public float Discount { get; set; } // real(24) + + // FK_Order_Details_Orders + [Association(ThisKey="OrderID", OtherKey="OrderID", CanBeNull=false)] + public Orders OrderDetailsOrders { get; set; } + + // FK_Order_Details_Products + [Association(ThisKey="ProductID", OtherKey="ProductID", CanBeNull=false)] + public Products OrderDetailsProducts { get; set; } + } + + // View + [TableName(Name="Order Details Extended")] + public partial class OrderDetailsExtended + { + public int OrderID { get; set; } // int(10) + public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + public decimal UnitPrice { get; set; } // money(19,4) + public short Quantity { get; set; } // smallint(5) + public float Discount { get; set; } // real(24) + [Nullable] public decimal? ExtendedPrice { get; set; } // money(19,4) + } + + // View + [TableName(Name="Order Subtotals")] + public partial class OrderSubtotals + { + public int OrderID { get; set; } // int(10) + [Nullable] public decimal? Subtotal { get; set; } // money(19,4) + } + + [TableName(Name="Orders")] + public partial class Orders + { + [Identity, PrimaryKey(1)] public int OrderID { get; set; } // int(10) + [Nullable ] public string CustomerID { get; set; } // nchar(5) + [Nullable ] public int? EmployeeID { get; set; } // int(10) + [Nullable ] public DateTime? OrderDate { get; set; } // datetime(3) + [Nullable ] public DateTime? RequiredDate { get; set; } // datetime(3) + [Nullable ] public DateTime? ShippedDate { get; set; } // datetime(3) + [Nullable ] public int? ShipVia { get; set; } // int(10) + [Nullable ] public decimal? Freight { get; set; } // money(19,4) + [Nullable ] public string ShipName { get; set; } // nvarchar(40) + [Nullable ] public string ShipAddress { get; set; } // nvarchar(60) + [Nullable ] public string ShipCity { get; set; } // nvarchar(15) + [Nullable ] public string ShipRegion { get; set; } // nvarchar(15) + [Nullable ] public string ShipPostalCode { get; set; } // nvarchar(10) + [Nullable ] public string ShipCountry { get; set; } // nvarchar(15) + + // FK_Orders_Shippers + [Association(ThisKey="ShipVia", OtherKey="ShipperID", CanBeNull=true)] + public Shippers Shippers { get; set; } + + // FK_Orders_Employees + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID", CanBeNull=true)] + public Employees Employees { get; set; } + + // FK_Orders_Customers + [Association(ThisKey="CustomerID", OtherKey="CustomerID", CanBeNull=true)] + public Customers Customers { get; set; } + + // FK_Order_Details_Orders_BackReference + [Association(ThisKey="OrderID", OtherKey="OrderID", CanBeNull=true)] + public IEnumerable OrderDetailss { get; set; } + } + + // View + [TableName(Name="Orders Qry")] + public partial class OrdersQry + { + public int OrderID { get; set; } // int(10) + [Nullable] public string CustomerID { get; set; } // nchar(5) + [Nullable] public int? EmployeeID { get; set; } // int(10) + [Nullable] public DateTime? OrderDate { get; set; } // datetime(3) + [Nullable] public DateTime? RequiredDate { get; set; } // datetime(3) + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + [Nullable] public int? ShipVia { get; set; } // int(10) + [Nullable] public decimal? Freight { get; set; } // money(19,4) + [Nullable] public string ShipName { get; set; } // nvarchar(40) + [Nullable] public string ShipAddress { get; set; } // nvarchar(60) + [Nullable] public string ShipCity { get; set; } // nvarchar(15) + [Nullable] public string ShipRegion { get; set; } // nvarchar(15) + [Nullable] public string ShipPostalCode { get; set; } // nvarchar(10) + [Nullable] public string ShipCountry { get; set; } // nvarchar(15) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable] public string Address { get; set; } // nvarchar(60) + [Nullable] public string City { get; set; } // nvarchar(15) + [Nullable] public string Region { get; set; } // nvarchar(15) + [Nullable] public string PostalCode { get; set; } // nvarchar(10) + [Nullable] public string Country { get; set; } // nvarchar(15) + } + + // View + [TableName(Name="Product Sales for 1997")] + public partial class ProductSalesFor1997 + { + public string CategoryName { get; set; } // nvarchar(15) + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public decimal? ProductSales { get; set; } // money(19,4) + } + + [TableName(Name="Products")] + public partial class Products + { + [Identity, PrimaryKey(1)] public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + [Nullable ] public int? SupplierID { get; set; } // int(10) + [Nullable ] public int? CategoryID { get; set; } // int(10) + [Nullable ] public string QuantityPerUnit { get; set; } // nvarchar(20) + [Nullable ] public decimal? UnitPrice { get; set; } // money(19,4) + [Nullable ] public short? UnitsInStock { get; set; } // smallint(5) + [Nullable ] public short? UnitsOnOrder { get; set; } // smallint(5) + [Nullable ] public short? ReorderLevel { get; set; } // smallint(5) + public bool Discontinued { get; set; } // bit + + // FK_Products_Suppliers + [Association(ThisKey="SupplierID", OtherKey="SupplierID", CanBeNull=true)] + public Suppliers Suppliers { get; set; } + + // FK_Products_Categories + [Association(ThisKey="CategoryID", OtherKey="CategoryID", CanBeNull=true)] + public Categories Categories { get; set; } + + // FK_Order_Details_Products_BackReference + [Association(ThisKey="ProductID", OtherKey="ProductID", CanBeNull=true)] + public IEnumerable OrderDetailss { get; set; } + } + + // View + [TableName(Name="Products Above Average Price")] + public partial class ProductsAboveAveragePrice + { + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public decimal? UnitPrice { get; set; } // money(19,4) + } + + // View + [TableName(Name="Products by Category")] + public partial class ProductsByCategory + { + public string CategoryName { get; set; } // nvarchar(15) + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public string QuantityPerUnit { get; set; } // nvarchar(20) + [Nullable] public short? UnitsInStock { get; set; } // smallint(5) + public bool Discontinued { get; set; } // bit + } + + // View + [TableName(Name="Quarterly Orders")] + public partial class QuarterlyOrders + { + [Nullable] public string CustomerID { get; set; } // nchar(5) + [Nullable] public string CompanyName { get; set; } // nvarchar(40) + [Nullable] public string City { get; set; } // nvarchar(15) + [Nullable] public string Country { get; set; } // nvarchar(15) + } + + [TableName(Name="Region")] + public partial class Region + { + [PrimaryKey(1)] public int RegionID { get; set; } // int(10) + public string RegionDescription { get; set; } // nchar(50) + + // FK_Territories_Region_BackReference + [Association(ThisKey="RegionID", OtherKey="RegionID", CanBeNull=true)] + public IEnumerable Territoriess { get; set; } + } + + // View + [TableName(Name="Sales by Category")] + public partial class SalesByCategory + { + public int CategoryID { get; set; } // int(10) + public string CategoryName { get; set; } // nvarchar(15) + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public decimal? ProductSales { get; set; } // money(19,4) + } + + // View + [TableName(Name="Sales Totals by Amount")] + public partial class SalesTotalsByAmount + { + [Nullable] public decimal? SaleAmount { get; set; } // money(19,4) + public int OrderID { get; set; } // int(10) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + } + + [TableName(Name="Shippers")] + public partial class Shippers + { + [Identity, PrimaryKey(1)] public int ShipperID { get; set; } // int(10) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable ] public string Phone { get; set; } // nvarchar(24) + + // FK_Orders_Shippers_BackReference + [Association(ThisKey="ShipperID", OtherKey="ShipVia", CanBeNull=true)] + public IEnumerable Orderss { get; set; } + } + + // View + [TableName(Name="Summary of Sales by Quarter")] + public partial class SummaryOfSalesByQuarter + { + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + public int OrderID { get; set; } // int(10) + [Nullable] public decimal? Subtotal { get; set; } // money(19,4) + } + + // View + [TableName(Name="Summary of Sales by Year")] + public partial class SummaryOfSalesByYear + { + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + public int OrderID { get; set; } // int(10) + [Nullable] public decimal? Subtotal { get; set; } // money(19,4) + } + + [TableName(Name="Suppliers")] + public partial class Suppliers + { + [Identity, PrimaryKey(1)] public int SupplierID { get; set; } // int(10) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable ] public string ContactName { get; set; } // nvarchar(30) + [Nullable ] public string ContactTitle { get; set; } // nvarchar(30) + [Nullable ] public string Address { get; set; } // nvarchar(60) + [Nullable ] public string City { get; set; } // nvarchar(15) + [Nullable ] public string Region { get; set; } // nvarchar(15) + [Nullable ] public string PostalCode { get; set; } // nvarchar(10) + [Nullable ] public string Country { get; set; } // nvarchar(15) + [Nullable ] public string Phone { get; set; } // nvarchar(24) + [Nullable ] public string Fax { get; set; } // nvarchar(24) + [Nullable ] public string HomePage { get; set; } // ntext(1073741823) + + // FK_Products_Suppliers_BackReference + [Association(ThisKey="SupplierID", OtherKey="SupplierID", CanBeNull=true)] + public IEnumerable Productss { get; set; } + } + + [TableName(Name="Territories")] + public partial class Territories + { + [PrimaryKey(1)] public string TerritoryID { get; set; } // nvarchar(20) + public string TerritoryDescription { get; set; } // nchar(50) + public int RegionID { get; set; } // int(10) + + // FK_Territories_Region + [Association(ThisKey="RegionID", OtherKey="RegionID", CanBeNull=false)] + public Region Region { get; set; } + + // FK_EmployeeTerritories_Territories_BackReference + [Association(ThisKey="TerritoryID", OtherKey="TerritoryID", CanBeNull=true)] + public IEnumerable EmployeeTerritoriess { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client.Web/DataModel.tt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client.Web/DataModel.tt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +<#@ template debug="True" hostspecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(SolutionDir)\Source\Templates\BLToolkit.ttinclude" #> +<#@ include file="$(SolutionDir)\Source\Templates\MSSQL.ttinclude" #> +<# + ConnectionString = "Server=.;Database=Northwind;Integrated Security=SSPI"; + + Namespace = "Client"; + DataContextName = "DataModel"; + + Usings.Add("BLToolkit.ServiceModel"); + Usings.Add("System.ServiceModel"); + + GenerateModel(); +#> diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client.Web/LinqWebService.asmx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client.Web/LinqWebService.asmx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1 @@ +<%@ WebService Language="C#" CodeBehind="LinqWebService.asmx.cs" Class="Client.Web.LinqWebService" %> diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client.Web/LinqWebService.asmx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client.Web/LinqWebService.asmx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ +using System; +using System.Web.Services; + +using BLToolkit.ServiceModel; + +namespace Client.Web +{ + [WebService(Namespace = "http://tempuri.org/")] + [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] + public class LinqWebService : LinqService + { + public override BLToolkit.Data.Linq.IDataContext CreateDataContext() + { + return new DataModel(); + } + + protected override void ValidateQuery(LinqServiceQuery query) + { + //base.ValidateQuery(query); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client.Web/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client.Web/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Client.Web")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Client.Web")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1f6edd10-7848-4e12-94bf-15b1fd341928")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client.Web/Silverlight.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client.Web/Silverlight.js Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2 @@ +//v2.0.30511.0 +if(!window.Silverlight)window.Silverlight={};Silverlight._silverlightCount=0;Silverlight.__onSilverlightInstalledCalled=false;Silverlight.fwlinkRoot="http://go2.microsoft.com/fwlink/?LinkID=";Silverlight.__installationEventFired=false;Silverlight.onGetSilverlight=null;Silverlight.onSilverlightInstalled=function(){window.location.reload(false)};Silverlight.isInstalled=function(b){if(b==undefined)b=null;var a=false,m=null;try{var i=null,j=false;if(window.ActiveXObject)try{i=new ActiveXObject("AgControl.AgControl");if(b===null)a=true;else if(i.IsVersionSupported(b))a=true;i=null}catch(l){j=true}else j=true;if(j){var k=navigator.plugins["Silverlight Plug-In"];if(k)if(b===null)a=true;else{var h=k.description;if(h==="1.0.30226.2")h="2.0.30226.2";var c=h.split(".");while(c.length>3)c.pop();while(c.length<4)c.push(0);var e=b.split(".");while(e.length>4)e.pop();var d,g,f=0;do{d=parseInt(e[f]);g=parseInt(c[f]);f++}while(f");delete a.id;delete a.width;delete a.height;for(var c in a)if(a[c])b.push('');b.push("");return b.join("")};Silverlight.createObjectEx=function(b){var a=b,c=Silverlight.createObject(a.source,a.parentElement,a.id,a.properties,a.events,a.initParams,a.context);if(a.parentElement==null)return c};Silverlight.buildPromptHTML=function(b){var a="",d=Silverlight.fwlinkRoot,c=b.version;if(b.alt)a=b.alt;else{if(!c)c="";a="Get Microsoft Silverlight";a=a.replace("{1}",c);a=a.replace("{2}",d+"108181")}return a};Silverlight.getSilverlight=function(e){if(Silverlight.onGetSilverlight)Silverlight.onGetSilverlight();var b="",a=String(e).split(".");if(a.length>1){var c=parseInt(a[0]);if(isNaN(c)||c<2)b="1.0";else b=a[0]+"."+a[1]}var d="";if(b.match(/^\d+\056\d+$/))d="&v="+b;Silverlight.followFWLink("149156"+d)};Silverlight.followFWLink=function(a){top.location=Silverlight.fwlinkRoot+String(a)};Silverlight.HtmlAttributeEncode=function(c){var a,b="";if(c==null)return null;for(var d=0;d96&&a<123||a>64&&a<91||a>43&&a<58&&a!=47||a==95)b=b+String.fromCharCode(a);else b=b+"&#"+a+";"}return b};Silverlight.default_error_handler=function(e,b){var d,c=b.ErrorType;d=b.ErrorCode;var a="\nSilverlight error message \n";a+="ErrorCode: "+d+"\n";a+="ErrorType: "+c+" \n";a+="Message: "+b.ErrorMessage+" \n";if(c=="ParserError"){a+="XamlFile: "+b.xamlFile+" \n";a+="Line: "+b.lineNumber+" \n";a+="Position: "+b.charPosition+" \n"}else if(c=="RuntimeError"){if(b.lineNumber!=0){a+="Line: "+b.lineNumber+" \n";a+="Position: "+b.charPosition+" \n"}a+="MethodName: "+b.methodName+" \n"}alert(a)};Silverlight.__cleanup=function(){for(var a=Silverlight._silverlightCount-1;a>=0;a--)window["__slEvent"+a]=null;Silverlight._silverlightCount=0;if(window.removeEventListener)window.removeEventListener("unload",Silverlight.__cleanup,false);else window.detachEvent("onunload",Silverlight.__cleanup)};Silverlight.__getHandlerName=function(b){var a="";if(typeof b=="string")a=b;else if(typeof b=="function"){if(Silverlight._silverlightCount==0)if(window.addEventListener)window.addEventListener("onunload",Silverlight.__cleanup,false);else window.attachEvent("onunload",Silverlight.__cleanup);var c=Silverlight._silverlightCount++;a="__slEvent"+c;window[a]=b}else a=null;return a};Silverlight.onRequiredVersionAvailable=function(){};Silverlight.onRestartRequired=function(){};Silverlight.onUpgradeRequired=function(){};Silverlight.onInstallRequired=function(){};Silverlight.IsVersionAvailableOnError=function(d,a){var b=false;try{if(a.ErrorCode==8001&&!Silverlight.__installationEventFired){Silverlight.onUpgradeRequired();Silverlight.__installationEventFired=true}else if(a.ErrorCode==8002&&!Silverlight.__installationEventFired){Silverlight.onRestartRequired();Silverlight.__installationEventFired=true}else if(a.ErrorCode==5014||a.ErrorCode==2106){if(Silverlight.__verifySilverlight2UpgradeSuccess(a.getHost()))b=true}else b=true}catch(c){}return b};Silverlight.IsVersionAvailableOnLoad=function(b){var a=false;try{if(Silverlight.__verifySilverlight2UpgradeSuccess(b.getHost()))a=true}catch(c){}return a};Silverlight.__verifySilverlight2UpgradeSuccess=function(d){var c=false,b="2.0.31005",a=null;try{if(d.IsVersionSupported(b+".99")){a=Silverlight.onRequiredVersionAvailable;c=true}else if(d.IsVersionSupported(b+".0"))a=Silverlight.onRestartRequired;else a=Silverlight.onUpgradeRequired;if(a&&!Silverlight.__installationEventFired){a();Silverlight.__installationEventFired=true}}catch(e){}return c} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client.Web/Web.Debug.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client.Web/Web.Debug.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client.Web/Web.Release.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client.Web/Web.Release.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client.Web/Web.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client.Web/Web.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client/App.xaml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client/App.xaml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ + + + + + diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client/App.xaml.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client/App.xaml.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Animation; +using System.Windows.Shapes; + +namespace Client +{ + public partial class App : Application + { + + public App() + { + this.Startup += this.Application_Startup; + this.Exit += this.Application_Exit; + this.UnhandledException += this.Application_UnhandledException; + + InitializeComponent(); + } + + private void Application_Startup(object sender, StartupEventArgs e) + { + this.RootVisual = new MainPage(); + } + + private void Application_Exit(object sender, EventArgs e) + { + + } + + private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) + { + // If the app is running outside of the debugger then report the exception using + // the browser's exception mechanism. On IE this will display it a yellow alert + // icon in the status bar and Firefox will display a script error. + if (!System.Diagnostics.Debugger.IsAttached) + { + + // NOTE: This will allow the application to continue running after an exception has been thrown + // but not handled. + // For production applications this error handling should be replaced with something that will + // report the error to the website and stop the application. + e.Handled = true; + Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); }); + } + } + + private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e) + { + try + { + string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace; + errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n"); + + System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");"); + } + catch (Exception) + { + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client/Client.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client/Client.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,169 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {28693777-369C-4C0D-B076-38F7C0E5D06C} + {A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Client + Client + Silverlight + v4.0 + $(TargetFrameworkVersion) + true + + + true + true + Client.xap + Properties\AppManifest.xml + Client.App + ClientTestPage.html + true + true + false + Properties\OutOfBrowserSettings.xml + false + true + + + + + + v3.5 + + + true + full + false + Bin\Debug + DEBUG;TRACE;SILVERLIGHT + true + true + prompt + 4 + + + pdbonly + true + Bin\Release + TRACE;SILVERLIGHT + true + true + prompt + 4 + + + true + bin\DebugMono\ + DEBUG;TRACE;SILVERLIGHT + true + full + AnyCPU + Bin\Debug\Client.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + true + + + bin\ReleaseMono\ + TRACE;SILVERLIGHT + true + true + pdbonly + AnyCPU + Bin\Release\Client.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + true + + + + + + + + + + + + + + + + + + App.xaml + + + True + True + DataModel.tt + + + MainPage.xaml + + + + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + + + TextTemplatingFileGenerator + DataModel.generated.cs + + + + + + {663D4BFC-F565-41F7-9409-510B560CCEE8} + BLToolkit.SL.4 + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client/DataModel.generated.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client/DataModel.generated.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,640 @@ +//--------------------------------------------------------------------------------------------------- +// +// This code was generated by BLToolkit template for T4. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// +//--------------------------------------------------------------------------------------------------- +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.ServiceModel; +using System.Text; + +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; +using BLToolkit.Data.Linq; +using BLToolkit.Data.Sql; +using BLToolkit.Data.Sql.SqlProvider; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; +using BLToolkit.ServiceModel; + +namespace Client +{ + public partial class DataModel : SoapDataContext + { + public Table AlphabeticalListOfProducts { get { return this.GetTable(); } } + /// + /// Description for Categories table. + /// + public Table Categories { get { return this.GetTable(); } } + public Table CategorySalesFor1997 { get { return this.GetTable(); } } + public Table CurrentProductList { get { return this.GetTable(); } } + public Table CustomerAndSuppliersByCity { get { return this.GetTable(); } } + public Table CustomerCustomerDemo { get { return this.GetTable(); } } + public Table CustomerDemographics { get { return this.GetTable(); } } + /// + /// Description of Customers table. + /// + public Table Customers { get { return this.GetTable(); } } + public Table Employees { get { return this.GetTable(); } } + public Table EmployeeTerritories { get { return this.GetTable(); } } + public Table Invoices { get { return this.GetTable(); } } + public Table OrderDetails { get { return this.GetTable(); } } + public Table OrderDetailsExtended { get { return this.GetTable(); } } + public Table OrderSubtotals { get { return this.GetTable(); } } + public Table Orders { get { return this.GetTable(); } } + public Table OrdersQry { get { return this.GetTable(); } } + public Table ProductSalesFor1997 { get { return this.GetTable(); } } + public Table Products { get { return this.GetTable(); } } + public Table ProductsAboveAveragePrice { get { return this.GetTable(); } } + public Table ProductsByCategory { get { return this.GetTable(); } } + public Table QuarterlyOrders { get { return this.GetTable(); } } + public Table Region { get { return this.GetTable(); } } + public Table SalesByCategory { get { return this.GetTable(); } } + public Table SalesTotalsByAmount { get { return this.GetTable(); } } + public Table Shippers { get { return this.GetTable(); } } + public Table SummaryOfSalesByQuarter { get { return this.GetTable(); } } + public Table SummaryOfSalesByYear { get { return this.GetTable(); } } + public Table Suppliers { get { return this.GetTable(); } } + public Table Territories { get { return this.GetTable(); } } + + #region FreeTextTable + + public class FreeTextKey + { + public T Key; + public int Rank; + } + + class FreeTextTableExpressionAttribute : TableExpressionAttribute + { + public FreeTextTableExpressionAttribute() + : base("") + { + } + + public override void SetTable(SqlTable table, MemberInfo member, IEnumerable expArgs, IEnumerable sqlArgs) + { + var aargs = sqlArgs.ToArray(); + var arr = ConvertArgs(member, aargs).ToList(); + var method = (MethodInfo)member; + var sp = new MsSql2008SqlProvider(); + + { + var ttype = method.GetGenericArguments()[0]; + var tbl = new SqlTable(ttype); + + var database = tbl.Database == null ? null : sp.Convert(tbl.Database, ConvertType.NameToDatabase). ToString(); + var owner = tbl.Owner == null ? null : sp.Convert(tbl.Owner, ConvertType.NameToOwner). ToString(); + var physicalName = tbl.PhysicalName == null ? null : sp.Convert(tbl.PhysicalName, ConvertType.NameToQueryTable).ToString(); + + var name = sp.BuildTableName(new StringBuilder(), database, owner, physicalName); + + arr.Add(new SqlExpression(name.ToString(), Precedence.Primary)); + } + + { + var field = ((ConstantExpression)expArgs.First()).Value; + + if (field is string) + { + arr[0] = new SqlExpression(field.ToString(), Precedence.Primary); + } + else if (field is LambdaExpression) + { + var body = ((LambdaExpression)field).Body; + + if (body is MemberExpression) + { + var name = ((MemberExpression)body).Member.Name; + + name = sp.Convert(name, ConvertType.NameToQueryField).ToString(); + + arr[0] = new SqlExpression(name, Precedence.Primary); + } + } + } + + table.SqlTableType = SqlTableType.Expression; + table.Name = "FREETEXTTABLE({6}, {2}, {3}) {1}"; + table.TableArguments = arr.ToArray(); + } + } + + [FreeTextTableExpressionAttribute] + public Table> FreeTextTable(string field, string text) + { + return this.GetTable>( + this, + ((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)), + field, + text); + } + + [FreeTextTableExpressionAttribute] + public Table> FreeTextTable(Expression> fieldSelector, string text) + { + return this.GetTable>( + this, + ((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)), + fieldSelector, + text); + } + + #endregion + } + + // View + [TableName(Name="Alphabetical list of products")] + public partial class AlphabeticalListOfProducts + { + public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public int? SupplierID { get; set; } // int(10) + [Nullable] public int? CategoryID { get; set; } // int(10) + [Nullable] public string QuantityPerUnit { get; set; } // nvarchar(20) + [Nullable] public decimal? UnitPrice { get; set; } // money(19,4) + [Nullable] public short? UnitsInStock { get; set; } // smallint(5) + [Nullable] public short? UnitsOnOrder { get; set; } // smallint(5) + [Nullable] public short? ReorderLevel { get; set; } // smallint(5) + public bool Discontinued { get; set; } // bit + public string CategoryName { get; set; } // nvarchar(15) + } + + /// + /// Description for Categories table. + /// + [TableName(Name="Categories")] + public partial class Categories + { + /// + /// Description of Categories.CategoryID field. + /// + [Identity, PrimaryKey(1)] public int CategoryID { get; set; } // int(10) + public string CategoryName { get; set; } // nvarchar(15) + [Nullable ] public string Description { get; set; } // ntext(1073741823) + [Nullable ] public byte[] Picture { get; set; } // image(2147483647) + + // FK_Products_Categories_BackReference + [Association(ThisKey="CategoryID", OtherKey="CategoryID", CanBeNull=true)] + public IEnumerable Productss { get; set; } + } + + // View + [TableName(Name="Category Sales for 1997")] + public partial class CategorySalesFor1997 + { + public string CategoryName { get; set; } // nvarchar(15) + [Nullable] public decimal? CategorySales { get; set; } // money(19,4) + } + + // View + [TableName(Name="Current Product List")] + public partial class CurrentProductList + { + [Identity] public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + } + + // View + [TableName(Name="Customer and Suppliers by City")] + public partial class CustomerAndSuppliersByCity + { + [Nullable] public string City { get; set; } // nvarchar(15) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable] public string ContactName { get; set; } // nvarchar(30) + public string Relationship { get; set; } // varchar(9) + } + + [TableName(Name="CustomerCustomerDemo")] + public partial class CustomerCustomerDemo + { + [PrimaryKey(1)] public string CustomerID { get; set; } // nchar(5) + [PrimaryKey(2)] public string CustomerTypeID { get; set; } // nchar(10) + + // FK_CustomerCustomerDemo + [Association(ThisKey="CustomerTypeID", OtherKey="CustomerTypeID", CanBeNull=false)] + public CustomerDemographics FK_CustomerCustomerDemo { get; set; } + + // FK_CustomerCustomerDemo_Customers + [Association(ThisKey="CustomerID", OtherKey="CustomerID", CanBeNull=false)] + public Customers Customers { get; set; } + } + + [TableName(Name="CustomerDemographics")] + public partial class CustomerDemographics + { + [ PrimaryKey(1)] public string CustomerTypeID { get; set; } // nchar(10) + [Nullable ] public string CustomerDesc { get; set; } // ntext(1073741823) + + // FK_CustomerCustomerDemo_BackReference + [Association(ThisKey="CustomerTypeID", OtherKey="CustomerTypeID", CanBeNull=true)] + public IEnumerable CustomerCustomerDemos { get; set; } + } + + /// + /// Description of Customers table. + /// + [TableName(Name="Customers")] + public partial class Customers + { + /// + /// Just ID. + /// + [ PrimaryKey(1)] public string CustomerID { get; set; } // nchar(5) + /// + /// Name of the Company. + /// + public string CompanyName { get; set; } // nvarchar(40) + [Nullable ] public string ContactName { get; set; } // nvarchar(30) + [Nullable ] public string ContactTitle { get; set; } // nvarchar(30) + [Nullable ] public string Address { get; set; } // nvarchar(60) + [Nullable ] public string City { get; set; } // nvarchar(15) + [Nullable ] public string Region { get; set; } // nvarchar(15) + [Nullable ] public string PostalCode { get; set; } // nvarchar(10) + [Nullable ] public string Country { get; set; } // nvarchar(15) + [Nullable ] public string Phone { get; set; } // nvarchar(24) + [Nullable ] public string Fax { get; set; } // nvarchar(24) + + // FK_Orders_Customers_BackReference + [Association(ThisKey="CustomerID", OtherKey="CustomerID", CanBeNull=true)] + public IEnumerable Orderss { get; set; } + + // FK_CustomerCustomerDemo_Customers_BackReference + [Association(ThisKey="CustomerID", OtherKey="CustomerID", CanBeNull=true)] + public IEnumerable CustomerCustomerDemos { get; set; } + } + + [TableName(Name="Employees")] + public partial class Employees + { + [Identity, PrimaryKey(1)] public int EmployeeID { get; set; } // int(10) + public string LastName { get; set; } // nvarchar(20) + public string FirstName { get; set; } // nvarchar(10) + [Nullable ] public string Title { get; set; } // nvarchar(30) + [Nullable ] public string TitleOfCourtesy { get; set; } // nvarchar(25) + [Nullable ] public DateTime? BirthDate { get; set; } // datetime(3) + [Nullable ] public DateTime? HireDate { get; set; } // datetime(3) + [Nullable ] public string Address { get; set; } // nvarchar(60) + [Nullable ] public string City { get; set; } // nvarchar(15) + [Nullable ] public string Region { get; set; } // nvarchar(15) + [Nullable ] public string PostalCode { get; set; } // nvarchar(10) + [Nullable ] public string Country { get; set; } // nvarchar(15) + [Nullable ] public string HomePhone { get; set; } // nvarchar(24) + [Nullable ] public string Extension { get; set; } // nvarchar(4) + [Nullable ] public byte[] Photo { get; set; } // image(2147483647) + [Nullable ] public string Notes { get; set; } // ntext(1073741823) + [Nullable ] public int? ReportsTo { get; set; } // int(10) + [Nullable ] public string PhotoPath { get; set; } // nvarchar(255) + + // FK_Employees_Employees + [Association(ThisKey="ReportsTo", OtherKey="EmployeeID", CanBeNull=true)] + public Employees FK_Employees_Employees { get; set; } + + // FK_Orders_Employees_BackReference + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID", CanBeNull=true)] + public IEnumerable Orderss { get; set; } + + // FK_EmployeeTerritories_Employees_BackReference + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID", CanBeNull=true)] + public IEnumerable EmployeeTerritoriess { get; set; } + + // FK_Employees_Employees_BackReference + [Association(ThisKey="EmployeeID", OtherKey="ReportsTo", CanBeNull=true)] + public IEnumerable FK_Employees_Employees_BackReference { get; set; } + } + + [TableName(Name="EmployeeTerritories")] + public partial class EmployeeTerritories + { + [PrimaryKey(1)] public int EmployeeID { get; set; } // int(10) + [PrimaryKey(2)] public string TerritoryID { get; set; } // nvarchar(20) + + // FK_EmployeeTerritories_Employees + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID", CanBeNull=false)] + public Employees Employees { get; set; } + + // FK_EmployeeTerritories_Territories + [Association(ThisKey="TerritoryID", OtherKey="TerritoryID", CanBeNull=false)] + public Territories Territories { get; set; } + } + + // View + [TableName(Name="Invoices")] + public partial class Invoices + { + [Nullable] public string ShipName { get; set; } // nvarchar(40) + [Nullable] public string ShipAddress { get; set; } // nvarchar(60) + [Nullable] public string ShipCity { get; set; } // nvarchar(15) + [Nullable] public string ShipRegion { get; set; } // nvarchar(15) + [Nullable] public string ShipPostalCode { get; set; } // nvarchar(10) + [Nullable] public string ShipCountry { get; set; } // nvarchar(15) + [Nullable] public string CustomerID { get; set; } // nchar(5) + public string CustomerName { get; set; } // nvarchar(40) + [Nullable] public string Address { get; set; } // nvarchar(60) + [Nullable] public string City { get; set; } // nvarchar(15) + [Nullable] public string Region { get; set; } // nvarchar(15) + [Nullable] public string PostalCode { get; set; } // nvarchar(10) + [Nullable] public string Country { get; set; } // nvarchar(15) + public string Salesperson { get; set; } // nvarchar(31) + public int OrderID { get; set; } // int(10) + [Nullable] public DateTime? OrderDate { get; set; } // datetime(3) + [Nullable] public DateTime? RequiredDate { get; set; } // datetime(3) + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + public string ShipperName { get; set; } // nvarchar(40) + public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + public decimal UnitPrice { get; set; } // money(19,4) + public short Quantity { get; set; } // smallint(5) + public float Discount { get; set; } // real(24) + [Nullable] public decimal? ExtendedPrice { get; set; } // money(19,4) + [Nullable] public decimal? Freight { get; set; } // money(19,4) + } + + [TableName(Name="Order Details")] + public partial class OrderDetails + { + [PrimaryKey(1)] public int OrderID { get; set; } // int(10) + [PrimaryKey(2)] public int ProductID { get; set; } // int(10) + public decimal UnitPrice { get; set; } // money(19,4) + public short Quantity { get; set; } // smallint(5) + public float Discount { get; set; } // real(24) + + // FK_Order_Details_Orders + [Association(ThisKey="OrderID", OtherKey="OrderID", CanBeNull=false)] + public Orders OrderDetailsOrders { get; set; } + + // FK_Order_Details_Products + [Association(ThisKey="ProductID", OtherKey="ProductID", CanBeNull=false)] + public Products OrderDetailsProducts { get; set; } + } + + // View + [TableName(Name="Order Details Extended")] + public partial class OrderDetailsExtended + { + public int OrderID { get; set; } // int(10) + public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + public decimal UnitPrice { get; set; } // money(19,4) + public short Quantity { get; set; } // smallint(5) + public float Discount { get; set; } // real(24) + [Nullable] public decimal? ExtendedPrice { get; set; } // money(19,4) + } + + // View + [TableName(Name="Order Subtotals")] + public partial class OrderSubtotals + { + public int OrderID { get; set; } // int(10) + [Nullable] public decimal? Subtotal { get; set; } // money(19,4) + } + + [TableName(Name="Orders")] + public partial class Orders + { + [Identity, PrimaryKey(1)] public int OrderID { get; set; } // int(10) + [Nullable ] public string CustomerID { get; set; } // nchar(5) + [Nullable ] public int? EmployeeID { get; set; } // int(10) + [Nullable ] public DateTime? OrderDate { get; set; } // datetime(3) + [Nullable ] public DateTime? RequiredDate { get; set; } // datetime(3) + [Nullable ] public DateTime? ShippedDate { get; set; } // datetime(3) + [Nullable ] public int? ShipVia { get; set; } // int(10) + [Nullable ] public decimal? Freight { get; set; } // money(19,4) + [Nullable ] public string ShipName { get; set; } // nvarchar(40) + [Nullable ] public string ShipAddress { get; set; } // nvarchar(60) + [Nullable ] public string ShipCity { get; set; } // nvarchar(15) + [Nullable ] public string ShipRegion { get; set; } // nvarchar(15) + [Nullable ] public string ShipPostalCode { get; set; } // nvarchar(10) + [Nullable ] public string ShipCountry { get; set; } // nvarchar(15) + + // FK_Orders_Shippers + [Association(ThisKey="ShipVia", OtherKey="ShipperID", CanBeNull=true)] + public Shippers Shippers { get; set; } + + // FK_Orders_Employees + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID", CanBeNull=true)] + public Employees Employees { get; set; } + + // FK_Orders_Customers + [Association(ThisKey="CustomerID", OtherKey="CustomerID", CanBeNull=true)] + public Customers Customers { get; set; } + + // FK_Order_Details_Orders_BackReference + [Association(ThisKey="OrderID", OtherKey="OrderID", CanBeNull=true)] + public IEnumerable OrderDetailss { get; set; } + } + + // View + [TableName(Name="Orders Qry")] + public partial class OrdersQry + { + public int OrderID { get; set; } // int(10) + [Nullable] public string CustomerID { get; set; } // nchar(5) + [Nullable] public int? EmployeeID { get; set; } // int(10) + [Nullable] public DateTime? OrderDate { get; set; } // datetime(3) + [Nullable] public DateTime? RequiredDate { get; set; } // datetime(3) + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + [Nullable] public int? ShipVia { get; set; } // int(10) + [Nullable] public decimal? Freight { get; set; } // money(19,4) + [Nullable] public string ShipName { get; set; } // nvarchar(40) + [Nullable] public string ShipAddress { get; set; } // nvarchar(60) + [Nullable] public string ShipCity { get; set; } // nvarchar(15) + [Nullable] public string ShipRegion { get; set; } // nvarchar(15) + [Nullable] public string ShipPostalCode { get; set; } // nvarchar(10) + [Nullable] public string ShipCountry { get; set; } // nvarchar(15) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable] public string Address { get; set; } // nvarchar(60) + [Nullable] public string City { get; set; } // nvarchar(15) + [Nullable] public string Region { get; set; } // nvarchar(15) + [Nullable] public string PostalCode { get; set; } // nvarchar(10) + [Nullable] public string Country { get; set; } // nvarchar(15) + } + + // View + [TableName(Name="Product Sales for 1997")] + public partial class ProductSalesFor1997 + { + public string CategoryName { get; set; } // nvarchar(15) + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public decimal? ProductSales { get; set; } // money(19,4) + } + + [TableName(Name="Products")] + public partial class Products + { + [Identity, PrimaryKey(1)] public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + [Nullable ] public int? SupplierID { get; set; } // int(10) + [Nullable ] public int? CategoryID { get; set; } // int(10) + [Nullable ] public string QuantityPerUnit { get; set; } // nvarchar(20) + [Nullable ] public decimal? UnitPrice { get; set; } // money(19,4) + [Nullable ] public short? UnitsInStock { get; set; } // smallint(5) + [Nullable ] public short? UnitsOnOrder { get; set; } // smallint(5) + [Nullable ] public short? ReorderLevel { get; set; } // smallint(5) + public bool Discontinued { get; set; } // bit + + // FK_Products_Suppliers + [Association(ThisKey="SupplierID", OtherKey="SupplierID", CanBeNull=true)] + public Suppliers Suppliers { get; set; } + + // FK_Products_Categories + [Association(ThisKey="CategoryID", OtherKey="CategoryID", CanBeNull=true)] + public Categories Categories { get; set; } + + // FK_Order_Details_Products_BackReference + [Association(ThisKey="ProductID", OtherKey="ProductID", CanBeNull=true)] + public IEnumerable OrderDetailss { get; set; } + } + + // View + [TableName(Name="Products Above Average Price")] + public partial class ProductsAboveAveragePrice + { + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public decimal? UnitPrice { get; set; } // money(19,4) + } + + // View + [TableName(Name="Products by Category")] + public partial class ProductsByCategory + { + public string CategoryName { get; set; } // nvarchar(15) + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public string QuantityPerUnit { get; set; } // nvarchar(20) + [Nullable] public short? UnitsInStock { get; set; } // smallint(5) + public bool Discontinued { get; set; } // bit + } + + // View + [TableName(Name="Quarterly Orders")] + public partial class QuarterlyOrders + { + [Nullable] public string CustomerID { get; set; } // nchar(5) + [Nullable] public string CompanyName { get; set; } // nvarchar(40) + [Nullable] public string City { get; set; } // nvarchar(15) + [Nullable] public string Country { get; set; } // nvarchar(15) + } + + [TableName(Name="Region")] + public partial class Region + { + [PrimaryKey(1)] public int RegionID { get; set; } // int(10) + public string RegionDescription { get; set; } // nchar(50) + + // FK_Territories_Region_BackReference + [Association(ThisKey="RegionID", OtherKey="RegionID", CanBeNull=true)] + public IEnumerable Territoriess { get; set; } + } + + // View + [TableName(Name="Sales by Category")] + public partial class SalesByCategory + { + public int CategoryID { get; set; } // int(10) + public string CategoryName { get; set; } // nvarchar(15) + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public decimal? ProductSales { get; set; } // money(19,4) + } + + // View + [TableName(Name="Sales Totals by Amount")] + public partial class SalesTotalsByAmount + { + [Nullable] public decimal? SaleAmount { get; set; } // money(19,4) + public int OrderID { get; set; } // int(10) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + } + + [TableName(Name="Shippers")] + public partial class Shippers + { + [Identity, PrimaryKey(1)] public int ShipperID { get; set; } // int(10) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable ] public string Phone { get; set; } // nvarchar(24) + + // FK_Orders_Shippers_BackReference + [Association(ThisKey="ShipperID", OtherKey="ShipVia", CanBeNull=true)] + public IEnumerable Orderss { get; set; } + } + + // View + [TableName(Name="Summary of Sales by Quarter")] + public partial class SummaryOfSalesByQuarter + { + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + public int OrderID { get; set; } // int(10) + [Nullable] public decimal? Subtotal { get; set; } // money(19,4) + } + + // View + [TableName(Name="Summary of Sales by Year")] + public partial class SummaryOfSalesByYear + { + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + public int OrderID { get; set; } // int(10) + [Nullable] public decimal? Subtotal { get; set; } // money(19,4) + } + + [TableName(Name="Suppliers")] + public partial class Suppliers + { + [Identity, PrimaryKey(1)] public int SupplierID { get; set; } // int(10) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable ] public string ContactName { get; set; } // nvarchar(30) + [Nullable ] public string ContactTitle { get; set; } // nvarchar(30) + [Nullable ] public string Address { get; set; } // nvarchar(60) + [Nullable ] public string City { get; set; } // nvarchar(15) + [Nullable ] public string Region { get; set; } // nvarchar(15) + [Nullable ] public string PostalCode { get; set; } // nvarchar(10) + [Nullable ] public string Country { get; set; } // nvarchar(15) + [Nullable ] public string Phone { get; set; } // nvarchar(24) + [Nullable ] public string Fax { get; set; } // nvarchar(24) + [Nullable ] public string HomePage { get; set; } // ntext(1073741823) + + // FK_Products_Suppliers_BackReference + [Association(ThisKey="SupplierID", OtherKey="SupplierID", CanBeNull=true)] + public IEnumerable Productss { get; set; } + } + + [TableName(Name="Territories")] + public partial class Territories + { + [PrimaryKey(1)] public string TerritoryID { get; set; } // nvarchar(20) + public string TerritoryDescription { get; set; } // nchar(50) + public int RegionID { get; set; } // int(10) + + // FK_Territories_Region + [Association(ThisKey="RegionID", OtherKey="RegionID", CanBeNull=false)] + public Region Region { get; set; } + + // FK_EmployeeTerritories_Territories_BackReference + [Association(ThisKey="TerritoryID", OtherKey="TerritoryID", CanBeNull=true)] + public IEnumerable EmployeeTerritoriess { get; set; } + } +} + +namespace Client +{ + public partial class DataModel + { + public DataModel() : base( + new BasicHttpBinding(BasicHttpSecurityMode.None) + { + MaxReceivedMessageSize = 10000000, + MaxBufferSize = 10000000, + CloseTimeout = new TimeSpan(00, 01, 00), + OpenTimeout = new TimeSpan(00, 01, 00), + ReceiveTimeout = new TimeSpan(00, 10, 00), + SendTimeout = new TimeSpan(00, 10, 00), + }, + new EndpointAddress("http://localhost:31020/LinqWebService.asmx")) + // base("TestLinqWebServiceSoap") + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client/DataModel.tt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client/DataModel.tt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,37 @@ +<#@ template debug="True" hostspecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(SolutionDir)\Source\Templates\BLToolkit.ttinclude" #> +<#@ include file="$(SolutionDir)\Source\Templates\MSSQL.ttinclude" #> +<# + ConnectionString = "Server=.;Database=Northwind;Integrated Security=SSPI"; + + Namespace = "Client"; + DataContextName = "DataModel"; + BaseDataContextClass = "SoapDataContext"; + + Usings.Add("BLToolkit.ServiceModel"); + Usings.Add("System.ServiceModel"); + + GenerateModel(); +#> + +namespace Client +{ + public partial class DataModel + { + public DataModel() : base( + new BasicHttpBinding(BasicHttpSecurityMode.None) + { + MaxReceivedMessageSize = 10000000, + MaxBufferSize = 10000000, + CloseTimeout = new TimeSpan(00, 01, 00), + OpenTimeout = new TimeSpan(00, 01, 00), + ReceiveTimeout = new TimeSpan(00, 10, 00), + SendTimeout = new TimeSpan(00, 10, 00), + }, + new EndpointAddress("http://localhost:31020/LinqWebService.asmx")) + // base("TestLinqWebServiceSoap") + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client/MainPage.xaml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client/MainPage.xaml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,14 @@ + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client/MainPage.xaml.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client/MainPage.xaml.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,62 @@ +using System; +using System.Linq; +using System.Threading; +using System.Windows.Controls; +using BLToolkit.Data.Linq; + +namespace Client +{ + public partial class MainPage : UserControl + { + public class Data + { + public string Name; + public int Sum; + } + + public MainPage() + { + InitializeComponent(); + + ThreadPool.QueueUserWorkItem(_ => + { + try + { + using (var dm = new DataModel()) + { + var q = + from c in dm.Categories + where !c.CategoryName.StartsWith("Con") + orderby c.CategoryName + select c.CategoryName; + + (from t in dm.Categories + group t by t.CategoryName into g + select new Data + { + Name = g.Key, + Sum = g.Sum(a => a.CategoryID) + }).ToList(); + + var text = string.Join("\n", q.ToArray()); + + Dispatcher.BeginInvoke(() => OutputText.Text = text); + + dm.BeginBatch(); + + dm.Categories.Delete(c => c.CategoryID == -99999); + dm.Categories.Delete(c => c.CategoryID == -999999); + + dm.CommitBatch(); + } + } + catch (Exception ex) + { + Dispatcher.BeginInvoke(() => OutputText.Text = ex.Message); + } + + //new ServiceReference1.TestLinqWebServiceSoap(); + }); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client/Properties/AppManifest.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client/Properties/AppManifest.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ + + + + diff -r 000000000000 -r f990fcb411a9 Demo/Silverlight/Client/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/Silverlight/Client/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Client")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Client")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c99402c7-fdba-44e6-a0ff-7635164f374e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/Client.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/Client.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,151 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {4EBBF9E9-53B2-493C-ABAB-E915C187558F} + Exe + Properties + Demo.WebServices.Client + Demo.WebServices.Client + v4.0 + 512 + + + 3.5 + + + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + false + bin\Debug\ + TRACE;DEBUG;FW4 + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE;FW3 + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + TRACE;DEBUG;FW4 + full + AnyCPU + bin\Debug\Demo.WebServices.Client.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ReleaseMono\ + TRACE;FW3 + true + pdbonly + AnyCPU + bin\Release\Demo.WebServices.Client.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + + 3.5 + + + + + + + + + + + + + + + + + + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6} + ObjectModel + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/Client.csproj.DotSettings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/Client.csproj.DotSettings Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2 @@ + + No \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/Client.csproj.ReSharper --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/Client.csproj.ReSharper Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3 @@ + + No + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/PersonClient.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/PersonClient.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Web.Services; + +namespace Demo.WebServices.Client +{ + using WebClient; + using ObjectModel; + + [WebServiceBinding(Namespace = "http://tempuri.org/PersonService.asmx")] + [GenerateXmlInclude(typeof(Person))] + public abstract class PersonClient: WebClientBase, IDataAccessor + { + public abstract List SelectAll(); + public abstract XmlMap SelectMap(); + public abstract Person SelectByKey(int id); + public abstract void SelectByKey(int id, Action callback); + + public abstract int MethodWithOutParams(out string str, out Guid guid); + public abstract void MethodWithOutParams(Action callback); + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/Program.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/Program.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,63 @@ +using System; +using System.Threading; +using System.Windows.Forms; + +namespace Demo.WebServices.Client +{ + using ObjectModel; + using WebClient; + + class Program + { + static void Main(string[] args) + { + WebClientBase.BaseUrl = args.Length == 0? "localhost:59179": args[1]; + + foreach (var p in PersonClient.Instance.SelectAll()) + { + PrintPerson(p); + } + + var map = PersonClient.Instance.SelectMap(); + + foreach (var pair in map) + { + Console.WriteLine("{0}: {1} {2} ({3})", + pair.Key, + pair.Value.FirstName, + pair.Value.LastName, + pair.Value.Gender); + } + + // Async call to server + // + PersonClient.Instance.SelectByKey(1, PrintPerson); + + string strVal; + Guid guidVal; + var intVal = PersonClient.Instance.MethodWithOutParams(out strVal, out guidVal); + + Console.WriteLine("int: {0}, str: {1}, guid: {2}", intVal, strVal, guidVal); + + PersonClient.Instance.MethodWithOutParams( + (i,s,g) => Console.WriteLine("[Callback] int: {0}, str: {1}, guid: {2}", i, s, g)); + + Console.WriteLine(); + Console.WriteLine("Press [Enter] key to continue"); + Console.WriteLine(); + + while (!Console.KeyAvailable) + { + Application.DoEvents(); + Thread.Sleep(200); + } + + Console.ReadKey(true); + } + + private static void PrintPerson(Person p) + { + Console.WriteLine("{0} {1} ({2})", p.FirstName, p.LastName, p.Gender); + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BLToolkit.Demo.Client")] +[assembly: AssemblyProduct("BLToolkit.Demo")] +[assembly: AssemblyCopyright("\xA9 2002-2012 www.bltoolkit.net")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a30a5d13-4b1d-471b-af64-b354ffc91647")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/WebClient/AsyncCallState.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/WebClient/AsyncCallState.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +namespace Demo.WebServices.Client.WebClient +{ + /// + /// Async call handle holder class. + /// + public class AsyncCallState + { + /// + /// Async call handle if call is in progress, null otherwise. + /// + public object PendingCall; + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/WebClient/Compatibility.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/WebClient/Compatibility.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,80 @@ +namespace Demo.WebServices.Client.WebClient +{ +#if !FW3 + + /// + /// Encapsulates a method that takes no parameters and does not return a value. + /// + public delegate void Action(); + + /// + /// Encapsulates a method that has two parameters and does not return a value. + /// + /// + /// The first parameter of the method that this delegate encapsulates. + /// + /// + /// The second parameter of the method that this delegate encapsulates. + /// + /// + /// The type of the first parameter of the method that this delegate encapsulates. + /// + /// + /// The type of the second parameter of the method that this delegate encapsulates. + /// + public delegate void Action(T1 arg1, T2 arg2); + + /// + /// Encapsulates a method that has three parameters and does not return a value. + /// + /// + /// The first parameter of the method that this delegate encapsulates. + /// + /// + /// The second parameter of the method that this delegate encapsulates. + /// + /// + /// The third parameter of the method that this delegate encapsulates. + /// + /// + /// The type of the first parameter of the method that this delegate encapsulates. + /// + /// + /// The type of the second parameter of the method that this delegate encapsulates. + /// + /// + /// The type of the third parameter of the method that this delegate encapsulates. + /// + public delegate void Action(T1 arg1, T2 arg2, T3 arg3); + + /// + /// Encapsulates a method that has four parameters and does not return a value. + /// + /// + /// The first parameter of the method that this delegate encapsulates. + /// + /// + /// The second parameter of the method that this delegate encapsulates. + /// + /// + /// The third parameter of the method that this delegate encapsulates. + /// + /// + /// The fourth parameter of the method that this delegate encapsulates. + /// + /// + /// The type of the first parameter of the method that this delegate encapsulates. + /// + /// + /// The type of the second parameter of the method that this delegate encapsulates. + /// + /// + /// The type of the third parameter of the method that this delegate encapsulates. + /// + /// + /// The type of the fourth parameter of the method that this delegate encapsulates. + /// + public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4); + +#endif +} diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/WebClient/GenerateXmlIncludeAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/WebClient/GenerateXmlIncludeAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +using System; +using System.Xml.Serialization; +using BLToolkit.Reflection; +using BLToolkit.TypeBuilder; + +namespace Demo.WebServices.Client.WebClient +{ + /// + /// Allows the to recognize a type generated + /// by the BLToolkit when it serializes or deserializes an object. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] + public class GenerateXmlIncludeAttribute : GenerateAttributeAttribute + { + /// + /// Initializes a new instance of the class. + /// + /// The of an abstract class to + /// include its BLToolkit extensions. + public GenerateXmlIncludeAttribute(Type type) + : base(typeof(XmlIncludeAbstractAttribute), type) + { + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/WebClient/UpToDateAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/WebClient/UpToDateAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace Demo.WebServices.Client.WebClient +{ + [AttributeUsage(AttributeTargets.Method)] + public class UpToDateAttribute : Attribute + { + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/WebClient/WebClientAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/WebClient/WebClientAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,14 @@ +using System; +using BLToolkit.TypeBuilder.Builders; + +namespace Demo.WebServices.Client.WebClient +{ + [AttributeUsage(AttributeTargets.Class)] + public class WebClientAttribute : AbstractTypeBuilderAttribute + { + public override IAbstractTypeBuilder TypeBuilder + { + get { return new WebClientTypeBuilder(); } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/WebClient/WebClientBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/WebClient/WebClientBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,465 @@ +using System; +using System.Diagnostics; +using System.Net; +using System.Reflection; +using System.Web.Services; +using System.Web.Services.Protocols; + +using BLToolkit.Common; + +namespace Demo.WebServices.Client.WebClient +{ + [DebuggerStepThrough] + [System.ComponentModel.DesignerCategory("Code")] + [WebClient] + public abstract class WebClientBase: SoapHttpClientProtocol + { + /// + /// Initializes a new instance of the class. + /// + protected WebClientBase() + { + if (DefaultCredentials == null) + UseDefaultCredentials = true; + else + Credentials = DefaultCredentials; + + // Use custom redirection since we need to repost some data. + // + AllowAutoRedirect = false; + + EnableDecompression = true; + PreAuthenticate = true; + + // Setup appropriate user agent string. + // + var asm = Assembly.GetEntryAssembly(); + if (asm != null) + UserAgent = asm.FullName; + +#if DEBUG + // By default the timeout value is about 2 minutes, + // wich is quite enought in a normal run, + // but not for debugging. + // + Timeout = Int32.MaxValue; +#endif + + if (string.IsNullOrEmpty(BaseUrl)) + return; + + var attr = (WebServiceBindingAttribute)Attribute.GetCustomAttribute(GetType(), typeof(WebServiceBindingAttribute)); + + if (attr == null) + throw new InvalidOperationException("Please specify relative url or mark the avatar with WebServiceBindingAttribute"); + + var ns = attr.Namespace; + + if (string.IsNullOrEmpty(ns)) + throw new InvalidOperationException("Please specify namespace in WebServiceBindingAttribute"); + + if (ns.EndsWith("/")) + ns = ns.Substring(0, ns.Length - 1); + + var builder = new UriBuilder(BaseUrl) { Path = new UriBuilder(ns).Path }; + + Url = builder.Uri.AbsoluteUri; + } + + /// + /// Initializes a new instance of the class. + /// + /// Path to web service, relative to . + protected WebClientBase(string relativeUrl) : this() + { + Debug.Assert(Url == BaseUrl + relativeUrl, string.Format("Expected url '{0}' got '{1}'", Url, BaseUrl + relativeUrl) ); + Url = BaseUrl + relativeUrl; + } + + public static ICredentials DefaultCredentials { get; set; } + + /// + /// Customizable url path. + /// + public static string BaseUrl { get; set; } + + /// + /// Returns , program runs in offline mode. + /// + public static bool OffLine + { + get { return string.IsNullOrEmpty(BaseUrl); } + } + + #region Invoke + + private object[] InvokeInternal(string methodName, object[] parameters) + { + object[] ret = null; + + for (;;) + { + try + { +#if DEBUG + var sw = Stopwatch.StartNew(); +#endif + ret = base.Invoke(methodName, parameters); +#if DEBUG + Debug.WriteLineIf(TS.TraceVerbose, + string.Format("Sync call {0}/{1} = {2} msec.", + Url, methodName, sw.ElapsedMilliseconds), TS.DisplayName); +#endif + } + catch (Exception ex) + { + if (ex is WebException) + { + var webException = (WebException) ex; + + if (webException.Status == WebExceptionStatus.RequestCanceled) + { + OnWebOperationCancelled(methodName, parameters); + break; + } + + // Internal redirection + // + if (webException.Status == WebExceptionStatus.ReceiveFailure) + continue; + } + + if (OnWebOperationException(methodName, parameters, ex)) + continue; + } + + break; + } + + return AcceptChanges(ret); + } + + /// + /// Invokes a web method synchronously. + /// + /// Web method name. + /// Web method parameters. + /// Web method return value or values on success, + /// a null reference otherwise. + public new object[] Invoke(string methodName, params object[] parameters) + { + return InvokeInternal(methodName, parameters) ?? new object[]{ null }; + } + + /// + /// Invokes a web method synchronously. + /// + /// Web method name. + /// Web method parameters. + /// Web method return value or default(T) if the call fails. + public T Invoke(string methodName, params object[] parameters) + { + var ret = InvokeInternal(methodName, parameters); + + return ret != null && ret.Length != 0? (T)ret[0]: default(T); + } + + /// + /// Invokes a web method asynchronously. + /// + /// Web method name. + /// Call state handle. + /// Upon return, may be used to cancel the call + /// Web method parameters. + /// Callback method to process the result. + /// Fail handler. + /// + public void InvokeAsync( + string methodName, + AsyncCallState asyncCallState, + Action exceptionHandler, + Delegate callback, + params object[] parameters) + { +#if DEBUG + var sw = Stopwatch.StartNew(); +#endif + + if (asyncCallState != null) + { +#if DEBUG + Debug.WriteLineIf(TS.TraceVerbose && asyncCallState.PendingCall != null, + string.Format("Cancelling async call {0}/{1}", + Url, methodName), TS.DisplayName); +#endif + CancelAsync(asyncCallState); + } + + var exceptionCallback = exceptionHandler ?? delegate(Exception ex) + { + if (ex is WebException) + { + var webException = (WebException)ex; + + // Request cancelled. + // + if (webException.Status == WebExceptionStatus.RequestCanceled) + { + OnWebOperationCancelled(methodName, parameters); + return; + } + } + + // Check for retry. + // + if (OnWebOperationException(methodName, parameters, ex)) + { + InvokeAsync(methodName, asyncCallState, exceptionHandler, callback, parameters); + } + }; + + System.Threading.SendOrPostCallback sendCallback = delegate(object obj) + { +#if DEBUG + Debug.WriteLineIf(TS.TraceVerbose, + string.Format("Async call {0}/{1} = {2} msec.", + Url, methodName, sw.ElapsedMilliseconds), TS.DisplayName); +#endif + + var ea = (InvokeCompletedEventArgs)obj; + + if (ea.Error != null) + { + // Internal redirection + // + if (ea.Error is WebException && ((WebException)ea.Error).Status == WebExceptionStatus.ReceiveFailure) + { + InvokeAsync(methodName, asyncCallState, exceptionHandler, callback, parameters); + } + else + { + exceptionCallback(ea.Error); + } + } + else if (ea.Cancelled || (asyncCallState != null && ea.UserState != asyncCallState.PendingCall)) + { + exceptionCallback(new WebException(methodName, WebExceptionStatus.RequestCanceled)); + } + else + { + callback.DynamicInvoke(AcceptChanges(ea.Results)); + } + + if (asyncCallState != null && ea.UserState == asyncCallState.PendingCall) + asyncCallState.PendingCall = null; + }; + + object cookie = new CompoundValue(methodName, parameters); + + if (asyncCallState!= null) + asyncCallState.PendingCall = cookie; + + InvokeAsync(methodName, parameters, sendCallback, cookie); + } + + /// + /// Invokes a web method asynchronously. + /// + /// Web method name. + /// Call state handle. + /// Upon return, may be used to cancel the call + /// Web method parameters. + /// Callback method to process the result. + /// + public void InvokeAsync( + string methodName, + AsyncCallState asyncCallState, + Delegate callback, + params object[] parameters) + { + InvokeAsync(methodName, asyncCallState, null, callback, parameters); + } + + private static void AcceptChanges(object obj) + { + if (obj == null || obj is IConvertible) + { + // + // Do nothing on bool, int, string, etc. + // + } + else if (obj is BLToolkit.EditableObjects.IEditable) + ((BLToolkit.EditableObjects.IEditable)obj).AcceptChanges(); + else if (obj is System.Collections.IDictionary) + { + foreach (System.Collections.DictionaryEntry pair in (System.Collections.IDictionary)obj) + { + AcceptChanges(pair.Key); + AcceptChanges(pair.Value); + } + } + else if (obj is System.Collections.IEnumerable) + { + foreach (var elm in (System.Collections.IEnumerable)obj) + AcceptChanges(elm); + } + } + + private static object[] AcceptChanges(object[] array) + { + if (array != null) + Array.ForEach(array, AcceptChanges); + + return array; + } + + /// + ///.Cancel an asynchronous call if it is not completed already. + /// + /// Async call state. + public void CancelAsync(AsyncCallState asyncCallState) + { + if (asyncCallState.PendingCall == null) + return; + + CancelAsync(asyncCallState.PendingCall); + asyncCallState.PendingCall = null; + } + + #endregion + + #region Events + + private static readonly object EventWebOperationCancelled = new object(); + public event EventHandler WebOperationCancelled + { + add { Events.AddHandler (EventWebOperationCancelled, value); } + remove { Events.RemoveHandler(EventWebOperationCancelled, value); } + } + + public static event EventHandler WebOperationCancelledDefaultHandler; + + protected virtual void OnWebOperationCancelled(string methodName, params object[] parameters) + { + Debug.WriteLineIf(TS.TraceInfo, string.Format("OnWebOperationCancelled; op={0}/{1}", Url, methodName)); + var handler = (EventHandler)Events[EventWebOperationCancelled] ?? WebOperationCancelledDefaultHandler; + if (handler != null) + { + var ea = new WebOperationCancelledEventArgs(Url, methodName, parameters); + handler(this, ea); + } + } + + private static readonly object EventWebOperationException = new object(); + public event EventHandler WebOperationException + { + add { Events.AddHandler (EventWebOperationException, value); } + remove { Events.RemoveHandler(EventWebOperationException, value); } + } + public static event EventHandler WebOperationExceptionDefaultHandler; + + protected virtual bool OnWebOperationException(string methodName, object[] parameters, Exception ex) + { + Debug.WriteLineIf(TS.TraceError, string.Format("OnWebOperationException; op={0}/{1}; ex={2}", Url, methodName, ex)); + var handler = (EventHandler)Events[EventWebOperationException] ?? WebOperationExceptionDefaultHandler; + + if (handler != null) + { + var ea = new WebOperationExceptionEventArgs(Url, methodName, parameters, ex); + handler(this, ea); + return ea.Retry; + } + + throw new TargetInvocationException(methodName, ex); + } + + #endregion + + #region Cookies + + private string _cookie; + + /// + /// Creates a for the specified uri. + /// + /// The . + /// The to use when creating the . + /// The uri parameter is null. + protected override WebRequest GetWebRequest(Uri uri) + { + var webRequest = base.GetWebRequest(uri); + PrepareRequest(webRequest); + return webRequest; + } + + /// + /// Returns a response from a synchronous request to an XML Web service method. + /// + /// The . + /// The + /// from which to get the response. + protected override WebResponse GetWebResponse(WebRequest request) + { + var response = (HttpWebResponse)base.GetWebResponse(request); + ProcessResponse(response); + return response; + } + + /// + /// Returns a response from an asynchronous request to an XML Web service method. + /// + /// The . + /// The to pass to + /// when the response has completed. + /// The from which to get the response. + protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result) + { + var response = (HttpWebResponse)base.GetWebResponse(request, result); + ProcessResponse(response); + return response; + } + + private void ProcessResponse(HttpWebResponse response) + { + if (response.StatusCode == HttpStatusCode.MovedPermanently) + { + var redirectedLocation = response.Headers["Location"]; + Url = new Uri(new Uri(Url), redirectedLocation).AbsoluteUri; + throw new WebException(redirectedLocation, WebExceptionStatus.ReceiveFailure); + } + + var cookies = response.Headers.GetValues("Set-Cookie"); + + if (cookies == null) + return; + + foreach (var cookie in cookies) + { + if (cookie.StartsWith("ASP.NET_SessionId=", StringComparison.Ordinal)) + { + _cookie = cookie; + break; + } + } + } + + private void PrepareRequest(WebRequest request) + { + if (!string.IsNullOrEmpty(_cookie)) + request.Headers.Add("Cookie", _cookie); + } + + #endregion + + #region Debug + + private static TraceSwitch _ts; + internal static TraceSwitch TS + { + get { return _ts ?? (_ts = new TraceSwitch("WebServiceClient", "Web service client trace switch")); } + } + + #endregion + + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/WebClient/WebClientBaseT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/WebClient/WebClientBaseT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,39 @@ +using BLToolkit.TypeBuilder; + +namespace Demo.WebServices.Client.WebClient +{ + [System.Diagnostics.DebuggerStepThrough] + [System.ComponentModel.DesignerCategory("Code")] + public abstract class WebClientBase : WebClientBase where T : WebClientBase /* commented due to csc.exe bug */ + { + /// + /// Initializes a new instance of the class + /// using the namespace from WebServiceBinding attribute as url. + /// + protected WebClientBase() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Path to web service, relative to . + protected WebClientBase(string relativeUrl) : base(relativeUrl) + { + } + + /// + /// Cached client instance. + /// + private static T _instance; + public static T Instance + { + get { return _instance ?? (_instance = CreateInstance()); } + } + + protected static T CreateInstance() + { + return TypeFactory.CreateInstance(); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/WebClient/WebClientTypeBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/WebClient/WebClientTypeBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,261 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; +using System.Web.Services.Protocols; +using BLToolkit.DataAccess; +using BLToolkit.Reflection; +using BLToolkit.Reflection.Emit; +using BLToolkit.TypeBuilder.Builders; + +namespace Demo.WebServices.Client.WebClient +{ + public class WebClientTypeBuilder : AbstractTypeBuilderBase + { + private readonly CustomAttributeBuilder _soapDocumentAttributeBuilder + = new CustomAttributeBuilder(TypeHelper.GetDefaultConstructor(typeof(SoapDocumentMethodAttribute)), Type.EmptyTypes); + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + return context.IsBuildStep && context.IsAbstractMethod; + } + + protected override void BuildAbstractMethod() + { + EmitHelper emit = Context.MethodBuilder.Emitter; + List parameters = new List(); + ParameterInfo callback = null; + ParameterInfo exceptionHandler = null; + + foreach (ParameterInfo p in Context.CurrentMethod.GetParameters()) + { + Type parameterType = p.ParameterType; + string paramTypeName = parameterType.Name.Split('`')[0]; + + if (paramTypeName == "Action") + { + if (parameterType.IsGenericType && parameterType.GetGenericArguments()[0] == typeof(Exception)) + exceptionHandler = p; + else + callback = p; + } + else + parameters.Add(p); + } + + EmitMethodName(emit); + + if (callback == null) + { + EmitSyncCall(parameters, emit); + } + else + { + EmitAsyncCall(parameters, emit, callback, exceptionHandler); + } + } + + private void EmitSyncCall(List parameters, EmitHelper emit) + { + Context.MethodBuilder.MethodBuilder.SetCustomAttribute(_soapDocumentAttributeBuilder); + + bool withOutParameters = EmitParameters(emit, parameters); + bool callGeneric = !withOutParameters && Context.CurrentMethod.ReturnType != typeof(void); + + // Use Invoke() for methods with return value but + // Invoke() for methods with no return value or with out/ref parameters. + // + MethodInfo invoke = TypeHelper.GetMethod( + typeof(WebClientBase), + callGeneric, + "Invoke", + BindingFlags.Public | BindingFlags.Instance); + + if (callGeneric) + { + emit + .call (invoke.MakeGenericMethod(Context.CurrentMethod.ReturnType)) + .stloc (Context.ReturnValue) + ; + } + else + { + if (withOutParameters) + { + LocalBuilder ret = emit.DeclareLocal(typeof(object[])); + Label exit = emit.DefineLabel(); + + emit + .call (invoke) + .dup + .stloc (ret) + .brfalse_s (exit) + ; + + int idx = 0; + + if (Context.CurrentMethod.ReturnType != typeof(void)) + { + emit + .ldloc (ret) + .ldc_i4_0 + .ldelem_ref + .CastFromObject (Context.CurrentMethod.ReturnType) + .stloc (Context.ReturnValue) + ; + + ++idx; + } + + for (int i = 0; i < parameters.Count; ++i) + { + ParameterInfo pi = parameters[i]; + Type type = pi.ParameterType; + + if (!type.IsByRef) + continue; + + // Get ride of ref + // + type = type.GetElementType(); + + emit + .ldarg (pi) + .ldloc (ret) + .ldc_i4_ (idx) + .ldelem_ref + .CastFromObject (type) + .stind (type) + ; + + ++idx; + } + + emit.MarkLabel(exit); + } + else + { + emit + .call (invoke) + .pop + .end () + ; + } + } + } + + private void EmitAsyncCall(List parameters, EmitHelper emit, ParameterInfo callback, ParameterInfo exceptionCallback) + { + if (Context.CurrentMethod.IsDefined(typeof(UpToDateAttribute), true)) + { + EmitCookie(emit); + } + else + { + emit.ldnull.end(); + } + + if (exceptionCallback != null) + { + emit.ldarg(exceptionCallback); + } + else + { + emit.ldnull.end(); + } + + emit.ldarg(callback); + + EmitParameters(emit, parameters); + + emit + .call(typeof(WebClientBase), "InvokeAsync", typeof(string), typeof(AsyncCallState), typeof(Action), typeof(Delegate), typeof(object[])) + ; + } + + private void EmitMethodName(EmitHelper emit) + { + object[] attrs = Context.CurrentMethod.GetCustomAttributes(typeof(ActionNameAttribute), true); + + string methodName = attrs == null || attrs.Length == 0? + Context.CurrentMethod.Name: ((ActionNameAttribute)attrs[0]).Name; + + emit + .ldarg_0 + .ldstr (methodName) + ; + } + + private void EmitCookie(EmitHelper emit) + { + string fieldName = "_cookie$" + Context.CurrentMethod.Name; + + FieldBuilder field = Context.GetField(fieldName) ?? + Context.CreateField(fieldName, typeof(AsyncCallState), FieldAttributes.Private); + + Label checkCookie = emit.DefineLabel(); + + emit + .ldarg_0 + .ldfld (field) + .dup + .brtrue_s (checkCookie) + .pop + .ldarg_0 + .dup + .newobj (typeof(AsyncCallState)) + .stfld (field) + .ldfld (field) + .MarkLabel (checkCookie) + ; + } + + private bool EmitParameters(EmitHelper emit, List parameters) + { + bool hasOutRefParameters = false; + + int count = parameters.Count; + for (int i = 0; i < count; i++) + { + if (parameters[i].IsOut) + { + count--; + hasOutRefParameters = true; + } + } + + emit + .ldc_i4_(count) + .newarr(typeof(object)) + ; + + int idx = 0; + for (int i = 0; i < parameters.Count; i++) + { + ParameterInfo pi = parameters[i]; + + if (pi.IsOut) + { + // Output-only parameter + // + continue; + } + + if (pi.ParameterType.IsByRef) + hasOutRefParameters = true; + + emit + .dup + .ldc_i4_ (idx) + .ldargEx (pi, true) + .stelem_ref + .end() + ; + + ++idx; + } + + return hasOutRefParameters; + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/WebClient/WebOperationCancelledEventArgs.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/WebClient/WebOperationCancelledEventArgs.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,92 @@ +using System; +using System.Text; +using System.Collections; + +namespace Demo.WebServices.Client.WebClient +{ + public class WebOperationCancelledEventArgs : EventArgs + { + private readonly string _url; + public string Url + { + get { return _url; } + } + + private readonly string _methodName; + public string MethodName + { + get { return _methodName; } + } + + private readonly object[] _parameters; + public object[] Parameters + { + get { return _parameters; } + } + + public WebOperationCancelledEventArgs(string url, string methodName, object[] parameters) + { + _url = url; + _methodName = methodName; + _parameters = parameters; + } + + public string Format() + { + StringBuilder sb = new StringBuilder(); + sb + .Append(Url) + .Append('/') + .Append(MethodName) + .Append('(') + ; + + if (Parameters != null) + { + bool first = true; + + foreach (object parameter in Parameters) + { + if (first) + first = false; + else + sb.Append(", "); + + try + { + FormatParameter(parameter, sb); + } + catch (Exception ex) + { + sb.Append(ex.ToString()); + } + } + } + + return sb.Append(')').ToString(); + } + + private static void FormatParameter(object parameter, StringBuilder sb) + { + if (parameter == null) + sb.Append("null"); + else if (parameter is string) + sb.Append('"').Append((string)parameter).Append('"'); + else if (parameter is char) + sb.Append('\'').Append((char)parameter).Append('\''); + else if (parameter is IEnumerable) + { + sb.Append('['); + bool first = true; + foreach (object item in (IEnumerable)parameter) + { + FormatParameter(item, first? sb: sb.Append(',')); + first = false; + } + sb.Append(']'); + } + else + sb.Append(parameter.ToString()); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/WebClient/WebOperationExceptionEventArgs.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/WebClient/WebOperationExceptionEventArgs.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; + +namespace Demo.WebServices.Client.WebClient +{ + public class WebOperationExceptionEventArgs : WebOperationCancelledEventArgs + { + private readonly Exception _exception; + public Exception Exception + { + get { return _exception; } + } + + private bool _retry; + public bool Retry + { + get { return _retry; } + set { _retry = value; } + } + + public WebOperationExceptionEventArgs(string url, string methodName, object[] parameters, Exception exception) + : base(url, methodName, parameters) + { + _exception = exception; + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Client/app.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Client/app.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ + + + + + + diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/DataContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/DataContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,18 @@ +using System; +using BLToolkit.Mapping; + +namespace NorthwindDataService +{ + partial class DataContext + { + } + + [InheritanceMapping(Code=true, Type=typeof(DiscontinuedProduct))] + [InheritanceMapping(Code=false, Type=typeof(ActiveProduct))] + partial class Product + { + } + + public class ActiveProduct : Product {} + public class DiscontinuedProduct : Product {} +} diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/DataContext.generated.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/DataContext.generated.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,617 @@ +//--------------------------------------------------------------------------------------------------- +// +// This code was generated by BLToolkit template for T4. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// +//--------------------------------------------------------------------------------------------------- +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; +using BLToolkit.Data.Linq; +using BLToolkit.Data.Sql; +using BLToolkit.Data.Sql.SqlProvider; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace NorthwindDS +{ + public partial class DataContext : DbManager + { + public Table AlphabeticalListOfProducts { get { return this.GetTable(); } } + /// + /// Description for Categories table. + /// + public Table Categories { get { return this.GetTable(); } } + public Table CategorySalesFor1997 { get { return this.GetTable(); } } + public Table CurrentProductLists { get { return this.GetTable(); } } + public Table CustomerAndSuppliersByCities { get { return this.GetTable(); } } + public Table CustomerCustomerDemos { get { return this.GetTable(); } } + public Table CustomerDemographics { get { return this.GetTable(); } } + /// + /// Description of Customers table. + /// + public Table Customers { get { return this.GetTable(); } } + public Table Employees { get { return this.GetTable(); } } + public Table EmployeeTerritories { get { return this.GetTable(); } } + public Table Invoices { get { return this.GetTable(); } } + public Table OrderDetails { get { return this.GetTable(); } } + public Table OrderDetailsExtendeds { get { return this.GetTable(); } } + public Table OrderSubtotals { get { return this.GetTable(); } } + public Table Orders { get { return this.GetTable(); } } + public Table OrdersQries { get { return this.GetTable(); } } + public Table ProductSalesFor1997 { get { return this.GetTable(); } } + public Table Products { get { return this.GetTable(); } } + public Table ProductsAboveAveragePrices { get { return this.GetTable(); } } + public Table ProductsByCategories { get { return this.GetTable(); } } + public Table QuarterlyOrders { get { return this.GetTable(); } } + public Table Regions { get { return this.GetTable(); } } + public Table SalesByCategories { get { return this.GetTable(); } } + public Table SalesTotalsByAmounts { get { return this.GetTable(); } } + public Table Shippers { get { return this.GetTable(); } } + public Table SummaryOfSalesByQuarters { get { return this.GetTable(); } } + public Table SummaryOfSalesByYears { get { return this.GetTable(); } } + public Table Suppliers { get { return this.GetTable(); } } + public Table Territories { get { return this.GetTable(); } } + + #region FreeTextTable + + public class FreeTextKey + { + public T Key; + public int Rank; + } + + class FreeTextTableExpressionAttribute : TableExpressionAttribute + { + public FreeTextTableExpressionAttribute() + : base("") + { + } + + public override void SetTable(SqlTable table, MemberInfo member, IEnumerable expArgs, IEnumerable sqlArgs) + { + var aargs = sqlArgs.ToArray(); + var arr = ConvertArgs(member, aargs).ToList(); + var method = (MethodInfo)member; + var sp = new MsSql2008SqlProvider(); + + { + var ttype = method.GetGenericArguments()[0]; + var tbl = new SqlTable(ttype); + + var database = tbl.Database == null ? null : sp.Convert(tbl.Database, ConvertType.NameToDatabase). ToString(); + var owner = tbl.Owner == null ? null : sp.Convert(tbl.Owner, ConvertType.NameToOwner). ToString(); + var physicalName = tbl.PhysicalName == null ? null : sp.Convert(tbl.PhysicalName, ConvertType.NameToQueryTable).ToString(); + + var name = sp.BuildTableName(new StringBuilder(), database, owner, physicalName); + + arr.Add(new SqlExpression(name.ToString(), Precedence.Primary)); + } + + { + var field = ((ConstantExpression)expArgs.First()).Value; + + if (field is string) + { + arr[0] = new SqlExpression(field.ToString(), Precedence.Primary); + } + else if (field is LambdaExpression) + { + var body = ((LambdaExpression)field).Body; + + if (body is MemberExpression) + { + var name = ((MemberExpression)body).Member.Name; + + name = sp.Convert(name, ConvertType.NameToQueryField).ToString(); + + arr[0] = new SqlExpression(name, Precedence.Primary); + } + } + } + + table.SqlTableType = SqlTableType.Expression; + table.Name = "FREETEXTTABLE({6}, {2}, {3}) {1}"; + table.TableArguments = arr.ToArray(); + } + } + + [FreeTextTableExpressionAttribute] + public Table> FreeTextTable(string field, string text) + { + return this.GetTable>( + this, + ((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)), + field, + text); + } + + [FreeTextTableExpressionAttribute] + public Table> FreeTextTable(Expression> fieldSelector, string text) + { + return this.GetTable>( + this, + ((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)), + fieldSelector, + text); + } + + #endregion + } + + // View + [TableName(Name="Alphabetical list of products")] + public partial class AlphabeticalListOfProduct + { + public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public int? SupplierID { get; set; } // int(10) + [Nullable] public int? CategoryID { get; set; } // int(10) + [Nullable] public string QuantityPerUnit { get; set; } // nvarchar(20) + [Nullable] public decimal? UnitPrice { get; set; } // money(19,4) + [Nullable] public short? UnitsInStock { get; set; } // smallint(5) + [Nullable] public short? UnitsOnOrder { get; set; } // smallint(5) + [Nullable] public short? ReorderLevel { get; set; } // smallint(5) + public bool Discontinued { get; set; } // bit + public string CategoryName { get; set; } // nvarchar(15) + } + + /// + /// Description for Categories table. + /// + [TableName(Name="Categories")] + public partial class Category + { + /// + /// Description of Categories.CategoryID field. + /// + [Identity, PrimaryKey(1)] public int CategoryID { get; set; } // int(10) + public string CategoryName { get; set; } // nvarchar(15) + [Nullable ] public string Description { get; set; } // ntext(1073741823) + [Nullable ] public byte[] Picture { get; set; } // image(2147483647) + + // FK_Products_Categories_BackReference + [Association(ThisKey="CategoryID", OtherKey="CategoryID", CanBeNull=true)] + public IEnumerable Products { get; set; } + } + + // View + [TableName(Name="Category Sales for 1997")] + public partial class CategorySalesFor1997 + { + public string CategoryName { get; set; } // nvarchar(15) + [Nullable] public decimal? CategorySales { get; set; } // money(19,4) + } + + // View + [TableName(Name="Current Product List")] + public partial class CurrentProductList + { + [Identity] public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + } + + // View + [TableName(Name="Customer and Suppliers by City")] + public partial class CustomerAndSuppliersByCity + { + [Nullable] public string City { get; set; } // nvarchar(15) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable] public string ContactName { get; set; } // nvarchar(30) + public string Relationship { get; set; } // varchar(9) + } + + [TableName(Name="CustomerCustomerDemo")] + public partial class CustomerCustomerDemo + { + [PrimaryKey(1)] public string CustomerID { get; set; } // nchar(5) + [PrimaryKey(2)] public string CustomerTypeID { get; set; } // nchar(10) + + // FK_CustomerCustomerDemo + [Association(ThisKey="CustomerTypeID", OtherKey="CustomerTypeID", CanBeNull=false)] + public CustomerDemographic FK_CustomerCustomerDemo { get; set; } + + // FK_CustomerCustomerDemo_Customers + [Association(ThisKey="CustomerID", OtherKey="CustomerID", CanBeNull=false)] + public Customer Customer { get; set; } + } + + [TableName(Name="CustomerDemographics")] + public partial class CustomerDemographic + { + [ PrimaryKey(1)] public string CustomerTypeID { get; set; } // nchar(10) + [Nullable ] public string CustomerDesc { get; set; } // ntext(1073741823) + + // FK_CustomerCustomerDemo_BackReference + [Association(ThisKey="CustomerTypeID", OtherKey="CustomerTypeID", CanBeNull=true)] + public IEnumerable CustomerCustomerDemos { get; set; } + } + + /// + /// Description of Customers table. + /// + [TableName(Name="Customers")] + public partial class Customer + { + /// + /// Just ID. + /// + [ PrimaryKey(1)] public string CustomerID { get; set; } // nchar(5) + /// + /// Name of the Company. + /// + public string CompanyName { get; set; } // nvarchar(40) + [Nullable ] public string ContactName { get; set; } // nvarchar(30) + [Nullable ] public string ContactTitle { get; set; } // nvarchar(30) + [Nullable ] public string Address { get; set; } // nvarchar(60) + [Nullable ] public string City { get; set; } // nvarchar(15) + [Nullable ] public string Region { get; set; } // nvarchar(15) + [Nullable ] public string PostalCode { get; set; } // nvarchar(10) + [Nullable ] public string Country { get; set; } // nvarchar(15) + [Nullable ] public string Phone { get; set; } // nvarchar(24) + [Nullable ] public string Fax { get; set; } // nvarchar(24) + + // FK_Orders_Customers_BackReference + [Association(ThisKey="CustomerID", OtherKey="CustomerID", CanBeNull=true)] + public IEnumerable Orders { get; set; } + + // FK_CustomerCustomerDemo_Customers_BackReference + [Association(ThisKey="CustomerID", OtherKey="CustomerID", CanBeNull=true)] + public IEnumerable CustomerCustomerDemos { get; set; } + } + + [TableName(Name="Employees")] + public partial class Employee + { + [Identity, PrimaryKey(1)] public int EmployeeID { get; set; } // int(10) + public string LastName { get; set; } // nvarchar(20) + public string FirstName { get; set; } // nvarchar(10) + [Nullable ] public string Title { get; set; } // nvarchar(30) + [Nullable ] public string TitleOfCourtesy { get; set; } // nvarchar(25) + [Nullable ] public DateTime? BirthDate { get; set; } // datetime(3) + [Nullable ] public DateTime? HireDate { get; set; } // datetime(3) + [Nullable ] public string Address { get; set; } // nvarchar(60) + [Nullable ] public string City { get; set; } // nvarchar(15) + [Nullable ] public string Region { get; set; } // nvarchar(15) + [Nullable ] public string PostalCode { get; set; } // nvarchar(10) + [Nullable ] public string Country { get; set; } // nvarchar(15) + [Nullable ] public string HomePhone { get; set; } // nvarchar(24) + [Nullable ] public string Extension { get; set; } // nvarchar(4) + [Nullable ] public byte[] Photo { get; set; } // image(2147483647) + [Nullable ] public string Notes { get; set; } // ntext(1073741823) + [Nullable ] public int? ReportsTo { get; set; } // int(10) + [Nullable ] public string PhotoPath { get; set; } // nvarchar(255) + + // FK_Employees_Employees + [Association(ThisKey="ReportsTo", OtherKey="EmployeeID", CanBeNull=true)] + public Employee FK_Employees_Employees { get; set; } + + // FK_Orders_Employees_BackReference + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID", CanBeNull=true)] + public IEnumerable Orders { get; set; } + + // FK_EmployeeTerritories_Employees_BackReference + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID", CanBeNull=true)] + public IEnumerable EmployeeTerritories { get; set; } + + // FK_Employees_Employees_BackReference + [Association(ThisKey="EmployeeID", OtherKey="ReportsTo", CanBeNull=true)] + public IEnumerable FK_Employees_Employees_BackReference { get; set; } + } + + [TableName(Name="EmployeeTerritories")] + public partial class EmployeeTerritory + { + [PrimaryKey(1)] public int EmployeeID { get; set; } // int(10) + [PrimaryKey(2)] public string TerritoryID { get; set; } // nvarchar(20) + + // FK_EmployeeTerritories_Employees + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID", CanBeNull=false)] + public Employee Employee { get; set; } + + // FK_EmployeeTerritories_Territories + [Association(ThisKey="TerritoryID", OtherKey="TerritoryID", CanBeNull=false)] + public Territory Territory { get; set; } + } + + // View + [TableName(Name="Invoices")] + public partial class Invoice + { + [Nullable] public string ShipName { get; set; } // nvarchar(40) + [Nullable] public string ShipAddress { get; set; } // nvarchar(60) + [Nullable] public string ShipCity { get; set; } // nvarchar(15) + [Nullable] public string ShipRegion { get; set; } // nvarchar(15) + [Nullable] public string ShipPostalCode { get; set; } // nvarchar(10) + [Nullable] public string ShipCountry { get; set; } // nvarchar(15) + [Nullable] public string CustomerID { get; set; } // nchar(5) + public string CustomerName { get; set; } // nvarchar(40) + [Nullable] public string Address { get; set; } // nvarchar(60) + [Nullable] public string City { get; set; } // nvarchar(15) + [Nullable] public string Region { get; set; } // nvarchar(15) + [Nullable] public string PostalCode { get; set; } // nvarchar(10) + [Nullable] public string Country { get; set; } // nvarchar(15) + public string Salesperson { get; set; } // nvarchar(31) + public int OrderID { get; set; } // int(10) + [Nullable] public DateTime? OrderDate { get; set; } // datetime(3) + [Nullable] public DateTime? RequiredDate { get; set; } // datetime(3) + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + public string ShipperName { get; set; } // nvarchar(40) + public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + public decimal UnitPrice { get; set; } // money(19,4) + public short Quantity { get; set; } // smallint(5) + public float Discount { get; set; } // real(24) + [Nullable] public decimal? ExtendedPrice { get; set; } // money(19,4) + [Nullable] public decimal? Freight { get; set; } // money(19,4) + } + + [TableName(Name="Order Details")] + public partial class OrderDetail + { + [PrimaryKey(1)] public int OrderID { get; set; } // int(10) + [PrimaryKey(2)] public int ProductID { get; set; } // int(10) + public decimal UnitPrice { get; set; } // money(19,4) + public short Quantity { get; set; } // smallint(5) + public float Discount { get; set; } // real(24) + + // FK_Order_Details_Orders + [Association(ThisKey="OrderID", OtherKey="OrderID", CanBeNull=false)] + public Order OrderDetailsOrder { get; set; } + + // FK_Order_Details_Products + [Association(ThisKey="ProductID", OtherKey="ProductID", CanBeNull=false)] + public Product OrderDetailsProduct { get; set; } + } + + // View + [TableName(Name="Order Details Extended")] + public partial class OrderDetailsExtended + { + public int OrderID { get; set; } // int(10) + public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + public decimal UnitPrice { get; set; } // money(19,4) + public short Quantity { get; set; } // smallint(5) + public float Discount { get; set; } // real(24) + [Nullable] public decimal? ExtendedPrice { get; set; } // money(19,4) + } + + // View + [TableName(Name="Order Subtotals")] + public partial class OrderSubtotal + { + public int OrderID { get; set; } // int(10) + [Nullable] public decimal? Subtotal { get; set; } // money(19,4) + } + + [TableName(Name="Orders")] + public partial class Order + { + [Identity, PrimaryKey(1)] public int OrderID { get; set; } // int(10) + [Nullable ] public string CustomerID { get; set; } // nchar(5) + [Nullable ] public int? EmployeeID { get; set; } // int(10) + [Nullable ] public DateTime? OrderDate { get; set; } // datetime(3) + [Nullable ] public DateTime? RequiredDate { get; set; } // datetime(3) + [Nullable ] public DateTime? ShippedDate { get; set; } // datetime(3) + [Nullable ] public int? ShipVia { get; set; } // int(10) + [Nullable ] public decimal? Freight { get; set; } // money(19,4) + [Nullable ] public string ShipName { get; set; } // nvarchar(40) + [Nullable ] public string ShipAddress { get; set; } // nvarchar(60) + [Nullable ] public string ShipCity { get; set; } // nvarchar(15) + [Nullable ] public string ShipRegion { get; set; } // nvarchar(15) + [Nullable ] public string ShipPostalCode { get; set; } // nvarchar(10) + [Nullable ] public string ShipCountry { get; set; } // nvarchar(15) + + // FK_Orders_Shippers + [Association(ThisKey="ShipVia", OtherKey="ShipperID", CanBeNull=true)] + public Shipper Shipper { get; set; } + + // FK_Orders_Employees + [Association(ThisKey="EmployeeID", OtherKey="EmployeeID", CanBeNull=true)] + public Employee Employee { get; set; } + + // FK_Orders_Customers + [Association(ThisKey="CustomerID", OtherKey="CustomerID", CanBeNull=true)] + public Customer Customer { get; set; } + + // FK_Order_Details_Orders_BackReference + [Association(ThisKey="OrderID", OtherKey="OrderID", CanBeNull=true)] + public IEnumerable OrderDetails { get; set; } + } + + // View + [TableName(Name="Orders Qry")] + public partial class OrdersQry + { + public int OrderID { get; set; } // int(10) + [Nullable] public string CustomerID { get; set; } // nchar(5) + [Nullable] public int? EmployeeID { get; set; } // int(10) + [Nullable] public DateTime? OrderDate { get; set; } // datetime(3) + [Nullable] public DateTime? RequiredDate { get; set; } // datetime(3) + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + [Nullable] public int? ShipVia { get; set; } // int(10) + [Nullable] public decimal? Freight { get; set; } // money(19,4) + [Nullable] public string ShipName { get; set; } // nvarchar(40) + [Nullable] public string ShipAddress { get; set; } // nvarchar(60) + [Nullable] public string ShipCity { get; set; } // nvarchar(15) + [Nullable] public string ShipRegion { get; set; } // nvarchar(15) + [Nullable] public string ShipPostalCode { get; set; } // nvarchar(10) + [Nullable] public string ShipCountry { get; set; } // nvarchar(15) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable] public string Address { get; set; } // nvarchar(60) + [Nullable] public string City { get; set; } // nvarchar(15) + [Nullable] public string Region { get; set; } // nvarchar(15) + [Nullable] public string PostalCode { get; set; } // nvarchar(10) + [Nullable] public string Country { get; set; } // nvarchar(15) + } + + // View + [TableName(Name="Product Sales for 1997")] + public partial class ProductSalesFor1997 + { + public string CategoryName { get; set; } // nvarchar(15) + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public decimal? ProductSales { get; set; } // money(19,4) + } + + [TableName(Name="Products")] + public partial class Product + { + [Identity, PrimaryKey(1) ] public int ProductID { get; set; } // int(10) + public string ProductName { get; set; } // nvarchar(40) + [Nullable ] public int? SupplierID { get; set; } // int(10) + [Nullable ] public int? CategoryID { get; set; } // int(10) + [Nullable ] public string QuantityPerUnit { get; set; } // nvarchar(20) + [Nullable ] public decimal? UnitPrice { get; set; } // money(19,4) + [Nullable ] public short? UnitsInStock { get; set; } // smallint(5) + [Nullable ] public short? UnitsOnOrder { get; set; } // smallint(5) + [Nullable ] public short? ReorderLevel { get; set; } // smallint(5) + [ MapField(IsInheritanceDiscriminator=true)] public bool Discontinued { get; set; } // bit + + // FK_Products_Suppliers + [Association(ThisKey="SupplierID", OtherKey="SupplierID", CanBeNull=true)] + public Supplier Supplier { get; set; } + + // FK_Products_Categories + [Association(ThisKey="CategoryID", OtherKey="CategoryID", CanBeNull=true)] + public Category Category { get; set; } + + // FK_Order_Details_Products_BackReference + [Association(ThisKey="ProductID", OtherKey="ProductID", CanBeNull=true)] + public IEnumerable OrderDetails { get; set; } + } + + // View + [TableName(Name="Products Above Average Price")] + public partial class ProductsAboveAveragePrice + { + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public decimal? UnitPrice { get; set; } // money(19,4) + } + + // View + [TableName(Name="Products by Category")] + public partial class ProductsByCategory + { + public string CategoryName { get; set; } // nvarchar(15) + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public string QuantityPerUnit { get; set; } // nvarchar(20) + [Nullable] public short? UnitsInStock { get; set; } // smallint(5) + public bool Discontinued { get; set; } // bit + } + + // View + [TableName(Name="Quarterly Orders")] + public partial class QuarterlyOrder + { + [Nullable] public string CustomerID { get; set; } // nchar(5) + [Nullable] public string CompanyName { get; set; } // nvarchar(40) + [Nullable] public string City { get; set; } // nvarchar(15) + [Nullable] public string Country { get; set; } // nvarchar(15) + } + + [TableName(Name="Region")] + public partial class Region + { + [PrimaryKey(1)] public int RegionID { get; set; } // int(10) + public string RegionDescription { get; set; } // nchar(50) + + // FK_Territories_Region_BackReference + [Association(ThisKey="RegionID", OtherKey="RegionID", CanBeNull=true)] + public IEnumerable Territories { get; set; } + } + + // View + [TableName(Name="Sales by Category")] + public partial class SalesByCategory + { + public int CategoryID { get; set; } // int(10) + public string CategoryName { get; set; } // nvarchar(15) + public string ProductName { get; set; } // nvarchar(40) + [Nullable] public decimal? ProductSales { get; set; } // money(19,4) + } + + // View + [TableName(Name="Sales Totals by Amount")] + public partial class SalesTotalsByAmount + { + [Nullable] public decimal? SaleAmount { get; set; } // money(19,4) + public int OrderID { get; set; } // int(10) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + } + + [TableName(Name="Shippers")] + public partial class Shipper + { + [Identity, PrimaryKey(1)] public int ShipperID { get; set; } // int(10) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable ] public string Phone { get; set; } // nvarchar(24) + + // FK_Orders_Shippers_BackReference + [Association(ThisKey="ShipperID", OtherKey="ShipVia", CanBeNull=true)] + public IEnumerable Orders { get; set; } + } + + // View + [TableName(Name="Summary of Sales by Quarter")] + public partial class SummaryOfSalesByQuarter + { + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + public int OrderID { get; set; } // int(10) + [Nullable] public decimal? Subtotal { get; set; } // money(19,4) + } + + // View + [TableName(Name="Summary of Sales by Year")] + public partial class SummaryOfSalesByYear + { + [Nullable] public DateTime? ShippedDate { get; set; } // datetime(3) + public int OrderID { get; set; } // int(10) + [Nullable] public decimal? Subtotal { get; set; } // money(19,4) + } + + [TableName(Name="Suppliers")] + public partial class Supplier + { + [Identity, PrimaryKey(1)] public int SupplierID { get; set; } // int(10) + public string CompanyName { get; set; } // nvarchar(40) + [Nullable ] public string ContactName { get; set; } // nvarchar(30) + [Nullable ] public string ContactTitle { get; set; } // nvarchar(30) + [Nullable ] public string Address { get; set; } // nvarchar(60) + [Nullable ] public string City { get; set; } // nvarchar(15) + [Nullable ] public string Region { get; set; } // nvarchar(15) + [Nullable ] public string PostalCode { get; set; } // nvarchar(10) + [Nullable ] public string Country { get; set; } // nvarchar(15) + [Nullable ] public string Phone { get; set; } // nvarchar(24) + [Nullable ] public string Fax { get; set; } // nvarchar(24) + [Nullable ] public string HomePage { get; set; } // ntext(1073741823) + + // FK_Products_Suppliers_BackReference + [Association(ThisKey="SupplierID", OtherKey="SupplierID", CanBeNull=true)] + public IEnumerable Products { get; set; } + } + + [TableName(Name="Territories")] + public partial class Territory + { + [PrimaryKey(1)] public string TerritoryID { get; set; } // nvarchar(20) + public string TerritoryDescription { get; set; } // nchar(50) + public int RegionID { get; set; } // int(10) + + // FK_Territories_Region + [Association(ThisKey="RegionID", OtherKey="RegionID", CanBeNull=false)] + public Region Region { get; set; } + + // FK_EmployeeTerritories_Territories_BackReference + [Association(ThisKey="TerritoryID", OtherKey="TerritoryID", CanBeNull=true)] + public IEnumerable EmployeeTerritories { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/DataContext.tt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/DataContext.tt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +<#@ template language="C#" debug="True" hostspecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(SolutionDir)\Source\Templates\BLToolkit.ttinclude" #> +<#@ include file="$(SolutionDir)\Source\Templates\MSSql.ttinclude" #> +<#@ include file="$(SolutionDir)\Source\Templates\PluralSingular.ttinclude" #> +<# + ConnectionString = "Server=.;Database=Northwind;Integrated Security=SSPI"; + Namespace = "NorthwindDS"; + + LoadMetadata(); + + Tables["Products"].Columns["Discontinued"].Attributes.Add("MapField(IsInheritanceDiscriminator=true)"); + + GenerateModel(); +#> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/DataService.svc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/DataService.svc Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3 @@ + + +<%@ ServiceHost Language="C#" Factory="System.Data.Services.DataServiceHostFactory, System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Service="NorthwindDataService.DataService" %> diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/DataService.svc.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/DataService.svc.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; +using System.Data.Services; +using System.Data.Services.Common; + +namespace NorthwindDataService +{ + public class DataService : BLToolkit.ServiceModel.DataService + { + // This method is called only once to initialize service-wide policies. + public static void InitializeService(DataServiceConfiguration config) + { + // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc. + // Examples: + config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); + // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All); + config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/EFDataService.svc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/EFDataService.svc Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3 @@ + + +<%@ ServiceHost Language="C#" Factory="System.Data.Services.DataServiceHostFactory, System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Service="NorthwindDataService.EFDataService" %> diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/EFDataService.svc.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/EFDataService.svc.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ +using System; +using System.Data.Metadata.Edm; +using System.Data.Objects; +using System.Data.Services; +using System.Data.Services.Common; + +namespace NorthwindDataService +{ + public class EFDataService : DataService + { + // This method is called only once to initialize service-wide policies. + public static void InitializeService(DataServiceConfiguration config) + { + var w = new MetadataWorkspace(); + var m = new ObjectStateManager(w); + + // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc. + // Examples: + config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); + // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All); + config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/NorthwindDataService.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/NorthwindDataService.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,149 @@ + + + + + Debug + AnyCPU + + + 2.0 + {87FB4F28-5DCC-4F21-B83E-59C85E1A7423} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + NorthwindDataService + NorthwindDataService + v4.0 + false + + + 4.0 + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Web.config + + + Web.config + + + + + + DataService.svc + + + True + True + DataContext.tt + Component + + + EFDataService.svc + + + True + True + NorthwindModel.edmx + + + + + + TextTemplatingFileGenerator + DataContext.generated.cs + + + EntityModelCodeGenerator + NorthwindModel.Designer.cs + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + False + True + 58025 + / + + + False + False + + + False + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/NorthwindModel.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/NorthwindModel.Designer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6960 @@ +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +using System; +using System.ComponentModel; +using System.Data.EntityClient; +using System.Data.Objects; +using System.Data.Objects.DataClasses; +using System.Linq; +using System.Runtime.Serialization; +using System.Xml.Serialization; + +[assembly: EdmSchemaAttribute()] +#region EDM Relationship Metadata + +[assembly: EdmRelationshipAttribute("NorthwindModel", "FK_Products_Categories", "Categories", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(NorthwindDataService.Category), "Products", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.Product), true)] +[assembly: EdmRelationshipAttribute("NorthwindModel", "FK_Orders_Customers", "Customers", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(NorthwindDataService.Customer), "Orders", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.Order), true)] +[assembly: EdmRelationshipAttribute("NorthwindModel", "FK_Employees_Employees", "Employees", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(NorthwindDataService.Employee), "Employees1", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.Employee), true)] +[assembly: EdmRelationshipAttribute("NorthwindModel", "FK_Orders_Employees", "Employees", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(NorthwindDataService.Employee), "Orders", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.Order), true)] +[assembly: EdmRelationshipAttribute("NorthwindModel", "FK_Order_Details_Orders", "Orders", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(NorthwindDataService.Order), "Order_Details", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.Order_Detail), true)] +[assembly: EdmRelationshipAttribute("NorthwindModel", "FK_Order_Details_Products", "Products", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(NorthwindDataService.Product), "Order_Details", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.Order_Detail), true)] +[assembly: EdmRelationshipAttribute("NorthwindModel", "FK_Orders_Shippers", "Shippers", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(NorthwindDataService.Shipper), "Orders", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.Order), true)] +[assembly: EdmRelationshipAttribute("NorthwindModel", "FK_Products_Suppliers", "Suppliers", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(NorthwindDataService.Supplier), "Products", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.Product), true)] +[assembly: EdmRelationshipAttribute("NorthwindModel", "FK_Territories_Region", "Region", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(NorthwindDataService.Region), "Territories", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.Territory), true)] +[assembly: EdmRelationshipAttribute("NorthwindModel", "CustomerCustomerDemo", "CustomerDemographics", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.CustomerDemographic), "Customers", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.Customer))] +[assembly: EdmRelationshipAttribute("NorthwindModel", "EmployeeTerritories", "Employees", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.Employee), "Territories", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(NorthwindDataService.Territory))] + +#endregion + +namespace NorthwindDataService +{ + #region Contexts + + /// + /// No Metadata Documentation available. + /// + public partial class NorthwindEntities : ObjectContext + { + #region Constructors + + /// + /// Initializes a new NorthwindEntities object using the connection string found in the 'NorthwindEntities' section of the application configuration file. + /// + public NorthwindEntities() : base("name=NorthwindEntities", "NorthwindEntities") + { + this.ContextOptions.LazyLoadingEnabled = true; + OnContextCreated(); + } + + /// + /// Initialize a new NorthwindEntities object. + /// + public NorthwindEntities(string connectionString) : base(connectionString, "NorthwindEntities") + { + this.ContextOptions.LazyLoadingEnabled = true; + OnContextCreated(); + } + + /// + /// Initialize a new NorthwindEntities object. + /// + public NorthwindEntities(EntityConnection connection) : base(connection, "NorthwindEntities") + { + this.ContextOptions.LazyLoadingEnabled = true; + OnContextCreated(); + } + + #endregion + + #region Partial Methods + + partial void OnContextCreated(); + + #endregion + + #region ObjectSet Properties + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Categories + { + get + { + if ((_Categories == null)) + { + _Categories = base.CreateObjectSet("Categories"); + } + return _Categories; + } + } + private ObjectSet _Categories; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet CustomerDemographics + { + get + { + if ((_CustomerDemographics == null)) + { + _CustomerDemographics = base.CreateObjectSet("CustomerDemographics"); + } + return _CustomerDemographics; + } + } + private ObjectSet _CustomerDemographics; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Customers + { + get + { + if ((_Customers == null)) + { + _Customers = base.CreateObjectSet("Customers"); + } + return _Customers; + } + } + private ObjectSet _Customers; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Employees + { + get + { + if ((_Employees == null)) + { + _Employees = base.CreateObjectSet("Employees"); + } + return _Employees; + } + } + private ObjectSet _Employees; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Order_Details + { + get + { + if ((_Order_Details == null)) + { + _Order_Details = base.CreateObjectSet("Order_Details"); + } + return _Order_Details; + } + } + private ObjectSet _Order_Details; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Orders + { + get + { + if ((_Orders == null)) + { + _Orders = base.CreateObjectSet("Orders"); + } + return _Orders; + } + } + private ObjectSet _Orders; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Products + { + get + { + if ((_Products == null)) + { + _Products = base.CreateObjectSet("Products"); + } + return _Products; + } + } + private ObjectSet _Products; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Regions + { + get + { + if ((_Regions == null)) + { + _Regions = base.CreateObjectSet("Regions"); + } + return _Regions; + } + } + private ObjectSet _Regions; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Shippers + { + get + { + if ((_Shippers == null)) + { + _Shippers = base.CreateObjectSet("Shippers"); + } + return _Shippers; + } + } + private ObjectSet _Shippers; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Suppliers + { + get + { + if ((_Suppliers == null)) + { + _Suppliers = base.CreateObjectSet("Suppliers"); + } + return _Suppliers; + } + } + private ObjectSet _Suppliers; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet sysdiagrams + { + get + { + if ((_sysdiagrams == null)) + { + _sysdiagrams = base.CreateObjectSet("sysdiagrams"); + } + return _sysdiagrams; + } + } + private ObjectSet _sysdiagrams; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Territories + { + get + { + if ((_Territories == null)) + { + _Territories = base.CreateObjectSet("Territories"); + } + return _Territories; + } + } + private ObjectSet _Territories; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Alphabetical_list_of_products + { + get + { + if ((_Alphabetical_list_of_products == null)) + { + _Alphabetical_list_of_products = base.CreateObjectSet("Alphabetical_list_of_products"); + } + return _Alphabetical_list_of_products; + } + } + private ObjectSet _Alphabetical_list_of_products; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Category_Sales_for_1997 + { + get + { + if ((_Category_Sales_for_1997 == null)) + { + _Category_Sales_for_1997 = base.CreateObjectSet("Category_Sales_for_1997"); + } + return _Category_Sales_for_1997; + } + } + private ObjectSet _Category_Sales_for_1997; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Current_Product_Lists + { + get + { + if ((_Current_Product_Lists == null)) + { + _Current_Product_Lists = base.CreateObjectSet("Current_Product_Lists"); + } + return _Current_Product_Lists; + } + } + private ObjectSet _Current_Product_Lists; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Customer_and_Suppliers_by_Cities + { + get + { + if ((_Customer_and_Suppliers_by_Cities == null)) + { + _Customer_and_Suppliers_by_Cities = base.CreateObjectSet("Customer_and_Suppliers_by_Cities"); + } + return _Customer_and_Suppliers_by_Cities; + } + } + private ObjectSet _Customer_and_Suppliers_by_Cities; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Invoices + { + get + { + if ((_Invoices == null)) + { + _Invoices = base.CreateObjectSet("Invoices"); + } + return _Invoices; + } + } + private ObjectSet _Invoices; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Order_Details_Extendeds + { + get + { + if ((_Order_Details_Extendeds == null)) + { + _Order_Details_Extendeds = base.CreateObjectSet("Order_Details_Extendeds"); + } + return _Order_Details_Extendeds; + } + } + private ObjectSet _Order_Details_Extendeds; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Order_Subtotals + { + get + { + if ((_Order_Subtotals == null)) + { + _Order_Subtotals = base.CreateObjectSet("Order_Subtotals"); + } + return _Order_Subtotals; + } + } + private ObjectSet _Order_Subtotals; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Orders_Qries + { + get + { + if ((_Orders_Qries == null)) + { + _Orders_Qries = base.CreateObjectSet("Orders_Qries"); + } + return _Orders_Qries; + } + } + private ObjectSet _Orders_Qries; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Product_Sales_for_1997 + { + get + { + if ((_Product_Sales_for_1997 == null)) + { + _Product_Sales_for_1997 = base.CreateObjectSet("Product_Sales_for_1997"); + } + return _Product_Sales_for_1997; + } + } + private ObjectSet _Product_Sales_for_1997; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Products_Above_Average_Prices + { + get + { + if ((_Products_Above_Average_Prices == null)) + { + _Products_Above_Average_Prices = base.CreateObjectSet("Products_Above_Average_Prices"); + } + return _Products_Above_Average_Prices; + } + } + private ObjectSet _Products_Above_Average_Prices; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Products_by_Categories + { + get + { + if ((_Products_by_Categories == null)) + { + _Products_by_Categories = base.CreateObjectSet("Products_by_Categories"); + } + return _Products_by_Categories; + } + } + private ObjectSet _Products_by_Categories; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Sales_by_Categories + { + get + { + if ((_Sales_by_Categories == null)) + { + _Sales_by_Categories = base.CreateObjectSet("Sales_by_Categories"); + } + return _Sales_by_Categories; + } + } + private ObjectSet _Sales_by_Categories; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Sales_Totals_by_Amounts + { + get + { + if ((_Sales_Totals_by_Amounts == null)) + { + _Sales_Totals_by_Amounts = base.CreateObjectSet("Sales_Totals_by_Amounts"); + } + return _Sales_Totals_by_Amounts; + } + } + private ObjectSet _Sales_Totals_by_Amounts; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Summary_of_Sales_by_Quarters + { + get + { + if ((_Summary_of_Sales_by_Quarters == null)) + { + _Summary_of_Sales_by_Quarters = base.CreateObjectSet("Summary_of_Sales_by_Quarters"); + } + return _Summary_of_Sales_by_Quarters; + } + } + private ObjectSet _Summary_of_Sales_by_Quarters; + + /// + /// No Metadata Documentation available. + /// + public ObjectSet Summary_of_Sales_by_Years + { + get + { + if ((_Summary_of_Sales_by_Years == null)) + { + _Summary_of_Sales_by_Years = base.CreateObjectSet("Summary_of_Sales_by_Years"); + } + return _Summary_of_Sales_by_Years; + } + } + private ObjectSet _Summary_of_Sales_by_Years; + + #endregion + + #region AddTo Methods + + /// + /// Deprecated Method for adding a new object to the Categories EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToCategories(Category category) + { + base.AddObject("Categories", category); + } + + /// + /// Deprecated Method for adding a new object to the CustomerDemographics EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToCustomerDemographics(CustomerDemographic customerDemographic) + { + base.AddObject("CustomerDemographics", customerDemographic); + } + + /// + /// Deprecated Method for adding a new object to the Customers EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToCustomers(Customer customer) + { + base.AddObject("Customers", customer); + } + + /// + /// Deprecated Method for adding a new object to the Employees EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToEmployees(Employee employee) + { + base.AddObject("Employees", employee); + } + + /// + /// Deprecated Method for adding a new object to the Order_Details EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToOrder_Details(Order_Detail order_Detail) + { + base.AddObject("Order_Details", order_Detail); + } + + /// + /// Deprecated Method for adding a new object to the Orders EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToOrders(Order order) + { + base.AddObject("Orders", order); + } + + /// + /// Deprecated Method for adding a new object to the Products EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToProducts(Product product) + { + base.AddObject("Products", product); + } + + /// + /// Deprecated Method for adding a new object to the Regions EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToRegions(Region region) + { + base.AddObject("Regions", region); + } + + /// + /// Deprecated Method for adding a new object to the Shippers EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToShippers(Shipper shipper) + { + base.AddObject("Shippers", shipper); + } + + /// + /// Deprecated Method for adding a new object to the Suppliers EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToSuppliers(Supplier supplier) + { + base.AddObject("Suppliers", supplier); + } + + /// + /// Deprecated Method for adding a new object to the sysdiagrams EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddTosysdiagrams(sysdiagram sysdiagram) + { + base.AddObject("sysdiagrams", sysdiagram); + } + + /// + /// Deprecated Method for adding a new object to the Territories EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToTerritories(Territory territory) + { + base.AddObject("Territories", territory); + } + + /// + /// Deprecated Method for adding a new object to the Alphabetical_list_of_products EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToAlphabetical_list_of_products(Alphabetical_list_of_product alphabetical_list_of_product) + { + base.AddObject("Alphabetical_list_of_products", alphabetical_list_of_product); + } + + /// + /// Deprecated Method for adding a new object to the Category_Sales_for_1997 EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToCategory_Sales_for_1997(Category_Sales_for_1997 category_Sales_for_1997) + { + base.AddObject("Category_Sales_for_1997", category_Sales_for_1997); + } + + /// + /// Deprecated Method for adding a new object to the Current_Product_Lists EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToCurrent_Product_Lists(Current_Product_List current_Product_List) + { + base.AddObject("Current_Product_Lists", current_Product_List); + } + + /// + /// Deprecated Method for adding a new object to the Customer_and_Suppliers_by_Cities EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToCustomer_and_Suppliers_by_Cities(Customer_and_Suppliers_by_City customer_and_Suppliers_by_City) + { + base.AddObject("Customer_and_Suppliers_by_Cities", customer_and_Suppliers_by_City); + } + + /// + /// Deprecated Method for adding a new object to the Invoices EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToInvoices(Invoice invoice) + { + base.AddObject("Invoices", invoice); + } + + /// + /// Deprecated Method for adding a new object to the Order_Details_Extendeds EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToOrder_Details_Extendeds(Order_Details_Extended order_Details_Extended) + { + base.AddObject("Order_Details_Extendeds", order_Details_Extended); + } + + /// + /// Deprecated Method for adding a new object to the Order_Subtotals EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToOrder_Subtotals(Order_Subtotal order_Subtotal) + { + base.AddObject("Order_Subtotals", order_Subtotal); + } + + /// + /// Deprecated Method for adding a new object to the Orders_Qries EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToOrders_Qries(Orders_Qry orders_Qry) + { + base.AddObject("Orders_Qries", orders_Qry); + } + + /// + /// Deprecated Method for adding a new object to the Product_Sales_for_1997 EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToProduct_Sales_for_1997(Product_Sales_for_1997 product_Sales_for_1997) + { + base.AddObject("Product_Sales_for_1997", product_Sales_for_1997); + } + + /// + /// Deprecated Method for adding a new object to the Products_Above_Average_Prices EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToProducts_Above_Average_Prices(Products_Above_Average_Price products_Above_Average_Price) + { + base.AddObject("Products_Above_Average_Prices", products_Above_Average_Price); + } + + /// + /// Deprecated Method for adding a new object to the Products_by_Categories EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToProducts_by_Categories(Products_by_Category products_by_Category) + { + base.AddObject("Products_by_Categories", products_by_Category); + } + + /// + /// Deprecated Method for adding a new object to the Sales_by_Categories EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToSales_by_Categories(Sales_by_Category sales_by_Category) + { + base.AddObject("Sales_by_Categories", sales_by_Category); + } + + /// + /// Deprecated Method for adding a new object to the Sales_Totals_by_Amounts EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToSales_Totals_by_Amounts(Sales_Totals_by_Amount sales_Totals_by_Amount) + { + base.AddObject("Sales_Totals_by_Amounts", sales_Totals_by_Amount); + } + + /// + /// Deprecated Method for adding a new object to the Summary_of_Sales_by_Quarters EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToSummary_of_Sales_by_Quarters(Summary_of_Sales_by_Quarter summary_of_Sales_by_Quarter) + { + base.AddObject("Summary_of_Sales_by_Quarters", summary_of_Sales_by_Quarter); + } + + /// + /// Deprecated Method for adding a new object to the Summary_of_Sales_by_Years EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. + /// + public void AddToSummary_of_Sales_by_Years(Summary_of_Sales_by_Year summary_of_Sales_by_Year) + { + base.AddObject("Summary_of_Sales_by_Years", summary_of_Sales_by_Year); + } + + #endregion + + } + + #endregion + + #region Entities + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Alphabetical_list_of_product")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Alphabetical_list_of_product : EntityObject + { + #region Factory Method + + /// + /// Create a new Alphabetical_list_of_product object. + /// + /// Initial value of the ProductID property. + /// Initial value of the ProductName property. + /// Initial value of the Discontinued property. + /// Initial value of the CategoryName property. + public static Alphabetical_list_of_product CreateAlphabetical_list_of_product(global::System.Int32 productID, global::System.String productName, global::System.Boolean discontinued, global::System.String categoryName) + { + Alphabetical_list_of_product alphabetical_list_of_product = new Alphabetical_list_of_product(); + alphabetical_list_of_product.ProductID = productID; + alphabetical_list_of_product.ProductName = productName; + alphabetical_list_of_product.Discontinued = discontinued; + alphabetical_list_of_product.CategoryName = categoryName; + return alphabetical_list_of_product; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 ProductID + { + get + { + return _ProductID; + } + set + { + if (_ProductID != value) + { + OnProductIDChanging(value); + ReportPropertyChanging("ProductID"); + _ProductID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ProductID"); + OnProductIDChanged(); + } + } + } + private global::System.Int32 _ProductID; + partial void OnProductIDChanging(global::System.Int32 value); + partial void OnProductIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String ProductName + { + get + { + return _ProductName; + } + set + { + if (_ProductName != value) + { + OnProductNameChanging(value); + ReportPropertyChanging("ProductName"); + _ProductName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("ProductName"); + OnProductNameChanged(); + } + } + } + private global::System.String _ProductName; + partial void OnProductNameChanging(global::System.String value); + partial void OnProductNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable SupplierID + { + get + { + return _SupplierID; + } + set + { + OnSupplierIDChanging(value); + ReportPropertyChanging("SupplierID"); + _SupplierID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("SupplierID"); + OnSupplierIDChanged(); + } + } + private Nullable _SupplierID; + partial void OnSupplierIDChanging(Nullable value); + partial void OnSupplierIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable CategoryID + { + get + { + return _CategoryID; + } + set + { + OnCategoryIDChanging(value); + ReportPropertyChanging("CategoryID"); + _CategoryID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("CategoryID"); + OnCategoryIDChanged(); + } + } + private Nullable _CategoryID; + partial void OnCategoryIDChanging(Nullable value); + partial void OnCategoryIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String QuantityPerUnit + { + get + { + return _QuantityPerUnit; + } + set + { + OnQuantityPerUnitChanging(value); + ReportPropertyChanging("QuantityPerUnit"); + _QuantityPerUnit = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("QuantityPerUnit"); + OnQuantityPerUnitChanged(); + } + } + private global::System.String _QuantityPerUnit; + partial void OnQuantityPerUnitChanging(global::System.String value); + partial void OnQuantityPerUnitChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable UnitPrice + { + get + { + return _UnitPrice; + } + set + { + OnUnitPriceChanging(value); + ReportPropertyChanging("UnitPrice"); + _UnitPrice = StructuralObject.SetValidValue(value); + ReportPropertyChanged("UnitPrice"); + OnUnitPriceChanged(); + } + } + private Nullable _UnitPrice; + partial void OnUnitPriceChanging(Nullable value); + partial void OnUnitPriceChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable UnitsInStock + { + get + { + return _UnitsInStock; + } + set + { + OnUnitsInStockChanging(value); + ReportPropertyChanging("UnitsInStock"); + _UnitsInStock = StructuralObject.SetValidValue(value); + ReportPropertyChanged("UnitsInStock"); + OnUnitsInStockChanged(); + } + } + private Nullable _UnitsInStock; + partial void OnUnitsInStockChanging(Nullable value); + partial void OnUnitsInStockChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable UnitsOnOrder + { + get + { + return _UnitsOnOrder; + } + set + { + OnUnitsOnOrderChanging(value); + ReportPropertyChanging("UnitsOnOrder"); + _UnitsOnOrder = StructuralObject.SetValidValue(value); + ReportPropertyChanged("UnitsOnOrder"); + OnUnitsOnOrderChanged(); + } + } + private Nullable _UnitsOnOrder; + partial void OnUnitsOnOrderChanging(Nullable value); + partial void OnUnitsOnOrderChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ReorderLevel + { + get + { + return _ReorderLevel; + } + set + { + OnReorderLevelChanging(value); + ReportPropertyChanging("ReorderLevel"); + _ReorderLevel = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ReorderLevel"); + OnReorderLevelChanged(); + } + } + private Nullable _ReorderLevel; + partial void OnReorderLevelChanging(Nullable value); + partial void OnReorderLevelChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Boolean Discontinued + { + get + { + return _Discontinued; + } + set + { + if (_Discontinued != value) + { + OnDiscontinuedChanging(value); + ReportPropertyChanging("Discontinued"); + _Discontinued = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Discontinued"); + OnDiscontinuedChanged(); + } + } + } + private global::System.Boolean _Discontinued; + partial void OnDiscontinuedChanging(global::System.Boolean value); + partial void OnDiscontinuedChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CategoryName + { + get + { + return _CategoryName; + } + set + { + if (_CategoryName != value) + { + OnCategoryNameChanging(value); + ReportPropertyChanging("CategoryName"); + _CategoryName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CategoryName"); + OnCategoryNameChanged(); + } + } + } + private global::System.String _CategoryName; + partial void OnCategoryNameChanging(global::System.String value); + partial void OnCategoryNameChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Category")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Category : EntityObject + { + #region Factory Method + + /// + /// Create a new Category object. + /// + /// Initial value of the CategoryID property. + /// Initial value of the CategoryName property. + public static Category CreateCategory(global::System.Int32 categoryID, global::System.String categoryName) + { + Category category = new Category(); + category.CategoryID = categoryID; + category.CategoryName = categoryName; + return category; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 CategoryID + { + get + { + return _CategoryID; + } + set + { + if (_CategoryID != value) + { + OnCategoryIDChanging(value); + ReportPropertyChanging("CategoryID"); + _CategoryID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("CategoryID"); + OnCategoryIDChanged(); + } + } + } + private global::System.Int32 _CategoryID; + partial void OnCategoryIDChanging(global::System.Int32 value); + partial void OnCategoryIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CategoryName + { + get + { + return _CategoryName; + } + set + { + OnCategoryNameChanging(value); + ReportPropertyChanging("CategoryName"); + _CategoryName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CategoryName"); + OnCategoryNameChanged(); + } + } + private global::System.String _CategoryName; + partial void OnCategoryNameChanging(global::System.String value); + partial void OnCategoryNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Description + { + get + { + return _Description; + } + set + { + OnDescriptionChanging(value); + ReportPropertyChanging("Description"); + _Description = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Description"); + OnDescriptionChanged(); + } + } + private global::System.String _Description; + partial void OnDescriptionChanging(global::System.String value); + partial void OnDescriptionChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.Byte[] Picture + { + get + { + return StructuralObject.GetValidValue(_Picture); + } + set + { + OnPictureChanging(value); + ReportPropertyChanging("Picture"); + _Picture = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Picture"); + OnPictureChanged(); + } + } + private global::System.Byte[] _Picture; + partial void OnPictureChanging(global::System.Byte[] value); + partial void OnPictureChanged(); + + #endregion + + + #region Navigation Properties + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Products_Categories", "Products")] + public EntityCollection Products + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.FK_Products_Categories", "Products"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.FK_Products_Categories", "Products", value); + } + } + } + + #endregion + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Category_Sales_for_1997")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Category_Sales_for_1997 : EntityObject + { + #region Factory Method + + /// + /// Create a new Category_Sales_for_1997 object. + /// + /// Initial value of the CategoryName property. + public static Category_Sales_for_1997 CreateCategory_Sales_for_1997(global::System.String categoryName) + { + Category_Sales_for_1997 category_Sales_for_1997 = new Category_Sales_for_1997(); + category_Sales_for_1997.CategoryName = categoryName; + return category_Sales_for_1997; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CategoryName + { + get + { + return _CategoryName; + } + set + { + if (_CategoryName != value) + { + OnCategoryNameChanging(value); + ReportPropertyChanging("CategoryName"); + _CategoryName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CategoryName"); + OnCategoryNameChanged(); + } + } + } + private global::System.String _CategoryName; + partial void OnCategoryNameChanging(global::System.String value); + partial void OnCategoryNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable CategorySales + { + get + { + return _CategorySales; + } + set + { + OnCategorySalesChanging(value); + ReportPropertyChanging("CategorySales"); + _CategorySales = StructuralObject.SetValidValue(value); + ReportPropertyChanged("CategorySales"); + OnCategorySalesChanged(); + } + } + private Nullable _CategorySales; + partial void OnCategorySalesChanging(Nullable value); + partial void OnCategorySalesChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Current_Product_List")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Current_Product_List : EntityObject + { + #region Factory Method + + /// + /// Create a new Current_Product_List object. + /// + /// Initial value of the ProductID property. + /// Initial value of the ProductName property. + public static Current_Product_List CreateCurrent_Product_List(global::System.Int32 productID, global::System.String productName) + { + Current_Product_List current_Product_List = new Current_Product_List(); + current_Product_List.ProductID = productID; + current_Product_List.ProductName = productName; + return current_Product_List; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 ProductID + { + get + { + return _ProductID; + } + set + { + if (_ProductID != value) + { + OnProductIDChanging(value); + ReportPropertyChanging("ProductID"); + _ProductID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ProductID"); + OnProductIDChanged(); + } + } + } + private global::System.Int32 _ProductID; + partial void OnProductIDChanging(global::System.Int32 value); + partial void OnProductIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String ProductName + { + get + { + return _ProductName; + } + set + { + if (_ProductName != value) + { + OnProductNameChanging(value); + ReportPropertyChanging("ProductName"); + _ProductName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("ProductName"); + OnProductNameChanged(); + } + } + } + private global::System.String _ProductName; + partial void OnProductNameChanging(global::System.String value); + partial void OnProductNameChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Customer")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Customer : EntityObject + { + #region Factory Method + + /// + /// Create a new Customer object. + /// + /// Initial value of the CustomerID property. + /// Initial value of the CompanyName property. + public static Customer CreateCustomer(global::System.String customerID, global::System.String companyName) + { + Customer customer = new Customer(); + customer.CustomerID = customerID; + customer.CompanyName = companyName; + return customer; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CustomerID + { + get + { + return _CustomerID; + } + set + { + if (_CustomerID != value) + { + OnCustomerIDChanging(value); + ReportPropertyChanging("CustomerID"); + _CustomerID = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CustomerID"); + OnCustomerIDChanged(); + } + } + } + private global::System.String _CustomerID; + partial void OnCustomerIDChanging(global::System.String value); + partial void OnCustomerIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CompanyName + { + get + { + return _CompanyName; + } + set + { + OnCompanyNameChanging(value); + ReportPropertyChanging("CompanyName"); + _CompanyName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CompanyName"); + OnCompanyNameChanged(); + } + } + private global::System.String _CompanyName; + partial void OnCompanyNameChanging(global::System.String value); + partial void OnCompanyNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ContactName + { + get + { + return _ContactName; + } + set + { + OnContactNameChanging(value); + ReportPropertyChanging("ContactName"); + _ContactName = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ContactName"); + OnContactNameChanged(); + } + } + private global::System.String _ContactName; + partial void OnContactNameChanging(global::System.String value); + partial void OnContactNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ContactTitle + { + get + { + return _ContactTitle; + } + set + { + OnContactTitleChanging(value); + ReportPropertyChanging("ContactTitle"); + _ContactTitle = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ContactTitle"); + OnContactTitleChanged(); + } + } + private global::System.String _ContactTitle; + partial void OnContactTitleChanging(global::System.String value); + partial void OnContactTitleChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Address + { + get + { + return _Address; + } + set + { + OnAddressChanging(value); + ReportPropertyChanging("Address"); + _Address = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Address"); + OnAddressChanged(); + } + } + private global::System.String _Address; + partial void OnAddressChanging(global::System.String value); + partial void OnAddressChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String City + { + get + { + return _City; + } + set + { + OnCityChanging(value); + ReportPropertyChanging("City"); + _City = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("City"); + OnCityChanged(); + } + } + private global::System.String _City; + partial void OnCityChanging(global::System.String value); + partial void OnCityChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Region + { + get + { + return _Region; + } + set + { + OnRegionChanging(value); + ReportPropertyChanging("Region"); + _Region = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Region"); + OnRegionChanged(); + } + } + private global::System.String _Region; + partial void OnRegionChanging(global::System.String value); + partial void OnRegionChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String PostalCode + { + get + { + return _PostalCode; + } + set + { + OnPostalCodeChanging(value); + ReportPropertyChanging("PostalCode"); + _PostalCode = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("PostalCode"); + OnPostalCodeChanged(); + } + } + private global::System.String _PostalCode; + partial void OnPostalCodeChanging(global::System.String value); + partial void OnPostalCodeChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Country + { + get + { + return _Country; + } + set + { + OnCountryChanging(value); + ReportPropertyChanging("Country"); + _Country = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Country"); + OnCountryChanged(); + } + } + private global::System.String _Country; + partial void OnCountryChanging(global::System.String value); + partial void OnCountryChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Phone + { + get + { + return _Phone; + } + set + { + OnPhoneChanging(value); + ReportPropertyChanging("Phone"); + _Phone = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Phone"); + OnPhoneChanged(); + } + } + private global::System.String _Phone; + partial void OnPhoneChanging(global::System.String value); + partial void OnPhoneChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Fax + { + get + { + return _Fax; + } + set + { + OnFaxChanging(value); + ReportPropertyChanging("Fax"); + _Fax = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Fax"); + OnFaxChanged(); + } + } + private global::System.String _Fax; + partial void OnFaxChanging(global::System.String value); + partial void OnFaxChanged(); + + #endregion + + + #region Navigation Properties + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Orders_Customers", "Orders")] + public EntityCollection Orders + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.FK_Orders_Customers", "Orders"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.FK_Orders_Customers", "Orders", value); + } + } + } + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "CustomerCustomerDemo", "CustomerDemographics")] + public EntityCollection CustomerDemographics + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.CustomerCustomerDemo", "CustomerDemographics"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.CustomerCustomerDemo", "CustomerDemographics", value); + } + } + } + + #endregion + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Customer_and_Suppliers_by_City")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Customer_and_Suppliers_by_City : EntityObject + { + #region Factory Method + + /// + /// Create a new Customer_and_Suppliers_by_City object. + /// + /// Initial value of the CompanyName property. + /// Initial value of the Relationship property. + public static Customer_and_Suppliers_by_City CreateCustomer_and_Suppliers_by_City(global::System.String companyName, global::System.String relationship) + { + Customer_and_Suppliers_by_City customer_and_Suppliers_by_City = new Customer_and_Suppliers_by_City(); + customer_and_Suppliers_by_City.CompanyName = companyName; + customer_and_Suppliers_by_City.Relationship = relationship; + return customer_and_Suppliers_by_City; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String City + { + get + { + return _City; + } + set + { + OnCityChanging(value); + ReportPropertyChanging("City"); + _City = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("City"); + OnCityChanged(); + } + } + private global::System.String _City; + partial void OnCityChanging(global::System.String value); + partial void OnCityChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CompanyName + { + get + { + return _CompanyName; + } + set + { + if (_CompanyName != value) + { + OnCompanyNameChanging(value); + ReportPropertyChanging("CompanyName"); + _CompanyName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CompanyName"); + OnCompanyNameChanged(); + } + } + } + private global::System.String _CompanyName; + partial void OnCompanyNameChanging(global::System.String value); + partial void OnCompanyNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ContactName + { + get + { + return _ContactName; + } + set + { + OnContactNameChanging(value); + ReportPropertyChanging("ContactName"); + _ContactName = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ContactName"); + OnContactNameChanged(); + } + } + private global::System.String _ContactName; + partial void OnContactNameChanging(global::System.String value); + partial void OnContactNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String Relationship + { + get + { + return _Relationship; + } + set + { + if (_Relationship != value) + { + OnRelationshipChanging(value); + ReportPropertyChanging("Relationship"); + _Relationship = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("Relationship"); + OnRelationshipChanged(); + } + } + } + private global::System.String _Relationship; + partial void OnRelationshipChanging(global::System.String value); + partial void OnRelationshipChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="CustomerDemographic")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class CustomerDemographic : EntityObject + { + #region Factory Method + + /// + /// Create a new CustomerDemographic object. + /// + /// Initial value of the CustomerTypeID property. + public static CustomerDemographic CreateCustomerDemographic(global::System.String customerTypeID) + { + CustomerDemographic customerDemographic = new CustomerDemographic(); + customerDemographic.CustomerTypeID = customerTypeID; + return customerDemographic; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CustomerTypeID + { + get + { + return _CustomerTypeID; + } + set + { + if (_CustomerTypeID != value) + { + OnCustomerTypeIDChanging(value); + ReportPropertyChanging("CustomerTypeID"); + _CustomerTypeID = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CustomerTypeID"); + OnCustomerTypeIDChanged(); + } + } + } + private global::System.String _CustomerTypeID; + partial void OnCustomerTypeIDChanging(global::System.String value); + partial void OnCustomerTypeIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String CustomerDesc + { + get + { + return _CustomerDesc; + } + set + { + OnCustomerDescChanging(value); + ReportPropertyChanging("CustomerDesc"); + _CustomerDesc = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("CustomerDesc"); + OnCustomerDescChanged(); + } + } + private global::System.String _CustomerDesc; + partial void OnCustomerDescChanging(global::System.String value); + partial void OnCustomerDescChanged(); + + #endregion + + + #region Navigation Properties + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "CustomerCustomerDemo", "Customers")] + public EntityCollection Customers + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.CustomerCustomerDemo", "Customers"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.CustomerCustomerDemo", "Customers", value); + } + } + } + + #endregion + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Employee")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Employee : EntityObject + { + #region Factory Method + + /// + /// Create a new Employee object. + /// + /// Initial value of the EmployeeID property. + /// Initial value of the LastName property. + /// Initial value of the FirstName property. + public static Employee CreateEmployee(global::System.Int32 employeeID, global::System.String lastName, global::System.String firstName) + { + Employee employee = new Employee(); + employee.EmployeeID = employeeID; + employee.LastName = lastName; + employee.FirstName = firstName; + return employee; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 EmployeeID + { + get + { + return _EmployeeID; + } + set + { + if (_EmployeeID != value) + { + OnEmployeeIDChanging(value); + ReportPropertyChanging("EmployeeID"); + _EmployeeID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("EmployeeID"); + OnEmployeeIDChanged(); + } + } + } + private global::System.Int32 _EmployeeID; + partial void OnEmployeeIDChanging(global::System.Int32 value); + partial void OnEmployeeIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String LastName + { + get + { + return _LastName; + } + set + { + OnLastNameChanging(value); + ReportPropertyChanging("LastName"); + _LastName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("LastName"); + OnLastNameChanged(); + } + } + private global::System.String _LastName; + partial void OnLastNameChanging(global::System.String value); + partial void OnLastNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String FirstName + { + get + { + return _FirstName; + } + set + { + OnFirstNameChanging(value); + ReportPropertyChanging("FirstName"); + _FirstName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("FirstName"); + OnFirstNameChanged(); + } + } + private global::System.String _FirstName; + partial void OnFirstNameChanging(global::System.String value); + partial void OnFirstNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Title + { + get + { + return _Title; + } + set + { + OnTitleChanging(value); + ReportPropertyChanging("Title"); + _Title = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Title"); + OnTitleChanged(); + } + } + private global::System.String _Title; + partial void OnTitleChanging(global::System.String value); + partial void OnTitleChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String TitleOfCourtesy + { + get + { + return _TitleOfCourtesy; + } + set + { + OnTitleOfCourtesyChanging(value); + ReportPropertyChanging("TitleOfCourtesy"); + _TitleOfCourtesy = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("TitleOfCourtesy"); + OnTitleOfCourtesyChanged(); + } + } + private global::System.String _TitleOfCourtesy; + partial void OnTitleOfCourtesyChanging(global::System.String value); + partial void OnTitleOfCourtesyChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable BirthDate + { + get + { + return _BirthDate; + } + set + { + OnBirthDateChanging(value); + ReportPropertyChanging("BirthDate"); + _BirthDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("BirthDate"); + OnBirthDateChanged(); + } + } + private Nullable _BirthDate; + partial void OnBirthDateChanging(Nullable value); + partial void OnBirthDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable HireDate + { + get + { + return _HireDate; + } + set + { + OnHireDateChanging(value); + ReportPropertyChanging("HireDate"); + _HireDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("HireDate"); + OnHireDateChanged(); + } + } + private Nullable _HireDate; + partial void OnHireDateChanging(Nullable value); + partial void OnHireDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Address + { + get + { + return _Address; + } + set + { + OnAddressChanging(value); + ReportPropertyChanging("Address"); + _Address = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Address"); + OnAddressChanged(); + } + } + private global::System.String _Address; + partial void OnAddressChanging(global::System.String value); + partial void OnAddressChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String City + { + get + { + return _City; + } + set + { + OnCityChanging(value); + ReportPropertyChanging("City"); + _City = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("City"); + OnCityChanged(); + } + } + private global::System.String _City; + partial void OnCityChanging(global::System.String value); + partial void OnCityChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Region + { + get + { + return _Region; + } + set + { + OnRegionChanging(value); + ReportPropertyChanging("Region"); + _Region = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Region"); + OnRegionChanged(); + } + } + private global::System.String _Region; + partial void OnRegionChanging(global::System.String value); + partial void OnRegionChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String PostalCode + { + get + { + return _PostalCode; + } + set + { + OnPostalCodeChanging(value); + ReportPropertyChanging("PostalCode"); + _PostalCode = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("PostalCode"); + OnPostalCodeChanged(); + } + } + private global::System.String _PostalCode; + partial void OnPostalCodeChanging(global::System.String value); + partial void OnPostalCodeChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Country + { + get + { + return _Country; + } + set + { + OnCountryChanging(value); + ReportPropertyChanging("Country"); + _Country = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Country"); + OnCountryChanged(); + } + } + private global::System.String _Country; + partial void OnCountryChanging(global::System.String value); + partial void OnCountryChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String HomePhone + { + get + { + return _HomePhone; + } + set + { + OnHomePhoneChanging(value); + ReportPropertyChanging("HomePhone"); + _HomePhone = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("HomePhone"); + OnHomePhoneChanged(); + } + } + private global::System.String _HomePhone; + partial void OnHomePhoneChanging(global::System.String value); + partial void OnHomePhoneChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Extension + { + get + { + return _Extension; + } + set + { + OnExtensionChanging(value); + ReportPropertyChanging("Extension"); + _Extension = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Extension"); + OnExtensionChanged(); + } + } + private global::System.String _Extension; + partial void OnExtensionChanging(global::System.String value); + partial void OnExtensionChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.Byte[] Photo + { + get + { + return StructuralObject.GetValidValue(_Photo); + } + set + { + OnPhotoChanging(value); + ReportPropertyChanging("Photo"); + _Photo = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Photo"); + OnPhotoChanged(); + } + } + private global::System.Byte[] _Photo; + partial void OnPhotoChanging(global::System.Byte[] value); + partial void OnPhotoChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Notes + { + get + { + return _Notes; + } + set + { + OnNotesChanging(value); + ReportPropertyChanging("Notes"); + _Notes = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Notes"); + OnNotesChanged(); + } + } + private global::System.String _Notes; + partial void OnNotesChanging(global::System.String value); + partial void OnNotesChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ReportsTo + { + get + { + return _ReportsTo; + } + set + { + OnReportsToChanging(value); + ReportPropertyChanging("ReportsTo"); + _ReportsTo = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ReportsTo"); + OnReportsToChanged(); + } + } + private Nullable _ReportsTo; + partial void OnReportsToChanging(Nullable value); + partial void OnReportsToChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String PhotoPath + { + get + { + return _PhotoPath; + } + set + { + OnPhotoPathChanging(value); + ReportPropertyChanging("PhotoPath"); + _PhotoPath = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("PhotoPath"); + OnPhotoPathChanged(); + } + } + private global::System.String _PhotoPath; + partial void OnPhotoPathChanging(global::System.String value); + partial void OnPhotoPathChanged(); + + #endregion + + + #region Navigation Properties + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Employees_Employees", "Employees1")] + public EntityCollection Employees1 + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.FK_Employees_Employees", "Employees1"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.FK_Employees_Employees", "Employees1", value); + } + } + } + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Employees_Employees", "Employees")] + public Employee Employee1 + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Employees_Employees", "Employees").Value; + } + set + { + ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Employees_Employees", "Employees").Value = value; + } + } + /// + /// No Metadata Documentation available. + /// + [BrowsableAttribute(false)] + [DataMemberAttribute()] + public EntityReference Employee1Reference + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Employees_Employees", "Employees"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference("NorthwindModel.FK_Employees_Employees", "Employees", value); + } + } + } + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Orders_Employees", "Orders")] + public EntityCollection Orders + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.FK_Orders_Employees", "Orders"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.FK_Orders_Employees", "Orders", value); + } + } + } + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "EmployeeTerritories", "Territories")] + public EntityCollection Territories + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.EmployeeTerritories", "Territories"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.EmployeeTerritories", "Territories", value); + } + } + } + + #endregion + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Invoice")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Invoice : EntityObject + { + #region Factory Method + + /// + /// Create a new Invoice object. + /// + /// Initial value of the CustomerName property. + /// Initial value of the Salesperson property. + /// Initial value of the OrderID property. + /// Initial value of the ShipperName property. + /// Initial value of the ProductID property. + /// Initial value of the ProductName property. + /// Initial value of the UnitPrice property. + /// Initial value of the Quantity property. + /// Initial value of the Discount property. + public static Invoice CreateInvoice(global::System.String customerName, global::System.String salesperson, global::System.Int32 orderID, global::System.String shipperName, global::System.Int32 productID, global::System.String productName, global::System.Decimal unitPrice, global::System.Int16 quantity, global::System.Single discount) + { + Invoice invoice = new Invoice(); + invoice.CustomerName = customerName; + invoice.Salesperson = salesperson; + invoice.OrderID = orderID; + invoice.ShipperName = shipperName; + invoice.ProductID = productID; + invoice.ProductName = productName; + invoice.UnitPrice = unitPrice; + invoice.Quantity = quantity; + invoice.Discount = discount; + return invoice; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipName + { + get + { + return _ShipName; + } + set + { + OnShipNameChanging(value); + ReportPropertyChanging("ShipName"); + _ShipName = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipName"); + OnShipNameChanged(); + } + } + private global::System.String _ShipName; + partial void OnShipNameChanging(global::System.String value); + partial void OnShipNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipAddress + { + get + { + return _ShipAddress; + } + set + { + OnShipAddressChanging(value); + ReportPropertyChanging("ShipAddress"); + _ShipAddress = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipAddress"); + OnShipAddressChanged(); + } + } + private global::System.String _ShipAddress; + partial void OnShipAddressChanging(global::System.String value); + partial void OnShipAddressChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipCity + { + get + { + return _ShipCity; + } + set + { + OnShipCityChanging(value); + ReportPropertyChanging("ShipCity"); + _ShipCity = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipCity"); + OnShipCityChanged(); + } + } + private global::System.String _ShipCity; + partial void OnShipCityChanging(global::System.String value); + partial void OnShipCityChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipRegion + { + get + { + return _ShipRegion; + } + set + { + OnShipRegionChanging(value); + ReportPropertyChanging("ShipRegion"); + _ShipRegion = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipRegion"); + OnShipRegionChanged(); + } + } + private global::System.String _ShipRegion; + partial void OnShipRegionChanging(global::System.String value); + partial void OnShipRegionChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipPostalCode + { + get + { + return _ShipPostalCode; + } + set + { + OnShipPostalCodeChanging(value); + ReportPropertyChanging("ShipPostalCode"); + _ShipPostalCode = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipPostalCode"); + OnShipPostalCodeChanged(); + } + } + private global::System.String _ShipPostalCode; + partial void OnShipPostalCodeChanging(global::System.String value); + partial void OnShipPostalCodeChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipCountry + { + get + { + return _ShipCountry; + } + set + { + OnShipCountryChanging(value); + ReportPropertyChanging("ShipCountry"); + _ShipCountry = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipCountry"); + OnShipCountryChanged(); + } + } + private global::System.String _ShipCountry; + partial void OnShipCountryChanging(global::System.String value); + partial void OnShipCountryChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String CustomerID + { + get + { + return _CustomerID; + } + set + { + OnCustomerIDChanging(value); + ReportPropertyChanging("CustomerID"); + _CustomerID = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("CustomerID"); + OnCustomerIDChanged(); + } + } + private global::System.String _CustomerID; + partial void OnCustomerIDChanging(global::System.String value); + partial void OnCustomerIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CustomerName + { + get + { + return _CustomerName; + } + set + { + if (_CustomerName != value) + { + OnCustomerNameChanging(value); + ReportPropertyChanging("CustomerName"); + _CustomerName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CustomerName"); + OnCustomerNameChanged(); + } + } + } + private global::System.String _CustomerName; + partial void OnCustomerNameChanging(global::System.String value); + partial void OnCustomerNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Address + { + get + { + return _Address; + } + set + { + OnAddressChanging(value); + ReportPropertyChanging("Address"); + _Address = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Address"); + OnAddressChanged(); + } + } + private global::System.String _Address; + partial void OnAddressChanging(global::System.String value); + partial void OnAddressChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String City + { + get + { + return _City; + } + set + { + OnCityChanging(value); + ReportPropertyChanging("City"); + _City = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("City"); + OnCityChanged(); + } + } + private global::System.String _City; + partial void OnCityChanging(global::System.String value); + partial void OnCityChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Region + { + get + { + return _Region; + } + set + { + OnRegionChanging(value); + ReportPropertyChanging("Region"); + _Region = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Region"); + OnRegionChanged(); + } + } + private global::System.String _Region; + partial void OnRegionChanging(global::System.String value); + partial void OnRegionChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String PostalCode + { + get + { + return _PostalCode; + } + set + { + OnPostalCodeChanging(value); + ReportPropertyChanging("PostalCode"); + _PostalCode = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("PostalCode"); + OnPostalCodeChanged(); + } + } + private global::System.String _PostalCode; + partial void OnPostalCodeChanging(global::System.String value); + partial void OnPostalCodeChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Country + { + get + { + return _Country; + } + set + { + OnCountryChanging(value); + ReportPropertyChanging("Country"); + _Country = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Country"); + OnCountryChanged(); + } + } + private global::System.String _Country; + partial void OnCountryChanging(global::System.String value); + partial void OnCountryChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String Salesperson + { + get + { + return _Salesperson; + } + set + { + if (_Salesperson != value) + { + OnSalespersonChanging(value); + ReportPropertyChanging("Salesperson"); + _Salesperson = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("Salesperson"); + OnSalespersonChanged(); + } + } + } + private global::System.String _Salesperson; + partial void OnSalespersonChanging(global::System.String value); + partial void OnSalespersonChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 OrderID + { + get + { + return _OrderID; + } + set + { + if (_OrderID != value) + { + OnOrderIDChanging(value); + ReportPropertyChanging("OrderID"); + _OrderID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("OrderID"); + OnOrderIDChanged(); + } + } + } + private global::System.Int32 _OrderID; + partial void OnOrderIDChanging(global::System.Int32 value); + partial void OnOrderIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable OrderDate + { + get + { + return _OrderDate; + } + set + { + OnOrderDateChanging(value); + ReportPropertyChanging("OrderDate"); + _OrderDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("OrderDate"); + OnOrderDateChanged(); + } + } + private Nullable _OrderDate; + partial void OnOrderDateChanging(Nullable value); + partial void OnOrderDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable RequiredDate + { + get + { + return _RequiredDate; + } + set + { + OnRequiredDateChanging(value); + ReportPropertyChanging("RequiredDate"); + _RequiredDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("RequiredDate"); + OnRequiredDateChanged(); + } + } + private Nullable _RequiredDate; + partial void OnRequiredDateChanging(Nullable value); + partial void OnRequiredDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ShippedDate + { + get + { + return _ShippedDate; + } + set + { + OnShippedDateChanging(value); + ReportPropertyChanging("ShippedDate"); + _ShippedDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ShippedDate"); + OnShippedDateChanged(); + } + } + private Nullable _ShippedDate; + partial void OnShippedDateChanging(Nullable value); + partial void OnShippedDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String ShipperName + { + get + { + return _ShipperName; + } + set + { + if (_ShipperName != value) + { + OnShipperNameChanging(value); + ReportPropertyChanging("ShipperName"); + _ShipperName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("ShipperName"); + OnShipperNameChanged(); + } + } + } + private global::System.String _ShipperName; + partial void OnShipperNameChanging(global::System.String value); + partial void OnShipperNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 ProductID + { + get + { + return _ProductID; + } + set + { + if (_ProductID != value) + { + OnProductIDChanging(value); + ReportPropertyChanging("ProductID"); + _ProductID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ProductID"); + OnProductIDChanged(); + } + } + } + private global::System.Int32 _ProductID; + partial void OnProductIDChanging(global::System.Int32 value); + partial void OnProductIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String ProductName + { + get + { + return _ProductName; + } + set + { + if (_ProductName != value) + { + OnProductNameChanging(value); + ReportPropertyChanging("ProductName"); + _ProductName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("ProductName"); + OnProductNameChanged(); + } + } + } + private global::System.String _ProductName; + partial void OnProductNameChanging(global::System.String value); + partial void OnProductNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Decimal UnitPrice + { + get + { + return _UnitPrice; + } + set + { + if (_UnitPrice != value) + { + OnUnitPriceChanging(value); + ReportPropertyChanging("UnitPrice"); + _UnitPrice = StructuralObject.SetValidValue(value); + ReportPropertyChanged("UnitPrice"); + OnUnitPriceChanged(); + } + } + } + private global::System.Decimal _UnitPrice; + partial void OnUnitPriceChanging(global::System.Decimal value); + partial void OnUnitPriceChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int16 Quantity + { + get + { + return _Quantity; + } + set + { + if (_Quantity != value) + { + OnQuantityChanging(value); + ReportPropertyChanging("Quantity"); + _Quantity = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Quantity"); + OnQuantityChanged(); + } + } + } + private global::System.Int16 _Quantity; + partial void OnQuantityChanging(global::System.Int16 value); + partial void OnQuantityChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Single Discount + { + get + { + return _Discount; + } + set + { + if (_Discount != value) + { + OnDiscountChanging(value); + ReportPropertyChanging("Discount"); + _Discount = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Discount"); + OnDiscountChanged(); + } + } + } + private global::System.Single _Discount; + partial void OnDiscountChanging(global::System.Single value); + partial void OnDiscountChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ExtendedPrice + { + get + { + return _ExtendedPrice; + } + set + { + OnExtendedPriceChanging(value); + ReportPropertyChanging("ExtendedPrice"); + _ExtendedPrice = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ExtendedPrice"); + OnExtendedPriceChanged(); + } + } + private Nullable _ExtendedPrice; + partial void OnExtendedPriceChanging(Nullable value); + partial void OnExtendedPriceChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable Freight + { + get + { + return _Freight; + } + set + { + OnFreightChanging(value); + ReportPropertyChanging("Freight"); + _Freight = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Freight"); + OnFreightChanged(); + } + } + private Nullable _Freight; + partial void OnFreightChanging(Nullable value); + partial void OnFreightChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Order")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Order : EntityObject + { + #region Factory Method + + /// + /// Create a new Order object. + /// + /// Initial value of the OrderID property. + public static Order CreateOrder(global::System.Int32 orderID) + { + Order order = new Order(); + order.OrderID = orderID; + return order; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 OrderID + { + get + { + return _OrderID; + } + set + { + if (_OrderID != value) + { + OnOrderIDChanging(value); + ReportPropertyChanging("OrderID"); + _OrderID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("OrderID"); + OnOrderIDChanged(); + } + } + } + private global::System.Int32 _OrderID; + partial void OnOrderIDChanging(global::System.Int32 value); + partial void OnOrderIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String CustomerID + { + get + { + return _CustomerID; + } + set + { + OnCustomerIDChanging(value); + ReportPropertyChanging("CustomerID"); + _CustomerID = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("CustomerID"); + OnCustomerIDChanged(); + } + } + private global::System.String _CustomerID; + partial void OnCustomerIDChanging(global::System.String value); + partial void OnCustomerIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable EmployeeID + { + get + { + return _EmployeeID; + } + set + { + OnEmployeeIDChanging(value); + ReportPropertyChanging("EmployeeID"); + _EmployeeID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("EmployeeID"); + OnEmployeeIDChanged(); + } + } + private Nullable _EmployeeID; + partial void OnEmployeeIDChanging(Nullable value); + partial void OnEmployeeIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable OrderDate + { + get + { + return _OrderDate; + } + set + { + OnOrderDateChanging(value); + ReportPropertyChanging("OrderDate"); + _OrderDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("OrderDate"); + OnOrderDateChanged(); + } + } + private Nullable _OrderDate; + partial void OnOrderDateChanging(Nullable value); + partial void OnOrderDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable RequiredDate + { + get + { + return _RequiredDate; + } + set + { + OnRequiredDateChanging(value); + ReportPropertyChanging("RequiredDate"); + _RequiredDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("RequiredDate"); + OnRequiredDateChanged(); + } + } + private Nullable _RequiredDate; + partial void OnRequiredDateChanging(Nullable value); + partial void OnRequiredDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ShippedDate + { + get + { + return _ShippedDate; + } + set + { + OnShippedDateChanging(value); + ReportPropertyChanging("ShippedDate"); + _ShippedDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ShippedDate"); + OnShippedDateChanged(); + } + } + private Nullable _ShippedDate; + partial void OnShippedDateChanging(Nullable value); + partial void OnShippedDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ShipVia + { + get + { + return _ShipVia; + } + set + { + OnShipViaChanging(value); + ReportPropertyChanging("ShipVia"); + _ShipVia = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ShipVia"); + OnShipViaChanged(); + } + } + private Nullable _ShipVia; + partial void OnShipViaChanging(Nullable value); + partial void OnShipViaChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable Freight + { + get + { + return _Freight; + } + set + { + OnFreightChanging(value); + ReportPropertyChanging("Freight"); + _Freight = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Freight"); + OnFreightChanged(); + } + } + private Nullable _Freight; + partial void OnFreightChanging(Nullable value); + partial void OnFreightChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipName + { + get + { + return _ShipName; + } + set + { + OnShipNameChanging(value); + ReportPropertyChanging("ShipName"); + _ShipName = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipName"); + OnShipNameChanged(); + } + } + private global::System.String _ShipName; + partial void OnShipNameChanging(global::System.String value); + partial void OnShipNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipAddress + { + get + { + return _ShipAddress; + } + set + { + OnShipAddressChanging(value); + ReportPropertyChanging("ShipAddress"); + _ShipAddress = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipAddress"); + OnShipAddressChanged(); + } + } + private global::System.String _ShipAddress; + partial void OnShipAddressChanging(global::System.String value); + partial void OnShipAddressChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipCity + { + get + { + return _ShipCity; + } + set + { + OnShipCityChanging(value); + ReportPropertyChanging("ShipCity"); + _ShipCity = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipCity"); + OnShipCityChanged(); + } + } + private global::System.String _ShipCity; + partial void OnShipCityChanging(global::System.String value); + partial void OnShipCityChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipRegion + { + get + { + return _ShipRegion; + } + set + { + OnShipRegionChanging(value); + ReportPropertyChanging("ShipRegion"); + _ShipRegion = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipRegion"); + OnShipRegionChanged(); + } + } + private global::System.String _ShipRegion; + partial void OnShipRegionChanging(global::System.String value); + partial void OnShipRegionChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipPostalCode + { + get + { + return _ShipPostalCode; + } + set + { + OnShipPostalCodeChanging(value); + ReportPropertyChanging("ShipPostalCode"); + _ShipPostalCode = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipPostalCode"); + OnShipPostalCodeChanged(); + } + } + private global::System.String _ShipPostalCode; + partial void OnShipPostalCodeChanging(global::System.String value); + partial void OnShipPostalCodeChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipCountry + { + get + { + return _ShipCountry; + } + set + { + OnShipCountryChanging(value); + ReportPropertyChanging("ShipCountry"); + _ShipCountry = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipCountry"); + OnShipCountryChanged(); + } + } + private global::System.String _ShipCountry; + partial void OnShipCountryChanging(global::System.String value); + partial void OnShipCountryChanged(); + + #endregion + + + #region Navigation Properties + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Orders_Customers", "Customers")] + public Customer Customer + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Orders_Customers", "Customers").Value; + } + set + { + ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Orders_Customers", "Customers").Value = value; + } + } + /// + /// No Metadata Documentation available. + /// + [BrowsableAttribute(false)] + [DataMemberAttribute()] + public EntityReference CustomerReference + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Orders_Customers", "Customers"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference("NorthwindModel.FK_Orders_Customers", "Customers", value); + } + } + } + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Orders_Employees", "Employees")] + public Employee Employee + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Orders_Employees", "Employees").Value; + } + set + { + ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Orders_Employees", "Employees").Value = value; + } + } + /// + /// No Metadata Documentation available. + /// + [BrowsableAttribute(false)] + [DataMemberAttribute()] + public EntityReference EmployeeReference + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Orders_Employees", "Employees"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference("NorthwindModel.FK_Orders_Employees", "Employees", value); + } + } + } + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Order_Details_Orders", "Order_Details")] + public EntityCollection Order_Details + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.FK_Order_Details_Orders", "Order_Details"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.FK_Order_Details_Orders", "Order_Details", value); + } + } + } + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Orders_Shippers", "Shippers")] + public Shipper Shipper + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Orders_Shippers", "Shippers").Value; + } + set + { + ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Orders_Shippers", "Shippers").Value = value; + } + } + /// + /// No Metadata Documentation available. + /// + [BrowsableAttribute(false)] + [DataMemberAttribute()] + public EntityReference ShipperReference + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Orders_Shippers", "Shippers"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference("NorthwindModel.FK_Orders_Shippers", "Shippers", value); + } + } + } + + #endregion + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Order_Detail")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Order_Detail : EntityObject + { + #region Factory Method + + /// + /// Create a new Order_Detail object. + /// + /// Initial value of the OrderID property. + /// Initial value of the ProductID property. + /// Initial value of the UnitPrice property. + /// Initial value of the Quantity property. + /// Initial value of the Discount property. + public static Order_Detail CreateOrder_Detail(global::System.Int32 orderID, global::System.Int32 productID, global::System.Decimal unitPrice, global::System.Int16 quantity, global::System.Single discount) + { + Order_Detail order_Detail = new Order_Detail(); + order_Detail.OrderID = orderID; + order_Detail.ProductID = productID; + order_Detail.UnitPrice = unitPrice; + order_Detail.Quantity = quantity; + order_Detail.Discount = discount; + return order_Detail; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 OrderID + { + get + { + return _OrderID; + } + set + { + if (_OrderID != value) + { + OnOrderIDChanging(value); + ReportPropertyChanging("OrderID"); + _OrderID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("OrderID"); + OnOrderIDChanged(); + } + } + } + private global::System.Int32 _OrderID; + partial void OnOrderIDChanging(global::System.Int32 value); + partial void OnOrderIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 ProductID + { + get + { + return _ProductID; + } + set + { + if (_ProductID != value) + { + OnProductIDChanging(value); + ReportPropertyChanging("ProductID"); + _ProductID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ProductID"); + OnProductIDChanged(); + } + } + } + private global::System.Int32 _ProductID; + partial void OnProductIDChanging(global::System.Int32 value); + partial void OnProductIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Decimal UnitPrice + { + get + { + return _UnitPrice; + } + set + { + OnUnitPriceChanging(value); + ReportPropertyChanging("UnitPrice"); + _UnitPrice = StructuralObject.SetValidValue(value); + ReportPropertyChanged("UnitPrice"); + OnUnitPriceChanged(); + } + } + private global::System.Decimal _UnitPrice; + partial void OnUnitPriceChanging(global::System.Decimal value); + partial void OnUnitPriceChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int16 Quantity + { + get + { + return _Quantity; + } + set + { + OnQuantityChanging(value); + ReportPropertyChanging("Quantity"); + _Quantity = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Quantity"); + OnQuantityChanged(); + } + } + private global::System.Int16 _Quantity; + partial void OnQuantityChanging(global::System.Int16 value); + partial void OnQuantityChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Single Discount + { + get + { + return _Discount; + } + set + { + OnDiscountChanging(value); + ReportPropertyChanging("Discount"); + _Discount = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Discount"); + OnDiscountChanged(); + } + } + private global::System.Single _Discount; + partial void OnDiscountChanging(global::System.Single value); + partial void OnDiscountChanged(); + + #endregion + + + #region Navigation Properties + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Order_Details_Orders", "Orders")] + public Order Order + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Order_Details_Orders", "Orders").Value; + } + set + { + ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Order_Details_Orders", "Orders").Value = value; + } + } + /// + /// No Metadata Documentation available. + /// + [BrowsableAttribute(false)] + [DataMemberAttribute()] + public EntityReference OrderReference + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Order_Details_Orders", "Orders"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference("NorthwindModel.FK_Order_Details_Orders", "Orders", value); + } + } + } + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Order_Details_Products", "Products")] + public Product Product + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Order_Details_Products", "Products").Value; + } + set + { + ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Order_Details_Products", "Products").Value = value; + } + } + /// + /// No Metadata Documentation available. + /// + [BrowsableAttribute(false)] + [DataMemberAttribute()] + public EntityReference ProductReference + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Order_Details_Products", "Products"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference("NorthwindModel.FK_Order_Details_Products", "Products", value); + } + } + } + + #endregion + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Order_Details_Extended")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Order_Details_Extended : EntityObject + { + #region Factory Method + + /// + /// Create a new Order_Details_Extended object. + /// + /// Initial value of the OrderID property. + /// Initial value of the ProductID property. + /// Initial value of the ProductName property. + /// Initial value of the UnitPrice property. + /// Initial value of the Quantity property. + /// Initial value of the Discount property. + public static Order_Details_Extended CreateOrder_Details_Extended(global::System.Int32 orderID, global::System.Int32 productID, global::System.String productName, global::System.Decimal unitPrice, global::System.Int16 quantity, global::System.Single discount) + { + Order_Details_Extended order_Details_Extended = new Order_Details_Extended(); + order_Details_Extended.OrderID = orderID; + order_Details_Extended.ProductID = productID; + order_Details_Extended.ProductName = productName; + order_Details_Extended.UnitPrice = unitPrice; + order_Details_Extended.Quantity = quantity; + order_Details_Extended.Discount = discount; + return order_Details_Extended; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 OrderID + { + get + { + return _OrderID; + } + set + { + if (_OrderID != value) + { + OnOrderIDChanging(value); + ReportPropertyChanging("OrderID"); + _OrderID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("OrderID"); + OnOrderIDChanged(); + } + } + } + private global::System.Int32 _OrderID; + partial void OnOrderIDChanging(global::System.Int32 value); + partial void OnOrderIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 ProductID + { + get + { + return _ProductID; + } + set + { + if (_ProductID != value) + { + OnProductIDChanging(value); + ReportPropertyChanging("ProductID"); + _ProductID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ProductID"); + OnProductIDChanged(); + } + } + } + private global::System.Int32 _ProductID; + partial void OnProductIDChanging(global::System.Int32 value); + partial void OnProductIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String ProductName + { + get + { + return _ProductName; + } + set + { + if (_ProductName != value) + { + OnProductNameChanging(value); + ReportPropertyChanging("ProductName"); + _ProductName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("ProductName"); + OnProductNameChanged(); + } + } + } + private global::System.String _ProductName; + partial void OnProductNameChanging(global::System.String value); + partial void OnProductNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Decimal UnitPrice + { + get + { + return _UnitPrice; + } + set + { + if (_UnitPrice != value) + { + OnUnitPriceChanging(value); + ReportPropertyChanging("UnitPrice"); + _UnitPrice = StructuralObject.SetValidValue(value); + ReportPropertyChanged("UnitPrice"); + OnUnitPriceChanged(); + } + } + } + private global::System.Decimal _UnitPrice; + partial void OnUnitPriceChanging(global::System.Decimal value); + partial void OnUnitPriceChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int16 Quantity + { + get + { + return _Quantity; + } + set + { + if (_Quantity != value) + { + OnQuantityChanging(value); + ReportPropertyChanging("Quantity"); + _Quantity = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Quantity"); + OnQuantityChanged(); + } + } + } + private global::System.Int16 _Quantity; + partial void OnQuantityChanging(global::System.Int16 value); + partial void OnQuantityChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Single Discount + { + get + { + return _Discount; + } + set + { + if (_Discount != value) + { + OnDiscountChanging(value); + ReportPropertyChanging("Discount"); + _Discount = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Discount"); + OnDiscountChanged(); + } + } + } + private global::System.Single _Discount; + partial void OnDiscountChanging(global::System.Single value); + partial void OnDiscountChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ExtendedPrice + { + get + { + return _ExtendedPrice; + } + set + { + OnExtendedPriceChanging(value); + ReportPropertyChanging("ExtendedPrice"); + _ExtendedPrice = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ExtendedPrice"); + OnExtendedPriceChanged(); + } + } + private Nullable _ExtendedPrice; + partial void OnExtendedPriceChanging(Nullable value); + partial void OnExtendedPriceChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Order_Subtotal")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Order_Subtotal : EntityObject + { + #region Factory Method + + /// + /// Create a new Order_Subtotal object. + /// + /// Initial value of the OrderID property. + public static Order_Subtotal CreateOrder_Subtotal(global::System.Int32 orderID) + { + Order_Subtotal order_Subtotal = new Order_Subtotal(); + order_Subtotal.OrderID = orderID; + return order_Subtotal; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 OrderID + { + get + { + return _OrderID; + } + set + { + if (_OrderID != value) + { + OnOrderIDChanging(value); + ReportPropertyChanging("OrderID"); + _OrderID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("OrderID"); + OnOrderIDChanged(); + } + } + } + private global::System.Int32 _OrderID; + partial void OnOrderIDChanging(global::System.Int32 value); + partial void OnOrderIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable Subtotal + { + get + { + return _Subtotal; + } + set + { + OnSubtotalChanging(value); + ReportPropertyChanging("Subtotal"); + _Subtotal = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Subtotal"); + OnSubtotalChanged(); + } + } + private Nullable _Subtotal; + partial void OnSubtotalChanging(Nullable value); + partial void OnSubtotalChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Orders_Qry")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Orders_Qry : EntityObject + { + #region Factory Method + + /// + /// Create a new Orders_Qry object. + /// + /// Initial value of the OrderID property. + /// Initial value of the CompanyName property. + public static Orders_Qry CreateOrders_Qry(global::System.Int32 orderID, global::System.String companyName) + { + Orders_Qry orders_Qry = new Orders_Qry(); + orders_Qry.OrderID = orderID; + orders_Qry.CompanyName = companyName; + return orders_Qry; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 OrderID + { + get + { + return _OrderID; + } + set + { + if (_OrderID != value) + { + OnOrderIDChanging(value); + ReportPropertyChanging("OrderID"); + _OrderID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("OrderID"); + OnOrderIDChanged(); + } + } + } + private global::System.Int32 _OrderID; + partial void OnOrderIDChanging(global::System.Int32 value); + partial void OnOrderIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String CustomerID + { + get + { + return _CustomerID; + } + set + { + OnCustomerIDChanging(value); + ReportPropertyChanging("CustomerID"); + _CustomerID = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("CustomerID"); + OnCustomerIDChanged(); + } + } + private global::System.String _CustomerID; + partial void OnCustomerIDChanging(global::System.String value); + partial void OnCustomerIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable EmployeeID + { + get + { + return _EmployeeID; + } + set + { + OnEmployeeIDChanging(value); + ReportPropertyChanging("EmployeeID"); + _EmployeeID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("EmployeeID"); + OnEmployeeIDChanged(); + } + } + private Nullable _EmployeeID; + partial void OnEmployeeIDChanging(Nullable value); + partial void OnEmployeeIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable OrderDate + { + get + { + return _OrderDate; + } + set + { + OnOrderDateChanging(value); + ReportPropertyChanging("OrderDate"); + _OrderDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("OrderDate"); + OnOrderDateChanged(); + } + } + private Nullable _OrderDate; + partial void OnOrderDateChanging(Nullable value); + partial void OnOrderDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable RequiredDate + { + get + { + return _RequiredDate; + } + set + { + OnRequiredDateChanging(value); + ReportPropertyChanging("RequiredDate"); + _RequiredDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("RequiredDate"); + OnRequiredDateChanged(); + } + } + private Nullable _RequiredDate; + partial void OnRequiredDateChanging(Nullable value); + partial void OnRequiredDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ShippedDate + { + get + { + return _ShippedDate; + } + set + { + OnShippedDateChanging(value); + ReportPropertyChanging("ShippedDate"); + _ShippedDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ShippedDate"); + OnShippedDateChanged(); + } + } + private Nullable _ShippedDate; + partial void OnShippedDateChanging(Nullable value); + partial void OnShippedDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ShipVia + { + get + { + return _ShipVia; + } + set + { + OnShipViaChanging(value); + ReportPropertyChanging("ShipVia"); + _ShipVia = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ShipVia"); + OnShipViaChanged(); + } + } + private Nullable _ShipVia; + partial void OnShipViaChanging(Nullable value); + partial void OnShipViaChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable Freight + { + get + { + return _Freight; + } + set + { + OnFreightChanging(value); + ReportPropertyChanging("Freight"); + _Freight = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Freight"); + OnFreightChanged(); + } + } + private Nullable _Freight; + partial void OnFreightChanging(Nullable value); + partial void OnFreightChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipName + { + get + { + return _ShipName; + } + set + { + OnShipNameChanging(value); + ReportPropertyChanging("ShipName"); + _ShipName = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipName"); + OnShipNameChanged(); + } + } + private global::System.String _ShipName; + partial void OnShipNameChanging(global::System.String value); + partial void OnShipNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipAddress + { + get + { + return _ShipAddress; + } + set + { + OnShipAddressChanging(value); + ReportPropertyChanging("ShipAddress"); + _ShipAddress = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipAddress"); + OnShipAddressChanged(); + } + } + private global::System.String _ShipAddress; + partial void OnShipAddressChanging(global::System.String value); + partial void OnShipAddressChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipCity + { + get + { + return _ShipCity; + } + set + { + OnShipCityChanging(value); + ReportPropertyChanging("ShipCity"); + _ShipCity = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipCity"); + OnShipCityChanged(); + } + } + private global::System.String _ShipCity; + partial void OnShipCityChanging(global::System.String value); + partial void OnShipCityChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipRegion + { + get + { + return _ShipRegion; + } + set + { + OnShipRegionChanging(value); + ReportPropertyChanging("ShipRegion"); + _ShipRegion = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipRegion"); + OnShipRegionChanged(); + } + } + private global::System.String _ShipRegion; + partial void OnShipRegionChanging(global::System.String value); + partial void OnShipRegionChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipPostalCode + { + get + { + return _ShipPostalCode; + } + set + { + OnShipPostalCodeChanging(value); + ReportPropertyChanging("ShipPostalCode"); + _ShipPostalCode = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipPostalCode"); + OnShipPostalCodeChanged(); + } + } + private global::System.String _ShipPostalCode; + partial void OnShipPostalCodeChanging(global::System.String value); + partial void OnShipPostalCodeChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ShipCountry + { + get + { + return _ShipCountry; + } + set + { + OnShipCountryChanging(value); + ReportPropertyChanging("ShipCountry"); + _ShipCountry = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ShipCountry"); + OnShipCountryChanged(); + } + } + private global::System.String _ShipCountry; + partial void OnShipCountryChanging(global::System.String value); + partial void OnShipCountryChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CompanyName + { + get + { + return _CompanyName; + } + set + { + if (_CompanyName != value) + { + OnCompanyNameChanging(value); + ReportPropertyChanging("CompanyName"); + _CompanyName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CompanyName"); + OnCompanyNameChanged(); + } + } + } + private global::System.String _CompanyName; + partial void OnCompanyNameChanging(global::System.String value); + partial void OnCompanyNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Address + { + get + { + return _Address; + } + set + { + OnAddressChanging(value); + ReportPropertyChanging("Address"); + _Address = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Address"); + OnAddressChanged(); + } + } + private global::System.String _Address; + partial void OnAddressChanging(global::System.String value); + partial void OnAddressChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String City + { + get + { + return _City; + } + set + { + OnCityChanging(value); + ReportPropertyChanging("City"); + _City = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("City"); + OnCityChanged(); + } + } + private global::System.String _City; + partial void OnCityChanging(global::System.String value); + partial void OnCityChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Region + { + get + { + return _Region; + } + set + { + OnRegionChanging(value); + ReportPropertyChanging("Region"); + _Region = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Region"); + OnRegionChanged(); + } + } + private global::System.String _Region; + partial void OnRegionChanging(global::System.String value); + partial void OnRegionChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String PostalCode + { + get + { + return _PostalCode; + } + set + { + OnPostalCodeChanging(value); + ReportPropertyChanging("PostalCode"); + _PostalCode = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("PostalCode"); + OnPostalCodeChanged(); + } + } + private global::System.String _PostalCode; + partial void OnPostalCodeChanging(global::System.String value); + partial void OnPostalCodeChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Country + { + get + { + return _Country; + } + set + { + OnCountryChanging(value); + ReportPropertyChanging("Country"); + _Country = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Country"); + OnCountryChanged(); + } + } + private global::System.String _Country; + partial void OnCountryChanging(global::System.String value); + partial void OnCountryChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Product")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Product : EntityObject + { + #region Factory Method + + /// + /// Create a new Product object. + /// + /// Initial value of the ProductID property. + /// Initial value of the ProductName property. + /// Initial value of the Discontinued property. + public static Product CreateProduct(global::System.Int32 productID, global::System.String productName, global::System.Boolean discontinued) + { + Product product = new Product(); + product.ProductID = productID; + product.ProductName = productName; + product.Discontinued = discontinued; + return product; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 ProductID + { + get + { + return _ProductID; + } + set + { + if (_ProductID != value) + { + OnProductIDChanging(value); + ReportPropertyChanging("ProductID"); + _ProductID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ProductID"); + OnProductIDChanged(); + } + } + } + private global::System.Int32 _ProductID; + partial void OnProductIDChanging(global::System.Int32 value); + partial void OnProductIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String ProductName + { + get + { + return _ProductName; + } + set + { + OnProductNameChanging(value); + ReportPropertyChanging("ProductName"); + _ProductName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("ProductName"); + OnProductNameChanged(); + } + } + private global::System.String _ProductName; + partial void OnProductNameChanging(global::System.String value); + partial void OnProductNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable SupplierID + { + get + { + return _SupplierID; + } + set + { + OnSupplierIDChanging(value); + ReportPropertyChanging("SupplierID"); + _SupplierID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("SupplierID"); + OnSupplierIDChanged(); + } + } + private Nullable _SupplierID; + partial void OnSupplierIDChanging(Nullable value); + partial void OnSupplierIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable CategoryID + { + get + { + return _CategoryID; + } + set + { + OnCategoryIDChanging(value); + ReportPropertyChanging("CategoryID"); + _CategoryID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("CategoryID"); + OnCategoryIDChanged(); + } + } + private Nullable _CategoryID; + partial void OnCategoryIDChanging(Nullable value); + partial void OnCategoryIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String QuantityPerUnit + { + get + { + return _QuantityPerUnit; + } + set + { + OnQuantityPerUnitChanging(value); + ReportPropertyChanging("QuantityPerUnit"); + _QuantityPerUnit = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("QuantityPerUnit"); + OnQuantityPerUnitChanged(); + } + } + private global::System.String _QuantityPerUnit; + partial void OnQuantityPerUnitChanging(global::System.String value); + partial void OnQuantityPerUnitChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable UnitPrice + { + get + { + return _UnitPrice; + } + set + { + OnUnitPriceChanging(value); + ReportPropertyChanging("UnitPrice"); + _UnitPrice = StructuralObject.SetValidValue(value); + ReportPropertyChanged("UnitPrice"); + OnUnitPriceChanged(); + } + } + private Nullable _UnitPrice; + partial void OnUnitPriceChanging(Nullable value); + partial void OnUnitPriceChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable UnitsInStock + { + get + { + return _UnitsInStock; + } + set + { + OnUnitsInStockChanging(value); + ReportPropertyChanging("UnitsInStock"); + _UnitsInStock = StructuralObject.SetValidValue(value); + ReportPropertyChanged("UnitsInStock"); + OnUnitsInStockChanged(); + } + } + private Nullable _UnitsInStock; + partial void OnUnitsInStockChanging(Nullable value); + partial void OnUnitsInStockChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable UnitsOnOrder + { + get + { + return _UnitsOnOrder; + } + set + { + OnUnitsOnOrderChanging(value); + ReportPropertyChanging("UnitsOnOrder"); + _UnitsOnOrder = StructuralObject.SetValidValue(value); + ReportPropertyChanged("UnitsOnOrder"); + OnUnitsOnOrderChanged(); + } + } + private Nullable _UnitsOnOrder; + partial void OnUnitsOnOrderChanging(Nullable value); + partial void OnUnitsOnOrderChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ReorderLevel + { + get + { + return _ReorderLevel; + } + set + { + OnReorderLevelChanging(value); + ReportPropertyChanging("ReorderLevel"); + _ReorderLevel = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ReorderLevel"); + OnReorderLevelChanged(); + } + } + private Nullable _ReorderLevel; + partial void OnReorderLevelChanging(Nullable value); + partial void OnReorderLevelChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Boolean Discontinued + { + get + { + return _Discontinued; + } + set + { + OnDiscontinuedChanging(value); + ReportPropertyChanging("Discontinued"); + _Discontinued = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Discontinued"); + OnDiscontinuedChanged(); + } + } + private global::System.Boolean _Discontinued; + partial void OnDiscontinuedChanging(global::System.Boolean value); + partial void OnDiscontinuedChanged(); + + #endregion + + + #region Navigation Properties + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Products_Categories", "Categories")] + public Category Category + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Products_Categories", "Categories").Value; + } + set + { + ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Products_Categories", "Categories").Value = value; + } + } + /// + /// No Metadata Documentation available. + /// + [BrowsableAttribute(false)] + [DataMemberAttribute()] + public EntityReference CategoryReference + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Products_Categories", "Categories"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference("NorthwindModel.FK_Products_Categories", "Categories", value); + } + } + } + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Order_Details_Products", "Order_Details")] + public EntityCollection Order_Details + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.FK_Order_Details_Products", "Order_Details"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.FK_Order_Details_Products", "Order_Details", value); + } + } + } + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Products_Suppliers", "Suppliers")] + public Supplier Supplier + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Products_Suppliers", "Suppliers").Value; + } + set + { + ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Products_Suppliers", "Suppliers").Value = value; + } + } + /// + /// No Metadata Documentation available. + /// + [BrowsableAttribute(false)] + [DataMemberAttribute()] + public EntityReference SupplierReference + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Products_Suppliers", "Suppliers"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference("NorthwindModel.FK_Products_Suppliers", "Suppliers", value); + } + } + } + + #endregion + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Product_Sales_for_1997")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Product_Sales_for_1997 : EntityObject + { + #region Factory Method + + /// + /// Create a new Product_Sales_for_1997 object. + /// + /// Initial value of the CategoryName property. + /// Initial value of the ProductName property. + public static Product_Sales_for_1997 CreateProduct_Sales_for_1997(global::System.String categoryName, global::System.String productName) + { + Product_Sales_for_1997 product_Sales_for_1997 = new Product_Sales_for_1997(); + product_Sales_for_1997.CategoryName = categoryName; + product_Sales_for_1997.ProductName = productName; + return product_Sales_for_1997; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CategoryName + { + get + { + return _CategoryName; + } + set + { + if (_CategoryName != value) + { + OnCategoryNameChanging(value); + ReportPropertyChanging("CategoryName"); + _CategoryName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CategoryName"); + OnCategoryNameChanged(); + } + } + } + private global::System.String _CategoryName; + partial void OnCategoryNameChanging(global::System.String value); + partial void OnCategoryNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String ProductName + { + get + { + return _ProductName; + } + set + { + if (_ProductName != value) + { + OnProductNameChanging(value); + ReportPropertyChanging("ProductName"); + _ProductName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("ProductName"); + OnProductNameChanged(); + } + } + } + private global::System.String _ProductName; + partial void OnProductNameChanging(global::System.String value); + partial void OnProductNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ProductSales + { + get + { + return _ProductSales; + } + set + { + OnProductSalesChanging(value); + ReportPropertyChanging("ProductSales"); + _ProductSales = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ProductSales"); + OnProductSalesChanged(); + } + } + private Nullable _ProductSales; + partial void OnProductSalesChanging(Nullable value); + partial void OnProductSalesChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Products_Above_Average_Price")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Products_Above_Average_Price : EntityObject + { + #region Factory Method + + /// + /// Create a new Products_Above_Average_Price object. + /// + /// Initial value of the ProductName property. + public static Products_Above_Average_Price CreateProducts_Above_Average_Price(global::System.String productName) + { + Products_Above_Average_Price products_Above_Average_Price = new Products_Above_Average_Price(); + products_Above_Average_Price.ProductName = productName; + return products_Above_Average_Price; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String ProductName + { + get + { + return _ProductName; + } + set + { + if (_ProductName != value) + { + OnProductNameChanging(value); + ReportPropertyChanging("ProductName"); + _ProductName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("ProductName"); + OnProductNameChanged(); + } + } + } + private global::System.String _ProductName; + partial void OnProductNameChanging(global::System.String value); + partial void OnProductNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable UnitPrice + { + get + { + return _UnitPrice; + } + set + { + OnUnitPriceChanging(value); + ReportPropertyChanging("UnitPrice"); + _UnitPrice = StructuralObject.SetValidValue(value); + ReportPropertyChanged("UnitPrice"); + OnUnitPriceChanged(); + } + } + private Nullable _UnitPrice; + partial void OnUnitPriceChanging(Nullable value); + partial void OnUnitPriceChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Products_by_Category")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Products_by_Category : EntityObject + { + #region Factory Method + + /// + /// Create a new Products_by_Category object. + /// + /// Initial value of the CategoryName property. + /// Initial value of the ProductName property. + /// Initial value of the Discontinued property. + public static Products_by_Category CreateProducts_by_Category(global::System.String categoryName, global::System.String productName, global::System.Boolean discontinued) + { + Products_by_Category products_by_Category = new Products_by_Category(); + products_by_Category.CategoryName = categoryName; + products_by_Category.ProductName = productName; + products_by_Category.Discontinued = discontinued; + return products_by_Category; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CategoryName + { + get + { + return _CategoryName; + } + set + { + if (_CategoryName != value) + { + OnCategoryNameChanging(value); + ReportPropertyChanging("CategoryName"); + _CategoryName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CategoryName"); + OnCategoryNameChanged(); + } + } + } + private global::System.String _CategoryName; + partial void OnCategoryNameChanging(global::System.String value); + partial void OnCategoryNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String ProductName + { + get + { + return _ProductName; + } + set + { + if (_ProductName != value) + { + OnProductNameChanging(value); + ReportPropertyChanging("ProductName"); + _ProductName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("ProductName"); + OnProductNameChanged(); + } + } + } + private global::System.String _ProductName; + partial void OnProductNameChanging(global::System.String value); + partial void OnProductNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String QuantityPerUnit + { + get + { + return _QuantityPerUnit; + } + set + { + OnQuantityPerUnitChanging(value); + ReportPropertyChanging("QuantityPerUnit"); + _QuantityPerUnit = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("QuantityPerUnit"); + OnQuantityPerUnitChanged(); + } + } + private global::System.String _QuantityPerUnit; + partial void OnQuantityPerUnitChanging(global::System.String value); + partial void OnQuantityPerUnitChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable UnitsInStock + { + get + { + return _UnitsInStock; + } + set + { + OnUnitsInStockChanging(value); + ReportPropertyChanging("UnitsInStock"); + _UnitsInStock = StructuralObject.SetValidValue(value); + ReportPropertyChanged("UnitsInStock"); + OnUnitsInStockChanged(); + } + } + private Nullable _UnitsInStock; + partial void OnUnitsInStockChanging(Nullable value); + partial void OnUnitsInStockChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Boolean Discontinued + { + get + { + return _Discontinued; + } + set + { + if (_Discontinued != value) + { + OnDiscontinuedChanging(value); + ReportPropertyChanging("Discontinued"); + _Discontinued = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Discontinued"); + OnDiscontinuedChanged(); + } + } + } + private global::System.Boolean _Discontinued; + partial void OnDiscontinuedChanging(global::System.Boolean value); + partial void OnDiscontinuedChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Region")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Region : EntityObject + { + #region Factory Method + + /// + /// Create a new Region object. + /// + /// Initial value of the RegionID property. + /// Initial value of the RegionDescription property. + public static Region CreateRegion(global::System.Int32 regionID, global::System.String regionDescription) + { + Region region = new Region(); + region.RegionID = regionID; + region.RegionDescription = regionDescription; + return region; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 RegionID + { + get + { + return _RegionID; + } + set + { + if (_RegionID != value) + { + OnRegionIDChanging(value); + ReportPropertyChanging("RegionID"); + _RegionID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("RegionID"); + OnRegionIDChanged(); + } + } + } + private global::System.Int32 _RegionID; + partial void OnRegionIDChanging(global::System.Int32 value); + partial void OnRegionIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String RegionDescription + { + get + { + return _RegionDescription; + } + set + { + OnRegionDescriptionChanging(value); + ReportPropertyChanging("RegionDescription"); + _RegionDescription = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("RegionDescription"); + OnRegionDescriptionChanged(); + } + } + private global::System.String _RegionDescription; + partial void OnRegionDescriptionChanging(global::System.String value); + partial void OnRegionDescriptionChanged(); + + #endregion + + + #region Navigation Properties + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Territories_Region", "Territories")] + public EntityCollection Territories + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.FK_Territories_Region", "Territories"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.FK_Territories_Region", "Territories", value); + } + } + } + + #endregion + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Sales_by_Category")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Sales_by_Category : EntityObject + { + #region Factory Method + + /// + /// Create a new Sales_by_Category object. + /// + /// Initial value of the CategoryID property. + /// Initial value of the CategoryName property. + /// Initial value of the ProductName property. + public static Sales_by_Category CreateSales_by_Category(global::System.Int32 categoryID, global::System.String categoryName, global::System.String productName) + { + Sales_by_Category sales_by_Category = new Sales_by_Category(); + sales_by_Category.CategoryID = categoryID; + sales_by_Category.CategoryName = categoryName; + sales_by_Category.ProductName = productName; + return sales_by_Category; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 CategoryID + { + get + { + return _CategoryID; + } + set + { + if (_CategoryID != value) + { + OnCategoryIDChanging(value); + ReportPropertyChanging("CategoryID"); + _CategoryID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("CategoryID"); + OnCategoryIDChanged(); + } + } + } + private global::System.Int32 _CategoryID; + partial void OnCategoryIDChanging(global::System.Int32 value); + partial void OnCategoryIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CategoryName + { + get + { + return _CategoryName; + } + set + { + if (_CategoryName != value) + { + OnCategoryNameChanging(value); + ReportPropertyChanging("CategoryName"); + _CategoryName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CategoryName"); + OnCategoryNameChanged(); + } + } + } + private global::System.String _CategoryName; + partial void OnCategoryNameChanging(global::System.String value); + partial void OnCategoryNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String ProductName + { + get + { + return _ProductName; + } + set + { + if (_ProductName != value) + { + OnProductNameChanging(value); + ReportPropertyChanging("ProductName"); + _ProductName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("ProductName"); + OnProductNameChanged(); + } + } + } + private global::System.String _ProductName; + partial void OnProductNameChanging(global::System.String value); + partial void OnProductNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ProductSales + { + get + { + return _ProductSales; + } + set + { + OnProductSalesChanging(value); + ReportPropertyChanging("ProductSales"); + _ProductSales = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ProductSales"); + OnProductSalesChanged(); + } + } + private Nullable _ProductSales; + partial void OnProductSalesChanging(Nullable value); + partial void OnProductSalesChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Sales_Totals_by_Amount")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Sales_Totals_by_Amount : EntityObject + { + #region Factory Method + + /// + /// Create a new Sales_Totals_by_Amount object. + /// + /// Initial value of the OrderID property. + /// Initial value of the CompanyName property. + public static Sales_Totals_by_Amount CreateSales_Totals_by_Amount(global::System.Int32 orderID, global::System.String companyName) + { + Sales_Totals_by_Amount sales_Totals_by_Amount = new Sales_Totals_by_Amount(); + sales_Totals_by_Amount.OrderID = orderID; + sales_Totals_by_Amount.CompanyName = companyName; + return sales_Totals_by_Amount; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable SaleAmount + { + get + { + return _SaleAmount; + } + set + { + OnSaleAmountChanging(value); + ReportPropertyChanging("SaleAmount"); + _SaleAmount = StructuralObject.SetValidValue(value); + ReportPropertyChanged("SaleAmount"); + OnSaleAmountChanged(); + } + } + private Nullable _SaleAmount; + partial void OnSaleAmountChanging(Nullable value); + partial void OnSaleAmountChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 OrderID + { + get + { + return _OrderID; + } + set + { + if (_OrderID != value) + { + OnOrderIDChanging(value); + ReportPropertyChanging("OrderID"); + _OrderID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("OrderID"); + OnOrderIDChanged(); + } + } + } + private global::System.Int32 _OrderID; + partial void OnOrderIDChanging(global::System.Int32 value); + partial void OnOrderIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CompanyName + { + get + { + return _CompanyName; + } + set + { + if (_CompanyName != value) + { + OnCompanyNameChanging(value); + ReportPropertyChanging("CompanyName"); + _CompanyName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CompanyName"); + OnCompanyNameChanged(); + } + } + } + private global::System.String _CompanyName; + partial void OnCompanyNameChanging(global::System.String value); + partial void OnCompanyNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ShippedDate + { + get + { + return _ShippedDate; + } + set + { + OnShippedDateChanging(value); + ReportPropertyChanging("ShippedDate"); + _ShippedDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ShippedDate"); + OnShippedDateChanged(); + } + } + private Nullable _ShippedDate; + partial void OnShippedDateChanging(Nullable value); + partial void OnShippedDateChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Shipper")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Shipper : EntityObject + { + #region Factory Method + + /// + /// Create a new Shipper object. + /// + /// Initial value of the ShipperID property. + /// Initial value of the CompanyName property. + public static Shipper CreateShipper(global::System.Int32 shipperID, global::System.String companyName) + { + Shipper shipper = new Shipper(); + shipper.ShipperID = shipperID; + shipper.CompanyName = companyName; + return shipper; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 ShipperID + { + get + { + return _ShipperID; + } + set + { + if (_ShipperID != value) + { + OnShipperIDChanging(value); + ReportPropertyChanging("ShipperID"); + _ShipperID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ShipperID"); + OnShipperIDChanged(); + } + } + } + private global::System.Int32 _ShipperID; + partial void OnShipperIDChanging(global::System.Int32 value); + partial void OnShipperIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CompanyName + { + get + { + return _CompanyName; + } + set + { + OnCompanyNameChanging(value); + ReportPropertyChanging("CompanyName"); + _CompanyName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CompanyName"); + OnCompanyNameChanged(); + } + } + private global::System.String _CompanyName; + partial void OnCompanyNameChanging(global::System.String value); + partial void OnCompanyNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Phone + { + get + { + return _Phone; + } + set + { + OnPhoneChanging(value); + ReportPropertyChanging("Phone"); + _Phone = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Phone"); + OnPhoneChanged(); + } + } + private global::System.String _Phone; + partial void OnPhoneChanging(global::System.String value); + partial void OnPhoneChanged(); + + #endregion + + + #region Navigation Properties + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Orders_Shippers", "Orders")] + public EntityCollection Orders + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.FK_Orders_Shippers", "Orders"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.FK_Orders_Shippers", "Orders", value); + } + } + } + + #endregion + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Summary_of_Sales_by_Quarter")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Summary_of_Sales_by_Quarter : EntityObject + { + #region Factory Method + + /// + /// Create a new Summary_of_Sales_by_Quarter object. + /// + /// Initial value of the OrderID property. + public static Summary_of_Sales_by_Quarter CreateSummary_of_Sales_by_Quarter(global::System.Int32 orderID) + { + Summary_of_Sales_by_Quarter summary_of_Sales_by_Quarter = new Summary_of_Sales_by_Quarter(); + summary_of_Sales_by_Quarter.OrderID = orderID; + return summary_of_Sales_by_Quarter; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ShippedDate + { + get + { + return _ShippedDate; + } + set + { + OnShippedDateChanging(value); + ReportPropertyChanging("ShippedDate"); + _ShippedDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ShippedDate"); + OnShippedDateChanged(); + } + } + private Nullable _ShippedDate; + partial void OnShippedDateChanging(Nullable value); + partial void OnShippedDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 OrderID + { + get + { + return _OrderID; + } + set + { + if (_OrderID != value) + { + OnOrderIDChanging(value); + ReportPropertyChanging("OrderID"); + _OrderID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("OrderID"); + OnOrderIDChanged(); + } + } + } + private global::System.Int32 _OrderID; + partial void OnOrderIDChanging(global::System.Int32 value); + partial void OnOrderIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable Subtotal + { + get + { + return _Subtotal; + } + set + { + OnSubtotalChanging(value); + ReportPropertyChanging("Subtotal"); + _Subtotal = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Subtotal"); + OnSubtotalChanged(); + } + } + private Nullable _Subtotal; + partial void OnSubtotalChanging(Nullable value); + partial void OnSubtotalChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Summary_of_Sales_by_Year")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Summary_of_Sales_by_Year : EntityObject + { + #region Factory Method + + /// + /// Create a new Summary_of_Sales_by_Year object. + /// + /// Initial value of the OrderID property. + public static Summary_of_Sales_by_Year CreateSummary_of_Sales_by_Year(global::System.Int32 orderID) + { + Summary_of_Sales_by_Year summary_of_Sales_by_Year = new Summary_of_Sales_by_Year(); + summary_of_Sales_by_Year.OrderID = orderID; + return summary_of_Sales_by_Year; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable ShippedDate + { + get + { + return _ShippedDate; + } + set + { + OnShippedDateChanging(value); + ReportPropertyChanging("ShippedDate"); + _ShippedDate = StructuralObject.SetValidValue(value); + ReportPropertyChanged("ShippedDate"); + OnShippedDateChanged(); + } + } + private Nullable _ShippedDate; + partial void OnShippedDateChanging(Nullable value); + partial void OnShippedDateChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 OrderID + { + get + { + return _OrderID; + } + set + { + if (_OrderID != value) + { + OnOrderIDChanging(value); + ReportPropertyChanging("OrderID"); + _OrderID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("OrderID"); + OnOrderIDChanged(); + } + } + } + private global::System.Int32 _OrderID; + partial void OnOrderIDChanging(global::System.Int32 value); + partial void OnOrderIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable Subtotal + { + get + { + return _Subtotal; + } + set + { + OnSubtotalChanging(value); + ReportPropertyChanging("Subtotal"); + _Subtotal = StructuralObject.SetValidValue(value); + ReportPropertyChanged("Subtotal"); + OnSubtotalChanged(); + } + } + private Nullable _Subtotal; + partial void OnSubtotalChanging(Nullable value); + partial void OnSubtotalChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Supplier")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Supplier : EntityObject + { + #region Factory Method + + /// + /// Create a new Supplier object. + /// + /// Initial value of the SupplierID property. + /// Initial value of the CompanyName property. + public static Supplier CreateSupplier(global::System.Int32 supplierID, global::System.String companyName) + { + Supplier supplier = new Supplier(); + supplier.SupplierID = supplierID; + supplier.CompanyName = companyName; + return supplier; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 SupplierID + { + get + { + return _SupplierID; + } + set + { + if (_SupplierID != value) + { + OnSupplierIDChanging(value); + ReportPropertyChanging("SupplierID"); + _SupplierID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("SupplierID"); + OnSupplierIDChanged(); + } + } + } + private global::System.Int32 _SupplierID; + partial void OnSupplierIDChanging(global::System.Int32 value); + partial void OnSupplierIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String CompanyName + { + get + { + return _CompanyName; + } + set + { + OnCompanyNameChanging(value); + ReportPropertyChanging("CompanyName"); + _CompanyName = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("CompanyName"); + OnCompanyNameChanged(); + } + } + private global::System.String _CompanyName; + partial void OnCompanyNameChanging(global::System.String value); + partial void OnCompanyNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ContactName + { + get + { + return _ContactName; + } + set + { + OnContactNameChanging(value); + ReportPropertyChanging("ContactName"); + _ContactName = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ContactName"); + OnContactNameChanged(); + } + } + private global::System.String _ContactName; + partial void OnContactNameChanging(global::System.String value); + partial void OnContactNameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String ContactTitle + { + get + { + return _ContactTitle; + } + set + { + OnContactTitleChanging(value); + ReportPropertyChanging("ContactTitle"); + _ContactTitle = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("ContactTitle"); + OnContactTitleChanged(); + } + } + private global::System.String _ContactTitle; + partial void OnContactTitleChanging(global::System.String value); + partial void OnContactTitleChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Address + { + get + { + return _Address; + } + set + { + OnAddressChanging(value); + ReportPropertyChanging("Address"); + _Address = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Address"); + OnAddressChanged(); + } + } + private global::System.String _Address; + partial void OnAddressChanging(global::System.String value); + partial void OnAddressChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String City + { + get + { + return _City; + } + set + { + OnCityChanging(value); + ReportPropertyChanging("City"); + _City = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("City"); + OnCityChanged(); + } + } + private global::System.String _City; + partial void OnCityChanging(global::System.String value); + partial void OnCityChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Region + { + get + { + return _Region; + } + set + { + OnRegionChanging(value); + ReportPropertyChanging("Region"); + _Region = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Region"); + OnRegionChanged(); + } + } + private global::System.String _Region; + partial void OnRegionChanging(global::System.String value); + partial void OnRegionChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String PostalCode + { + get + { + return _PostalCode; + } + set + { + OnPostalCodeChanging(value); + ReportPropertyChanging("PostalCode"); + _PostalCode = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("PostalCode"); + OnPostalCodeChanged(); + } + } + private global::System.String _PostalCode; + partial void OnPostalCodeChanging(global::System.String value); + partial void OnPostalCodeChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Country + { + get + { + return _Country; + } + set + { + OnCountryChanging(value); + ReportPropertyChanging("Country"); + _Country = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Country"); + OnCountryChanged(); + } + } + private global::System.String _Country; + partial void OnCountryChanging(global::System.String value); + partial void OnCountryChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Phone + { + get + { + return _Phone; + } + set + { + OnPhoneChanging(value); + ReportPropertyChanging("Phone"); + _Phone = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Phone"); + OnPhoneChanged(); + } + } + private global::System.String _Phone; + partial void OnPhoneChanging(global::System.String value); + partial void OnPhoneChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String Fax + { + get + { + return _Fax; + } + set + { + OnFaxChanging(value); + ReportPropertyChanging("Fax"); + _Fax = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("Fax"); + OnFaxChanged(); + } + } + private global::System.String _Fax; + partial void OnFaxChanging(global::System.String value); + partial void OnFaxChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.String HomePage + { + get + { + return _HomePage; + } + set + { + OnHomePageChanging(value); + ReportPropertyChanging("HomePage"); + _HomePage = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("HomePage"); + OnHomePageChanged(); + } + } + private global::System.String _HomePage; + partial void OnHomePageChanging(global::System.String value); + partial void OnHomePageChanged(); + + #endregion + + + #region Navigation Properties + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Products_Suppliers", "Products")] + public EntityCollection Products + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.FK_Products_Suppliers", "Products"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.FK_Products_Suppliers", "Products", value); + } + } + } + + #endregion + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="sysdiagram")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class sysdiagram : EntityObject + { + #region Factory Method + + /// + /// Create a new sysdiagram object. + /// + /// Initial value of the name property. + /// Initial value of the principal_id property. + /// Initial value of the diagram_id property. + public static sysdiagram Createsysdiagram(global::System.String name, global::System.Int32 principal_id, global::System.Int32 diagram_id) + { + sysdiagram sysdiagram = new sysdiagram(); + sysdiagram.name = name; + sysdiagram.principal_id = principal_id; + sysdiagram.diagram_id = diagram_id; + return sysdiagram; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String name + { + get + { + return _name; + } + set + { + OnnameChanging(value); + ReportPropertyChanging("name"); + _name = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("name"); + OnnameChanged(); + } + } + private global::System.String _name; + partial void OnnameChanging(global::System.String value); + partial void OnnameChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 principal_id + { + get + { + return _principal_id; + } + set + { + Onprincipal_idChanging(value); + ReportPropertyChanging("principal_id"); + _principal_id = StructuralObject.SetValidValue(value); + ReportPropertyChanged("principal_id"); + Onprincipal_idChanged(); + } + } + private global::System.Int32 _principal_id; + partial void Onprincipal_idChanging(global::System.Int32 value); + partial void Onprincipal_idChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 diagram_id + { + get + { + return _diagram_id; + } + set + { + if (_diagram_id != value) + { + Ondiagram_idChanging(value); + ReportPropertyChanging("diagram_id"); + _diagram_id = StructuralObject.SetValidValue(value); + ReportPropertyChanged("diagram_id"); + Ondiagram_idChanged(); + } + } + } + private global::System.Int32 _diagram_id; + partial void Ondiagram_idChanging(global::System.Int32 value); + partial void Ondiagram_idChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public Nullable version + { + get + { + return _version; + } + set + { + OnversionChanging(value); + ReportPropertyChanging("version"); + _version = StructuralObject.SetValidValue(value); + ReportPropertyChanged("version"); + OnversionChanged(); + } + } + private Nullable _version; + partial void OnversionChanging(Nullable value); + partial void OnversionChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] + [DataMemberAttribute()] + public global::System.Byte[] definition + { + get + { + return StructuralObject.GetValidValue(_definition); + } + set + { + OndefinitionChanging(value); + ReportPropertyChanging("definition"); + _definition = StructuralObject.SetValidValue(value, true); + ReportPropertyChanged("definition"); + OndefinitionChanged(); + } + } + private global::System.Byte[] _definition; + partial void OndefinitionChanging(global::System.Byte[] value); + partial void OndefinitionChanged(); + + #endregion + + + } + + /// + /// No Metadata Documentation available. + /// + [EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Territory")] + [Serializable()] + [DataContractAttribute(IsReference=true)] + public partial class Territory : EntityObject + { + #region Factory Method + + /// + /// Create a new Territory object. + /// + /// Initial value of the TerritoryID property. + /// Initial value of the TerritoryDescription property. + /// Initial value of the RegionID property. + public static Territory CreateTerritory(global::System.String territoryID, global::System.String territoryDescription, global::System.Int32 regionID) + { + Territory territory = new Territory(); + territory.TerritoryID = territoryID; + territory.TerritoryDescription = territoryDescription; + territory.RegionID = regionID; + return territory; + } + + #endregion + + #region Primitive Properties + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String TerritoryID + { + get + { + return _TerritoryID; + } + set + { + if (_TerritoryID != value) + { + OnTerritoryIDChanging(value); + ReportPropertyChanging("TerritoryID"); + _TerritoryID = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("TerritoryID"); + OnTerritoryIDChanged(); + } + } + } + private global::System.String _TerritoryID; + partial void OnTerritoryIDChanging(global::System.String value); + partial void OnTerritoryIDChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.String TerritoryDescription + { + get + { + return _TerritoryDescription; + } + set + { + OnTerritoryDescriptionChanging(value); + ReportPropertyChanging("TerritoryDescription"); + _TerritoryDescription = StructuralObject.SetValidValue(value, false); + ReportPropertyChanged("TerritoryDescription"); + OnTerritoryDescriptionChanged(); + } + } + private global::System.String _TerritoryDescription; + partial void OnTerritoryDescriptionChanging(global::System.String value); + partial void OnTerritoryDescriptionChanged(); + + /// + /// No Metadata Documentation available. + /// + [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] + [DataMemberAttribute()] + public global::System.Int32 RegionID + { + get + { + return _RegionID; + } + set + { + OnRegionIDChanging(value); + ReportPropertyChanging("RegionID"); + _RegionID = StructuralObject.SetValidValue(value); + ReportPropertyChanged("RegionID"); + OnRegionIDChanged(); + } + } + private global::System.Int32 _RegionID; + partial void OnRegionIDChanging(global::System.Int32 value); + partial void OnRegionIDChanged(); + + #endregion + + + #region Navigation Properties + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Territories_Region", "Region")] + public Region Region + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Territories_Region", "Region").Value; + } + set + { + ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Territories_Region", "Region").Value = value; + } + } + /// + /// No Metadata Documentation available. + /// + [BrowsableAttribute(false)] + [DataMemberAttribute()] + public EntityReference RegionReference + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("NorthwindModel.FK_Territories_Region", "Region"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference("NorthwindModel.FK_Territories_Region", "Region", value); + } + } + } + + /// + /// No Metadata Documentation available. + /// + [XmlIgnoreAttribute()] + [SoapIgnoreAttribute()] + [DataMemberAttribute()] + [EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "EmployeeTerritories", "Employees")] + public EntityCollection Employees + { + get + { + return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("NorthwindModel.EmployeeTerritories", "Employees"); + } + set + { + if ((value != null)) + { + ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("NorthwindModel.EmployeeTerritories", "Employees", value); + } + } + } + + #endregion + + } + + #endregion + + +} diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/NorthwindModel.edmx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/NorthwindModel.edmx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1800 @@ + + + + + + + + + + + + + + + + + + + + + + + + SELECT + [Alphabetical list of products].[ProductID] AS [ProductID], + [Alphabetical list of products].[ProductName] AS [ProductName], + [Alphabetical list of products].[SupplierID] AS [SupplierID], + [Alphabetical list of products].[CategoryID] AS [CategoryID], + [Alphabetical list of products].[QuantityPerUnit] AS [QuantityPerUnit], + [Alphabetical list of products].[UnitPrice] AS [UnitPrice], + [Alphabetical list of products].[UnitsInStock] AS [UnitsInStock], + [Alphabetical list of products].[UnitsOnOrder] AS [UnitsOnOrder], + [Alphabetical list of products].[ReorderLevel] AS [ReorderLevel], + [Alphabetical list of products].[Discontinued] AS [Discontinued], + [Alphabetical list of products].[CategoryName] AS [CategoryName] + FROM [dbo].[Alphabetical list of products] AS [Alphabetical list of products] + + + SELECT + [Category Sales for 1997].[CategoryName] AS [CategoryName], + [Category Sales for 1997].[CategorySales] AS [CategorySales] + FROM [dbo].[Category Sales for 1997] AS [Category Sales for 1997] + + + SELECT + [Current Product List].[ProductID] AS [ProductID], + [Current Product List].[ProductName] AS [ProductName] + FROM [dbo].[Current Product List] AS [Current Product List] + + + SELECT + [Customer and Suppliers by City].[City] AS [City], + [Customer and Suppliers by City].[CompanyName] AS [CompanyName], + [Customer and Suppliers by City].[ContactName] AS [ContactName], + [Customer and Suppliers by City].[Relationship] AS [Relationship] + FROM [dbo].[Customer and Suppliers by City] AS [Customer and Suppliers by City] + + + SELECT + [Invoices].[ShipName] AS [ShipName], + [Invoices].[ShipAddress] AS [ShipAddress], + [Invoices].[ShipCity] AS [ShipCity], + [Invoices].[ShipRegion] AS [ShipRegion], + [Invoices].[ShipPostalCode] AS [ShipPostalCode], + [Invoices].[ShipCountry] AS [ShipCountry], + [Invoices].[CustomerID] AS [CustomerID], + [Invoices].[CustomerName] AS [CustomerName], + [Invoices].[Address] AS [Address], + [Invoices].[City] AS [City], + [Invoices].[Region] AS [Region], + [Invoices].[PostalCode] AS [PostalCode], + [Invoices].[Country] AS [Country], + [Invoices].[Salesperson] AS [Salesperson], + [Invoices].[OrderID] AS [OrderID], + [Invoices].[OrderDate] AS [OrderDate], + [Invoices].[RequiredDate] AS [RequiredDate], + [Invoices].[ShippedDate] AS [ShippedDate], + [Invoices].[ShipperName] AS [ShipperName], + [Invoices].[ProductID] AS [ProductID], + [Invoices].[ProductName] AS [ProductName], + [Invoices].[UnitPrice] AS [UnitPrice], + [Invoices].[Quantity] AS [Quantity], + [Invoices].[Discount] AS [Discount], + [Invoices].[ExtendedPrice] AS [ExtendedPrice], + [Invoices].[Freight] AS [Freight] + FROM [dbo].[Invoices] AS [Invoices] + + + SELECT + [Order Details Extended].[OrderID] AS [OrderID], + [Order Details Extended].[ProductID] AS [ProductID], + [Order Details Extended].[ProductName] AS [ProductName], + [Order Details Extended].[UnitPrice] AS [UnitPrice], + [Order Details Extended].[Quantity] AS [Quantity], + [Order Details Extended].[Discount] AS [Discount], + [Order Details Extended].[ExtendedPrice] AS [ExtendedPrice] + FROM [dbo].[Order Details Extended] AS [Order Details Extended] + + + SELECT + [Order Subtotals].[OrderID] AS [OrderID], + [Order Subtotals].[Subtotal] AS [Subtotal] + FROM [dbo].[Order Subtotals] AS [Order Subtotals] + + + SELECT + [Orders Qry].[OrderID] AS [OrderID], + [Orders Qry].[CustomerID] AS [CustomerID], + [Orders Qry].[EmployeeID] AS [EmployeeID], + [Orders Qry].[OrderDate] AS [OrderDate], + [Orders Qry].[RequiredDate] AS [RequiredDate], + [Orders Qry].[ShippedDate] AS [ShippedDate], + [Orders Qry].[ShipVia] AS [ShipVia], + [Orders Qry].[Freight] AS [Freight], + [Orders Qry].[ShipName] AS [ShipName], + [Orders Qry].[ShipAddress] AS [ShipAddress], + [Orders Qry].[ShipCity] AS [ShipCity], + [Orders Qry].[ShipRegion] AS [ShipRegion], + [Orders Qry].[ShipPostalCode] AS [ShipPostalCode], + [Orders Qry].[ShipCountry] AS [ShipCountry], + [Orders Qry].[CompanyName] AS [CompanyName], + [Orders Qry].[Address] AS [Address], + [Orders Qry].[City] AS [City], + [Orders Qry].[Region] AS [Region], + [Orders Qry].[PostalCode] AS [PostalCode], + [Orders Qry].[Country] AS [Country] + FROM [dbo].[Orders Qry] AS [Orders Qry] + + + SELECT + [Product Sales for 1997].[CategoryName] AS [CategoryName], + [Product Sales for 1997].[ProductName] AS [ProductName], + [Product Sales for 1997].[ProductSales] AS [ProductSales] + FROM [dbo].[Product Sales for 1997] AS [Product Sales for 1997] + + + SELECT + [Products Above Average Price].[ProductName] AS [ProductName], + [Products Above Average Price].[UnitPrice] AS [UnitPrice] + FROM [dbo].[Products Above Average Price] AS [Products Above Average Price] + + + SELECT + [Products by Category].[CategoryName] AS [CategoryName], + [Products by Category].[ProductName] AS [ProductName], + [Products by Category].[QuantityPerUnit] AS [QuantityPerUnit], + [Products by Category].[UnitsInStock] AS [UnitsInStock], + [Products by Category].[Discontinued] AS [Discontinued] + FROM [dbo].[Products by Category] AS [Products by Category] + + + SELECT + [Sales by Category].[CategoryID] AS [CategoryID], + [Sales by Category].[CategoryName] AS [CategoryName], + [Sales by Category].[ProductName] AS [ProductName], + [Sales by Category].[ProductSales] AS [ProductSales] + FROM [dbo].[Sales by Category] AS [Sales by Category] + + + SELECT + [Sales Totals by Amount].[SaleAmount] AS [SaleAmount], + [Sales Totals by Amount].[OrderID] AS [OrderID], + [Sales Totals by Amount].[CompanyName] AS [CompanyName], + [Sales Totals by Amount].[ShippedDate] AS [ShippedDate] + FROM [dbo].[Sales Totals by Amount] AS [Sales Totals by Amount] + + + SELECT + [Summary of Sales by Quarter].[ShippedDate] AS [ShippedDate], + [Summary of Sales by Quarter].[OrderID] AS [OrderID], + [Summary of Sales by Quarter].[Subtotal] AS [Subtotal] + FROM [dbo].[Summary of Sales by Quarter] AS [Summary of Sales by Quarter] + + + SELECT + [Summary of Sales by Year].[ShippedDate] AS [ShippedDate], + [Summary of Sales by Year].[OrderID] AS [OrderID], + [Summary of Sales by Year].[Subtotal] AS [Subtotal] + FROM [dbo].[Summary of Sales by Year] AS [Summary of Sales by Year] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("NorthwindDataService")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("NorthwindDataService")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("34ee2431-e447-42f9-8bfb-d8174d9d5090")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/Web.Debug.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/Web.Debug.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/Web.Release.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/Web.Release.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/NorthwindDataService/Web.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/NorthwindDataService/Web.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/ObjectModel/Gender.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/ObjectModel/Gender.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using BLToolkit.Mapping; + +namespace Demo.WebServices.ObjectModel +{ + public enum Gender + { + [MapValue("F")] Female, + [MapValue("M")] Male, + [MapValue("U")] Unknown, + [MapValue("O")] Other + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/ObjectModel/IDataAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/ObjectModel/IDataAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; + +namespace Demo.WebServices.ObjectModel +{ + public interface IDataAccessor + { + Person SelectByKey(int id); + List SelectAll(); + XmlMap SelectMap(); + + int MethodWithOutParams(out string str, out Guid guid); + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/ObjectModel/ObjectModel.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/ObjectModel/ObjectModel.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,135 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6} + Library + Properties + Demo.WebServices.ObjectModel + Demo.WebServices.ObjectModel + v4.0 + 512 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + TRACE;DEBUG;FW3 + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE;FW3 + prompt + 4 + ISO-2 + AllRules.ruleset + + + true + bin\DebugMono\ + TRACE;DEBUG;FW3 + full + AnyCPU + bin\Debug\Demo.WebServices.ObjectModel.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ReleaseMono\ + TRACE;FW3 + true + pdbonly + AnyCPU + bin\Release\Demo.WebServices.ObjectModel.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + ISO-2 + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + + 3.5 + + + + + + + + + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/ObjectModel/Person.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/ObjectModel/Person.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Xml.Serialization; + +using BLToolkit.DataAccess; +using BLToolkit.EditableObjects; +using BLToolkit.Mapping; +using BLToolkit.Validation; + +namespace Demo.WebServices.ObjectModel +{ + [XmlType(AnonymousType = true)] + public abstract class Person: EditableObject + { + [PrimaryKey, MapField("PersonID")] public abstract int Id { get; set; } + [MaxLength(50), Required] public abstract string LastName { get; set; } + [MaxLength(50), Required] public abstract string FirstName { get; set; } + [MaxLength(50)] public abstract string MiddleName { get; set; } + public abstract Gender Gender { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/ObjectModel/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/ObjectModel/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BLToolkit.Demo.ObjectModel")] +[assembly: AssemblyProduct("BLToolkit.Demo")] +[assembly: AssemblyCopyright("\xA9 2002-2012 www.bltoolkit.net")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9ced2775-83ef-4122-916b-9217fd665c24")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/ObjectModel/XmlMap.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/ObjectModel/XmlMap.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +using BLToolkit.TypeBuilder; + +namespace Demo.WebServices.ObjectModel +{ + [Serializable] + public class XmlMap: Dictionary, IXmlSerializable + { + private const string KEY_NAME = "k"; + private const string VALUE_NAME = "v"; + + private static readonly XmlSerializer _keySerializer = new XmlSerializer(KEY_NAME); + private static readonly XmlSerializer _valueSerializer = new XmlSerializer(VALUE_NAME); + + #region IXmlSerializable members + + XmlSchema IXmlSerializable.GetSchema() + { + return null; + } + + void IXmlSerializable.ReadXml(XmlReader reader) + { + if (!reader.ReadToDescendant(KEY_NAME)) + { + reader.Skip(); + return; + } + + do + { + Add(_keySerializer.Deserialize(reader), + _valueSerializer.Deserialize(reader)); + } + while (reader.NodeType != XmlNodeType.EndElement); + + reader.ReadEndElement(); + } + + void IXmlSerializable.WriteXml(XmlWriter writer) + { + foreach (KeyValuePair pair in this) + { + _keySerializer .Serialize(writer, pair.Key); + _valueSerializer.Serialize(writer, pair.Value); + } + } + + #endregion + + private class XmlSerializer + { + private readonly XmlSerializer _instance; + + public XmlSerializer(string elementName) + { + _instance = new XmlSerializer( + TypeFactory.GetType(typeof(T)), new XmlRootAttribute(elementName)); + } + + public void Serialize(XmlWriter writer, T value) + { + _instance.Serialize(writer, value); + } + + public T Deserialize(XmlReader reader) + { + return (T)_instance.Deserialize(reader); + } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Server/PersonService.asmx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Server/PersonService.asmx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1 @@ +<%@ WebService Language="C#" Class="Demo.WebServices.Server.BLToolkitExtension.PersonService" %> diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Server/PersonService.asmx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Server/PersonService.asmx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Web.Services; + +using BLToolkit.DataAccess; + +namespace Demo.WebServices.Server +{ + using ObjectModel; + using WebServices; + + [GenerateWebService("http://tempuri.org/PersonService.asmx")] + [GenerateXmlInclude(typeof(Person))] + public abstract class PersonService : DataAccessor, IDataAccessor + { + [GenerateWebMethod] + public abstract Person SelectByKey(int id); + + [GenerateWebMethod(true)] + public abstract List SelectAll(); + + [GenerateWebMethod, ActionName("SelectAll")] + public abstract XmlMap SelectMap(); + + [WebMethod] + public int MethodWithOutParams(out string str, out Guid guid) + { + str = "string"; + guid = Guid.NewGuid(); + + return 123; + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Server/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Server/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BLToolkit.Demo.Server")] +[assembly: AssemblyProduct("BLToolkit.Demo")] +[assembly: AssemblyCopyright("\xA9 2002-2012 www.bltoolkit.net")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3d5900ae-111a-45be-96b3-d9e4606ca793")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Server/Server.2005.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Server/Server.2005.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,94 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {711A3803-4395-4E92-9B26-DC8DDDF80366} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Demo.WebServices.Server + Demo.WebServices.Server + false + ..\..\..\Source\BLToolkit.snk + OnOutputUpdated + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + PersonService.asmx + + + + + + + + + {F4DF7358-8EE6-49FD-AB13-EA5145058D79} + BLToolkit.2 + + + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6} + ObjectModel.2005 + + + + + + + + + + False + True + 1636 + / + + + False + + + + + + $(SolutionDir)Tools\BLTGen\bin\$(ConfigurationName)\BLTgen.exe $(TargetPath) -D -B:BLToolkit.DataAccess.DataAccessor + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Server/Server.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Server/Server.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,161 @@ + + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {711A3803-4395-4E92-9B26-DC8DDDF80366} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Demo.WebServices.Server + Demo.WebServices.Server + v4.0 + false + ..\..\..\Source\BLToolkit.snk + OnOutputUpdated + + + 4.0 + + + false + + + + + + + true + full + false + bin\ + TRACE;DEBUG;FW3 + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\ + TRACE;FW3 + prompt + 4 + ISO-2 + AllRules.ruleset + + + true + bin\ + TRACE;DEBUG;FW3 + full + AnyCPU + bin\Demo.WebServices.Server.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + bin\ + TRACE;FW3 + true + pdbonly + AnyCPU + bin\Demo.WebServices.Server.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + ISO-2 + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + + + + + + + + + + + + + + + + + + + + Designer + + + + + PersonService.asmx + + + + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + {8F9F4193-9104-4AA6-8E04-91CD9FDEC2E6} + ObjectModel + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + + False + False + 59179 + / + + + False + False + + + False + + + + + + $(SolutionDir)Tools\BLTGen\bin\$(ConfigurationName)\BLTgen.4.exe $(TargetPath) -D -B:BLToolkit.DataAccess.DataAccessor + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Server/Web.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Server/Web.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Server/WebServices/GenerateWebMethodAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Server/WebServices/GenerateWebMethodAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,68 @@ +using System; +using System.EnterpriseServices; +using System.Web.Services; +using BLToolkit.TypeBuilder; + +namespace Demo.WebServices.Server.WebServices +{ + [AttributeUsage(AttributeTargets.Method)] + public class GenerateWebMethodAttribute : GenerateAttributeAttribute + { + /// + /// Initializes a new instance of the class. + /// + public GenerateWebMethodAttribute(): base(typeof(WebMethodAttribute)) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Initializes whether session state is enabled for the XML Web service method. + public GenerateWebMethodAttribute(bool enableSession): base(typeof(WebMethodAttribute), enableSession) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Initializes whether session state is enabled for the XML Web service method. + /// Initializes the transaction support of an XML Web service method. + public GenerateWebMethodAttribute( + bool enableSession, + TransactionOption transactionOption) + : base(typeof(WebMethodAttribute), enableSession, transactionOption) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Initializes whether session state is enabled for the XML Web service method. + /// Initializes the transaction support of an XML Web service method. + /// Initializes the number of seconds the response is cached. + public GenerateWebMethodAttribute( + bool enableSession, + TransactionOption transactionOption, + int cacheDuration) + : base(typeof(WebMethodAttribute), enableSession, transactionOption, cacheDuration) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Initializes whether session state is enabled for the XML Web service method. + /// Initializes the transaction support of an XML Web service method. + /// Initializes the number of seconds the response is cached. + /// Initializes whether the response for this request is buffered. + public GenerateWebMethodAttribute( + bool enableSession, + TransactionOption transactionOption, + int cacheDuration, + bool bufferResponse) + : base(typeof(WebMethodAttribute), enableSession, transactionOption, cacheDuration, bufferResponse) + { + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Server/WebServices/GenerateWebServiceAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Server/WebServices/GenerateWebServiceAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; +using BLToolkit.TypeBuilder; +using System.Web.Services; + +namespace Demo.WebServices.Server.WebServices +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] + public class GenerateWebServiceAttribute : GenerateAttributeAttribute + { + /// + /// Initializes a new instance of the class. + /// + /// The namespace of the web service. + public GenerateWebServiceAttribute(string @namespace): base(typeof(WebServiceAttribute)) + { + this["Namespace"] = @namespace; + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WebServices/Server/WebServices/GenerateXmlIncludeAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WebServices/Server/WebServices/GenerateXmlIncludeAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; +using System.Xml.Serialization; + +using BLToolkit.Reflection; +using BLToolkit.TypeBuilder; + +namespace Demo.WebServices.Server.WebServices +{ + /// + /// Allows the to recognize a type generated + /// by the BLToolkit when it serializes or deserializes an object. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] + public class GenerateXmlIncludeAttribute : GenerateAttributeAttribute + { + /// + /// Initializes a new instance of the class. + /// + /// The of an abstract class to + /// include its BLToolkit extensions. + public GenerateXmlIncludeAttribute(Type type) + : base(typeof(XmlIncludeAbstractAttribute), type) + { + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/App.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/App.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ + + + + + + diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/BLToolkit.Demo.2005.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/BLToolkit.Demo.2005.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,119 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {854749E5-9264-42FF-A576-3B5784C7C14C} + WinExe + Properties + BLToolkit.Demo + BLToolkit.Demo + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + Component + + + EnumSelector.cs + + + Form + + + Form + + + EditPersonForm.cs + + + Form + + + MainForm.cs + + + + + + + + + Designer + EditPersonForm.cs + + + Designer + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {F4DF7358-8EE6-49FD-AB13-EA5145058D79} + BLToolkit.2 + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/BLToolkit.Demo.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/BLToolkit.Demo.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,205 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {854749E5-9264-42FF-A576-3B5784C7C14C} + WinExe + Properties + BLToolkit.Demo + BLToolkit.Demo + + + 3.5 + + + false + v4.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\BLToolkit.Demo.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\BLToolkit.Demo.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + + + + + + + + + + + + + Component + + + EnumSelector.cs + + + Form + + + Form + + + EditPersonForm.cs + + + Form + + + MainForm.cs + + + + + + + + + Designer + EditPersonForm.cs + + + Designer + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/BusinessLogic/DataAccess/AccessorBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/BusinessLogic/DataAccess/AccessorBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +using System; + +using BLToolkit.DataAccess; + +using BLToolkit.Demo.ObjectModel; + +namespace BLToolkit.Demo.BusinessLogic.DataAccess +{ + public abstract class AccessorBase : DataAccessor + where T : BizEntity + where A : DataAccessor + { + public abstract int Insert(T obj); + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/BusinessLogic/DataAccess/PersonAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/BusinessLogic/DataAccess/PersonAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +using System; + +using BLToolkit.Demo.ObjectModel; + +namespace BLToolkit.Demo.BusinessLogic.DataAccess +{ + public abstract class PersonAccessor : AccessorBase + { + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/BusinessLogic/ManagerBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/BusinessLogic/ManagerBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,79 @@ +using System; + +using BLToolkit.DataAccess; +using BLToolkit.EditableObjects; + +using BLToolkit.Demo.ObjectModel; +using BLToolkit.Demo.BusinessLogic.DataAccess; + +namespace BLToolkit.Demo.BusinessLogic +{ + public abstract class ManagerBase + where T : BizEntity + where A : AccessorBase + { + #region Insert, Update, Delete + + public void Insert(T obj) + { + obj.Validate(); + + obj.ID = Accessor.Insert(obj); + + obj.AcceptChanges(); + } + + public void Update(T obj) + { + obj.Validate(); + + Query.Update(obj); + + obj.AcceptChanges(); + } + + public void Delete(T obj) + { + Query.Delete(obj); + } + + public void Delete(int id) + { + Query.DeleteByKey(id); + } + + #endregion + + #region Select + + public EditableList SelectAll() + { + EditableList list = new EditableList(); + + return Query.SelectAll(list); + } + + #endregion + + #region Protected Members + + protected virtual A Accessor + { + get { return AccessorBase.CreateInstance(); } + } + + private SqlQuery _query; + protected virtual SqlQuery Query + { + get + { + if (null == _query) + _query = new SqlQuery(); + + return _query; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/BusinessLogic/PersonManager.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/BusinessLogic/PersonManager.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +using System; + +using BLToolkit.Demo.BusinessLogic.DataAccess; +using BLToolkit.Demo.ObjectModel; + +namespace BLToolkit.Demo.BusinessLogic +{ + public class PersonManager : ManagerBase + { + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Controls/EnumSelector.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Controls/EnumSelector.Designer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +namespace BLToolkit.Demo.Controls +{ + partial class EnumSelector + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Controls/EnumSelector.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Controls/EnumSelector.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,107 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Drawing.Design; + +using BLToolkit.ComponentModel; +using System.Reflection; + +namespace BLToolkit.Demo.Controls +{ + public partial class EnumSelector : GroupBox + { + public EnumSelector() + { + InitializeComponent(); + } + + public EnumSelector(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + + [RefreshProperties(RefreshProperties.Repaint)] + [Category("Data")] + [Bindable(true)] + public object Value + { + get + { + foreach (RadioButton r in _controls.Keys) + if (r.Checked) + return Enum.Parse(_valueType, (string)_controls[r]); + + + return -1; + } + set + { + if (value != null) + { + string s = value.ToString(); + + foreach (DictionaryEntry de in _controls) + { + RadioButton r = (RadioButton)de.Key; + + if (r.Checked != (de.Value.ToString() == s)) + r.Checked = !r.Checked; + } + } + } + } + + const FieldAttributes EnumField = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal; + + private Hashtable _controls = new Hashtable(); + + private Type _valueType; + [RefreshProperties(RefreshProperties.Repaint)] + [DefaultValue(null)] + [Category("Data")] + [TypeConverter(typeof(TypeTypeConverter))] + [Editor(typeof(EnumEditor), typeof(UITypeEditor))] + public Type ValueType + { + get { return _valueType; } + set + { + _valueType = value; + + foreach (Control c in _controls.Keys) + Controls.Remove(c); + + FieldInfo[] fields = _valueType.GetFields(); + + foreach (FieldInfo fi in fields) + { + if ((fi.Attributes & EnumField) == EnumField) + { + RadioButton r = new RadioButton(); + + Controls.Add(r); + _controls.Add(r, fi.Name); + + r.Text = fi.Name; + r.Name = fi.Name + "RadioButton"; + r.TabIndex = _controls.Count; + r.AutoSize = true; + r.Location = new System.Drawing.Point(10, 23 * _controls.Count - 4); + r.UseVisualStyleBackColor = true; + } + } + } + } + + class EnumEditor : ComponentModel.Design.TypeEditor + { + protected override bool FilterTypeList(Type type) + { + return type.IsPublic && type.IsEnum; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Forms/BizEntityForm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Forms/BizEntityForm.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,404 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using Microsoft.Win32; + +using BLToolkit.Validation; +using BLToolkit.Reflection; + +using BLToolkit.Demo.ObjectModel; + +namespace BLToolkit.Demo.Forms +{ + public class BizEntityForm : Form + where F : BizEntityForm, new() + where T : BizEntity + { + #region Static Members + + public static bool Edit(T entity, Action saveAction) + { + T clone = (T)entity.Clone(); + F form = new F(); + + form.SetBizEntity(clone); + form.Init(clone, delegate + { + saveAction(clone); + + clone.CopyTo(entity); + entity.AcceptChanges(); + }); + + return form.ShowDialog() == DialogResult.OK; + } + + public static T EditNew(Action saveAction) + { + T entity = TypeAccessor.CreateInstanceEx(); + F form = new F(); + + form.SetBizEntity(entity); + form.Init(entity, delegate + { + saveAction(entity); + entity.AcceptChanges(); + }); + + return form.ShowDialog() == DialogResult.OK? entity: null; + } + + private void Init(BizEntity entity, SaveHandler saveHandler) + { + if (AcceptButton is Button) + ((Button)AcceptButton).Click += SaveEntity; + + _entity = entity; + _saveHandler = saveHandler; + } + + #endregion + + #region Abstracts + + protected virtual void SetBizEntity(T entity) + { + throw new NotImplementedException(); + } + + #endregion + + #region SaveEntity Handler + + private delegate void SaveHandler(); + + private SaveHandler _saveHandler; + private BizEntity _entity; + + protected void SaveEntity(object sender, EventArgs e) + { + if (_entity.IsDirty) + { + try + { + _entity.Validate(); + + UseWaitCursor = true; + _saveHandler(); + UseWaitCursor = false; + + DialogResult = DialogResult.OK; + Close(); + } + catch (Exception ex) + { + UseWaitCursor = false; + MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + DialogResult = DialogResult.None; + } + } + else + { + DialogResult = DialogResult.Cancel; + Close(); + } + } + + #endregion + + #region Scan Controls + + private static void ForEach(Control control, Hashtable scanedControls, Predicate controlHandler) + { + if (control != null && !scanedControls.ContainsKey(control)) + { + scanedControls.Add(control, control); + + if (controlHandler(control)) + foreach (Control c in control.Controls) + ForEach(c, scanedControls, controlHandler); + } + } + + protected virtual void ScanControls(Predicate controlHandler) + { + ForEach(this, new Hashtable(), controlHandler); + } + + protected virtual void ScanControls(Control control, Predicate controlHandler) + { + ForEach(control, new Hashtable(), controlHandler); + } + + #endregion + + #region OnLoad + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + _toolTip.ToolTipIcon = ToolTipIcon.Warning; + _toolTip.ToolTipTitle = "Validation"; + + try + { + _toolTip.IsBalloon = (int)Registry.GetValue( + @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced", + "EnableBalloonTips", 1) != 0; + } + catch + { + } + + if (!DesignMode) + { + ScanControls(InitBindableControls); + ValidateForm(); + } + } + + #endregion + + #region Binding + + class ControlInfo + { + public ControlInfo(Control control, bool isValidatable, PropertyDescriptor pd) + { + Control = control; + IsValidatable = isValidatable; + PropertyDescriptor = pd; + } + + public Control Control; + public bool IsValidatable; + public PropertyDescriptor PropertyDescriptor; + } + + ToolTip _toolTip = new ToolTip(); + + Dictionary _keyToControl = new Dictionary(); + List _bindableControls = new List(); + + private bool InitBindableControls(Control control) + { + foreach (Binding binding in control.DataBindings) + { + BizEntity item = binding.BindingManagerBase.Current as BizEntity; + + if (item != null) + { + string key = GetBindingKey(item, binding, control); + + if (_keyToControl.ContainsKey(key)) + continue; + + string[] str = null; + PropertyDescriptor pd = null; + + ITypedList typedList = binding.DataSource as ITypedList; + + if (typedList != null) + { + pd = typedList.GetItemProperties(null).Find( + binding.BindingMemberInfo.BindingField, false); + + if (pd != null) + str = Validator.GetErrorMessages(item, pd); + } + + if (str == null) + str = item.GetErrorMessages(binding.BindingMemberInfo.BindingField); + + if (str.Length > 0) + Array.Sort(str); + + ControlInfo ci = new ControlInfo(control, str.Length > 0, pd); + + _bindableControls.Add(ci); + _keyToControl.Add(key, ci); + + if (ci.IsValidatable) + _toolTip.SetToolTip(control, string.Join("\r\n", str)); + + control.LostFocus += ValidateControl; + control.Validated += ValidateControl; + control.EnabledChanged += ValidateControl; + } + } + + return true; + } + + private void ValidateControl(object sender, EventArgs e) + { + Validate((Control)sender, true); + } + + private static string GetBindingKey(BizEntity entity, Binding binding, Control control) + { + return string.Format("{0}.{1}.{2}", + entity.GetHashCode(), binding.BindingMemberInfo.BindingField, control.Name); + } + + protected bool Validate(Control control, bool validateCombines) + { + bool result = true; + + foreach (Binding binding in control.DataBindings) + { + if (binding.BindingManagerBase == null || binding.BindingManagerBase.Count == 0) + continue; + + BizEntity item = binding.BindingManagerBase.Current as BizEntity; + + if (item != null) + { + string key = GetBindingKey(item, binding, control); + + if (!_keyToControl.ContainsKey(key)) + continue; + + ControlInfo ci = _keyToControl[key]; + string fieldName = binding.BindingMemberInfo.BindingField; + + bool isValid = ci.IsValidatable? + ci.PropertyDescriptor != null? + Validator.IsValid(item, ci.PropertyDescriptor): + item.IsValid(fieldName): + true; + + if (isValid) + { + if (item.IsDirtyMember(fieldName)) + SetDirty(control); + else + ResetControl(control); + } + else + { + SetInvalid(control); + + result = false; + } + + /* + if (validateCombines) + { + PropertyInfo pi = + item.GetType().GetProperty(binding.BindingMemberInfo.BindingField); + + if (pi != null) + { + object[] attrs = pi.GetCustomAttributes(typeof(CombineAttribute), true); + + foreach (CombineAttribute a in attrs) + { + string key = GetBindingKey(item, binding, control); + string key = item.GetHashCode() + "." + a.Name; + + ControlInfo ci = (ControlInfo)nameToControl[key]; + + if (ci != null) + result = Validate(ci.Control, false) && result; + } + } + } + */ + } + } + + return result; + } + + Dictionary _modifiedControls = new Dictionary(); + Dictionary _originalColors = new Dictionary(); + + protected virtual void SetInvalid(Control control) + { + if (control.Enabled == false) + return; + + if (_modifiedControls.ContainsKey(control) == false) + _modifiedControls.Add(control, control); + + if (_originalColors.ContainsKey(control) == false) + _originalColors.Add(control, control.BackColor); + + Color color = Modify((Color)_originalColors[control], 45, 0, 0); + + if (color != control.BackColor) + control.BackColor = color; + } + + protected virtual void SetDirty(Control control) + { + if (control.Enabled == false) + return; + + if (_modifiedControls.ContainsKey(control) == false) + _modifiedControls.Add(control, control); + + if (_originalColors.ContainsKey(control) == false) + _originalColors.Add(control, control.BackColor); + + Color color = Modify((Color)_originalColors[control], 50, 50, -15); + + if (color != control.BackColor) + control.BackColor = color; + } + + protected virtual void ResetControl(Control control) + { + if (_modifiedControls.ContainsKey(control)) + { + _modifiedControls.Remove(control); + + if (_originalColors.ContainsKey(control)) + { + control.BackColor = control.Enabled? + (Color)_originalColors[control]: + Color.FromKnownColor(KnownColor.Control); + } + } + } + + public virtual bool ValidateForm() + { + bool isValid = true; + + foreach (ControlInfo ci in _bindableControls) + isValid = Validate(ci.Control, false) && isValid; + + return isValid; + } + + public static Color Modify(Color original, int dr, int dg, int db) + { + int r = original.R + dr; + int g = original.G + dg; + int b = original.B + db; + + if (r > 255 || g > 255 || b > 255) + { + int d = Math.Max(r, Math.Max(g, b)) - 255; + + r -= d; + g -= d; + b -= d; + } + + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + + return Color.FromArgb(r, g, b); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Forms/EditPersonForm.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Forms/EditPersonForm.Designer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,176 @@ +namespace BLToolkit.Demo.Forms +{ + partial class EditPersonForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.firstNameTextBox = new System.Windows.Forms.TextBox(); + this.personBinder = new BLToolkit.ComponentModel.ObjectBinder(this.components); + this.firstNameLabel = new System.Windows.Forms.Label(); + this.middleNameLabel = new System.Windows.Forms.Label(); + this.middleNameTextBox = new System.Windows.Forms.TextBox(); + this.lastNameLabel = new System.Windows.Forms.Label(); + this.lastNameTextBox = new System.Windows.Forms.TextBox(); + this.okButton = new System.Windows.Forms.Button(); + this.cancelButton = new System.Windows.Forms.Button(); + this.genderSelector = new BLToolkit.Demo.Controls.EnumSelector(this.components); + this.SuspendLayout(); + // + // firstNameTextBox + // + this.firstNameTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.personBinder, "FirstName", true)); + this.firstNameTextBox.Location = new System.Drawing.Point(90, 12); + this.firstNameTextBox.Name = "firstNameTextBox"; + this.firstNameTextBox.Size = new System.Drawing.Size(160, 20); + this.firstNameTextBox.TabIndex = 2; + // + // personBinder + // + this.personBinder.IsNull = null; + this.personBinder.ItemType = typeof(BLToolkit.Demo.ObjectModel.Person); + this.personBinder.ObjectViewType = typeof(BLToolkit.Demo.Forms.ObjectViews.PersonView); + // + // firstNameLabel + // + this.firstNameLabel.AutoSize = true; + this.firstNameLabel.Location = new System.Drawing.Point(12, 15); + this.firstNameLabel.Name = "firstNameLabel"; + this.firstNameLabel.Size = new System.Drawing.Size(60, 13); + this.firstNameLabel.TabIndex = 1; + this.firstNameLabel.Text = "First Name:"; + // + // middleNameLabel + // + this.middleNameLabel.AutoSize = true; + this.middleNameLabel.Location = new System.Drawing.Point(12, 47); + this.middleNameLabel.Name = "middleNameLabel"; + this.middleNameLabel.Size = new System.Drawing.Size(72, 13); + this.middleNameLabel.TabIndex = 3; + this.middleNameLabel.Text = "Middle Name:"; + // + // middleNameTextBox + // + this.middleNameTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.personBinder, "MiddleName", true)); + this.middleNameTextBox.Location = new System.Drawing.Point(90, 44); + this.middleNameTextBox.Name = "middleNameTextBox"; + this.middleNameTextBox.Size = new System.Drawing.Size(160, 20); + this.middleNameTextBox.TabIndex = 4; + // + // lastNameLabel + // + this.lastNameLabel.AutoSize = true; + this.lastNameLabel.Location = new System.Drawing.Point(12, 80); + this.lastNameLabel.Name = "lastNameLabel"; + this.lastNameLabel.Size = new System.Drawing.Size(61, 13); + this.lastNameLabel.TabIndex = 5; + this.lastNameLabel.Text = "Last Name:"; + // + // lastNameTextBox + // + this.lastNameTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.personBinder, "LastName", true)); + this.lastNameTextBox.Location = new System.Drawing.Point(90, 77); + this.lastNameTextBox.Name = "lastNameTextBox"; + this.lastNameTextBox.Size = new System.Drawing.Size(160, 20); + this.lastNameTextBox.TabIndex = 6; + // + // okButton + // + this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; + this.okButton.Location = new System.Drawing.Point(33, 235); + this.okButton.Name = "okButton"; + this.okButton.Size = new System.Drawing.Size(75, 23); + this.okButton.TabIndex = 100; + this.okButton.Text = "Save"; + this.okButton.UseVisualStyleBackColor = true; + // + // cancelButton + // + this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.cancelButton.Location = new System.Drawing.Point(157, 235); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 101; + this.cancelButton.Text = "Cancel"; + this.cancelButton.UseVisualStyleBackColor = true; + // + // genderSelector + // + this.genderSelector.DataBindings.Add(new System.Windows.Forms.Binding("Value", this.personBinder, "Gender", true)); + this.genderSelector.Location = new System.Drawing.Point(90, 103); + this.genderSelector.Name = "genderSelector"; + this.genderSelector.Size = new System.Drawing.Size(102, 113); + this.genderSelector.TabIndex = 7; + this.genderSelector.TabStop = false; + this.genderSelector.Text = "Gender"; + this.genderSelector.Value = -1; + this.genderSelector.ValueType = typeof(BLToolkit.Demo.ObjectModel.Gender); + // + // EditPersonForm + // + this.AcceptButton = this.okButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.cancelButton; + this.ClientSize = new System.Drawing.Size(269, 268); + this.Controls.Add(this.cancelButton); + this.Controls.Add(this.okButton); + this.Controls.Add(this.genderSelector); + this.Controls.Add(this.lastNameLabel); + this.Controls.Add(this.middleNameLabel); + this.Controls.Add(this.firstNameLabel); + this.Controls.Add(this.lastNameTextBox); + this.Controls.Add(this.middleNameTextBox); + this.Controls.Add(this.firstNameTextBox); + this.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.personBinder, "FormTitle", true)); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "EditPersonForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Edit Person"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private BLToolkit.ComponentModel.ObjectBinder personBinder; + private System.Windows.Forms.TextBox firstNameTextBox; + private System.Windows.Forms.Label firstNameLabel; + private System.Windows.Forms.Label middleNameLabel; + private System.Windows.Forms.TextBox middleNameTextBox; + private System.Windows.Forms.Label lastNameLabel; + private System.Windows.Forms.TextBox lastNameTextBox; + private System.Windows.Forms.Button okButton; + private System.Windows.Forms.Button cancelButton; + private BLToolkit.Demo.Controls.EnumSelector genderSelector; + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Forms/EditPersonForm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Forms/EditPersonForm.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ +using System; + +using BLToolkit.Demo.ObjectModel; + +namespace BLToolkit.Demo.Forms +{ + public partial class EditPersonForm : EditPersonFormBase + { + public EditPersonForm() + { + InitializeComponent(); + } + + protected override void SetBizEntity(Person person) + { + personBinder.Object = person; + } + } + + // This additional inheritance is required to avoid a WinForms bug, + // which does not allow using generic classes as base classes for forms and uer controls. + // + public class EditPersonFormBase : BizEntityForm {} +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Forms/EditPersonForm.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Forms/EditPersonForm.resx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 17, 17 + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Forms/MainForm.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Forms/MainForm.Designer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,319 @@ +namespace BLToolkit.Demo.Forms +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + this.personGridView = new System.Windows.Forms.DataGridView(); + this.toolStripContainer = new System.Windows.Forms.ToolStripContainer(); + this.menu = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.newMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.editMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.deleteMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.tool = new System.Windows.Forms.ToolStrip(); + this.newToolStripButton = new System.Windows.Forms.ToolStripButton(); + this.editToolStripButton = new System.Windows.Forms.ToolStripButton(); + this.deleteToolStripButton = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); + this.helpToolStripButton = new System.Windows.Forms.ToolStripButton(); + this.iDDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.fullNameDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.genderDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.personBinder = new BLToolkit.ComponentModel.ObjectBinder(this.components); + ((System.ComponentModel.ISupportInitialize)(this.personGridView)).BeginInit(); + this.toolStripContainer.ContentPanel.SuspendLayout(); + this.toolStripContainer.TopToolStripPanel.SuspendLayout(); + this.toolStripContainer.SuspendLayout(); + this.menu.SuspendLayout(); + this.tool.SuspendLayout(); + this.SuspendLayout(); + // + // personGridView + // + this.personGridView.AllowUserToOrderColumns = true; + this.personGridView.AutoGenerateColumns = false; + this.personGridView.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.personGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.personGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.iDDataGridViewTextBoxColumn, + this.fullNameDataGridViewTextBoxColumn, + this.genderDataGridViewTextBoxColumn}); + this.personGridView.DataSource = this.personBinder; + this.personGridView.Dock = System.Windows.Forms.DockStyle.Fill; + this.personGridView.Location = new System.Drawing.Point(0, 0); + this.personGridView.Name = "personGridView"; + this.personGridView.Size = new System.Drawing.Size(615, 344); + this.personGridView.TabIndex = 0; + this.personGridView.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.personGridView_CellDoubleClick); + // + // toolStripContainer + // + // + // toolStripContainer.ContentPanel + // + this.toolStripContainer.ContentPanel.Controls.Add(this.personGridView); + this.toolStripContainer.ContentPanel.Size = new System.Drawing.Size(615, 344); + this.toolStripContainer.Dock = System.Windows.Forms.DockStyle.Fill; + this.toolStripContainer.Location = new System.Drawing.Point(0, 0); + this.toolStripContainer.Name = "toolStripContainer"; + this.toolStripContainer.Size = new System.Drawing.Size(615, 393); + this.toolStripContainer.TabIndex = 2; + this.toolStripContainer.Text = "toolStripContainer1"; + // + // toolStripContainer.TopToolStripPanel + // + this.toolStripContainer.TopToolStripPanel.Controls.Add(this.menu); + this.toolStripContainer.TopToolStripPanel.Controls.Add(this.tool); + // + // menu + // + this.menu.Dock = System.Windows.Forms.DockStyle.None; + this.menu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.editToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menu.Location = new System.Drawing.Point(0, 0); + this.menu.Name = "menu"; + this.menu.Size = new System.Drawing.Size(615, 24); + this.menu.TabIndex = 0; + this.menu.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.exitMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(40, 20); + this.fileToolStripMenuItem.Text = "&File"; + // + // exitMenuItem + // + this.exitMenuItem.Name = "exitMenuItem"; + this.exitMenuItem.Size = new System.Drawing.Size(109, 22); + this.exitMenuItem.Text = "E&xit"; + this.exitMenuItem.Click += new System.EventHandler(this.exit_Click); + // + // editToolStripMenuItem + // + this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.newMenuItem, + this.editMenuItem, + this.deleteMenuItem}); + this.editToolStripMenuItem.Name = "editToolStripMenuItem"; + this.editToolStripMenuItem.Size = new System.Drawing.Size(41, 20); + this.editToolStripMenuItem.Text = "&Edit"; + // + // newMenuItem + // + this.newMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("newMenuItem.Image"))); + this.newMenuItem.Name = "newMenuItem"; + this.newMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N))); + this.newMenuItem.Size = new System.Drawing.Size(158, 22); + this.newMenuItem.Text = "&New"; + this.newMenuItem.Click += new System.EventHandler(this.new_Click); + // + // editMenuItem + // + this.editMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("editMenuItem.Image"))); + this.editMenuItem.Name = "editMenuItem"; + this.editMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.E))); + this.editMenuItem.Size = new System.Drawing.Size(158, 22); + this.editMenuItem.Text = "&Edit"; + this.editMenuItem.Click += new System.EventHandler(this.edit_Click); + // + // deleteMenuItem + // + this.deleteMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("deleteMenuItem.Image"))); + this.deleteMenuItem.Name = "deleteMenuItem"; + this.deleteMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Delete; + this.deleteMenuItem.Size = new System.Drawing.Size(158, 22); + this.deleteMenuItem.Text = "&Delete"; + this.deleteMenuItem.Click += new System.EventHandler(this.delete_Click); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.aboutToolStripMenuItem}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(45, 20); + this.helpToolStripMenuItem.Text = "&Help"; + // + // aboutToolStripMenuItem + // + this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; + this.aboutToolStripMenuItem.Size = new System.Drawing.Size(134, 22); + this.aboutToolStripMenuItem.Text = "&About"; + // + // tool + // + this.tool.Dock = System.Windows.Forms.DockStyle.None; + this.tool.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.newToolStripButton, + this.editToolStripButton, + this.deleteToolStripButton, + this.toolStripSeparator7, + this.helpToolStripButton}); + this.tool.Location = new System.Drawing.Point(3, 24); + this.tool.Name = "tool"; + this.tool.Size = new System.Drawing.Size(110, 25); + this.tool.TabIndex = 1; + this.tool.Text = "toolStrip1"; + // + // newToolStripButton + // + this.newToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.newToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("newToolStripButton.Image"))); + this.newToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; + this.newToolStripButton.Name = "newToolStripButton"; + this.newToolStripButton.Size = new System.Drawing.Size(23, 22); + this.newToolStripButton.Text = "&New"; + this.newToolStripButton.Click += new System.EventHandler(this.new_Click); + // + // editToolStripButton + // + this.editToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.editToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("editToolStripButton.Image"))); + this.editToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; + this.editToolStripButton.Name = "editToolStripButton"; + this.editToolStripButton.Size = new System.Drawing.Size(23, 22); + this.editToolStripButton.Text = "&Edit"; + this.editToolStripButton.Click += new System.EventHandler(this.edit_Click); + // + // deleteToolStripButton + // + this.deleteToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.deleteToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("deleteToolStripButton.Image"))); + this.deleteToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; + this.deleteToolStripButton.Name = "deleteToolStripButton"; + this.deleteToolStripButton.Size = new System.Drawing.Size(23, 22); + this.deleteToolStripButton.Text = "&Delete"; + this.deleteToolStripButton.Click += new System.EventHandler(this.delete_Click); + // + // toolStripSeparator7 + // + this.toolStripSeparator7.Name = "toolStripSeparator7"; + this.toolStripSeparator7.Size = new System.Drawing.Size(6, 25); + // + // helpToolStripButton + // + this.helpToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.helpToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("helpToolStripButton.Image"))); + this.helpToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; + this.helpToolStripButton.Name = "helpToolStripButton"; + this.helpToolStripButton.Size = new System.Drawing.Size(23, 22); + this.helpToolStripButton.Text = "He&lp"; + // + // iDDataGridViewTextBoxColumn + // + this.iDDataGridViewTextBoxColumn.DataPropertyName = "ID"; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleRight; + dataGridViewCellStyle1.Padding = new System.Windows.Forms.Padding(0, 0, 5, 0); + this.iDDataGridViewTextBoxColumn.DefaultCellStyle = dataGridViewCellStyle1; + this.iDDataGridViewTextBoxColumn.HeaderText = "ID"; + this.iDDataGridViewTextBoxColumn.MinimumWidth = 20; + this.iDDataGridViewTextBoxColumn.Name = "iDDataGridViewTextBoxColumn"; + // + // fullNameDataGridViewTextBoxColumn + // + this.fullNameDataGridViewTextBoxColumn.DataPropertyName = "FullName"; + this.fullNameDataGridViewTextBoxColumn.HeaderText = "Name"; + this.fullNameDataGridViewTextBoxColumn.Name = "fullNameDataGridViewTextBoxColumn"; + this.fullNameDataGridViewTextBoxColumn.ReadOnly = true; + this.fullNameDataGridViewTextBoxColumn.Width = 250; + // + // genderDataGridViewTextBoxColumn + // + this.genderDataGridViewTextBoxColumn.DataPropertyName = "Gender"; + this.genderDataGridViewTextBoxColumn.FillWeight = 200F; + this.genderDataGridViewTextBoxColumn.HeaderText = "Gender"; + this.genderDataGridViewTextBoxColumn.Name = "genderDataGridViewTextBoxColumn"; + // + // personBinder + // + this.personBinder.AllowEdit = false; + this.personBinder.AllowNew = false; + this.personBinder.AllowRemove = false; + this.personBinder.IsNull = null; + this.personBinder.ItemType = typeof(BLToolkit.Demo.ObjectModel.Person); + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(615, 393); + this.Controls.Add(this.toolStripContainer); + this.MainMenuStrip = this.menu; + this.Name = "MainForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Business Logic Toolkit Demo"; + ((System.ComponentModel.ISupportInitialize)(this.personGridView)).EndInit(); + this.toolStripContainer.ContentPanel.ResumeLayout(false); + this.toolStripContainer.TopToolStripPanel.ResumeLayout(false); + this.toolStripContainer.TopToolStripPanel.PerformLayout(); + this.toolStripContainer.ResumeLayout(false); + this.toolStripContainer.PerformLayout(); + this.menu.ResumeLayout(false); + this.menu.PerformLayout(); + this.tool.ResumeLayout(false); + this.tool.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private BLToolkit.ComponentModel.ObjectBinder personBinder; + private System.Windows.Forms.DataGridView personGridView; + private System.Windows.Forms.ToolStripContainer toolStripContainer; + private System.Windows.Forms.MenuStrip menu; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitMenuItem; + private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; + private System.Windows.Forms.ToolStrip tool; + private System.Windows.Forms.ToolStripButton newToolStripButton; + private System.Windows.Forms.ToolStripButton editToolStripButton; + private System.Windows.Forms.ToolStripButton deleteToolStripButton; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; + private System.Windows.Forms.ToolStripButton helpToolStripButton; + private System.Windows.Forms.ToolStripMenuItem deleteMenuItem; + private System.Windows.Forms.ToolStripMenuItem editMenuItem; + private System.Windows.Forms.ToolStripMenuItem newMenuItem; + private System.Windows.Forms.DataGridViewTextBoxColumn iDDataGridViewTextBoxColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn fullNameDataGridViewTextBoxColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn genderDataGridViewTextBoxColumn; + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Forms/MainForm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Forms/MainForm.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,77 @@ +using System; +using System.Windows.Forms; + +using BLToolkit.Demo.ObjectModel; +using BLToolkit.Demo.BusinessLogic; + +namespace BLToolkit.Demo.Forms +{ + public partial class MainForm : Form + { + public MainForm() + { + InitializeComponent(); + + personBinder.List = new PersonManager().SelectAll(); + } + + private void Edit(Person person) + { + EditPersonForm.Edit(person, delegate(Person p) + { + new PersonManager().Update(p); + }); + } + + private void personGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e) + { + DataGridViewRow row = personGridView.Rows[e.RowIndex]; + + Edit((Person)row.DataBoundItem); + } + + private void edit_Click(object sender, EventArgs e) + { + if (personGridView.CurrentRow != null) + Edit((Person)personGridView.CurrentRow.DataBoundItem); + } + + private void new_Click(object sender, EventArgs e) + { + Person person = EditPersonForm.EditNew(delegate(Person p) + { + new PersonManager().Insert(p); + }); + + if (person != null) + personBinder.List.Add(person); + } + + private void delete_Click(object sender, EventArgs e) + { + if (personGridView.CurrentRow != null) + { + Person person = (Person)personGridView.CurrentRow.DataBoundItem; + + try + { + UseWaitCursor = true; + new PersonManager().Delete(person); + UseWaitCursor = false; + + personBinder.List.Remove(person); + } + catch (Exception ex) + { + UseWaitCursor = false; + MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void exit_Click(object sender, EventArgs e) + { + Close(); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Forms/MainForm.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Forms/MainForm.resx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 146, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAeBJREFUOE+dk81L + G1EUxW/+s1IqFOzOXRciLrrR0FAohtSYaNEoxS9cWGpSUBcqoS2BiNGq0ahRtLqRGsIkY1sKJkRFMdZk + ZpLT+16MMU7TFi8c7puB+zvnvTdjIa7etyGIruuGaKSVu1Z6zms6pX4maPqd0yJf3C0B+FvZuqbQMRDA + wyfN0uifgGKxiAJLM4rI6wUIQPzHpYQ8qG8yQzyjc6YAAqIXKgABKcuUwD0UqAnIcYJs3sBpNo9vqTPY + XO8Ri8WqU7gHP0nAl71D7OweIrqtYiWqYmFdRXBVxYdlFX7W6S8D1nZvbYCILffP0XXev3AX55AzCrji + 9QkDWtvHzADXQCnBykYCYdbSuoL5iIJgWMG+kgGNEGiY1U8Y94fNAEefXwLWNhVEWMsbCuJqBgeJTAkw + SBi+agT1ET7ObZkBds+MBIjh1aiCRU4QS/LgtSu9IfRfPAW95hSdLCfrdtnckxLweU3BAivE8b+yu4gs + nMVwz3EDXn1/DLtaB7JTdYrnrgkJmI0kr5XA7kEa5GGn7pKrGCYHr1+ybHcAz9rGJCCd1W6UutBwxDrP + GTJyW/IR6AXBN7Mk3au+hRa+GmuHj+WtyOlFK0ucetmVrDVuQZxHmfq//Y8/1X1e/gYma0jabNkatwAA + AABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAjBJREFUOE+dk99P + klEYx4E7b/obuuiqVVubF11UF6x10VUXWZvXzogi8go1ClotaLksc/FTWwkZK9eciBKrIYTNAketlODl + tRhjwEzLpOB9gW/nHHMOX9Zaz/bds3POns/5nuecI5eRMFunQbMoVmmSCZtZ2BhXBFHWoijJTPoOOZvY + HhTwt7h2dwJx/wwiyv0Y3tHCNmuI7YB6vY4akVCtoyLWMBfnwdv6AJ0SiWN70a+QN0JMlimJAQoRaxQi + 4lHEzdZLA93gDu2EUSFDMBjcghhvjzcFUBdPV+/AXG2Da8YOXyCGPs15VtwI6H/GANH5JbyNLWH2DY+P + nwrwF8dg/tkOCzpwJqnEYVMrfC9mG4tpM4x/ANQ2Oz+xzpXf4erKCTiggo47jgPDu+DjpjB43ycFGG5t + OAhGOITneCxkUzBkTmEIaui/tOGgazcGXzmxVq7irN4hBfTeeMIA4dcpfFjMYTRugxWduL7cjqNj+3Dl + pQnRRBHFkkgAdimg2+RhgBABJNMFzAce4+REK45490Dr7cL71DJGAxzy6wRw0SYFXDCOMEAgnMJiuogu + jRb3bg7AHwsjupCHezoJt59D7ocAdW8TgNbwkAEmQ2kml2cS9gfj8IZS8JCd3c85jBBlvgtQ9VilDjp1 + DgYorAtMfGEFiUwe2W+/kFsTkCWFn1crSH4t43SPRQqgndVcHiJybumSE+eI6BqVmjRPRc7f9BboW9h8 + Xf+am/7K/5n8DcuiWeO3KOM2AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAF1JREFUOE9jYBgs + 4D/QITBMjJtAalEAsgEYkkgq8VpCyBCiXYjNO0RrhrkW3TX4vIUzzEgNWLyBSpILKAoDfM4mGJDE+Bmn + VwilAeQAwmoIMbYTTOKkhDQpavFbDABDWTnHlh+ydwAAAABJRU5ErkJggg== + + + + 266, 17 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAeBJREFUOE+dk81L + G1EUxW/+s1IqFOzOXRciLrrR0FAohtSYaNEoxS9cWGpSUBcqoS2BiNGq0ahRtLqRGsIkY1sKJkRFMdZk + ZpLT+16MMU7TFi8c7puB+zvnvTdjIa7etyGIruuGaKSVu1Z6zms6pX4maPqd0yJf3C0B+FvZuqbQMRDA + wyfN0uifgGKxiAJLM4rI6wUIQPzHpYQ8qG8yQzyjc6YAAqIXKgABKcuUwD0UqAnIcYJs3sBpNo9vqTPY + XO8Ri8WqU7gHP0nAl71D7OweIrqtYiWqYmFdRXBVxYdlFX7W6S8D1nZvbYCILffP0XXev3AX55AzCrji + 9QkDWtvHzADXQCnBykYCYdbSuoL5iIJgWMG+kgGNEGiY1U8Y94fNAEefXwLWNhVEWMsbCuJqBgeJTAkw + SBi+agT1ET7ObZkBds+MBIjh1aiCRU4QS/LgtSu9IfRfPAW95hSdLCfrdtnckxLweU3BAivE8b+yu4gs + nMVwz3EDXn1/DLtaB7JTdYrnrgkJmI0kr5XA7kEa5GGn7pKrGCYHr1+ybHcAz9rGJCCd1W6UutBwxDrP + GTJyW/IR6AXBN7Mk3au+hRa+GmuHj+WtyOlFK0ucetmVrDVuQZxHmfq//Y8/1X1e/gYma0jabNkatwAA + AABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAjBJREFUOE+dk99P + klEYx4E7b/obuuiqVVubF11UF6x10VUXWZvXzogi8go1ClotaLksc/FTWwkZK9eciBKrIYTNAketlODl + tRhjwEzLpOB9gW/nHHMOX9Zaz/bds3POns/5nuecI5eRMFunQbMoVmmSCZtZ2BhXBFHWoijJTPoOOZvY + HhTwt7h2dwJx/wwiyv0Y3tHCNmuI7YB6vY4akVCtoyLWMBfnwdv6AJ0SiWN70a+QN0JMlimJAQoRaxQi + 4lHEzdZLA93gDu2EUSFDMBjcghhvjzcFUBdPV+/AXG2Da8YOXyCGPs15VtwI6H/GANH5JbyNLWH2DY+P + nwrwF8dg/tkOCzpwJqnEYVMrfC9mG4tpM4x/ANQ2Oz+xzpXf4erKCTiggo47jgPDu+DjpjB43ycFGG5t + OAhGOITneCxkUzBkTmEIaui/tOGgazcGXzmxVq7irN4hBfTeeMIA4dcpfFjMYTRugxWduL7cjqNj+3Dl + pQnRRBHFkkgAdimg2+RhgBABJNMFzAce4+REK45490Dr7cL71DJGAxzy6wRw0SYFXDCOMEAgnMJiuogu + jRb3bg7AHwsjupCHezoJt59D7ocAdW8TgNbwkAEmQ2kml2cS9gfj8IZS8JCd3c85jBBlvgtQ9VilDjp1 + DgYorAtMfGEFiUwe2W+/kFsTkCWFn1crSH4t43SPRQqgndVcHiJybumSE+eI6BqVmjRPRc7f9BboW9h8 + Xf+am/7K/5n8DcuiWeO3KOM2AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAF1JREFUOE9jYBgs + 4D/QITBMjJtAalEAsgEYkkgq8VpCyBCiXYjNO0RrhrkW3TX4vIUzzEgNWLyBSpILKAoDfM4mGJDE+Bmn + VwilAeQAwmoIMbYTTOKkhDQpavFbDABDWTnHlh+ydwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAhhJREFUOE+1U09r + E0EU70fIR9iPUBQ8eMrR46IN5JhCDz2oBA8SBHEpCMFgG5GiwdJdq2Ijqe6ldo3Wrmhri0gXazW2YbMt + UdNmm45ulf7R/HwzU1hLIzn54LFvhvn9eW9nOjr+R0wvBLhTXEf6bgV9w0sYLJQx/uoz2mq9c7eRn2pA + L67Bq+/i29YeWLBL9Q6u5ktI6w6Kr1dbE3HwA3sT/o8mbAfQRgE1LZPXtsPgbjZxaXAG4y/Kh0m48sbP + JgwbiKYAwwLYNkR4DEje5HsMFSI5l3l2kGD6/RYezzeEMgfzwzzMWSCRlV9OFk0xqhl06wNy+Tchyb2n + dXxhv4TVaFLazppAJ9VKL0MySxYoVI0hkXaw5AbovjAWEmTur4qBqZoEdfbKVCgTBObqdolBUW0ocRs1 + P8Cx2PWQ4PJtl6a9J+xLIB1OMHIilU2b1gSMqCZ9TdTq33FEHQgJcg8rWPF3qHcJVOKeyOyoJIioDqUk + UFM2SuUqus4YIcHEzFdYji8GxIGROAc41JJHc6E1B58wRRqWhzFrEVduTR78E5mRBSz7v0l1H0AgXgsH + +2DNcPBp3cep0/rhezA5V0Vfbg5ug+4CqaiaI/rmyWu+t1zdQIysDxdmW9/GiZcVnO+fgvHkI+YXV7BG + 067VA9Ezt91Fyvq/wH8/lKHCW/RcfITj8Rs4evIaYmdHkBl63v4xtX1tLQ78AZ3a8qxOv4hDAAAAAElF + TkSuQmCC + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Forms/ObjectViews/PersonView.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Forms/ObjectViews/PersonView.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,27 @@ +using System; + +using BLToolkit.ComponentModel; + +using BLToolkit.Demo.ObjectModel; + +namespace BLToolkit.Demo.Forms.ObjectViews +{ + public class PersonView : IObjectView + { + #region IObjectView Members + + private Person _person; + object IObjectView.Object + { + get { return _person; } + set { _person = (Person)value; } + } + + #endregion + + public string FormTitle + { + get { return _person.ID > 0? _person.FullName: "New Person"; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/ObjectModel/BizEntity.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/ObjectModel/BizEntity.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,32 @@ +using System; + +using BLToolkit.DataAccess; +using BLToolkit.EditableObjects; +using BLToolkit.Mapping; +using BLToolkit.Reflection; + +namespace BLToolkit.Demo.ObjectModel +{ + public abstract class BizEntity : EditableObject + { + [PrimaryKey(0), NonUpdatable] + public abstract int ID { get; protected internal set; } + + public virtual BizEntity CopyTo(BizEntity obj) + { + Map.ObjectToObject(this, obj); + + return obj; + } + + public virtual BizEntity Clone() + { + BizEntity obj = (BizEntity)TypeAccessor.CreateInstanceEx(GetType()); + + CopyTo(obj); + obj.AcceptChanges(); + + return obj; + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/ObjectModel/Gender.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/ObjectModel/Gender.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,14 @@ +using System; + +using BLToolkit.Mapping; + +namespace BLToolkit.Demo.ObjectModel +{ + public enum Gender + { + [MapValue("F")] Female, + [MapValue("M")] Male, + [MapValue("U")] Unknown, + [MapValue("O")] Other + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/ObjectModel/Person.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/ObjectModel/Person.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,27 @@ +using System; + +using BLToolkit.Mapping; +using BLToolkit.Validation; + +namespace BLToolkit.Demo.ObjectModel +{ + [MapField("PersonID", "ID")] + public abstract class Person : BizEntity + { + [MaxLength(50), Required] public abstract string LastName { get; set; } + [MaxLength(50), Required] public abstract string FirstName { get; set; } + [MaxLength(50)] public abstract string MiddleName { get; set; } + public abstract Gender Gender { get; set; } + + [MapIgnore] + public string FullName + { + get + { + return string.Format( + string.IsNullOrEmpty(MiddleName)? "{2}, {0}": "{2}, {0} {1}.", + FirstName, MiddleName, LastName); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Program.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Program.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using System; +using System.Windows.Forms; + +using BLToolkit.Demo.Forms; + +namespace BLToolkit.Demo +{ + static class Program + { + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + MainForm form = new MainForm(); + + ToolStripManager.LoadSettings(form, "BLToolkit.Demo"); + + form.FormClosing += delegate + { + ToolStripManager.SaveSettings(form, "BLToolkit.Demo"); + }; + + Application.Run(form); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BLToolkit.Demo")] +[assembly: AssemblyProduct("BLToolkit.Demo")] +[assembly: AssemblyCopyright("\xA9 2002-2012 www.bltoolkit.net")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("dd989791-7b52-4271-b3c1-e1a2d1eb85e9")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Properties/DataSources/BLToolkit.Demo.Forms.ObjectViews.PersonView.datasource --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Properties/DataSources/BLToolkit.Demo.Forms.ObjectViews.PersonView.datasource Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ + + + + BLToolkit.Demo.Forms.ObjectViews.PersonView, BLToolkit.Demo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Properties/DataSources/BLToolkit.Demo.ObjectModel.Gender.datasource --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Properties/DataSources/BLToolkit.Demo.ObjectModel.Gender.datasource Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ + + + + BLToolkit.Demo.ObjectModel.Gender, BLToolkit.Demo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Properties/DataSources/BLToolkit.Demo.ObjectModel.Person.datasource --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Properties/DataSources/BLToolkit.Demo.ObjectModel.Person.datasource Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ + + + + BLToolkit.Demo.ObjectModel.Person, BLToolkit.Demo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Properties/Resources.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Properties/Resources.Designer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.1 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BLToolkit.Demo.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BLToolkit.Demo.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Properties/Resources.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Properties/Resources.resx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Properties/Settings.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Properties/Settings.Designer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.1 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BLToolkit.Demo.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Demo/WinForms/Properties/Settings.settings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Properties/Settings.settings Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ + + + + + + + diff -r 000000000000 -r f990fcb411a9 Documentation/BLToolkit.ndoc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Documentation/BLToolkit.ndoc Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,55 @@ + + + + + + The BLToolkit.Reflection.Emit namespace contains helpers and wrappers around System.Reflection.Emit namespace classes. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Examples/CS/Examples.CS.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/CS/Examples.CS.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,140 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {34989C73-F82A-4905-9349-D0CF1419CD1C} + Library + Properties + Examples.CS + Examples.CS + + + 3.5 + + + false + v4.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + x86 + bin\Debug\Examples.CS.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\Examples.CS.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + + + + False + ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + + + + + + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Examples/CS/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/CS/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Examples.CS.2")] +[assembly: AssemblyProduct("Examples.CS.2")] +[assembly: AssemblyCopyright("\xA9 2002-2012 www.bltoolkit.net")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM componenets. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("da3e2397-3b38-42d4-b3ac-782ecef311c9")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion ("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Examples/CS/Reflection.Emit/HelloWorld.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/CS/Reflection.Emit/HelloWorld.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,48 @@ +//@ example: +//@ emit Emit +using System; + +using NUnit.Framework; + +using BLToolkit.Reflection; +using BLToolkit.Reflection.Emit; + +namespace Examples.Reflection.Emit +{ + [TestFixture] + public class HelloWorld + { + public interface IHello + { + void SayHello(string toWhom); + } + + [Test] + public void Test() + { + EmitHelper emit = new AssemblyBuilderHelper("HelloWorld.dll") + .DefineType ("Hello", typeof(object), typeof(IHello)) + .DefineMethod(typeof(IHello).GetMethod("SayHello")) + .Emitter; + + /*[a]*/emit/*[/a]*/ + // string.Format("Hello, {0}!", toWhom) + // + ./*[a]*/ldstr/*[/a]*/ ("Hello, {0}!") + ./*[a]*/ldarg_1/*[/a]*/ + ./*[a]*/call/*[/a]*/ (typeof(string), "Format", typeof(string), typeof(object)) + + // Console.WriteLine("Hello, World!"); + // + ./*[a]*/call/*[/a]*/ (typeof(Console), "WriteLine", typeof(string)) + ./*[a]*/ret/*[/a]*/() + ; + + Type type = emit.Method.Type.Create(); + + IHello hello = (IHello)TypeAccessor.CreateInstance(type); + + hello.SayHello("World"); + } + } +} diff -r 000000000000 -r f990fcb411a9 Examples/CS/Reflection.Emit/HelloWorldNormal.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/CS/Reflection.Emit/HelloWorldNormal.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,63 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; +using System.Threading; + +using NUnit.Framework; + +namespace Examples.Reflection.Emit +{ + [TestFixture] + public class HelloWorldNormal + { + public interface IHello + { + void SayHello(string toWhom); + } + + [Test] + public void Test() + { + AssemblyName asmName = new AssemblyName(); + + asmName.Name = "HelloWorld"; + + AssemblyBuilder asmBuilder = + Thread.GetDomain().DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave); + + ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule("HelloWorld"); + + TypeBuilder typeBuilder = modBuilder.DefineType( + "Hello", + TypeAttributes.Public, + typeof(object), + new Type[] { typeof(IHello) }); + + MethodBuilder methodBuilder = typeBuilder.DefineMethod("SayHello", + MethodAttributes.Private | MethodAttributes.Virtual, + typeof(void), + new Type[] { typeof(string) }); + + typeBuilder.DefineMethodOverride(methodBuilder, typeof(IHello).GetMethod("SayHello")); + + ILGenerator il = methodBuilder.GetILGenerator(); + + // string.Format("Hello, {0} World!", toWhom) + // + /*[a]*/il.Emit/*[/a]*/(OpCodes.Ldstr, "Hello, {0} World!"); + /*[a]*/il.Emit/*[/a]*/(OpCodes.Ldarg_1); + /*[a]*/il.Emit/*[/a]*/(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(object) })); + + // Console.WriteLine("Hello, World!"); + // + /*[a]*/il.Emit/*[/a]*/(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); + /*[a]*/il.Emit/*[/a]*/(OpCodes.Ret); + + Type type = typeBuilder.CreateType(); + + IHello hello = (IHello)Activator.CreateInstance(type); + + hello.SayHello("Emit"); + } + } +} diff -r 000000000000 -r f990fcb411a9 Examples/CS/packages.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/CS/packages.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Examples/Cpp/AssemblyInfo.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Cpp/AssemblyInfo.cpp Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,40 @@ +#include "stdafx.h" + +using namespace System; +using namespace System::Reflection; +using namespace System::Runtime::CompilerServices; +using namespace System::Runtime::InteropServices; +using namespace System::Security::Permissions; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly:AssemblyTitleAttribute("ExamplesCpp")]; +[assembly:AssemblyDescriptionAttribute("")]; +[assembly:AssemblyConfigurationAttribute("")]; +[assembly:AssemblyCompanyAttribute("")]; +[assembly:AssemblyProductAttribute("ExamplesCpp")]; +[assembly:AssemblyCopyrightAttribute("Copyright (c) 2013")]; +[assembly:AssemblyTrademarkAttribute("")]; +[assembly:AssemblyCultureAttribute("")]; + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the value or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly:AssemblyVersionAttribute("1.0.*")]; + +[assembly:ComVisible(false)]; + +[assembly:CLSCompliantAttribute(true)]; + +[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)]; diff -r 000000000000 -r f990fcb411a9 Examples/Cpp/Examples.Cpp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Cpp/Examples.Cpp.cpp Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ +// This is the main DLL file. + +#include "stdafx.h" + +#include "Examples.Cpp.h" + diff -r 000000000000 -r f990fcb411a9 Examples/Cpp/Examples.Cpp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Cpp/Examples.Cpp.h Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +// Examples.Cpp.h + +#pragma once + +using namespace System; + +namespace ExamplesCpp { + + public ref class Class1 + { + // TODO: Add your methods for this class here. + }; +} diff -r 000000000000 -r f990fcb411a9 Examples/Cpp/Examples.Cpp.vcxproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Cpp/Examples.Cpp.vcxproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,112 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {9D063CAA-4C44-4C5E-9C9E-74EFA4049FEC} + v4.5 + ManagedCProj + ExamplesCpp + + + + DynamicLibrary + true + v110 + true + Unicode + + + DynamicLibrary + false + v110 + true + Unicode + + + + + + + + + + + + + true + + + false + + + + Level3 + Disabled + WIN32;_DEBUG;%(PreprocessorDefinitions) + Use + + + true + + + + + + Level3 + WIN32;NDEBUG;%(PreprocessorDefinitions) + Use + + + true + + + + + + ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + {0c325f5d-e50e-4340-8724-d29896ccc583} + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Examples/Cpp/Examples.Cpp.vcxproj.filters --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Cpp/Examples.Cpp.vcxproj.filters Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,55 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Examples/Cpp/HelloWorld.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Cpp/HelloWorld.cpp Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,57 @@ +//@ example: +//@ emit Emit +#include "stdafx.h" + +using namespace System; + +using namespace NUnit::Framework; + +using namespace BLToolkit::Reflection; +using namespace BLToolkit::Reflection::Emit; + +namespace Examples { +namespace Reflection { +namespace Emit +{ + [TestFixture] + public ref class HelloWorld + { + public: + + interface class IHello + { + void SayHello(String ^toWhom); + }; + + [Test] + void Test() + { + AssemblyBuilderHelper ^assembly = gcnew AssemblyBuilderHelper("HelloWorld.dll"); + + EmitHelper ^emit = assembly + ->DefineType ("Hello", Object::typeid, IHello::typeid) + ->DefineMethod(IHello::typeid->GetMethod("SayHello")) + ->Emitter; + + emit + // string.Format("Hello, {0} World!", toWhom) + // + ->ldstr ("Hello, {0} World!") + ->ldarg_1 + ->call (String::typeid, "Format", String::typeid, Object::typeid) + + // Console.WriteLine("Hello, World!"); + // + ->call (Console::typeid, "WriteLine", String::typeid) + ->ret() + ; + + Type ^type = emit->Method->Type->Create(); + + IHello ^hello = (IHello^)TypeAccessor::CreateInstance(type); + + hello->SayHello("C++"); + } + }; +}}} + diff -r 000000000000 -r f990fcb411a9 Examples/Cpp/ReadMe.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Cpp/ReadMe.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,38 @@ +======================================================================== + DYNAMIC LINK LIBRARY : Examples.Cpp Project Overview +======================================================================== + +AppWizard has created this Examples.Cpp DLL for you. + +This file contains a summary of what you will find in each of the files that +make up your Examples.Cpp application. + +Examples.Cpp.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +Examples.Cpp.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +Examples.Cpp.cpp + This is the main DLL source file. + +Examples.Cpp.h + This file contains a class declaration. + +AssemblyInfo.cpp + Contains custom attributes for modifying assembly metadata. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff -r 000000000000 -r f990fcb411a9 Examples/Cpp/Stdafx.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Cpp/Stdafx.cpp Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,5 @@ +// stdafx.cpp : source file that includes just the standard includes +// Examples.Cpp.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff -r 000000000000 -r f990fcb411a9 Examples/Cpp/Stdafx.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Cpp/Stdafx.h Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, +// but are changed infrequently + +#pragma once + + diff -r 000000000000 -r f990fcb411a9 Examples/Cpp/app.ico Binary file Examples/Cpp/app.ico has changed diff -r 000000000000 -r f990fcb411a9 Examples/Cpp/app.rc Binary file Examples/Cpp/app.rc has changed diff -r 000000000000 -r f990fcb411a9 Examples/Cpp/resource.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Cpp/resource.h Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by app.rc diff -r 000000000000 -r f990fcb411a9 Examples/Nemerle/Examples.Nemerle.2.nproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Nemerle/Examples.Nemerle.2.nproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,68 @@ + + + true + $(ProgramFiles)\Nemerle + + + Debug + AnyCPU + "Examples.Nemerle.2" + 8.0.30703 + 2.0 + {f8f33d46-a839-409b-9fcb-c41a514358f8} + Exe + Examples.Nemerle.2 + Examples.Nemerle.2 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + BLToolkit.2 + {0c325f5d-e50e-4340-8724-d29896ccc583} + True + + + + + Content + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Examples/Nemerle/Main.n --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Nemerle/Main.n Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +using System.Console; +using BLToolkit.Data; +using BLToolkit.Mapping; +using BLToolkit.Reflection; + +namespace Test +{ + public enum Gender + { + [MapValue("F")] | Female + [MapValue("M")] | Male + [MapValue("U")] | Unknown + [MapValue("O")] | Other + } + + [MapField("PersonID", "ID")] + public class Person + { + public mutable PersonID : int; + public mutable FirstName : string; + public mutable LastName : string; + public mutable MiddleName : string; + public mutable Gender : Gender; + } + + module Program + { + Main() : void + { + def p = Person(); + p.FirstName = "John"; + p.LastName = "Pupkin"; + + using (db = DbManager()) + { + def p = db + .SetSpCommand("Person_SelectByName", db.CreateParameters(p)) + .ExecuteObject() : Person; + + TypeAccessor.WriteConsole(p); + } + + WriteLine("Press enter to continue..."); + _ = ReadLine(); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Examples/Nemerle/app.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/Nemerle/app.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Examples/VB/AssemblyInfo.vb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/VB/AssemblyInfo.vb Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,32 @@ +Imports System +Imports System.Reflection +Imports System.Runtime.InteropServices + +' General Information about an assembly is controlled through the following +' set of attributes. Change these attribute values to modify the information +' associated with an assembly. + +' Review the values of the assembly attributes + + + + + + + + + +'The following GUID is for the ID of the typelib if this project is exposed to COM + + +' Version information for an assembly consists of the following four values: +' +' Major Version +' Minor Version +' Build Number +' Revision +' +' You can specify all the values or you can default the Build and Revision Numbers +' by using the '*' as shown below: + + diff -r 000000000000 -r f990fcb411a9 Examples/VB/Examples.VB.vbproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/VB/Examples.VB.vbproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,187 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {308A4189-53AB-460D-B2B1-0EB4B9219654} + Library + + + Examples.VB + Windows + + + 3.5 + + + false + v4.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + true + true + bin\Debug\ + Examples.VB.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022,42353,42354,42355 + AllRules.ruleset + x86 + + + pdbonly + false + true + true + bin\Release\ + Examples.VB.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022,42353,42354,42355 + AllRules.ruleset + + + true + true + true + bin\DebugMono\ + Examples.VB.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022,42353,42354,42355 + full + x86 + bin\Debug\Examples.VB.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.vb + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + true + bin\ReleaseMono\ + Examples.VB.xml + true + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022,42353,42354,42355 + pdbonly + AnyCPU + bin\Release\Examples.VB.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.vb + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + False + ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + + + + + + + + + + + + + + + + + + True + Application.myapp + + + True + True + Resources.resx + + + True + Settings.settings + True + + + + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + Designer + + + + + MyApplicationCodeGenerator + Application.Designer.vb + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Examples/VB/My Project/Application.Designer.vb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/VB/My Project/Application.Designer.vb Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.1 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + diff -r 000000000000 -r f990fcb411a9 Examples/VB/My Project/Application.myapp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/VB/My Project/Application.myapp Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ + + + false + false + 0 + true + 0 + 1 + true + diff -r 000000000000 -r f990fcb411a9 Examples/VB/My Project/AssemblyInfo.vb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/VB/My Project/AssemblyInfo.vb Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,37 @@ +Imports System +Imports System.Reflection +Imports System.Runtime.InteropServices + +' General Information about an assembly is controlled through the following +' set of attributes. Change these attribute values to modify the information +' associated with an assembly. + +' Review the values of the assembly attributes + + + + + + + + + + + + +'The following GUID is for the ID of the typelib if this project is exposed to COM + + +' Version information for an assembly consists of the following four values: +' +' Major Version +' Minor Version +' Build Number +' Revision +' +' You can specify all the values or you can default the Build and Revision Numbers +' by using the '*' as shown below: +' + + + diff -r 000000000000 -r f990fcb411a9 Examples/VB/My Project/Resources.Designer.vb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/VB/My Project/Resources.Designer.vb Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,63 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.1 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + +Imports System + +Namespace My.Resources + + 'This class was auto-generated by the StronglyTypedResourceBuilder + 'class via a tool like ResGen or Visual Studio. + 'To add or remove a member, edit your .ResX file then rerun ResGen + 'with the /str option, or rebuild your VS project. + ''' + ''' A strongly-typed resource class, for looking up localized strings, etc. + ''' + _ + Friend Module Resources + + Private resourceMan As Global.System.Resources.ResourceManager + + Private resourceCulture As Global.System.Globalization.CultureInfo + + ''' + ''' Returns the cached ResourceManager instance used by this class. + ''' + _ + Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager + Get + If Object.ReferenceEquals(resourceMan, Nothing) Then + Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("Resources", GetType(Resources).Assembly) + resourceMan = temp + End If + Return resourceMan + End Get + End Property + + ''' + ''' Overrides the current thread's CurrentUICulture property for all + ''' resource lookups using this strongly typed resource class. + ''' + _ + Friend Property Culture() As Global.System.Globalization.CultureInfo + Get + Return resourceCulture + End Get + Set + resourceCulture = value + End Set + End Property + End Module +End Namespace diff -r 000000000000 -r f990fcb411a9 Examples/VB/My Project/Resources.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/VB/My Project/Resources.resx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Examples/VB/My Project/Settings.Designer.vb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/VB/My Project/Settings.Designer.vb Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,71 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.1 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + + + + _ +Partial Friend NotInheritable Class Settings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As Settings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New Settings()),Settings) + +#Region "My.Settings Auto-Save Functionality" +#If _MyType = "WindowsForms" Then + Private Shared addedHandler As Boolean + + Private Shared addedHandlerLockObject As New Object + + _ + Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) + If My.Application.SaveMySettingsOnExit Then + My.Settings.Save() + End If + End Sub +#End If +#End Region + + Public Shared ReadOnly Property [Default]() As Settings + Get + +#If _MyType = "WindowsForms" Then + If Not addedHandler Then + SyncLock addedHandlerLockObject + If Not addedHandler Then + AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings + addedHandler = True + End If + End SyncLock + End If +#End If + Return defaultInstance + End Get + End Property +End Class + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.Settings + Get + Return Global.Settings.Default + End Get + End Property + End Module +End Namespace diff -r 000000000000 -r f990fcb411a9 Examples/VB/My Project/Settings.settings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/VB/My Project/Settings.settings Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ + + + + + + + diff -r 000000000000 -r f990fcb411a9 Examples/VB/OverloadWithDefValue.vb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/VB/OverloadWithDefValue.vb Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,40 @@ +''@ example: +''@ emit Emit +Imports System +Imports BLToolkit.Aspects +Imports NUnit.Framework + +Imports BLToolkit.Reflection + +Namespace Examples + + _ + Public Class OverloadWithDefValue + + Public MustInherit Class TestObject + + Public Sub TestMethod( _ + ByVal passthrough As Integer, _ + Optional ByVal strVal As String = "str", _ + Optional ByVal intVal As Integer = 123) + Assert.AreEqual(321, passthrough) + Assert.AreEqual("str", strVal) + Assert.AreEqual(123, intVal) + End Sub + + _ + Public MustOverride Sub TestMethod( _ + ByVal passthrough As Integer, _ + ByVal dateVal As Date) + + End Class + + _ + Sub Test() + Dim o As TestObject = TypeAccessor(Of TestObject).CreateInstance + o.TestMethod(321, Today) + End Sub + + End Class + +End Namespace diff -r 000000000000 -r f990fcb411a9 Examples/VB/Reflection.Emit/HelloWorld.vb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/VB/Reflection.Emit/HelloWorld.vb Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +''@ example: +''@ emit Emit +Imports System +Imports NUnit.Framework + +Imports BLToolkit.Reflection +Imports BLToolkit.Reflection.Emit + +Namespace Examples.Reflection.Emit + + _ + Public Class HelloWorld + + Public Interface IHello + Sub SayHello(ByVal toWhom As String) + End Interface + + _ + Sub Test() + Dim assemblyHelper As AssemblyBuilderHelper = New AssemblyBuilderHelper("HelloWorld.dll") + Dim typeHelper As TypeBuilderHelper = assemblyHelper.DefineType("Hello", GetType(Object), GetType(IHello)) + Dim methodHelper As MethodBuilderHelper = typeHelper.DefineMethod(GetType(IHello).GetMethod("SayHello")) + Dim emit As EmitHelper = methodHelper.Emitter + + ' string.Format("Hello, {0} World!", toWhom) + ' + emit _ + .ldstr("Hello, {0} World!") _ + .ldarg_1 _ + .call(GetType(String), "Format", GetType(String), GetType(Object)) + + ' Console.WriteLine("Hello, World!"); + ' + emit _ + .call(GetType(Console), "WriteLine", GetType(String)) _ + .ret() + + Dim type As Type = typeHelper.Create() + + Dim hello As IHello = TypeAccessor.CreateInstance(type) + + hello.SayHello("VB") + End Sub + + End Class + +End Namespace diff -r 000000000000 -r f990fcb411a9 Examples/VB/packages.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Examples/VB/packages.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/BLToolkit.4.JointureAddOn.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/BLToolkit.4.JointureAddOn.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,86 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {9FD2722C-1E6C-4061-8AC0-32EE28808FC0} + Library + Properties + BLToolkit + BLToolkit.4.JointureAddOn + v4.0 + 512 + + + true + full + false + bin\Debug\ + TRACE;DEBUG;FW4;OVERRIDETOSTRING; + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\packages\Castle.Core.3.2.1\lib\net40-client\Castle.Core.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/DataAccess/FullSqlQuery.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/DataAccess/FullSqlQuery.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,289 @@ +#region + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using BLToolkit.Aspects; +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; +using BLToolkit.Mapping; + +#endregion + +namespace BLToolkit.DataAccess +{ + public class FullSqlQuery : SqlQuery + { + private readonly bool _ignoreLazyLoad; + + #region Constructors + + public FullSqlQuery(DbManager dbManager, bool ignoreLazyLoad = false, FactoryType factoryType = FactoryType.LazyLoading) + : base(dbManager) + { + dbManager.MappingSchema = new FullMappingSchema(dbManager, ignoreLazyLoad, dbManager.MappingSchema, factoryType); + + _ignoreLazyLoad = ignoreLazyLoad; + } + + #endregion + + #region Overrides + + private readonly Hashtable _actionSqlQueryInfo = new Hashtable(); + + [NoInterception] + protected override SqlQueryInfo CreateSqlText(DbManager db, Type type, string actionName) + { + switch (actionName) + { + case "SelectByKey": + return CreateSelectFullByKeySqlText(db, type); + case "SelectAll": + return CreateSelectAllFullSqlText(db, type); + default: + return base.CreateSqlText(db, type, actionName); + } + } + + [NoInterception] + public override SqlQueryInfo GetSqlQueryInfo(DbManager db, Type type, string actionName) + { + var key = type.FullName + "$" + actionName + "$" + db.DataProvider.UniqueName + "$" + GetTableName(type); + var query = (SqlQueryInfo) _actionSqlQueryInfo[key]; + + if (query == null) + { + query = CreateSqlText(db, type, actionName); + _actionSqlQueryInfo[key] = query; + } + + return query; + } + + #endregion + + #region Private methods + + private SqlQueryInfo CreateSelectAllFullSqlText(DbManager db, Type type) + { + var sb = new StringBuilder(); + var query = new FullSqlQueryInfo(); + + sb.Append("SELECT\n"); + + var mainMapper = (FullObjectMapper) db.MappingSchema.GetObjectMapper(type); + + BuildSelectSql(mainMapper, sb, db); + + sb.Remove(sb.Length - 2, 1); + + sb.Append("FROM\n\t"); + + FullAppendTableName(sb, db, type); + + AppendJoinTableName(mainMapper, sb, db, type); + + query.QueryText = sb.ToString(); + + return query; + } + + private SqlQueryInfo CreateSelectFullByKeySqlText(DbManager db, Type type) + { + var sb = new StringBuilder(); + var query = new FullSqlQueryInfo(); + + sb.Append("SELECT\n"); + + var mainMapper = (FullObjectMapper) db.MappingSchema.GetObjectMapper(type); + BuildSelectSql(mainMapper, sb, db); + + sb.Remove(sb.Length - 2, 1); + + sb.Append("FROM\n\t"); + + FullAppendTableName(sb, db, type); + + AppendJoinTableName(mainMapper, sb, db, type); + + AddWherePK(db, query, sb, -1, mainMapper); + + query.QueryText = sb.ToString(); + + return query; + } + + private void FullAppendTableName(StringBuilder sb, DbManager db, Type type) + { + var database = GetDatabaseName(type); + var owner = GetOwnerName(type); + var name = base.GetTableName(type); + + db.DataProvider.CreateSqlProvider().BuildTableName(sb, + database == null ? null : db.DataProvider.Convert(database, ConvertType.NameToDatabase).ToString(), + owner == null ? null : db.DataProvider.Convert(owner, ConvertType.NameToOwner).ToString(), + name == null ? null : db.DataProvider.Convert(name, ConvertType.NameToQueryTable).ToString()); + + //TODO Override OracleSqlProvider in order to avoid this mess... + string alias = FullGetTableName(type); + sb.Append(" " + "T" /*alias*/); + sb.AppendLine(); + } + + private string FullGetTableName(Type type) + { + //bool isSet; + //return MappingSchema.MetadataProvider.GetTableName(type, Extensions, out isSet); + + return type.Name; + } + + private void BuildSelectSql(IObjectMapper mapper, StringBuilder sb, DbManager db, string tableName = "T") + { + int tableNr = 0; + + foreach (IMapper mapField in mapper.PropertiesMapping) + { + if (mapField is ValueMapper) + sb.AppendFormat("\t{0}.{1} {2},\n" + , tableName /* (mapper).PropertyType.Name */, + db.DataProvider.Convert(((ValueMapper) mapField).ColumnName, ConvertType.NameToQueryField), + ((ValueMapper) mapField).ColumnAlias + ); + else if (mapField is IPropertiesMapping) + { + var propertiesMapping = (IPropertiesMapping) mapField; + var cel = propertiesMapping.ParentMapping; + while (cel != null) + { + // To avoid recursion dont take in account types already loaded. + if (((IMapper) cel).PropertyType == mapField.PropertyType) + continue; + cel = cel.ParentMapping; + } + + var objectMapper = (IObjectMapper) mapField; + if (!objectMapper.IsLazy) + BuildSelectSql(objectMapper, sb, db, tableName + tableNr.ToString()); + + tableNr++; + } + else + throw new NotImplementedException(mapField.GetType() + " is not yet implemented."); + } + } + + private void AppendJoinTableName(IPropertiesMapping mapper, StringBuilder sb, DbManager db, Type type, string tableName = "T") + { + string parentName = FullGetTableName(type); + Dictionary valueMappers = mapper.PropertiesMapping.Where(e => e is ValueMapper).Cast().ToDictionary(e => e.PropertyName, e => e); + + int tableNr = 0; + + foreach (IMapper mapField in mapper.PropertiesMapping) + { + var objectMapper = mapField as IObjectMapper; + if (objectMapper != null) + { + if (!_ignoreLazyLoad) + { + if (objectMapper.IsLazy) + continue; + } + + string thisKey = objectMapper.Association.ThisKey[0]; + + // TITLE + string parentDbField = valueMappers.ContainsKey(thisKey) ? valueMappers[thisKey].ColumnName : thisKey; + + // ARTIST + string childDbField = objectMapper.PropertiesMapping.Where(e => e is ValueMapper).Cast().First( + e => e.PropertyName == objectMapper.Association.OtherKey[0]).ColumnName; + + string childDatabase = GetDatabaseName(mapField.PropertyType); + string childOwner = base.GetOwnerName(mapField.PropertyType); + string childName = base.GetTableName(mapField.PropertyType); + string childAlias = FullGetTableName(mapField.PropertyType); + + StringBuilder childFullName = db.DataProvider.CreateSqlProvider().BuildTableName( + new StringBuilder(), + childDatabase == null + ? null + : db.DataProvider.Convert(childDatabase, ConvertType.NameToDatabase).ToString(), + childOwner == null + ? null + : db.DataProvider.Convert(childOwner, ConvertType.NameToOwner).ToString(), + childName == null + ? null + : db.DataProvider.Convert(childName, ConvertType.NameToQueryTable).ToString()); + + sb.AppendFormat("\tFULL OUTER JOIN {0} {1} ON {2}.{3}={4}.{5}\n", + childFullName, + tableName + tableNr.ToString() /*childAlias*/, + tableName /*parentName*/, + parentDbField, + tableName + tableNr.ToString() /*childAlias*/, + childDbField + ); + + AppendJoinTableName((IPropertiesMapping)mapField, sb, db, mapField.PropertyType, tableName + tableNr.ToString()); + + tableNr++; + } + } + + sb.AppendLine(); + + //SELECT + // ARTIST2.ID_ARTIST, + // ARTIST2.ARTIST, + // TRACK.ID_TRACK, + // TRACK.TRACK, + // TRACK.ID_ARTIST, + // ARTIST.ID_ARTIST, + // ARTIST.ARTIST + //FROM + // PITAFR01.ARTIST ARTIST2 + // INNER JOIN PITAFR01.TRACK TRACK ON ARTIST2.ID_ARTIST=TRACK.ID_ARTIST + // INNER JOIN PITAFR01.ARTIST ARTIST ON TRACK.ID_ARTIST=ARTIST.ID_ARTIST + //WHERE + // ARTIST2.ID_ARTIST = 2566 + } + + private void AddWherePK(DbManager db, SqlQueryInfo query, StringBuilder sb, int nParameter, FullObjectMapper mapper) + { + sb.Append("WHERE\n"); + + foreach (IMapper mm in mapper.PropertiesMapping) + { + if (mm is ValueMapper && mm.DataReaderIndex == mapper.DataReaderIndex) + { + var valueMapper = (ValueMapper) mm; + + string tableAlias = mapper.PropertyType.Name; + + //mm.Name = ID_TRACK + SqlQueryParameterInfo p = query.AddParameter( + db.DataProvider.Convert(valueMapper.ColumnName + "_W", ConvertType.NameToQueryParameter). + ToString(), + valueMapper.ColumnName); + + sb.AppendFormat("\t{0}.{1} = ", "T" /* tableAlias */, + db.DataProvider.Convert(p.FieldName, ConvertType.NameToQueryField)); + + if (nParameter < 0) + sb.AppendFormat("{0} AND\n", p.ParameterName); + else + sb.AppendFormat("{{{0}}} AND\n", nParameter++); + } + } + + sb.Remove(sb.Length - 5, 5); + } + + #endregion + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/DataAccess/FullSqlQueryBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/DataAccess/FullSqlQueryBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,280 @@ +using System; +using System.Collections; +using System.Linq; +using System.Reflection; +using System.Text; +using BLToolkit.Aspects; +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; +using BLToolkit.Mapping; +using BLToolkit.TypeBuilder; + +namespace BLToolkit.DataAccess +{ + public abstract class FullSqlQueryBase : SqlQueryBase + { + private readonly bool _ignoreLazyLoad; + + #region Constructors + + protected FullSqlQueryBase(DbManager dbManager, bool ignoreLazyLoad = false, MappingOrder mappingOrder = MappingOrder.ByColumnIndex) + : base(dbManager) + { + dbManager.MappingSchema = new FullMappingSchema(dbManager, mappingOrder: mappingOrder); + + _ignoreLazyLoad = ignoreLazyLoad; + } + + #endregion + + #region Overrides + + [NoInterception] + protected override SqlQueryInfo CreateSqlText(DbManager db, Type type, string actionName) + { + switch (actionName) + { + case "SelectByKey": + return CreateSelectFullByKeySqlText(db, type); + case "SelectAll": + return CreateSelectAllFullSqlText(db, type); + default: + return base.CreateSqlText(db, type, actionName); + } + } + + protected override void AppendTableName(StringBuilder sb, DbManager db, Type type) + { + var database = GetDatabaseName(type); + var owner = GetOwnerName(type); + var name = base.GetTableName(type); + + db.DataProvider.CreateSqlProvider().BuildTableName(sb, + database == null ? null : db.DataProvider.Convert(database, ConvertType.NameToDatabase).ToString(), + owner == null ? null : db.DataProvider.Convert(owner, ConvertType.NameToOwner).ToString(), + name == null ? null : db.DataProvider.Convert(name, ConvertType.NameToQueryTable).ToString()); + + //TODO Override OracleSqlProvider in order to avoid this mess... + string alias = GetTableName(type); + sb.Append(" " + alias); + sb.AppendLine(); + } + + protected override string GetTableName(Type type) + { + //bool isSet; + //return MappingSchema.MetadataProvider.GetTableName(type, Extensions, out isSet); + + return type.Name; + } + + #endregion + + private SqlQueryInfo CreateSelectAllFullSqlText(DbManager db, Type type) + { + var sb = new StringBuilder(); + var query = new FullSqlQueryInfo(); + + sb.Append("SELECT\n"); + + var mainMapper = (FullObjectMapper)db.MappingSchema.GetObjectMapper(type); ; + BuildSelectSQL(mainMapper, sb, db); + + sb.Remove(sb.Length - 2, 1); + + sb.Append("FROM\n\t"); + + AppendTableName(sb, db, type); + + AppendJoinTableName(sb, db, type); + + query.QueryText = sb.ToString(); + + return query; + } + + private SqlQueryInfo CreateSelectFullByKeySqlText(DbManager db, Type type) + { + var sb = new StringBuilder(); + var query = new FullSqlQueryInfo(); + + sb.Append("SELECT\n"); + + var mainMapper = (FullObjectMapper)db.MappingSchema.GetObjectMapper(type); + + BuildSelectSQL(mainMapper, sb, db); + + sb.Remove(sb.Length - 2, 1); + + sb.Append("FROM\n\t"); + + AppendTableName(sb, db, type); + + AppendJoinTableName(sb, db, type); + + AddWherePK(db, query, sb, -1, mainMapper); + + query.QueryText = sb.ToString(); + + return query; + } + + private void BuildSelectSQL(IPropertiesMapping mapper, StringBuilder sb, DbManager db) + { + foreach (IMapper mapField in mapper.PropertiesMapping) + { + if (mapField is ValueMapper) + sb.AppendFormat("\t{0}.{1},\n", ((IObjectMapper)mapper).PropertyType.Name, + db.DataProvider.Convert(((ValueMapper)mapField).ColumnName, ConvertType.NameToQueryField)); + else if (mapField is IPropertiesMapping) + { + var propertiesMapping = (IPropertiesMapping)mapField; + var cel = propertiesMapping.ParentMapping; + while (cel != null) + { + // To avoid recursion dont take in account types already loaded. + if (((IMapper)cel).PropertyType == mapField.PropertyType) + continue; + cel = cel.ParentMapping; + } + var objectMapper = (IObjectMapper)mapField; + if (!objectMapper.IsLazy) + BuildSelectSQL(propertiesMapping, sb, db); + } + else + throw new NotImplementedException(mapField.GetType() + " is not yet implemented."); + } + } + + private void AppendJoinTableName(StringBuilder sb, DbManager db, Type type) + { + string parentName = GetTableName(type); + + foreach (PropertyInfo prop in type.GetProperties()) + { + bool isCollection = prop.PropertyType.GetInterfaces().ToList().Contains(typeof(IList)); + Type listElementType = null; + if (isCollection) + { + listElementType = FullMappingSchema.GetGenericType(prop.PropertyType); + } + + if (!_ignoreLazyLoad) + { + object[] lazy = prop.GetCustomAttributes(typeof(LazyInstanceAttribute), true); + if (lazy.Length > 0) + { + if (((LazyInstanceAttribute)lazy[0]).IsLazy) + { + continue; + } + } + } + + object[] attribs = prop.GetCustomAttributes(typeof(AssociationAttribute), true); + if (attribs.Length > 0) + { + var assocAttrib = (AssociationAttribute)attribs[0]; + + PropertyInfo parentField = type.GetProperty(assocAttrib.ThisKey); + PropertyInfo childField = prop.PropertyType.GetProperty(assocAttrib.OtherKey); + if (isCollection) + { + childField = listElementType.GetProperty(assocAttrib.OtherKey); + //FullMappingSchema.GetColumnFromProperty(listElementType, associationAttribute.OtherKey); + } + + object[] parentFieldAttributes = parentField.GetCustomAttributes(typeof(MapFieldAttribute), true); + string parentDbField = parentFieldAttributes.Length > 0 + ? ((MapFieldAttribute)parentFieldAttributes[0]).MapName + : assocAttrib.ThisKey; + + object[] childFieldAttributes = childField.GetCustomAttributes(typeof(MapFieldAttribute), true); + string childDbField = childFieldAttributes.Length > 0 + ? ((MapFieldAttribute)childFieldAttributes[0]).MapName + : assocAttrib.OtherKey; + + + string childDatabase = isCollection + ? GetDatabaseName(listElementType) + : GetDatabaseName(prop.PropertyType); + + string childOwner = isCollection ? base.GetOwnerName(listElementType) : base.GetOwnerName(prop.PropertyType); + string childName = isCollection ? base.GetTableName(listElementType) : base.GetTableName(prop.PropertyType); + string childAlias = isCollection ? GetTableName(listElementType) : GetTableName(prop.PropertyType); + + StringBuilder childFullName = db.DataProvider.CreateSqlProvider().BuildTableName( + new StringBuilder(), + childDatabase == null + ? null + : db.DataProvider.Convert(childDatabase, ConvertType.NameToDatabase).ToString(), + childOwner == null + ? null + : db.DataProvider.Convert(childOwner, ConvertType.NameToOwner).ToString(), + childName == null + ? null + : db.DataProvider.Convert(childName, ConvertType.NameToQueryTable).ToString()); + + sb.AppendFormat("\tINNER JOIN {0} {1} ON {2}.{3}={4}.{5}\n", + childFullName, + childAlias, + parentName, + parentDbField, + childAlias, + childDbField + ); + + AppendJoinTableName(sb, db, isCollection ? listElementType : prop.PropertyType); + } + } + + sb.AppendLine(); + + //SELECT + // ARTIST2.ID_ARTIST, + // ARTIST2.ARTIST, + // TRACK.ID_TRACK, + // TRACK.TRACK, + // TRACK.ID_ARTIST, + // ARTIST.ID_ARTIST, + // ARTIST.ARTIST + //FROM + // PITAFR01.ARTIST ARTIST2 + // INNER JOIN PITAFR01.TRACK TRACK ON ARTIST2.ID_ARTIST=TRACK.ID_ARTIST + // INNER JOIN PITAFR01.ARTIST ARTIST ON TRACK.ID_ARTIST=ARTIST.ID_ARTIST + //WHERE + // ARTIST2.ID_ARTIST = 2566 + } + + private void AddWherePK(DbManager db, SqlQueryInfo query, StringBuilder sb, int nParameter, + FullObjectMapper mapper) + { + sb.Append("WHERE\n"); + + foreach (IMapper mm in mapper.PropertiesMapping) + { + if (mm is ValueMapper && mm.DataReaderIndex == mapper.DataReaderIndex) + { + var valueMapper = (ValueMapper)mm; + + string tableAlias = mapper.PropertyType.Name; + + //mm.Name = ID_TRACK + SqlQueryParameterInfo p = query.AddParameter( + db.DataProvider.Convert(valueMapper.ColumnName + "_W", ConvertType.NameToQueryParameter). + ToString(), + valueMapper.ColumnName); + + sb.AppendFormat("\t{0}.{1} = ", tableAlias, db.DataProvider.Convert(p.FieldName, ConvertType.NameToQueryField)); + + if (nParameter < 0) + sb.AppendFormat("{0} AND\n", p.ParameterName); + else + sb.AppendFormat("{{{0}}} AND\n", nParameter++); + } + } + + sb.Remove(sb.Length - 5, 5); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/DataAccess/FullSqlQueryInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/DataAccess/FullSqlQueryInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +namespace BLToolkit.DataAccess +{ + public class FullSqlQueryInfo : SqlQueryInfo + { + public override SqlQueryParameterInfo AddParameter(string parameterName, string fieldName) + { + var parameter = new FullSqlQueryParameterInfo { ParameterName = parameterName, FieldName = fieldName }; + + parameter.SetMemberMapper(ObjectMapper); + + Parameters.Add(parameter); + + return parameter; + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/DataAccess/FullSqlQueryParameterInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/DataAccess/FullSqlQueryParameterInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using BLToolkit.Mapping; + +namespace BLToolkit.DataAccess +{ + public class FullSqlQueryParameterInfo : SqlQueryParameterInfo + { + public override void SetMemberMapper(ObjectMapper objectMapper) + { + + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/DataAccess/FullSqlQueryT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/DataAccess/FullSqlQueryT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,164 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using BLToolkit.Data; + +namespace BLToolkit.DataAccess +{ + public class FullSqlQueryT : FullSqlQuery, ISqlQueryT + { + #region Constructors + + public FullSqlQueryT(DbManager dbManager, bool ignoreLazyLoad = false) + : base(dbManager, ignoreLazyLoad) + { + } + + #endregion + + #region Implementation of ISqlQueryT + + public T SelectByKey(DbManager db, params object[] keys) + { + return (T) base.SelectByKey(db, typeof(T), keys); + } + + public T SelectByKey(params object[] keys) + { + return (T)base.SelectByKey(typeof(T), keys); + } + + public List SelectAll(DbManager db) + { + return base.SelectAll(db, typeof(T)).Cast().ToList(); + } + + public TL SelectAll(DbManager db, TL list) where TL : IList + { + return (TL)base.SelectAll(db, (IList)list, typeof(T)); + } + + public TL SelectAll(DbManager db) where TL : IList, new() + { + return SelectAll(db, new TL()); + } + + public List SelectAll() + { + return base.SelectAll(typeof(T)).Cast().ToList(); + } + + public TL SelectAll(TL list) where TL : IList + { + return SelectAll(DbManager, list); + } + + public TL SelectAll() where TL : IList, new() + { + return SelectAll(DbManager); + } + + public int Insert(DbManager db, T obj) + { + return base.Insert(db, obj); + } + + public int Insert(T obj) + { + return base.Insert(obj); + } + + public int Insert(DbManager db, int maxBatchSize, IEnumerable list) + { + throw new NotImplementedException(); + } + + public int Insert(int maxBatchSize, IEnumerable list) + { + return Insert(DbManager, maxBatchSize, list); + } + + public int Insert(DbManager db, IEnumerable list) + { + return Insert(db, int.MaxValue, list); + } + + public int Insert(IEnumerable list) + { + return Insert(DbManager, list); + } + + public int Update(DbManager db, T obj) + { + return base.Update(db, obj); + } + + public int Update(T obj) + { + return base.Update(obj); + } + + public int Update(DbManager db, int maxBatchSize, IEnumerable list) + { + throw new NotImplementedException(); + } + + public int Update(int maxBatchSize, IEnumerable list) + { + return Update(DbManager, maxBatchSize, list); + } + + public int Update(DbManager db, IEnumerable list) + { + return Update(db, int.MaxValue, list); + } + + public int Update(IEnumerable list) + { + return Update(DbManager, list); + } + + public int DeleteByKey(DbManager db, params object[] key) + { + return base.DeleteByKey(db, typeof(T), key); + } + + public int DeleteByKey(params object[] key) + { + return base.DeleteByKey(typeof(T), key); + } + + public int Delete(DbManager db, T obj) + { + return base.Delete(db, obj); + } + + public int Delete(T obj) + { + return base.Delete(obj); + } + + public int Delete(DbManager db, int maxBatchSize, IEnumerable list) + { + throw new NotImplementedException(); + } + + public int Delete(int maxBatchSize, IEnumerable list) + { + return Delete(DbManager, maxBatchSize, list); + } + + public int Delete(DbManager db, IEnumerable list) + { + return Delete(int.MaxValue, list); + } + + public int Delete(IEnumerable list) + { + return Delete(DbManager, list); + } + + #endregion + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Emit/DynamicCompilationSpike.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Emit/DynamicCompilationSpike.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,129 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +namespace BLToolkit.Emit +{ + public delegate object GetHandler(object source); + + public delegate void SetHandler(object source, object value); + + public delegate object InstantiateObjectHandler(); + + public static class DynamicMethodCompiler + { + // DynamicMethodCompiler + + // CreateInstantiateObjectDelegate + internal static InstantiateObjectHandler CreateInstantiateObjectHandler(Type type) + { + ConstructorInfo constructorInfo = + type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, + new Type[0], null); + if (constructorInfo == null) + { + throw new ApplicationException( + string.Format( + "The type {0} must declare an empty constructor (the constructor may be private, internal, protected, protected internal, or public).", + type)); + } + + var dynamicMethod = new DynamicMethod("InstantiateObject", MethodAttributes.Static | MethodAttributes.Public, + CallingConventions.Standard, typeof(object), null, type, true); + ILGenerator generator = dynamicMethod.GetILGenerator(); + generator.Emit(OpCodes.Newobj, constructorInfo); + generator.Emit(OpCodes.Ret); + return (InstantiateObjectHandler)dynamicMethod.CreateDelegate(typeof(InstantiateObjectHandler)); + } + + // CreateGetDelegate + internal static GetHandler CreateGetHandler(Type type, PropertyInfo propertyInfo) + { + MethodInfo getMethodInfo = propertyInfo.GetGetMethod(true); + DynamicMethod dynamicGet = CreateGetDynamicMethod(type); + ILGenerator getGenerator = dynamicGet.GetILGenerator(); + + getGenerator.Emit(OpCodes.Ldarg_0); + getGenerator.Emit(OpCodes.Call, getMethodInfo); + BoxIfNeeded(getMethodInfo.ReturnType, getGenerator); + getGenerator.Emit(OpCodes.Ret); + + return (GetHandler)dynamicGet.CreateDelegate(typeof(GetHandler)); + } + + // CreateGetDelegate + internal static GetHandler CreateGetHandler(Type type, FieldInfo fieldInfo) + { + DynamicMethod dynamicGet = CreateGetDynamicMethod(type); + ILGenerator getGenerator = dynamicGet.GetILGenerator(); + + getGenerator.Emit(OpCodes.Ldarg_0); + getGenerator.Emit(OpCodes.Ldfld, fieldInfo); + BoxIfNeeded(fieldInfo.FieldType, getGenerator); + getGenerator.Emit(OpCodes.Ret); + + return (GetHandler)dynamicGet.CreateDelegate(typeof(GetHandler)); + } + + // CreateSetDelegate + internal static SetHandler CreateSetHandler(Type type, PropertyInfo propertyInfo) + { + MethodInfo setMethodInfo = propertyInfo.GetSetMethod(true); + DynamicMethod dynamicSet = CreateSetDynamicMethod(type); + ILGenerator setGenerator = dynamicSet.GetILGenerator(); + + setGenerator.Emit(OpCodes.Ldarg_0); + setGenerator.Emit(OpCodes.Ldarg_1); + UnboxIfNeeded(setMethodInfo.GetParameters()[0].ParameterType, setGenerator); + setGenerator.Emit(OpCodes.Call, setMethodInfo); + setGenerator.Emit(OpCodes.Ret); + + return (SetHandler)dynamicSet.CreateDelegate(typeof(SetHandler)); + } + + // CreateSetDelegate + internal static SetHandler CreateSetHandler(Type type, FieldInfo fieldInfo) + { + DynamicMethod dynamicSet = CreateSetDynamicMethod(type); + ILGenerator setGenerator = dynamicSet.GetILGenerator(); + + setGenerator.Emit(OpCodes.Ldarg_0); + setGenerator.Emit(OpCodes.Ldarg_1); + UnboxIfNeeded(fieldInfo.FieldType, setGenerator); + setGenerator.Emit(OpCodes.Stfld, fieldInfo); + setGenerator.Emit(OpCodes.Ret); + + return (SetHandler)dynamicSet.CreateDelegate(typeof(SetHandler)); + } + + // CreateGetDynamicMethod + private static DynamicMethod CreateGetDynamicMethod(Type type) + { + return new DynamicMethod("DynamicGet", typeof(object), new[] { typeof(object) }, type, true); + } + + // CreateSetDynamicMethod + private static DynamicMethod CreateSetDynamicMethod(Type type) + { + return new DynamicMethod("DynamicSet", typeof(void), new[] { typeof(object), typeof(object) }, type, true); + } + + // BoxIfNeeded + private static void BoxIfNeeded(Type type, ILGenerator generator) + { + if (type.IsValueType) + { + generator.Emit(OpCodes.Box, type); + } + } + + // UnboxIfNeeded + private static void UnboxIfNeeded(Type type, ILGenerator generator) + { + if (type.IsValueType) + { + generator.Emit(OpCodes.Unbox_Any, type); + } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Emit/FunctionFactory.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Emit/FunctionFactory.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,323 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Reflection.Emit; + +namespace BLToolkit.Emit +{ + /// + /// Creates and compiles types instances and methods using expressions, IL code generation + /// + /// + /// Inspired from: + /// http://abhi.dcmembers.com/blog/2009/03/25/lambda-based-reflection-vs-normal-reflection-vs-direct-call-4/ + /// + public static class FunctionFactory + { + #region Delegates + + public delegate object GenericGetter(object target); + + public delegate void GenericSetter(object target, object value); + + #endregion + + #region Nested type: Il + + public static class Il + { + public static object CreateInstance(Type type) + { + InstantiateObjectHandler instantiateObjectHandler = + DynamicMethodCompiler.CreateInstantiateObjectHandler(type); + + return instantiateObjectHandler(); + } + + public static T CreateInstance() + { + return (T) CreateInstance(typeof (T)); + } + + public static SetHandler CreateSetHandler(Type type, string property) + { + PropertyInfo propertyInfo = type.GetProperty(property); + return CreateSetHandler(type, propertyInfo); + } + + public static SetHandler CreateSetHandler(Type type, PropertyInfo propertyInfo) + { + SetHandler setHandler = DynamicMethodCompiler.CreateSetHandler(type, propertyInfo); + return setHandler; + } + + public static SetHandler CreateSetHandler(string property) + { + return CreateSetHandler(typeof (T), property); + } + + public static GetHandler CreateGetHandler(Type type, PropertyInfo propertyInfo) + { + GetHandler getHandler = DynamicMethodCompiler.CreateGetHandler(type, propertyInfo); + return getHandler; + } + + public static GetHandler CreateGetHandler(PropertyInfo propertyInfo) + { + return CreateGetHandler(typeof (T), propertyInfo); + } + + public static GetHandler CreateGetHandler(string property) + { + PropertyInfo propertyInfo = typeof (T).GetProperty(property); + return CreateGetHandler(propertyInfo); + } + + /// + /// Creates a dynamic setter for the property + /// + public static GenericSetter CreateSetMethod(PropertyInfo propertyInfo) + { + /* + * If there's no setter return null + */ + MethodInfo setMethod = propertyInfo.GetSetMethod(); + if (setMethod == null) + return null; + + /* + * Create the dynamic method + */ + var arguments = new Type[2]; + arguments[0] = arguments[1] = typeof (object); + + var setter = new DynamicMethod( + String.Concat("_Set", propertyInfo.Name, "_"), + typeof (void), arguments, propertyInfo.DeclaringType); + ILGenerator generator = setter.GetILGenerator(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Castclass, propertyInfo.DeclaringType); + generator.Emit(OpCodes.Ldarg_1); + + if (propertyInfo.PropertyType.IsClass) + generator.Emit(OpCodes.Castclass, propertyInfo.PropertyType); + else + generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); + + generator.EmitCall(OpCodes.Callvirt, setMethod, null); + generator.Emit(OpCodes.Ret); + + /* + * Create the delegate and return it + */ + return (GenericSetter) setter.CreateDelegate(typeof (GenericSetter)); + } + + /// + /// Creates a dynamic getter for the property + /// + public static GenericGetter CreateGetMethod(PropertyInfo propertyInfo) + { + /* + * If there's no getter return null + */ + MethodInfo getMethod = propertyInfo.GetGetMethod(); + if (getMethod == null) + return null; + + /* + * Create the dynamic method + */ + var arguments = new Type[1]; + arguments[0] = typeof (object); + + var getter = new DynamicMethod( + String.Concat("_Get", propertyInfo.Name, "_"), + typeof (object), arguments, propertyInfo.DeclaringType); + + ILGenerator generator = getter.GetILGenerator(); + generator.DeclareLocal(typeof (object)); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Castclass, propertyInfo.DeclaringType); + generator.EmitCall(OpCodes.Callvirt, getMethod, null); + + if (!propertyInfo.PropertyType.IsClass) + generator.Emit(OpCodes.Box, propertyInfo.PropertyType); + + generator.Emit(OpCodes.Ret); + + /* + * Create the delegate and return it + */ + return (GenericGetter) getter.CreateDelegate(typeof (GenericGetter)); + } + } + + #endregion + + #region Nested type: Lambda + + public static class Lambda + { + public static T CreateInstance() + { + return InstanceCreator.CreateInstance(); + } + + public static List CreateListInstance() + { + return InstanceCreator.CreateListInstance(); + } + + public static Action BuildSet(string property) + { + string[] props = property.Split('.'); + Type type = typeof (T); + ParameterExpression arg = Expression.Parameter(type, "x"); + ParameterExpression valArg = Expression.Parameter(typeof (TValue), "val"); + Expression expr = arg; + foreach (string prop in props.Take(props.Length - 1)) + { + // use reflection (not ComponentModel) to mirror LINQ + PropertyInfo pi = type.GetProperty(prop); + expr = Expression.Property(expr, pi); + type = pi.PropertyType; + } + // final property set... + PropertyInfo finalProp = type.GetProperty(props.Last()); + MethodInfo setter = finalProp.GetSetMethod(); + expr = Expression.Call(expr, setter, valArg); + return Expression.Lambda>(expr, arg, valArg).Compile(); + } + + public static Func BuildGet(string property) + { + string[] props = property.Split('.'); + Type type = typeof (T); + ParameterExpression arg = Expression.Parameter(type, "x"); + Expression expr = arg; + foreach (string prop in props) + { + // use reflection (not ComponentModel) to mirror LINQ + PropertyInfo pi = type.GetProperty(prop); + expr = Expression.Property(expr, pi); + type = pi.PropertyType; + } + return Expression.Lambda>(expr, arg).Compile(); + } + + /// + /// Creates a compiled delegate function for the specified type and method name + /// + /// Delegate Func to create + /// Constant to get method from + /// Method to examine + /// Delegate function of the specified methodname + public static TFunc CreateFunc(object obj, string methodName) + { + var args = new List(); + + Type targetType = obj.GetType(); + MethodInfo minfo = targetType.GetMethod(methodName, + BindingFlags.Instance | BindingFlags.Public | + BindingFlags.SetProperty); + + if (minfo != null) + { + ConstantExpression target = Expression.Constant(obj); + foreach (ParameterInfo arg in minfo.GetParameters()) + args.Add(Expression.Parameter(arg.ParameterType, arg.Name)); + MethodCallExpression methodinvokeExpression = Expression.Call(target, minfo, args.ToArray()); + Expression lambda = Expression.Lambda(methodinvokeExpression, args.ToArray()); + + //now the following Lambda is created: + // (TArg1, TArg2) => obj.MethodName(TArg1, TArg2); + + return lambda.Compile(); + } + return default(TFunc); + } + + /// + /// Creates a compiled delegate function using expressions, + /// the first Func{TObject,TReturn} parameter must be the constant to be passed in + /// + /// Delegate Func to create + /// Type of constant to pass in to the Func + /// Method to examine + /// Delegate function of the specified methodname + /// + /// The function Func{TType,TArg1,TArg2} with a method name of "CallMe" would create the following + /// lambda: + /// + /// (TType, TArg1, TArg2) => TType.CallMe(TArg1, TArg2); + /// + /// + public static TFunc CreateFunc(Type targetType, string methodName) + { + var args = new List(); + MethodInfo minfo = targetType.GetMethod(methodName, + BindingFlags.Instance | BindingFlags.Public | + BindingFlags.SetProperty); + + if (minfo != null) + { + Type objectType = typeof (TFunc).GetGenericArguments().First(); + ParameterExpression targetParam = Expression.Parameter(objectType, "a"); + + if (!targetType.IsAssignableFrom(objectType)) + throw new InvalidCastException(string.Format("{0} cannot be cast to {1}", targetType.Name, + objectType.Name)); + + UnaryExpression target = Expression.Convert(targetParam, targetType); + foreach (ParameterInfo arg in minfo.GetParameters()) + args.Add(Expression.Parameter(arg.ParameterType, arg.Name)); + + MethodCallExpression methodinvokeExpression = Expression.Call(target, minfo, args.ToArray()); + Expression lambda = Expression.Lambda(methodinvokeExpression, + new[] {targetParam}.Concat(args)); + + //now the following Lambda is created: + // (a, TArg1, TArg2) => a.MethodName(TArg1, TArg2); + + return lambda.Compile(); + } + return default(TFunc); + } + + #region Nested type: InstanceCreator + + private static class InstanceCreator + { + public static readonly Func CreateInstance = + Expression.Lambda>(Expression.New(typeof (T))).Compile(); + + public static readonly Func> CreateListInstance = + Expression.Lambda>>(Expression.New(typeof(List))).Compile(); + } + + #endregion + } + + #endregion + + #region Nested type: Remote + + public static class Remote + { + public static T CreateInstance() + { + return Activator.CreateInstance(); + } + + public static object CreateInstance(Type type) + { + return Activator.CreateInstance(type); + } + } + + #endregion + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/CollectionFullObjectMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/CollectionFullObjectMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using BLToolkit.Data; +using BLToolkit.DataAccess; +using BLToolkit.Emit; + +namespace BLToolkit.Mapping +{ + public class CollectionFullObjectMapper : TableDescription, IObjectMapper + { + private readonly DbManager _db; + private readonly FactoryType _factoryType; + + public CollectionFullObjectMapper(DbManager db, FactoryType factoryType) + { + _db = db; + _factoryType = factoryType; + + PropertiesMapping = new List(); + PrimaryKeyValueGetters = new List(); + PrimaryKeyNames = new List(); + } + + public Type PropertyCollectionType { get; set; } + + #region IMapper Members + + public int DataReaderIndex { get; set; } + public SetHandler Setter { get; set; } + public Type PropertyType { get; set; } + public string PropertyName { get; set; } + + #endregion + + #region IObjectMapper + + public bool IsLazy { get; set; } + public bool ContainsLazyChild { get; set; } + public GetHandler Getter { get; set; } + + public List PrimaryKeyValueGetters { get; set; } + public Association Association { get; set; } + + public List PrimaryKeyNames { get; set; } + + #endregion + + #region ILazyMapper + + public GetHandler ParentKeyGetter { get; set; } + + #endregion + + public object CreateInstance() + { + object result = ContainsLazyChild + ? (_factoryType == FactoryType.LazyLoading + ? TypeFactory.LazyLoading.Create(PropertyType, this, LoadLazy) + : TypeFactory.LazyLoadingWithDataBinding.Create(PropertyType, this, LoadLazy)) + : FunctionFactory.Remote.CreateInstance(PropertyType); + + return result; + } + + private object LoadLazy(IMapper mapper, object proxy, Type parentType) + { + var lazyMapper = (ILazyMapper) mapper; + object key = lazyMapper.ParentKeyGetter(proxy); + + var fullSqlQuery = new FullSqlQuery(_db, true); + object parentLoadFull = fullSqlQuery.SelectByKey(parentType, key); + if (parentLoadFull == null) + { + object value = Activator.CreateInstance(mapper is CollectionFullObjectMapper + ? (mapper as CollectionFullObjectMapper).PropertyCollectionType + : mapper.PropertyType); + return value; + } + + var objectMapper = (IObjectMapper) mapper; + return objectMapper.Getter(parentLoadFull); + } + + #region IPropertiesMapping Members + + public List PropertiesMapping { get; private set; } + public IPropertiesMapping ParentMapping { get; set; } + + #endregion + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/DataBindingFactory.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/DataBindingFactory.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,69 @@ +using System; +using System.ComponentModel; +using Castle.DynamicProxy; + +namespace BLToolkit.Mapping +{ + public static class DataBindingFactory + { + private static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator(); + + public static T Create() + { + return (T) Create(typeof (T)); + } + + public static object Create(Type type) + { + return ProxyGenerator.CreateClassProxy(type, new[] + { + typeof (INotifyPropertyChanged), + typeof (IMarkerInterface) + }, new NotifyPropertyChangedInterceptor(type.FullName)); + } + + public interface IMarkerInterface + { + string TypeName { get; } + } + + public class NotifyPropertyChangedInterceptor : IInterceptor + { + private readonly string typeName; + private PropertyChangedEventHandler subscribers = delegate { }; + + public NotifyPropertyChangedInterceptor(string typeName) + { + this.typeName = typeName; + } + + public void Intercept(IInvocation invocation) + { + if (invocation.Method.DeclaringType == typeof (IMarkerInterface)) + { + invocation.ReturnValue = typeName; + return; + } + if (invocation.Method.DeclaringType == typeof (INotifyPropertyChanged)) + { + var propertyChangedEventHandler = (PropertyChangedEventHandler) invocation.Arguments[0]; + if (invocation.Method.Name.StartsWith("add_")) + { + subscribers += propertyChangedEventHandler; + } + else + { + subscribers -= propertyChangedEventHandler; + } + return; + } + invocation.Proceed(); + if (invocation.Method.Name.StartsWith("set_")) + { + var propertyName = invocation.Method.Name.Substring(4); + subscribers(invocation.InvocationTarget, new PropertyChangedEventArgs(propertyName)); + } + } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/DataBindingMappingSchema.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/DataBindingMappingSchema.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,33 @@ +using System; +using BLToolkit.Data; + +namespace BLToolkit.Mapping +{ + public class DataBindingMappingSchema : MappingSchema + { + protected override ObjectMapper CreateObjectMapperInstance(Type type) + { + var res = new DataBindingObjectMapper(type); + + return res; + } + } + + public class FullDataBindingMappingSchema : FullMappingSchema + { + private readonly DbManager _db; + private readonly bool _ignoreLazyLoad; + + public FullDataBindingMappingSchema(DbManager db, bool ignoreLazyLoad = false, MappingSchema parentMappingSchema = null) + : base(db, ignoreLazyLoad, parentMappingSchema, FactoryType.LazyLoadingWithDataBinding) + { + _db = db; + _ignoreLazyLoad = ignoreLazyLoad; + } + + protected override ObjectMapper CreateObjectMapperInstance(Type type) + { + return new FullDataBindingObjectMapper(_db, _ignoreLazyLoad); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/DataBindingObjectMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/DataBindingObjectMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,46 @@ +#region + +using System; +using BLToolkit.Data; +using BLToolkit.Reflection; + +#endregion + +namespace BLToolkit.Mapping +{ + public class DataBindingObjectMapper : ObjectMapper + { + private readonly Type _type; + + public DataBindingObjectMapper(Type type) + { + _type = type; + } + + public override object CreateInstance() + { + return TypeFactory.DataBindingFactory.Create(_type); + } + + public override object CreateInstance(InitContext context) + { + return CreateInstance(); + } + } + + public class FullDataBindingObjectMapper : FullObjectMapper + { + public FullDataBindingObjectMapper(DbManager db, bool ignoreLazyLoading) : base(db, ignoreLazyLoading, FactoryType.LazyLoadingWithDataBinding) + { + } + + public override object CreateInstance() + { + object result = ContainsLazyChild + ? TypeFactory.LazyLoadingWithDataBinding.Create(PropertyType, this, LoadLazy) + : base.CreateInstance(); + + return result; + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/FactoryType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/FactoryType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +namespace BLToolkit.Mapping +{ + public enum FactoryType + { + LazyLoading, + LazyLoadingWithDataBinding, + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/FullMappingSchema.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/FullMappingSchema.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,306 @@ +#region + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using BLToolkit.Data; +using BLToolkit.Reflection.Extension; + +#endregion + +namespace BLToolkit.Mapping +{ + public class FullMappingSchema : MappingSchema + { + #region Fields + + private readonly DbManager _db; + private readonly bool _ignoreLazyLoad; + private DataTable _schema; + private List _schemaColumns; + private readonly MappingSchema _parentMappingSchema; + private readonly FactoryType _factoryType; + + private ExtensionList _extensions; + + #endregion + + public FullMappingSchema(DbManager db, bool ignoreLazyLoad = false, MappingSchema parentMappingSchema = null, + FactoryType factoryType = FactoryType.LazyLoading) + { + _db = db; + _parentMappingSchema = parentMappingSchema; + _factoryType = factoryType; + _ignoreLazyLoad = ignoreLazyLoad; + } + + #region Overrides + + public override ExtensionList Extensions + { + get + { + if (_parentMappingSchema != null) + return this._parentMappingSchema.Extensions; + return _extensions; + } + set + { + if (_parentMappingSchema != null) + this._parentMappingSchema.Extensions = value; + _extensions = value; + } + } + + protected override ObjectMapper CreateObjectMapperInstance(Type type) + { + return new FullObjectMapper(_db, _ignoreLazyLoad,_factoryType); + } + + protected override void MapInternal(Reflection.InitContext initContext, IMapDataSource source, object sourceObject, IMapDataDestination dest, object destObject, params object[] parameters) + { + FullObjectMapper mapper = (FullObjectMapper)initContext.ObjectMapper; + IDataReader dataReader = (IDataReader)sourceObject; + + //int[] index = GetIndex(source, dest); + //IValueMapper[] mappers = GetValueMappers(source, dest, index); + + //foreach (var valueMapper in mappers) + //{ + + //} + + InitSchema(dataReader); + + if (mapper.ColParent) + { + FillObject(mapper, dataReader, destObject); + while (dataReader.Read()) + { + destObject = FillObject(destObject, mapper, dataReader); + } + } + else + FillObject(mapper, dataReader, destObject); + } + + public override IList MapDataReaderToList( + IDataReader reader, + IList list, + Type destObjectType, + params object[] parameters) + { + return internalMapDataReaderToList(reader, list, destObjectType, parameters); + } + + #endregion + + #region Private methods + + private object FillObject(object result, IObjectMapper mapper, IDataReader datareader) + { + foreach (IMapper map in mapper.PropertiesMapping) + { + if (map is IObjectMapper && (map as IObjectMapper).IsLazy) + continue; + + if (map is CollectionFullObjectMapper) + { + var collectionFullObjectMapper = (CollectionFullObjectMapper) map; + object listInstance = collectionFullObjectMapper.Getter(result); + if (listInstance == null) + { + listInstance = Activator.CreateInstance((map as CollectionFullObjectMapper).PropertyCollectionType); + map.Setter(result, listInstance); + } + var list = (IList) listInstance; + object fillObject = ((CollectionFullObjectMapper)map).CreateInstance(); + FillObject((CollectionFullObjectMapper) map, datareader, fillObject); + + if (list.Count > 0) + { + var curMapper = (FullObjectMapper)GetObjectMapper(fillObject.GetType()); + + object lastElement = list[list.Count - 1]; + + bool allPksEqual = true; + + //This is needed, because DBValue can be Null, but the Field can be Guid, wich then is filled with Guid.Empty and this is also a valid value! + /*foreach (var pkIndex in pkIndexes) + { + var dbValue = reader.GetValue(pkIndex); + if (dbValue == DBNull.Value) + { + pkIsNull = true; + break; + } + }*/ + + foreach (var pkGetter in curMapper.PrimaryKeyValueGetters) + { + object lastPk = pkGetter.Invoke(lastElement); + object currentPk = pkGetter.Invoke(fillObject); + + if (!lastPk.Equals(currentPk)) + { + allPksEqual = false; + break; + } + } + + if (allPksEqual) + continue; + } + + ((IList) listInstance).Add(fillObject); + } + } + + return result; + } + + private void FillObject(IObjectMapper mapper, IDataReader datareader, object result) + { + foreach (IMapper map in mapper.PropertiesMapping) + { + if (map is IObjectMapper && (map as IObjectMapper).IsLazy) + continue; + + if (map is ValueMapper) + { + if (((ValueMapper)map).SetDataReaderIndex(_schemaColumns)) + continue; + } + + if (datareader.IsDBNull(map.DataReaderIndex)) + continue; + + if (map is ValueMapper) + { + object value = datareader.GetValue(map.DataReaderIndex); + + try + { + map.Setter(result, value); + } + catch (Exception exception) + { + throw new Exception( + string.Format("FillOject failed for field : {0} of class: {1}.\nColumn name : {2} Db type is: {3} and value : {4}", + map.PropertyName, mapper.PropertyType, + ((ValueMapper) map).ColumnName, + value == null ? "Null" : value.GetType().ToString(), value), exception); + } + } + + if (map is FullObjectMapper) + { + object fillObject = ((FullObjectMapper) map).CreateInstance(); + FillObject((FullObjectMapper) map, datareader, fillObject); + map.Setter(result, fillObject); + } + + if (map is CollectionFullObjectMapper) + { + var collectionFullObjectMapper = (CollectionFullObjectMapper) map; + + object listInstance = collectionFullObjectMapper.Getter(result); + if (listInstance == null) + { + listInstance = Activator.CreateInstance((map as CollectionFullObjectMapper).PropertyCollectionType); + map.Setter(result, listInstance); + } + + object fillObject = ((CollectionFullObjectMapper)map).CreateInstance(); + FillObject((CollectionFullObjectMapper) map, datareader, fillObject); + ((IList) listInstance).Add(fillObject); + } + } + } + + private void InitSchema(IDataReader reader) + { + _schemaColumns = new List(); + _schema = reader.GetSchemaTable(); + if (_schema != null) + _schema.Rows.Cast().ToList().ForEach(dr => _schemaColumns.Add((string)dr["ColumnName"])); + } + + private IList internalMapDataReaderToList( + IDataReader reader, + IList list, + Type destObjectType, + params object[] parameters) + { + FullObjectMapper mapper = (FullObjectMapper)GetObjectMapper(destObjectType); + + InitSchema(reader); + + object currentItem = null; + + List pkIndexes = new List(); + foreach (var nm in mapper.PrimaryKeyNames) + { + pkIndexes.Add(mapper.PropertiesMapping.First(x => x.PropertyName == nm).DataReaderIndex); + } + + while (reader.Read()) + { + var result = mapper.CreateInstance(); + + FillObject(mapper, reader, result); + if (currentItem == null) + { + currentItem = result; + list.Add(result); + continue; + } + + bool pkIsNull = false; + bool allPksEqual = true; + + //This is needed, because DBValue can be Null, but the Field can be Guid, wich then is filled with Guid.Empty and this is also a valid value! + foreach (var pkIndex in pkIndexes) + { + var dbValue = reader.GetValue(pkIndex); + if (dbValue == DBNull.Value) + { + pkIsNull = true; + break; + } + } + + if (!pkIsNull) + foreach (var pkGetter in mapper.PrimaryKeyValueGetters) + { + object resultPk = pkGetter.Invoke(result); + object currentItemPk = pkGetter.Invoke(currentItem); + + if (!resultPk.Equals(currentItemPk)) + { + allPksEqual = false; + break; + } + } + + if (!pkIsNull && !allPksEqual) + { + currentItem = result; + list.Add(result); + //continue; + } + + if (mapper.ColParent) + { + FillObject(currentItem, mapper, reader); + } + } + + return list; + } + + #endregion + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/FullObjectMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/FullObjectMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,354 @@ +#region + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using BLToolkit.Data; +using BLToolkit.DataAccess; +using BLToolkit.Emit; +using BLToolkit.Reflection; +using BLToolkit.Reflection.Extension; + +#endregion + +namespace BLToolkit.Mapping +{ + public class FullObjectMapper : ObjectMapper, IObjectMapper + { + #region Fields + + private static readonly object SetterHandlersLock = new object(); + + private static readonly Dictionary> SettersHandlers = + new Dictionary>(); + + private static readonly Dictionary> GettersHandlers = + new Dictionary>(); + + private readonly DbManager _db; + private readonly FactoryType _factoryType; + private readonly bool _ignoreLazyLoad; + + #endregion + + public FullObjectMapper(DbManager db, bool ignoreLazyLoading, FactoryType factoryType) + { + _db = db; + _ignoreLazyLoad = ignoreLazyLoading; + _factoryType = factoryType; + + PropertiesMapping = new List(); + PrimaryKeyValueGetters = new List(); + PrimaryKeyNames = new List(); + } + + #region IPropertiesMapping Members + + public List PropertiesMapping { get; private set; } + public IPropertiesMapping ParentMapping { get; set; } + + #endregion + + public bool IsNullable { get; set; } + public bool ColParent { get; set; } + + #region IMapper Members + + public int DataReaderIndex { get; set; } + public SetHandler Setter { get; set; } + public Type PropertyType { get; set; } + public string PropertyName { get; set; } + public Association Association { get; set; } + + #endregion + + #region IObjectMapper + + public bool IsLazy { get; set; } + public bool ContainsLazyChild { get; set; } + public GetHandler Getter { get; set; } + + public List PrimaryKeyNames { get; set; } + + #endregion + + #region ILazyMapper + + public GetHandler ParentKeyGetter { get; set; } + public List PrimaryKeyValueGetters { get; set; } + + #endregion + + #region Overrides + + public override void Init(MappingSchema mappingSchema, Type type) + { + PropertyType = type; + + // TODO implement this method + base.Init(mappingSchema, type); + + int startIndex = 0; + GetObjectMapper(this, ref startIndex, _typeAccessor); + } + + public override object CreateInstance() + { + object result = ContainsLazyChild + ? (_factoryType == FactoryType.LazyLoading + ? TypeFactory.LazyLoading.Create(PropertyType, this, LoadLazy) + : TypeFactory.LazyLoadingWithDataBinding.Create(PropertyType, this, LoadLazy)) + : FunctionFactory.Remote.CreateInstance(PropertyType); + + return result; + } + + public override object CreateInstance(InitContext context) + { + return CreateInstance(); + } + + #endregion + + #region Private methods + + private TableDescription GetTableDescription(Type type) + { + var tableDescription = new TableDescription(); + object[] tableAtt = type.GetCustomAttributes(typeof (TableNameAttribute), true); + + if (tableAtt.Length > 0) + { + var tna = (TableNameAttribute) tableAtt[0]; + + tableDescription.Database = tna.Database; + tableDescription.Owner = tna.Owner; + tableDescription.TableName = tna.Name; + } + + return tableDescription; + } + + private IMapper GetObjectMapper(IObjectMapper mapper, ref int startIndex, TypeAccessor akTypeAccessor) + { + //Todo: Remove this Call! + _extension = TypeExtension.GetTypeExtension(mapper.PropertyType /*_typeAccessor.OriginalType*/, MappingSchema.Extensions); + + Type mapperType = mapper.PropertyType; + var objectMappers = new List(); + + TableDescription tableDescription = GetTableDescription(mapperType); + + lock (SetterHandlersLock) + { + if (!SettersHandlers.ContainsKey(mapperType)) + SettersHandlers.Add(mapperType, new Dictionary()); + + if (!GettersHandlers.ContainsKey(mapperType)) + GettersHandlers.Add(mapperType, new Dictionary()); + } + + PropertyInfo[] properties = mapperType.GetProperties(); + + MemberAccessor primaryKeyMemberAccessor = null; + foreach (MemberAccessor ma in akTypeAccessor) + { + // Setters + lock (SetterHandlersLock) + { + if (!SettersHandlers[mapper.PropertyType].ContainsKey(ma.Name)) + { + SettersHandlers[mapper.PropertyType].Add(ma.Name, ma.SetValue); + } + } + + if (GetPrimaryKey(ma) != null) + { + primaryKeyMemberAccessor = ma; + + lock (SetterHandlersLock) + { + if (!GettersHandlers[mapperType].ContainsKey(ma.Name)) + { + GettersHandlers[mapperType].Add(ma.Name, ma.GetValue); + } + } + mapper.PrimaryKeyValueGetters.Add(GettersHandlers[mapperType][ma.Name]); + mapper.PrimaryKeyNames.Add(ma.Name); + + if (mapper.Association != null && (mapper.Association.OtherKey == null || mapper.Association.OtherKey.Length == 0)) + { + mapper.Association.OtherKey = new[] {ma.Name}; + } + } + } + if (primaryKeyMemberAccessor == null) + throw new Exception("PrimaryKey attribute not found on type: " + mapperType); + + foreach (PropertyInfo prop in properties) + { + var ma = akTypeAccessor.First(x => x.Name == prop.Name); + + // Check if the accessor is an association + var association = GetAssociation(ma); + if (association != null) + { + // Getters for IObjectMapper + lock (SetterHandlersLock) + if (!GettersHandlers[mapperType].ContainsKey(prop.Name)) + { + GettersHandlers[mapperType].Add(prop.Name, ma.GetValue); + } + + bool isCollection = prop.PropertyType.GetInterfaces().ToList().Contains(typeof (IList)); + IObjectMapper propertiesMapping; + if (!isCollection) + { + // TODO Generate this instance using the CreateObjectMapperInstance method of fullMappingSchema + // _db.MappingSchema.CreateObjectMapperInstance(prop.PropertyType) + + propertiesMapping = new FullObjectMapper(_db, _ignoreLazyLoad, _factoryType) + { + PropertyType = prop.PropertyType, + IsNullable = association.CanBeNull, + Getter = GettersHandlers[mapperType][prop.Name], + }; + } + else + { + Type listElementType = GetGenericType(prop.PropertyType); + TableDescription colElementTableDescription = GetTableDescription(listElementType); + + // TODO Generate this instance using the CreateObjectMapperInstance method of fullMappingSchema + propertiesMapping = new CollectionFullObjectMapper(_db, _factoryType) + { + PropertyType = listElementType, + Getter = GettersHandlers[mapperType][prop.Name], + TableName = colElementTableDescription.TableName, + PropertyCollectionType = prop.PropertyType, + }; + + if (mapper is FullObjectMapper) + ((FullObjectMapper) mapper).ColParent = true; + } + + if (association.ThisKey == null || association.ThisKey.Length == 0) + association.ThisKey = new[] {primaryKeyMemberAccessor.Name}; + + bool isLazy = false; + if (!_ignoreLazyLoad) + { + var lazy = GetLazyInstance(ma); // prop.GetCustomAttributes(typeof(LazyInstanceAttribute), true); + if (lazy) + { + isLazy = true; + mapper.ContainsLazyChild = true; + + // Getters + lock (SetterHandlersLock) + if (!GettersHandlers[mapperType].ContainsKey(primaryKeyMemberAccessor.Name)) + { + GettersHandlers[mapperType].Add(primaryKeyMemberAccessor.Name, primaryKeyMemberAccessor.GetValue); + } + } + } + + propertiesMapping.Association = association; + propertiesMapping.PropertyName = prop.Name; + propertiesMapping.IsLazy = isLazy; + propertiesMapping.Setter = SettersHandlers[mapperType][prop.Name]; + + if (propertiesMapping.IsLazy) + { + propertiesMapping.ParentKeyGetter = GettersHandlers[mapperType][primaryKeyMemberAccessor.Name]; + } + objectMappers.Add(propertiesMapping); + } + else + { + var mapIgnore = GetMapIgnore(ma); + if (mapIgnore) + continue; + + var mapField = GetMapField(ma); + string columnName = mapField != null ? mapField.MapName : prop.Name; + + var map = new ValueMapper + { + PropertyName = prop.Name, + PropertyType = prop.PropertyType, + DataReaderIndex = startIndex, + Setter = SettersHandlers[mapperType][prop.Name], + TableName = tableDescription.TableName, + ColumnName = columnName, + }; + + var mapColumnName = map.GetColumnName(columnName); + map.ColumnAlias = columnName == mapColumnName ? null : mapColumnName; + + mapper.PropertiesMapping.Add(map); + + var pkField = GetPrimaryKey(ma); + if (pkField != null) + mapper.DataReaderIndex = startIndex; + + startIndex++; + } + } + + foreach (IObjectMapper objMap in objectMappers) + { + #region Check mapping recursion + + IObjectMapper cel = mapper; + while (cel != null) + { + if (mapper.PropertyType == objMap.PropertyType) + continue; + + cel = (IObjectMapper) cel.ParentMapping; + } + + #endregion + + objMap.ParentMapping = mapper; + mapper.PropertiesMapping.Add(GetObjectMapper(objMap, ref startIndex, MappingSchema.GetObjectMapper(objMap.PropertyType).TypeAccessor)); + } + + return mapper; + } + + protected object LoadLazy(IMapper mapper, object proxy, Type parentType) + { + var lazyMapper = (ILazyMapper) mapper; + object key = lazyMapper.ParentKeyGetter(proxy); + + var fullSqlQuery = new FullSqlQuery(_db, ignoreLazyLoad: true); + object parentLoadFull = fullSqlQuery.SelectByKey(parentType, key); + if (parentLoadFull == null) + { + object value = Activator.CreateInstance(mapper is CollectionFullObjectMapper + ? (mapper as CollectionFullObjectMapper).PropertyCollectionType + : mapper.PropertyType); + return value; + } + + var objectMapper = (IObjectMapper) mapper; + return objectMapper.Getter(parentLoadFull); + } + + private static Type GetGenericType(Type t) + { + if (t.IsGenericType) + { + Type[] at = t.GetGenericArguments(); + return at.FirstOrDefault(); + } + return null; + } + + #endregion + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/ILazyMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/ILazyMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using BLToolkit.Emit; + +namespace BLToolkit.Mapping +{ + public interface ILazyMapper + { + GetHandler ParentKeyGetter { get; set; } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/IMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/IMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; +using BLToolkit.Emit; + +namespace BLToolkit.Mapping +{ + public interface IMapper + { + int DataReaderIndex { get; set; } + SetHandler Setter { get; set; } + Type PropertyType { get; set; } + string PropertyName { get; set; } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/IObjectMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/IObjectMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ + +using System.Collections.Generic; +using BLToolkit.Emit; + +namespace BLToolkit.Mapping +{ + public interface IObjectMapper : IPropertiesMapping, IMapper, ILazyMapper + { + bool IsLazy { get; set; } + + bool ContainsLazyChild { get; set; } + + List PrimaryKeyNames { get; set; } + + /// + /// Is set only for CollectionFullObjectMapper. TODO : Should refactor this? + /// + GetHandler Getter { get; set; } + + List PrimaryKeyValueGetters { get; set; } + Association Association { get; set; } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/IPropertiesMapping.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/IPropertiesMapping.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace BLToolkit.Mapping +{ + public interface IPropertiesMapping + { + List PropertiesMapping { get; } + IPropertiesMapping ParentMapping { get; set; } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/LazyValueLoadInterceptor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/LazyValueLoadInterceptor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +using System; +using Castle.DynamicProxy; +using IInterceptor = Castle.DynamicProxy.IInterceptor; + +namespace BLToolkit.Mapping +{ + public class LazyValueLoadInterceptor : IInterceptor + { + #region Fields + + private readonly IObjectMapper _mapper; + private readonly Func _lazyLoader; + private bool _intercepted; + + #endregion + + public LazyValueLoadInterceptor(IObjectMapper mapper, Func lazyLoader) + { + _mapper = mapper; + _lazyLoader = lazyLoader; + } + + public void Intercept(IInvocation invocation) + { + if (invocation.Method.Name.StartsWith("get_")) + { + string propertyName = invocation.Method.Name.Substring(4); + + foreach (IMapper map in _mapper.PropertiesMapping) + { + if (map.PropertyName == propertyName) + { + if (!_intercepted) + { + _intercepted = true; + map.Setter(invocation.Proxy, _lazyLoader(map, invocation.Proxy, invocation.TargetType)); + } + break; + } + } + } + + // let the original call go through first, so we can notify *after* + invocation.Proceed(); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/MappingOrder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/MappingOrder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +namespace BLToolkit.Mapping +{ + public enum MappingOrder + { + ByColumnName, + ByColumnIndex, + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/NotifyPropertyChangedInterceptor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/NotifyPropertyChangedInterceptor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,48 @@ +#region + +using System.ComponentModel; +using Castle.DynamicProxy; + +#endregion + +namespace BLToolkit.Mapping +{ + public class NotifyPropertyChangedInterceptor : IInterceptor + { + private readonly string _typeName; + private PropertyChangedEventHandler _subscribers = delegate { }; + + public NotifyPropertyChangedInterceptor(string typeName) + { + _typeName = typeName; + } + + public void Intercept(IInvocation invocation) + { + if (invocation.Method.DeclaringType == typeof (TypeFactory.DataBindingFactory.IMarkerInterface)) + { + invocation.ReturnValue = _typeName; + return; + } + if (invocation.Method.DeclaringType == typeof (INotifyPropertyChanged)) + { + var propertyChangedEventHandler = (PropertyChangedEventHandler) invocation.Arguments[0]; + if (invocation.Method.Name.StartsWith("add_")) + { + _subscribers += propertyChangedEventHandler; + } + else + { + _subscribers -= propertyChangedEventHandler; + } + return; + } + invocation.Proceed(); + if (invocation.Method.Name.StartsWith("set_")) + { + var propertyName = invocation.Method.Name.Substring(4); + _subscribers(invocation.InvocationTarget, new PropertyChangedEventArgs(propertyName)); + } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/OwnerDescription.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/OwnerDescription.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +namespace BLToolkit.Mapping +{ + public class OwnerDescription + { + public string Database { get; set; } + public string Owner { get; set; } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/TableDescription.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/TableDescription.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ +namespace BLToolkit.Mapping +{ + public class TableDescription : OwnerDescription + { + public string TableName { get; set; } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/TypeFactory.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/TypeFactory.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,48 @@ +using System; +using System.ComponentModel; +using Castle.DynamicProxy; + +namespace BLToolkit.Mapping +{ + public static class TypeFactory + { + private static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator(); + + public static class LazyLoading + { + public static object Create(Type type, IObjectMapper mapper, Func lazyLoader) + { + return ProxyGenerator.CreateClassProxy(type, new LazyValueLoadInterceptor(mapper, lazyLoader)); + } + } + + public static class LazyLoadingWithDataBinding + { + public static object Create(Type type, IObjectMapper mapper, Func lazyLoader) + { + return ProxyGenerator.CreateClassProxy(type, new[] + { + typeof (INotifyPropertyChanged), + typeof (DataBindingFactory.IMarkerInterface) + }, new LazyValueLoadInterceptor(mapper, lazyLoader), new NotifyPropertyChangedInterceptor(type.FullName)); + } + } + + public static class DataBindingFactory + { + public static object Create(Type type) + { + return ProxyGenerator.CreateClassProxy(type, new[] + { + typeof (INotifyPropertyChanged), + typeof (IMarkerInterface) + }, new NotifyPropertyChangedInterceptor(type.FullName)); + } + + public interface IMarkerInterface + { + string TypeName { get; } + } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Mapping/ValueMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Mapping/ValueMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using BLToolkit.Emit; + +namespace BLToolkit.Mapping +{ + public class ValueMapper : TableDescription, IMapper + { + private readonly Dictionary> _columnVariations = new Dictionary>(); + private readonly Dictionary _columnOccurences = new Dictionary(); + + public string ColumnAlias { get; set; } + public string ColumnName { get; set; } + + #region IMapper Members + + public int DataReaderIndex { get; set; } + public SetHandler Setter { get; set; } + public Type PropertyType { get; set; } + public string PropertyName { get; set; } + + #endregion + + public string GetColumnName(string columnName) + { + int occurenceCount; + if (_columnOccurences.ContainsKey(columnName)) + { + occurenceCount = _columnOccurences[columnName] + 1; + _columnOccurences[columnName] = occurenceCount; + } + else + { + _columnOccurences[columnName] = 1; + occurenceCount = 1; + } + + string res = columnName + (occurenceCount > 1 ? string.Format("_{0}", occurenceCount - 1) : ""); + + var variations = new List(); + if (_columnVariations.ContainsKey(columnName)) + { + variations = _columnVariations[columnName]; + } + + variations.Add(res); + _columnVariations[columnName] = variations; + + return res; + } + + public bool SetDataReaderIndex(List schemaColumns) + { + string colName = ColumnName; + int index = -1; + if (!schemaColumns.Contains(colName)) + { + bool found = false; + int order = 1; + foreach (string key in _columnVariations.Keys) + { + List variations = _columnVariations[key]; + if (variations.Contains(colName)) + { + if (colName.Contains(key + "_")) + { + string orderString = colName.Replace(key + "_", ""); + order = int.Parse(orderString) + 1; + colName = key; + found = true; + break; + } + } + } + if (found) + { + int i = 0, occurenceCnt = 0; + foreach (string column in schemaColumns) + { + if (column == colName) + { + occurenceCnt++; + if (occurenceCnt == order) + { + index = i; + break; + } + } + i++; + } + } + else + { + // TODO Check this condition... + //if (!_ignoreMissingColumns) + //{ + // throw new Exception(string.Format("Couldnt find db column {0} in the query result", colName)); + //} + return true; + } + } + else + index = schemaColumns.IndexOf(colName); + + DataReaderIndex = index; + return false; + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using BLToolkit; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle(BLToolkitConstants.ProductName + " JointureAddOn")] +[assembly: AssemblyDescription(BLToolkitConstants.ProductDescription + " JointureAddOn")] +[assembly: AssemblyProduct(BLToolkitConstants.ProductName + " JointureAddOn")] +[assembly: AssemblyCopyright(BLToolkitConstants.Copyright)] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("0ec636e7-9d1d-458b-b899-2f1d101cf7b6")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion(BLToolkitConstants.FullVersionString)] +[assembly: AssemblyFileVersion(BLToolkitConstants.FullVersionString)] diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/Reflection/FullInitContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/Reflection/FullInitContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; + +using BLToolkit.Mapping; + +namespace BLToolkit.Reflection +{ + public class FullInitContext + { + public object[] MemberParameters { get; set; } + public object[] Parameters { get; set; } + public bool IsInternal { get; set; } + public bool IsLazyInstance { get; set; } + public object Parent { get; set; } + public object SourceObject { get; set; } + public FullObjectMapper ObjectMapper { get; set; } + public MappingSchema MappingSchema { get; set; } + public bool IsSource { get; set; } + public bool StopMapping { get; set; } + public IMapDataSource DataSource { get; set; } + + private Dictionary _items; + public Dictionary Items + { + [DebuggerStepThrough] + get { return _items ?? (_items = new Dictionary()); } + } + + public bool IsDestination + { + [DebuggerStepThrough] + get { return !IsSource; } + [DebuggerStepThrough] + set { IsSource = !value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Extensions/JointureAddOn/packages.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/packages.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 HowTo/Aspects/AsyncAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Aspects/AsyncAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,83 @@ +using System; +using System.Threading; + +using NUnit.Framework; + +using BLToolkit.Aspects; +using BLToolkit.Reflection; + +namespace HowTo.Aspects +{ + public /*[a]*/abstract/*[/a]*/ class AsyncTestObject + { + // This is a member we will call asynchronously. + // + public /*[a]*/int/*[/a]*/ /*[a]*/Test/*[/a]*/(/*[a]*/int intVal, string strVal/*[/a]*/) + { + Thread.Sleep(200); + return intVal; + } + + // Begin async method should take the same parameter list as the Test method and return IAsyncResult. + // Two additional parameters can be provided: AsyncCallback and state object. + // 'Begin' prefix is a part of the default naming convention. + // + [/*[a]*/Async/*[/a]*/] public abstract /*[a]*/IAsyncResult/*[/a]*/ /*[a]*/BeginTest/*[/a]*/(/*[a]*/int intVal, string strVal/*[/a]*/); + [/*[a]*/Async/*[/a]*/] public abstract /*[a]*/IAsyncResult/*[/a]*/ /*[a]*/BeginTest/*[/a]*/(/*[a]*/int intVal, string strVal/*[/a]*/, /*[a]*/AsyncCallback/*[/a]*/ callback); + [/*[a]*/Async/*[/a]*/] public abstract /*[a]*/IAsyncResult/*[/a]*/ /*[a]*/BeginTest/*[/a]*/(/*[a]*/int intVal, string strVal/*[/a]*/, /*[a]*/AsyncCallback/*[/a]*/ callback, /*[a]*/object/*[/a]*/ state); + + // End async method should take IAsyncResult and return the same type as the Test method. + // 'End' prefix is a part of the default naming convention. + // + [/*[a]*/Async/*[/a]*/] public abstract /*[a]*/int/*[/a]*/ /*[a]*/EndTest/*[/a]*/ (/*[a]*/IAsyncResult/*[/a]*/ asyncResult); + + // Begin/End naming convention is not required. You can use any name + // if you provide the target method name as a parameter of the Async attribute. + // + [/*[a]*/Async/*[/a]*/("Test")] + public abstract /*[a]*/IAsyncResult/*[/a]*/ AnyName(/*[a]*/int intVal/*[/a]*/, /*[a]*/string strVal/*[/a]*/, /*[a]*/AsyncCallback/*[/a]*/ callback, /*[a]*/object/*[/a]*/ state); + + // Here we provide the parameter list along with the method name. + // + [/*[a]*/Async/*[/a]*/("Test", typeof(int), typeof(string))] + public abstract /*[a]*/int/*[/a]*/ AnyName(/*[a]*/IAsyncResult/*[/a]*/ asyncResult); + } + + [TestFixture] + public class AsyncAspectTest + { + [Test] + public void AsyncTest() + { + AsyncTestObject o = /*[a]*/TypeAccessor/*[/a]*/.CreateInstance(); + + IAsyncResult ar = o./*[a]*/BeginTest/*[/a]*/(1, "10"); + Assert.AreEqual(1, o./*[a]*/EndTest/*[/a]*/(ar)); + } + + private static void /*[a]*/CallBack/*[/a]*/(IAsyncResult ar) + { + Console.WriteLine("Callback"); + + AsyncTestObject o = (AsyncTestObject)ar.AsyncState; + o.EndTest(ar); + } + + [Test] + public void CallbackTest() + { + AsyncTestObject o = TypeAccessor.CreateInstance(); + + o.BeginTest(2, null, /*[a]*/CallBack/*[/a]*/, /*[a]*/o/*[/a]*/); + } + + [Test] + public void AnyNameTest() + { + AsyncTestObject o = TypeAccessor.CreateInstance(); + + IAsyncResult ar = o./*[a]*/AnyName/*[/a]*/(2, null, null, null); + Assert.AreEqual(2, o./*[a]*/AnyName/*[/a]*/(ar)); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Aspects/CacheAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Aspects/CacheAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,87 @@ +using System; +using System.Reflection; + +using NUnit.Framework; + +using BLToolkit.Aspects; +using BLToolkit.Reflection; + +namespace HowTo.Aspects +{ + public /*[a]*/abstract/*[/a]*/ class TestClass + { + public static int Value; + + // This is a method we will cache. Cached return value depends on input parameters. + // We will change the 'Value' field outside of the class and see how it affects the result. + // + [/*[a]*/Cache/*[/a]*/(MaxCacheTime=500, IsWeak=false)] + public /*[a]*/virtual/*[/a]*/ int CachedMethod(int p1, int p2) + { + return Value; + } + + public static TestClass CreateInstance() + { + // Use TypeAccessor to create an instance of an abstract class. + // + return /*[a]*/TypeAccessor/*[/a]*/.CreateInstance(); + } + } + + [TestFixture] + public class CacheAspectTest + { + [Test] + public void Test1() + { + TestClass tc = TestClass.CreateInstance(); + + DateTime begin = DateTime.Now; + + // Initial setup for the test static variable. + // + TestClass.Value = 777; + + while (tc.CachedMethod(2, 2) == 777) + { + // This change will not affect the Test method return value for 500 ms. + // + TestClass.Value++; + } + + double totalMilliseconds = (DateTime.Now - begin).TotalMilliseconds; + + Assert.GreaterOrEqual(totalMilliseconds, 500); + } + + [Test] + public void Test2() + { + TestClass tc = TestClass.CreateInstance(); + + // Return value depends on parameter values. + // + TestClass.Value = /*[a]*/1/*[/a]*/; Assert.AreEqual(/*[a]*/1/*[/a]*/, tc.CachedMethod(1, 1)); + TestClass.Value = /*[a]*/2/*[/a]*/; Assert.AreEqual(/*[a]*/1/*[/a]*/, tc.CachedMethod(1, 1)); // no change + TestClass.Value = /*[a]*/3/*[/a]*/; Assert.AreEqual(/*[a]*/3/*[/a]*/, tc.CachedMethod(2, 1)); + + // However we can clear cache manually. + // For particular method: + // + CacheAspect.ClearCache(typeof(TestClass), "CachedMethod", typeof(int), typeof(int)); + TestClass.Value = /*[a]*/4/*[/a]*/; Assert.AreEqual(/*[a]*/4/*[/a]*/, tc.CachedMethod(2, 1)); + + // By MethodInfo: + // + MethodInfo methodInfo = tc.GetType().GetMethod("CachedMethod", new Type[] { typeof(int), typeof(int) }); + CacheAspect.ClearCache(methodInfo); + TestClass.Value = /*[a]*/5/*[/a]*/; Assert.AreEqual(/*[a]*/5/*[/a]*/, tc.CachedMethod(2, 1)); + + // For the all cached methods. + // + CacheAspect.ClearCache(); + TestClass.Value = /*[a]*/6/*[/a]*/; Assert.AreEqual(/*[a]*/6/*[/a]*/, tc.CachedMethod(2, 1)); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Aspects/ClearCacheAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Aspects/ClearCacheAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,83 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Aspects; +using BLToolkit.Reflection; + +namespace HowTo.Aspects +{ + [TestFixture] + public class ClearCacheAspect + { + public /*[a]*/abstract/*[/a]*/ class TestClass + { + public static int Value; + + // This is a method we will cache. Cached return value depends on input parameters. + // We will change the 'Value' field outside of the class and see how it affects the result. + // + [/*[a]*/Cache/*[/a]*/(MaxCacheTime=500, IsWeak=false)] + public /*[a]*/virtual/*[/a]*/ int CachedMethod(int p1, int p2) + { + return Value; + } + + // This method clears the CachedMethod cache. + // + [/*[a]*/ClearCache/*[/a]*/(/*[a]*/"CachedMethod"/*[/a]*/)] + public abstract void ClearCache(); + + // The CachedMethod is specified by name and parameters. + // Also you can use declaring method type. + // + [/*[a]*/ClearCache/*[/a]*/(/*[a]*/"CachedMethod"/*[/a]*/, /*[a]*/typeof(int), typeof(int)/*[/a]*/)] + public abstract void ClearCache2(); + + // This method clears all caches for provided type. + // + [/*[a]*/ClearCache/*[/a]*/(/*[a]*/typeof(TestClass)/*[/a]*/)] + public abstract void ClearAll(); + + // This method clears all caches for current type. + // + [/*[a]*/ClearCache/*[/a]*/] + public abstract void ClearAll2(); + + public static TestClass CreateInstance() + { + // Use TypeAccessor to create an instance of an abstract class. + // + return /*[a]*/TypeAccessor/*[/a]*/.CreateInstance(); + } + } + + [Test] + public void Test() + { + TestClass tc = TypeAccessor.CreateInstance(); + + TestClass.Value = 1; + + int value1 = tc.CachedMethod(1, 2); + + TestClass.Value = 2; + + int value2 = tc.CachedMethod(1, 2); + + // The cached values are equal. + // + Assert.AreEqual(value1, value2); + + tc.ClearCache(); + + TestClass.Value = 3; + + // Previous and returned values are not equal. + // + Assert.AreNotEqual(value1, tc.CachedMethod(1, 2)); + + tc.ClearCache2(); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Aspects/CounterAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Aspects/CounterAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,62 @@ +using System; +using System.Reflection; + +using NUnit.Framework; + +using BLToolkit.Aspects; +using BLToolkit.Reflection; + +namespace HowTo.Aspects +{ + [TestFixture] + public class CounterAspectTest + { + public /*[a]*/abstract/*[/a]*/ class TestClass + { + // This is a method we collect statistic for. + // Actually the entire class or even a base class + // can be decorated with the attribute. + // + [/*[a]*/Counter/*[/a]*/] + public /*[a]*/virtual/*[/a]*/ void TestMethod() + { + } + } + + [Test] + public void Test() + { + TestClass t = TypeAccessor.CreateInstance(); + + for (int i = 0; i < 10; i++) + t.TestMethod(); + + MethodInfo methodInfo = typeof(TestClass).GetMethod("TestMethod"); + MethodCallCounter counter = CounterAspect.GetCounter(methodInfo); + + Assert.AreEqual(10, counter.TotalCount); + + Console.WriteLine(@" +Method : {0}.{1} +TotalCount : {2} +ExceptionCount : {3} +CachedCount : {4} +CurrentCalls : {5} +TotalTime : {6} +MinTime : {7} +MaxTime : {8} +AverageTime : {9} +", + counter.MethodInfo.DeclaringType.Name, + counter.MethodInfo.Name, + counter.TotalCount, // total actual calls (no cached calls) + counter.ExceptionCount, // calls with exceptions + counter.CachedCount, // cached calls + counter.CurrentCalls.Count, // current calls (make sense for multithreading) + counter.TotalTime, // total work time + counter.MinTime, // min call time + counter.MaxTime, // max call time + counter.AverageTime); // average call time + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Aspects/LoggingAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Aspects/LoggingAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,63 @@ +using System; +using System.Threading; + +using NUnit.Framework; + +using BLToolkit.Aspects; +using BLToolkit.Reflection; + +namespace HowTo.Aspects +{ + [TestFixture] + public class LoggingAspectTest + { + [/*[a]*/Log/*[/a]*/] + public /*[a]*/abstract/*[/a]*/ class TestClass + { + // Here we customize the logging settings. + // This call will be logged in spite of default settings. + // + [/*[a]*/Log/*[/a]*/(/*[a]*/MinCallTime=50/*[/a]*/)] + public /*[a]*/virtual/*[/a]*/ void Test1(int i) + { + Thread.Sleep(/*[a]*/100/*[/a]*/); + } + + // This call is not going to be logged (see default settings below). + // + public /*[a]*/virtual/*[/a]*/ void Test2(DateTime dt) + { + Thread.Sleep(/*[a]*/100/*[/a]*/); + } + + // By default exception calls are logged. + // + public /*[a]*/virtual/*[/a]*/ void Test3(string s) + { + throw new ApplicationException("Test exception."); + } + } + + [Test] + public void Test() + { + // By setting MinCallTime to some value, we prevent logging any call + // which is shorter than the provided value. + // + LoggingAspect.MinCallTime = /*[a]*/1000/*[/a]*/; + + TestClass t = /*[a]*/TypeAccessor/*[/a]*/.CreateInstance(); + + t.Test1(1); + t.Test2(DateTime.Now); + + try + { + t.Test3("3"); + } + catch + { + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Aspects/MixinAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Aspects/MixinAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,68 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Aspects; +using BLToolkit.Reflection; + +namespace HowTo.Aspects +{ + [TestFixture] + public class MixinAspectTest + { + public interface ITestInterface1 + { + int TestMethod(int value); + } + + public class TestInterface1Impl : ITestInterface1 + { + public int TestMethod(int value) { return value; } + } + + public interface ITestInterface2 + { + int TestMethod1(int value); + int TestMethod2(int value); + } + + public class TestInterface2Impl : ITestInterface2 + { + public int TestMethod1(int value) { return value; } + public int TestMethod2(int value) { return value; } + } + + [/*[a]*/Mixin/*[/a]*/(/*[a]*/typeof/*[/a]*/(/*[a]*/ITestInterface1/*[/a]*/), /*[a]*/"_testInterface1"/*[/a]*/)] + [/*[a]*/Mixin/*[/a]*/(/*[a]*/typeof/*[/a]*/(/*[a]*/ITestInterface2/*[/a]*/), /*[a]*/"TestInterface2"/*[/a]*/, "'{0}.{1}' is null.")] + public /*[a]*/abstract/*[/a]*/ class TestClass + { + public TestClass() + { + /*[a]*/_testInterface1/*[/a]*/ = new /*[a]*/TestInterface1Impl/*[/a]*/(); + } + + /*[a]*/protected/*[/a]*/ /*[a]*/object/*[/a]*/ /*[a]*/_testInterface1/*[/a]*/; + + private ITestInterface2 _testInterface2; + public /*[a]*/ITestInterface2/*[/a]*/ /*[a]*/TestInterface2/*[/a]*/ + { + get { return _testInterface2 ?? (_testInterface2 = new /*[a]*/TestInterface2Impl/*[/a]*/()); } + } + + [/*[a]*/MixinOverride/*[/a]*/(typeof(/*[a]*/ITestInterface2/*[/a]*/))] + protected int TestMethod1(int value) { return /*[a]*/15/*[/a]*/; } + } + + [Test] + public void Test() + { + TestClass tc = /*[a]*/TypeAccessor/*[/a]*/.CreateInstance(); + ITestInterface1 i1 = (ITestInterface1)tc; + ITestInterface2 i2 = (ITestInterface2)tc; + + Assert.AreEqual(/*[a]*/10/*[/a]*/, i1.TestMethod (/*[a]*/10/*[/a]*/)); + Assert.AreEqual(/*[a]*/15/*[/a]*/, i2.TestMethod1(/*[a]*/20/*[/a]*/)); + Assert.AreEqual(/*[a]*/30/*[/a]*/, i2.TestMethod2(/*[a]*/30/*[/a]*/)); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Aspects/NoCache.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Aspects/NoCache.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,49 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Aspects; +using BLToolkit.Reflection; + +namespace HowTo.Aspects +{ + [/*[a]*/Cache/*[/a]*/] + public /*[a]*/abstract/*[/a]*/ class NoCacheTestClass + { + public static int Value; + + public /*[a]*/virtual/*[/a]*/ int CachedMethod(int p1, int p2) + { + return Value; + } + + [/*[a]*/NoCache/*[/a]*/] + public /*[a]*/virtual/*[/a]*/ int NoCacheMethod(int p1, int p2) + { + return Value; + } + + public static NoCacheTestClass CreateInstance() + { + // Use TypeAccessor to create an instance of an abstract class. + // + return /*[a]*/TypeAccessor/*[/a]*/.CreateInstance(); + } + } + + [TestFixture] + public class NoCacheAttributeTest + { + [Test] + public void Test() + { + NoCacheTestClass t = TypeAccessor.CreateInstance(); + + NoCacheTestClass.Value = 1; Assert.AreEqual(/*[a]*/1/*[/a]*/, t.CachedMethod(1, 1)); + NoCacheTestClass.Value = 2; Assert.AreEqual(/*[a]*/1/*[/a]*/, t.CachedMethod(1, 1)); // no change + + NoCacheTestClass.Value = 3; Assert.AreEqual(/*[a]*/3/*[/a]*/, t.NoCacheMethod(2, 1)); + NoCacheTestClass.Value = 4; Assert.AreEqual(/*[a]*/4/*[/a]*/, t.NoCacheMethod(2, 1)); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Aspects/NotNull.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Aspects/NotNull.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,48 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Aspects; +using BLToolkit.Reflection; + +namespace HowTo.Aspects +{ + [TestFixture] + public class NotNullTest + { + public /*[a]*/abstract/*[/a]*/ class TestObject + { + public /*[a]*/virtual/*[/a]*/ void Foo1(string str1, [/*[a]*/NotNull/*[/a]*/] string str2, string str3) {} + public /*[a]*/virtual/*[/a]*/ void Foo2(string str1, [/*[a]*/NotNull/*[/a]*/(/*[a]*/"Null"/*[/a]*/)] string str2, string str3) {} + public /*[a]*/virtual/*[/a]*/ void Foo3(string str1, [/*[a]*/NotNull/*[/a]*/(/*[a]*/"Null: {0}"/*[/a]*/)] string str2, string str3) {} + + public static TestObject CreateInstance() { return /*[a]*/TypeAccessor/*[/a]*/.CreateInstance(); } + } + + [Test, ExpectedException(typeof(ArgumentNullException))] // Error message is localized by framework. + public void Test1() + { + TestObject o = TestObject.CreateInstance(); + + o.Foo1("str1", /*[a]*/null/*[/a]*/, "str3"); + } + + [Test] + [ExpectedException(typeof(ArgumentNullException), ExpectedMessage="Null")] + public void Test2() + { + TestObject o = TestObject.CreateInstance(); + + o.Foo2("str1", /*[a]*/null/*[/a]*/, "str3"); + } + + [Test] + [ExpectedException(typeof(ArgumentNullException), ExpectedMessage="Null: str2")] + public void Test3() + { + TestObject o = TestObject.CreateInstance(); + + o.Foo3("str1", /*[a]*/null/*[/a]*/, "str3"); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Aspects/OverloadAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Aspects/OverloadAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,37 @@ +using NUnit.Framework; + +using BLToolkit.Aspects; +using BLToolkit.Reflection; + +namespace HowTo.Aspects +{ + public /*[a]*/abstract/*[/a]*/ class OverloadTestObject + { + // This is a member we will overload. + // + public int /*[a]*/Test/*[/a]*/(/*[a]*/int intVal, string strVal/*[/a]*/) + { + return intVal; + } + + // Overloaded methods simply calls a base method with same name + // and has a few parameters less or more. + // + [/*[a]*/Overload/*[/a]*/] public abstract int /*[a]*/Test/*[/a]*/(/*[a]*/int intVal/*[/a]*/); + [/*[a]*/Overload/*[/a]*/] public abstract int /*[a]*/Test/*[/a]*/(/*[a]*/string strVal/*[/a]*/); + [/*[a]*/Overload/*[/a]*/] public abstract int /*[a]*/Test/*[/a]*/(int intVal, string strVal, /*[a]*/bool boolVal/*[/a]*/); + } + + [TestFixture] + public class OverloadAspectTest + { + [Test] + public void OverloadTest() + { + OverloadTestObject o = /*[a]*/TypeAccessor/*[/a]*/.CreateInstance(); + + Assert.AreEqual(1, o./*[a]*/Test/*[/a]*/(1)); + Assert.AreEqual(0, o./*[a]*/Test/*[/a]*/("str")); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/AdoDemo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/AdoDemo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data.SqlClient; + +using NUnit.Framework; + +namespace HowTo.Data +{ + [TestFixture] + public class AdoDemo + { + // Typified definition of the Gender database field. + // + public enum Gender + { + Female, + Male, + Unknown, + Other + } + + // Business object. + // + public class Person + { + public int ID { get; set; } + public string FirstName { get; set; } + public string MiddleName { get; set; } + public string LastName { get; set; } + public /*[a]*/Gender/*[/a]*/ Gender { get; set; } + } + + // ADO.NET data access method. + // + public List /*[a]*/GetList/*[/a]*/(Gender gender) + { + // Map the typified parameter value to its database representation. + // + string paramValue = ""; + + switch (gender) + { + case Gender.Female: paramValue = "F"; break; + case Gender.Male: paramValue = "M"; break; + case Gender.Unknown: paramValue = "U"; break; + case Gender.Other: paramValue = "O"; break; + } + + // Read a database configuration string. + // + string cs = ConfigurationManager.ConnectionStrings["DemoConnection"].ConnectionString; + + // Create and open a database connection. + // + using (SqlConnection con = new SqlConnection(cs)) + { + con.Open(); + + // Create and initialize a Command object. + // + using (SqlCommand cmd = con.CreateCommand()) + { + cmd.CommandText = "SELECT * FROM Person WHERE Gender = @gender"; + cmd.Parameters.AddWithValue("@gender", paramValue); + + // Execute query. + // + using (SqlDataReader rd = cmd.ExecuteReader()) + { + List list = new List(); + + while (rd.Read()) + { + Person person = new Person(); + + // Map a data reader row to a business object. + // + person.ID = Convert.ToInt32 (rd["PersonID"]); + person.FirstName = Convert.ToString(rd["FirstName"]); + person.MiddleName = Convert.ToString(rd["MiddleName"]); + person.LastName = Convert.ToString(rd["LastName"]); + + switch (rd["Gender"].ToString()) + { + case "F": person.Gender = Gender.Female; break; + case "M": person.Gender = Gender.Male; break; + case "U": person.Gender = Gender.Unknown; break; + case "O": person.Gender = Gender.Other; break; + } + + list.Add(person); + } + + return list; + } + } + } + } + + [Test] + public void Test() + { + List list = GetList(Gender.Male); + Assert.Greater(list.Count, 0); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/Close.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/Close.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,37 @@ +using System; +using NUnit.Framework; +using BLToolkit.Data; + +namespace HowTo.Data +{ + [TestFixture] + public class Close + { + [Test] + public void Test1() + { + var db = new DbManager(); + + /*[a]*/try/*[/a]*/ + { + // ... + } + /*[a]*/finally/*[/a]*/ + { + if (db != null) + db./*[a]*/Close/*[/a]*/(); + } + } + + // Consider using the C# [b][i]using[/i][/b] statement instead. + // + [Test] + public void Test2() + { + /*[a]*/using (var db = new DbManager())/*[/a]*/ + { + // ... + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/ComplexMapping.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/ComplexMapping.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,216 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Mapping; +using BLToolkit.Data; +using BLToolkit.DataAccess; +using BLToolkit.Reflection.Extension; + +namespace HowTo.Data +{ + [TestFixture] + public class ComplexMapping + { + const string TestQuery = @" + -- Parent Data + SELECT 1 as ParentID + UNION SELECT 2 as ParentID + + -- Child Data + SELECT 4 ChildID, 1 as ParentID + UNION SELECT 5 ChildID, 2 as ParentID + UNION SELECT 6 ChildID, 2 as ParentID + UNION SELECT 7 ChildID, 1 as ParentID + + -- Grandchild Data + SELECT 1 GrandchildID, 4 as ChildID + UNION SELECT 2 GrandchildID, 4 as ChildID + UNION SELECT 3 GrandchildID, 5 as ChildID + UNION SELECT 4 GrandchildID, 5 as ChildID + UNION SELECT 5 GrandchildID, 6 as ChildID + UNION SELECT 6 GrandchildID, 6 as ChildID + UNION SELECT 7 GrandchildID, 7 as ChildID + UNION SELECT 8 GrandchildID, 7 as ChildID +"; + + public class Parent + { + [MapField("ParentID"), /*[a]*/PrimaryKey/*[/a]*/] + public int ID; + + /*[a]*/[Relation(typeof(Child))]/*[/a]*/ + public List Children = new List(); + } + + [MapField("ParentID", "Parent.ID")] + public class Child + { + [MapField("ChildID"), /*[a]*/PrimaryKey/*[/a]*/] + public int ID; + + /*[a]*/[Relation]/*[/a]*/ + public Parent Parent = new Parent(); + + /*[a]*/[Relation(typeof(Grandchild))]/*[/a]*/ + public List Grandchildren = new List(); + } + + [MapField("ChildID", "Child.ID")] + public class Grandchild + { + [MapField("GrandchildID"), /*[a]*/PrimaryKey/*[/a]*/] + public int ID; + + /*[a]*/[Relation]/*[/a]*/ + public Child Child = new Child(); + } + + [Test] + public void Test() + { + List parents = new List(); + /*[a]*/MapResultSet/*[/a]*/[] sets = new MapResultSet[3]; + + sets[0] = new MapResultSet(typeof(Parent), parents); + sets[1] = new MapResultSet(typeof(Child)); + sets[2] = new MapResultSet(typeof(Grandchild)); + + sets[0].AddRelation(sets[1], "ParentID", "ParentID", "Children"); + sets[1].AddRelation(sets[0], "ParentID", "ParentID", "Parent"); + + sets[1].AddRelation(sets[2], "ChildID", "ChildID", "Grandchildren"); + sets[2].AddRelation(sets[1], "ChildID", "ChildID", "Child"); + + using (DbManager db = new DbManager()) + { + db + .SetCommand (TestQuery) + ./*[a]*/ExecuteResultSet/*[/a]*/(sets); + } + + Assert.IsNotEmpty(parents); + + foreach (Parent parent in parents) + { + Assert.IsNotNull(parent); + Assert.IsNotEmpty(parent.Children); + + foreach (Child child in parent.Children) + { + Assert.AreEqual(parent, child.Parent); + Assert.IsNotEmpty(child.Grandchildren); + + foreach (Grandchild grandchild in child.Grandchildren) + { + Assert.AreEqual(child, grandchild.Child); + Assert.AreEqual(parent, grandchild.Child.Parent); + } + } + } + } + + [Test] + public void Test2() + { + List parents = new List(); + /*[a]*/MapResultSet/*[/a]*/[] sets = new MapResultSet[3]; + + sets[0] = new MapResultSet(typeof(Parent), parents); + sets[1] = new MapResultSet(typeof(Child)); + sets[2] = new MapResultSet(typeof(Grandchild)); + + using (DbManager db = new DbManager()) + { + db + .SetCommand(TestQuery) + ./*[a]*/ExecuteResultSet/*[/a]*/(sets); + } + + Assert.IsNotEmpty(parents); + + foreach (Parent parent in parents) + { + Assert.IsNotNull(parent); + Assert.IsNotEmpty(parent.Children); + + foreach (Child child in parent.Children) + { + Assert.AreEqual(parent, child.Parent); + Assert.IsNotEmpty(child.Grandchildren); + + foreach (Grandchild grandchild in child.Grandchildren) + { + Assert.AreEqual(child, grandchild.Child); + Assert.AreEqual(parent, grandchild.Child.Parent); + } + } + } + } + + public class ParentEx + { + public int ID; + public List Children = new List(); + } + + public class ChildEx + { + public int ID; + public ParentEx Parent = new ParentEx(); + public List Grandchildren = new List(); + } + + public class GrandchildEx + { + public int ID; + public ChildEx Child = new ChildEx(); + } + + static readonly MappingSchema _mappingSchema = new MappingSchema + { + Extensions = TypeExtension.GetExtensions("RelationExtension.xml") + }; + + [Test] + public void Test3() + { + var parents = new List(); + var sets = new /*[a]*/MapResultSet/*[/a]*/[3]; + + sets[0] = new MapResultSet(typeof(ParentEx), parents); + sets[1] = new MapResultSet(typeof(ChildEx)); + sets[2] = new MapResultSet(typeof(GrandchildEx)); + + using (var db = new DbManager()) + { + db.MappingSchema = _mappingSchema; + + db + .SetCommand(TestQuery) + ./*[a]*/ExecuteResultSet/*[/a]*/(sets); + } + + Assert.IsNotEmpty(parents); + + foreach (ParentEx parent in parents) + { + Assert.IsNotNull(parent); + Assert.IsNotEmpty(parent.Children); + + foreach (ChildEx child in parent.Children) + { + Assert.AreEqual(parent, child.Parent); + Assert.IsNotEmpty(child.Grandchildren); + + foreach (GrandchildEx grandchild in child.Grandchildren) + { + Assert.AreEqual(child, grandchild.Child); + Assert.AreEqual(parent, grandchild.Child.Parent); + } + } + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/DataProvider/AddDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/DataProvider/AddDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; + +namespace HowTo.Data.DataProvider +{ + [TestFixture] + public class AddDataProvider + { + const string connectionString = + "Provider=ASEOLEDB;Data Source=server;Catalog=database;User Id=user;Password=pwd;"; + + [Test] + public void Test() + { + // 3rd party data provider registration. + // + DbManager./*[a]*/AddDataProvider/*[/a]*/(new /*[a]*/SybaseAdoDataProvider/*[/a]*/()); + + // It can be configured by App.config. + // We use this way for the demo purpose only. + // + DbManager.AddConnectionString( + "SybaseAdo", // Provider name + "Default", // Configuration + connectionString); // Connection string + + using (DbManager db = new DbManager("SybaseAdo", "Default")) + { + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/DbManagerDemo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/DbManagerDemo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.Mapping; + +namespace HowTo.Data +{ + [TestFixture] + public class DbManagerDemo + { + // The MapValue attribute is used by BLToolkit. + // + public enum Gender + { + [MapValue("F")] Female, + [MapValue("M")] Male, + [MapValue("U")] Unknown, + [MapValue("O")] Other + } + + // Business object. Here we use C# 3.0 automatic properties, + // however it can be public fields, regular or abstract properties. + // The MapField attribute is used by BLToolkit to associate a database field + // with a business object property if they have different names. + // + public class Person + { + [MapField("PersonID")] + public int ID { get; set; } + public string FirstName { get; set; } + public string MiddleName { get; set; } + public string LastName { get; set; } + public /*[a]*/Gender/*[/a]*/ Gender { get; set; } + } + + // BLToolkit data access method. + // + public List /*[a]*/GetList/*[/a]*/(Gender gender) + { + /*[a]*/using/*[/a]*/ (/*[a]*/DbManager/*[/a]*/ db = new DbManager(/*[a]*/"DemoConnection"/*[/a]*/)) + { + return db + ./*[a]*/SetCommand/*[/a]*/( + "SELECT * FROM Person WHERE Gender = @gender", + db./*[a]*/Parameter/*[/a]*/("@gender", /*[a]*/Map.EnumToValue/*[/a]*/(gender))) + ./*[a]*/ExecuteList/*[/a]*/(); + } + } + + [Test] + public void Test() + { + List list = GetList(Gender.Male); + Assert.Greater(list.Count, 0); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/ExecuteDataSet.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/ExecuteDataSet.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; +using System.Data; + +using NUnit.Framework; + +using BLToolkit.Data; + +namespace HowTo.Data +{ + [TestFixture] + public class ExecuteDataSet + { + [Test] + public void Test() + { + using (DbManager db = new DbManager()) + { + DataSet ds = db + .SetCommand("SELECT * FROM Person") + ./*[a]*/ExecuteDataSet/*[/a]*/(); + + Assert.AreNotEqual(0, ds.Tables[0].Rows.Count); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/ExecuteDataTable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/ExecuteDataTable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; +using System.Data; + +using NUnit.Framework; + +using BLToolkit.Data; + +namespace HowTo.Data +{ + [TestFixture] + public class ExecuteDataTable + { + [Test] + public void Test() + { + using (DbManager db = new DbManager()) + { + DataTable dt = db + .SetCommand("SELECT * FROM Person") + ./*[a]*/ExecuteDataTable/*[/a]*/(); + + Assert.AreNotEqual(0, dt.Rows.Count); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/ExecuteDictionary.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/ExecuteDictionary.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Common; +using BLToolkit.Data; +using BLToolkit.Mapping; + +namespace HowTo.Data +{ + using DataAccess; + + [TestFixture] + public class ExecuteDictionary + { + // The dictionary key is built from an object field/property. + // + Dictionary GetPersonDictionary1() + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand("SELECT * FROM Person") + ./*[a]*/ExecuteDictionary/*[/a]*/(/*[a]*/"ID"/*[/a]*/); + } + } + + [Test] + public void Test1() + { + Dictionary dic = GetPersonDictionary1(); + + Assert.AreNotEqual(0, dic.Count); + } + + // The dictionary key is built from a recordset field value ('@' prefix). + // + Dictionary GetPersonDictionary2() + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand("SELECT * FROM Person") + ./*[a]*/ExecuteDictionary/*[/a]*/(/*[a]*/"@PersonID"/*[/a]*/); + } + } + + [Test] + public void Test2() + { + Dictionary dic = GetPersonDictionary2(); + + Assert.AreNotEqual(0, dic.Count); + } + + // Complex dictionary key. + // + Dictionary GetPersonDictionary3() + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand("SELECT * FROM Person") + ./*[a]*/ExecuteDictionary/*[/a]*/(new /*[a]*/MapIndex("FirstName", "LastName")/*[/a]*/); + } + } + + [Test] + public void Test3() + { + Dictionary dic = GetPersonDictionary3(); + + Assert.AreNotEqual(0, dic.Count); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/ExecuteForEach.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/ExecuteForEach.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; + +namespace HowTo.Data +{ + using DataAccess; + + [TestFixture] + public class ExecuteForEach + { + [Test] + public void Test() + { + List list = new List + { + new Person { FirstName = "John", LastName = "Smith", Gender = Gender.Male }, + new Person { FirstName = "Jane", LastName = "Smith", Gender = Gender.Female } + }; + + using (DbManager db = new DbManager()) + { + db.BeginTransaction(); + + // Execute. + // + db + .SetSpCommand("Person_Insert") + ./*[a]*/ExecuteForEach/*[/a]*/(list); + + // Check the result. + // + list = db + .SetCommand( + "SELECT * FROM Person WHERE LastName = @lastName", + db.Parameter("@lastName", "Smith")) + .ExecuteList(); + + Assert.GreaterOrEqual(2, list.Count); + + // Cleanup. + // + db + .SetCommand( + "DELETE FROM Person WHERE LastName = @lastName", + db.Parameter("@lastName", "Smith")) + .ExecuteNonQuery(); + + db.CommitTransaction(); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/ExecuteList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/ExecuteList.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,98 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.Mapping; +using BLToolkit.Reflection; + +namespace HowTo.Data +{ + [TestFixture] + public class ExecuteList + { + [MapValue(Gender.Female, "F")] + [MapValue(Gender.Male, "M")] + [MapValue(Gender.Unknown, "U")] + [MapValue(Gender.Other, "O")] + public enum Gender + { + Female, + Male, + Unknown, + Other + } + + [MapField("PersonID", "ID")] + public class Person + { + public int ID; + + public string LastName; + public string FirstName; + public string MiddleName; + public Gender Gender; + } + + IList GetPersonListSqlText() + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand("SELECT * FROM Person") + ./*[a]*/ExecuteList()/*[/a]*/; + } + } + + [Test] + public void SqlText() + { + IList list = GetPersonListSqlText(); + + foreach (Person p in list) + TypeAccessor.WriteDebug(p); + } + + IList GetPersonListSproc() + { + using (DbManager db = new DbManager()) + { + return db + .SetSpCommand("Person_SelectAll") + ./*[a]*/ExecuteList()/*[/a]*/; + } + } + + [Test] + public void Sproc() + { + IList list = GetPersonListSproc(); + + foreach (Person p in list) + TypeAccessor.WriteDebug(p); + } + + void GetCustomPersonList(IList list) + { + using (DbManager db = new DbManager()) + { + db + .SetSpCommand("Person_SelectAll") + ./*[a]*/ExecuteList(list, typeof(Person))/*[/a]*/; + } + } + + [Test] + public void CustomList() + { + ArrayList list = new ArrayList(10); + + GetCustomPersonList(list); + + foreach (Person p in list) + TypeAccessor.WriteDebug(p); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/ExecuteNonQuery.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/ExecuteNonQuery.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,53 @@ +using System; +using NUnit.Framework; +using BLToolkit.Data; + +namespace HowTo.Data +{ + using DataAccess; + + [TestFixture] + public class ExecuteNonQuery + { + [Test] + public void Test() + { + Person person = new Person(); + + person.FirstName = "John"; + person.LastName = "Smith"; + person.Gender = Gender.Male; + + using (DbManager db = new DbManager()) + { + db.BeginTransaction(); + + // Execute. + // + db + .SetSpCommand("Person_Insert", db.CreateParameters(person)) + ./*[a]*/ExecuteNonQuery/*[/a]*/(); + + // Check the result. + // + person = db + .SetCommand( + "SELECT * FROM Person WHERE LastName = @lastName", + db.Parameter("@lastName", "Smith")) + .ExecuteObject(); + + Assert.IsNotNull(person); + + // Cleanup. + // + db + .SetCommand( + "DELETE FROM Person WHERE LastName = @lastName", + db.Parameter("@lastName", "Smith")) + ./*[a]*/ExecuteNonQuery/*[/a]*/(); + + db.CommitTransaction(); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/ExecuteObject.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/ExecuteObject.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,89 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.Mapping; +using BLToolkit.Reflection; + +namespace HowTo.Data +{ + [TestFixture] + public class ExecuteObject + { + public enum Gender + { + [MapValue("F")] Female, + [MapValue("M")] Male, + [MapValue("U")] Unknown, + [MapValue("O")] Other + } + + public abstract class Person + { + [MapField("PersonID")] + public abstract int ID { get; } + + public abstract string LastName { get; set; } + public abstract string FirstName { get; set; } + public abstract string MiddleName { get; set; } + public abstract Gender Gender { get; set; } + } + + Person GetPersonSqlText(int id) + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand("SELECT * FROM Person WHERE PersonID = @id", + db.Parameter("@id", id)) + ./*[a]*/ExecuteObject()/*[/a]*/; + } + } + + [Test] + public void SqlText() + { + Person person = GetPersonSqlText(1); + + TypeAccessor.WriteConsole(person); + } + + Person GetPersonSproc1(int id) + { + using (DbManager db = new DbManager()) + { + return db + .SetSpCommand("Person_SelectByKey", + db.Parameter("@id", id)) + ./*[a]*/ExecuteObject()/*[/a]*/; + } + } + + [Test] + public void Sproc1() + { + Person person = GetPersonSproc1(1); + + TypeAccessor.WriteConsole(person); + } + + Person GetPersonSproc2(int id) + { + using (DbManager db = new DbManager()) + { + return db + .SetSpCommand("Person_SelectByKey", id) + ./*[a]*/ExecuteObject()/*[/a]*/; + } + } + + [Test] + public void Sproc2() + { + Person person = GetPersonSproc2(1); + + TypeAccessor.WriteConsole(person); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/ExecuteReader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/ExecuteReader.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ +using System; +using System.Data; + +using NUnit.Framework; + +using BLToolkit.Data; + +namespace HowTo.Data +{ + [TestFixture] + public class ExecuteReader + { + [Test] + public void Test() + { + using (DbManager db = new DbManager()) + { + db.SetCommand("SELECT * FROM Person"); + + using (IDataReader rd = db./*[a]*/ExecuteReader/*[/a]*/()) + { + while (rd.Read()) + { + // ... + } + } + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/ExecuteScalar.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/ExecuteScalar.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,73 @@ +using System; +using NUnit.Framework; +using BLToolkit.Data; + +namespace HowTo.Data +{ + [TestFixture] + public class ExecuteScalar + { + string GetFirstName(int id) + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand("SELECT FirstName FROM Person WHERE PersonID = @id", + db.Parameter("@id", id)) + ./*[a]*/ExecuteScalar/*[/a]*/(); + } + } + + [Test] + public void ReaderTest() + { + string firstName = GetFirstName(1); + + Assert.IsNotNull(firstName); + } + + [Test] + public void ReturnValueTest() + { + using (DbManager db = new DbManager()) + { + /* + * CREATE Function Scalar_ReturnParameter() + * RETURNS int + * AS + * BEGIN + * RETURN 12345 + * END + */ + int n = db + .SetSpCommand("Scalar_ReturnParameter") + ./*[a]*/ExecuteScalar/*[/a]*/(/*[a]*/ScalarSourceType.ReturnValue/*[/a]*/); + + Assert.AreEqual(12345, n); + } + } + + [Test] + public void OutputParameterAsReturnValueTest() + { + using (DbManager db = new DbManager()) + { + /* + * CREATE Procedure Scalar_OutputParameter + * @outputInt int = 0 output, + * @outputString varchar(50) = '' output + * AS + * BEGIN + * SET @outputInt = 12345 + * SET @outputString = '54321' + * END + */ + string returnValue = db + .SetSpCommand("Scalar_OutputParameter") + ./*[a]*/ExecuteScalar/*[/a]*/(/*[a]*/ScalarSourceType.OutputParameter/*[/a]*/, /*[a]*/"outputString"/*[/a]*/); + + Assert.AreEqual("54321", returnValue); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/ExecuteScalarDictionary.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/ExecuteScalarDictionary.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; + +namespace HowTo.Data +{ + using DataAccess; + + [TestFixture] + public class ExecuteScalarDictionary + { + Dictionary GetNameDictionary() + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand("SELECT * FROM Person") + ./*[a]*/ExecuteScalarDictionary/*[/a]*/(/*[a]*/"PersonID"/*[/a]*/, /*[a]*/"FirstName"/*[/a]*/); + } + } + + [Test] + public void Test() + { + Dictionary dic = GetNameDictionary(); + + Assert.AreNotEqual(0, dic.Count); + Assert.IsNotNull(dic[1]); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/ExecuteScalarList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/ExecuteScalarList.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; + +namespace HowTo.Data +{ + using DataAccess; + + [TestFixture] + public class ExecuteScalarList + { + List GetNameList1() + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand("SELECT FirstName FROM Person") + ./*[a]*/ExecuteScalarList/*[/a]*/(); + } + } + + [Test] + public void Test1() + { + List list = GetNameList1(); + + Assert.AreNotEqual(0, list.Count); + Assert.IsNotNull(list[0]); + } + + List GetNameList2() + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand("SELECT * FROM Person") + ./*[a]*/ExecuteScalarList/*[/a]*/(/*[a]*/"FirstName"/*[/a]*/); + } + } + + [Test] + public void Test2() + { + List list = GetNameList2(); + + Assert.AreNotEqual(0, list.Count); + Assert.IsNotNull(list[0]); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/OpenConfig1.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/OpenConfig1.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,79 @@ +using System; +using System.Data; + +using NUnit.Framework; + +using BLToolkit.Data; + +namespace HowTo.Data +{ + [TestFixture] + public class OpenConfig1 + { + [Test] + public void DefaultConfiguration() + { + // Default configuration and default data provider. + // + using (DbManager db = new DbManager/*[a]*/()/*[/a]*/) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + } + + [Test] + public void DevelopmentConfiguration() + { + // Development configuration and default data provider. + // + using (DbManager db = new DbManager(/*[a]*/"Development"/*[/a]*/)) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + } + + [Test] + public void ProductionConfiguration() + { + // Production configuration and default data provider. + // + using (DbManager db = new DbManager(/*[a]*/"Production"/*[/a]*/)) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + } + + [Test] + public void OleDbDefaultConfiguration() + { + // Default configuration and OleDb data provider. + // + using (DbManager db = new DbManager(/*[a]*/"OleDb"/*[/a]*/)) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + } + + [Test] + public void OleDbDevelopmentConfiguration() + { + // Development configuration and OleDb data provider. + // + using (DbManager db = new DbManager(/*[a]*/"OleDb"/*[/a]*/, /*[a]*/"Development"/*[/a]*/)) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + } + + [Test] + public void OleDbProductionConfiguration() + { + // Production configuration and OleDb data provider. + // + using (DbManager db = new DbManager(/*[a]*/"OleDb"/*[/a]*/, /*[a]*/"Production"/*[/a]*/)) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/OpenConfig1FW2.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/OpenConfig1FW2.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ +using System; +using System.Data; + +using NUnit.Framework; + +using BLToolkit.Data; + +namespace HowTo.Data +{ + [TestFixture] + public class OpenConfig1FW2 + { + [Test] + public void FW2Configuration() + { + // section configuration supported in FW 2.0+. + // + using (DbManager db = new DbManager(/*[a]*/"DemoConnection"/*[/a]*/)) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/OpenConfig2.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/OpenConfig2.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,68 @@ +using System; +using System.Data; + +using NUnit.Framework; + +using BLToolkit.Data; + +namespace HowTo.Data +{ + [TestFixture] + public class OpenConfig2 + { + const string sqlConnectionString = + "Server=.;Database=BLToolkitData;Integrated Security=SSPI"; + const string oleDbConnectionString = + "Provider=SQLOLEDB;Data Source=.;Integrated Security=SSPI;Initial Catalog=BLToolkitData"; + + [Test] + public void Test1() + { + string defaultConfiguration = DbManager.DefaultConfiguration; + DbManager.DefaultConfiguration = ""; //to reset possible previous changes + + try + { + /*[a]*/DbManager.AddConnectionString/*[/a]*/( + sqlConnectionString); // connection string + + using (DbManager db = /*[a]*/new DbManager()/*[/a]*/) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + } + finally + { + DbManager.DefaultConfiguration = defaultConfiguration; // to restore previous settings + } + + } + + [Test] + public void Test2() + { + /*[a]*/DbManager.AddConnectionString/*[/a]*/( + "NewConfig", // configuration string + sqlConnectionString); // connection string + + using (DbManager db = /*[a]*/new DbManager("NewConfig")/*[/a]*/) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + } + + [Test] + public void Test3() + { + /*[a]*/DbManager.AddConnectionString/*[/a]*/( + "OleDb", // provider name + "NewConfig", // configuration string + oleDbConnectionString); // connection string + + using (DbManager db = /*[a]*/new DbManager("OleDb", "NewConfig")/*[/a]*/) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/OpenConfig3.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/OpenConfig3.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,61 @@ +using System; +using System.Data; +using System.Data.SqlClient; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; + +namespace HowTo.Data +{ + [TestFixture] + public class OpenConfig3 + { + const string connectionString = + "Server=.;Database=BLToolkitData;Integrated Security=SSPI"; + + [Test] + public void DbConnectionConfiguration() + { + using (SqlConnection con = new SqlConnection(connectionString)) + { + con.Open(); + + using (DbManager db = /*[a]*/new DbManager(con)/*[/a]*/) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + } + } + + [Test] + public void DbTransactionConfiguration() + { + using (SqlConnection con = new SqlConnection(connectionString)) + { + con.Open(); + + SqlTransaction tran = con.BeginTransaction(); + + using (DbManager db = /*[a]*/new DbManager(tran)/*[/a]*/) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + + tran.Commit(); + } + } + + [Test] + public void DataProviderConfiguration() + { + SqlDataProvider dp = new SqlDataProvider(); + + using (DbManager db = /*[a]*/new DbManager(dp, connectionString)/*[/a]*/) + { + Assert.AreEqual(ConnectionState.Open, db.Connection.State); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/Parameter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/Parameter.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,162 @@ +using System; +using System.Data; + +using NUnit.Framework; + +using BLToolkit.Data; + +namespace HowTo.Data +{ + using DataAccess; + + [TestFixture] + public class Parameter + { + [Test] + public void AssignParameterTest() + { + using (DbManager db = new DbManager()) + { + int n = db + .SetCommand("SELECT @par1 + @par2", + db./*[a]*/Parameter/*[/a]*/("@par1", 2), + db./*[a]*/Parameter/*[/a]*/("@par2", 2)) + .ExecuteScalar(); + + Assert.AreEqual(4, n); + } + } + + [Test] + public void SetValueTest() + { + using (DbManager db = new DbManager()) + { + db.SetCommand("SELECT @par * 2", + db./*[a]*/Parameter/*[/a]*/("@par", DbType.Int32)); + + db./*[a]*/Parameter("@par").Value/*[/a]*/ = 2; + + Assert.AreEqual(4, db.ExecuteScalar()); + } + } + + [Test] + public void ReturnValueTest() + { + using (DbManager db = new DbManager()) + { + /* + * CREATE Function Scalar_ReturnParameter() + * RETURNS int + * AS + * BEGIN + * RETURN 12345 + * END + */ + db + .SetSpCommand("Scalar_ReturnParameter") + .ExecuteNonQuery(); + + int n = (int)db./*[a]*/Parameter("@RETURN_VALUE").Value/*[/a]*/; + + Assert.AreEqual(12345, n); + } + } + + [Test] + public void ReturnValueTest2() + { + using (DbManager db = new DbManager()) + { + int n = db + .SetSpCommand("Scalar_ReturnParameter") + .ExecuteScalar(ScalarSourceType.ReturnValue); + + Assert.AreEqual(12345, n); + } + } + + [Test] + public void OutputParameterTest() + { + using (DbManager db = new DbManager()) + { + /* + * CREATE Procedure Scalar_OutputParameter + * @outputInt int = 0 output, + * @outputString varchar(50) = '' output + * AS + * BEGIN + * SET @outputInt = 12345 + * SET @outputString = '54321' + * END + */ + + db + .SetSpCommand("Scalar_OutputParameter", + db./*[a]*/OutputParameter/*[/a]*/("@outputInt", 1), + db./*[a]*/OutputParameter/*[/a]*/("@outputString", "1")) + .ExecuteNonQuery(); + + Assert.AreEqual(12345, (int) db./*[a]*/Parameter("@outputInt"). Value/*[/a]*/); + Assert.AreEqual("54321", (string)db./*[a]*/Parameter("@outputString").Value/*[/a]*/); + } + } + + [Test] + public void OutputParameterAsReturnValueTest() + { + using (DbManager db = new DbManager()) + { + string returnValue = db + .SetSpCommand("Scalar_OutputParameter") + .ExecuteScalar(/*[a]*/ScalarSourceType.OutputParameter/*[/a]*/, /*[a]*/"outputString"/*[/a]*/); + + Assert.AreEqual("54321", returnValue); + } + } + + [Test] + public void CreateParametersTest() + { + Person person = new Person(); + + person.FirstName = "John"; + person.LastName = "Smith"; + person.Gender = Gender.Male; + + using (DbManager db = new DbManager()) + { + db.BeginTransaction(); + + // Prepare command. + // + int id = db + .SetSpCommand("Person_Insert", + db./*[a]*/CreateParameters/*[/a]*/(person)) + .ExecuteScalar(); + + // Check the result. + // + person = db + .SetCommand( + "SELECT * FROM Person WHERE PersonID = @id", + db.Parameter("@id", id)) + .ExecuteObject(); + + Assert.IsNotNull(person); + + // Cleanup. + // + db + .SetCommand( + "DELETE FROM Person WHERE PersonID = @id", + db.Parameter("@id", id)) + .ExecuteNonQuery(); + + db.CommitTransaction(); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/Prepare.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/Prepare.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; + +namespace HowTo.Data +{ + using DataAccess; + + [TestFixture] + public class Prepare + { + [Test] + public void Test() + { + List list = new List + { + new Person { FirstName = "John", LastName = "Smith", Gender = Gender.Male }, + new Person { FirstName = "Jane", LastName = "Smith", Gender = Gender.Female } + }; + + using (DbManager db = new DbManager()) + { + db.BeginTransaction(); + + // Prepare command. + // + db + .SetSpCommand("Person_Insert", + db.CreateParameters(list[0])) + ./*[a]*/Prepare/*[/a]*/(); + + // Insert. + // + foreach (Person person in list) + { + db./*[a]*/AssignParameterValues/*[/a]*/(person); + db.ExecuteNonQuery(); + } + + // Check the result. + // + list = db + .SetCommand( + "SELECT * FROM Person WHERE LastName = @lastName", + db.Parameter("@lastName", "Smith")) + .ExecuteList(); + + Assert.GreaterOrEqual(2, list.Count); + + // Cleanup. + // + db + .SetCommand( + "DELETE FROM Person WHERE LastName = @lastName", + db.Parameter("@lastName", "Smith")) + .ExecuteNonQuery(); + + db.CommitTransaction(); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/RelationExtension.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/RelationExtension.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 HowTo/Data/SetCommand.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/SetCommand.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.Mapping; + +namespace HowTo.Data +{ + using DataAccess; + + [TestFixture] + public class SetCommand + { + // Select a person list. + // + public IList GetPersonList() + { + using (DbManager db = new DbManager()) + { + return db + ./*[a]*/SetCommand/*[/a]*/("SELECT * FROM Person") + .ExecuteList(); + } + } + + [Test] + public void Test1() + { + IList list = GetPersonList(); + + Assert.AreNotEqual(0, list.Count); + } + + // Select a person. + // + public Person GetPersonByID(int id) + { + using (DbManager db = new DbManager()) + { + return db + ./*[a]*/SetCommand/*[/a]*/("SELECT * FROM Person WHERE PersonID = @id", + db./*[a]*/Parameter/*[/a]*/("@id", id)) + .ExecuteObject(); + } + } + + [Test] + public void Test2() + { + Person person = GetPersonByID(1); + + Assert.IsNotNull(person); + } + + // Insert, Update, and Delete a person. + // + public Person GetPersonByID(DbManager db, int id) + { + return db + ./*[a]*/SetCommand/*[/a]*/("SELECT * FROM Person WHERE PersonID = @id", + db./*[a]*/Parameter/*[/a]*/("@id", id)) + .ExecuteObject(); + } + + public Person CreatePerson(DbManager db) + { + int id = db + ./*[a]*/SetCommand/*[/a]*/(@" + INSERT INTO Person ( LastName, FirstName, Gender) + VALUES (@LastName, @FirstName, @Gender) + + SELECT Cast(SCOPE_IDENTITY() as int) PersonID", + db./*[a]*/Parameter/*[/a]*/("@LastName", "Frog"), + db./*[a]*/Parameter/*[/a]*/("@FirstName", "Crazy"), + db./*[a]*/Parameter/*[/a]*/("@Gender", Map.EnumToValue(Gender.Male))) + .ExecuteScalar(); + + return GetPersonByID(db, id); + } + + public Person UpdatePerson(DbManager db, Person person) + { + db + ./*[a]*/SetCommand/*[/a]*/(@" + UPDATE + Person + SET + LastName = @LastName, + FirstName = @FirstName, + Gender = @Gender + WHERE + PersonID = @PersonID", + db./*[a]*/CreateParameters/*[/a]*/(person)) + .ExecuteNonQuery(); + + return GetPersonByID(db, person.ID); + } + + public Person DeletePerson(DbManager db, Person person) + { + db + ./*[a]*/SetCommand/*[/a]*/("DELETE FROM Person WHERE PersonID = @id", + db./*[a]*/Parameter/*[/a]*/("@id", person.ID)) + .ExecuteNonQuery(); + + return GetPersonByID(db, person.ID); + } + + [Test] + public void Test3() + { + using (DbManager db = new DbManager()) + { + db.BeginTransaction(); + + // Insert. + // + Person person = CreatePerson(db); + + Assert.IsNotNull(person); + + // Update. + // + Assert.AreEqual(Gender.Male, person.Gender); + + person.Gender = Gender.Female; + + person = UpdatePerson(db, person); + + Assert.AreEqual(Gender.Female, person.Gender); + + // Delete. + // + person = DeletePerson(db, person); + + Assert.IsNull(person); + + db.CommitTransaction(); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/SetSpCommand.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/SetSpCommand.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,146 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.Mapping; + +namespace HowTo.Data +{ + using DataAccess; + + [TestFixture] + public class SetSpCommand + { + // Select a person list. + // + public IList GetPersonList() + { + using (DbManager db = new DbManager()) + { + return db + ./*[a]*/SetSpCommand/*[/a]*/("Person_SelectAll") + .ExecuteList(); + } + } + + [Test] + public void Test1() + { + IList list = GetPersonList(); + + Assert.AreNotEqual(0, list.Count); + } + + // Select a person. + // + public Person GetPersonByID1(int id) + { + using (DbManager db = new DbManager()) + { + // Pass a parameter using the [b]Parameter[/b] method. + // + return db + ./*[a]*/SetSpCommand/*[/a]*/("Person_SelectByKey", + db./*[a]*/Parameter/*[/a]*/("@id", id)) + .ExecuteObject(); + } + } + + public Person GetPersonByID2(int id) + { + using (DbManager db = new DbManager()) + { + // Pass a parameter using the [b]params[/b] parameter of the SetSpCommand method. + // + return db + ./*[a]*/SetSpCommand/*[/a]*/("Person_SelectByKey", /*[a]*/id/*[/a]*/) + .ExecuteObject(); + } + } + + [Test] + public void Test2() + { + Person person = GetPersonByID1(1); + Assert.IsNotNull(person); + + person = GetPersonByID2(1); + Assert.IsNotNull(person); + } + + // Insert, Update, and Delete a person. + // + public Person GetPersonByID(DbManager db, int id) + { + return db + ./*[a]*/SetSpCommand/*[/a]*/("Person_SelectByKey", /*[a]*/id/*[/a]*/) + .ExecuteObject(); + } + + public Person CreatePerson(DbManager db) + { + int id = db + ./*[a]*/SetSpCommand/*[/a]*/("Person_Insert", + db./*[a]*/Parameter/*[/a]*/("@LastName", "Frog"), + db./*[a]*/Parameter/*[/a]*/("@MiddleName", null), + db./*[a]*/Parameter/*[/a]*/("@FirstName", "Crazy"), + db./*[a]*/Parameter/*[/a]*/("@Gender", Map.EnumToValue(Gender.Male))) + .ExecuteScalar(); + + return GetPersonByID(db, id); + } + + public Person UpdatePerson(DbManager db, Person person) + { + db + ./*[a]*/SetSpCommand/*[/a]*/("Person_Update", db./*[a]*/CreateParameters/*[/a]*/(person)) + .ExecuteNonQuery(); + + return GetPersonByID(db, person.ID); + } + + public Person DeletePerson(DbManager db, Person person) + { + db + ./*[a]*/SetSpCommand/*[/a]*/("Person_Delete", /*[a]*/person.ID/*[/a]*/) + .ExecuteNonQuery(); + + return GetPersonByID(db, person.ID); + } + + [Test] + public void Test3() + { + using (DbManager db = new DbManager()) + { + db.BeginTransaction(); + + // Insert. + // + Person person = CreatePerson(db); + + Assert.IsNotNull(person); + + // Update. + // + Assert.AreEqual(Gender.Male, person.Gender); + + person.Gender = Gender.Female; + + person = UpdatePerson(db, person); + + Assert.AreEqual(Gender.Female, person.Gender); + + // Delete. + // + person = DeletePerson(db, person); + + Assert.IsNull(person); + + db.CommitTransaction(); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/Transaction.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/Transaction.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,39 @@ +using System; +using System.Data; + +using NUnit.Framework; + +using BLToolkit.Data; + +namespace HowTo.Data +{ + [TestFixture] + public class Transaction + { + [Test] + public void Test1() + { + using (DbManager db = new DbManager()) + { + db./*[a]*/BeginTransaction()/*[/a]*/; + + // ... + + db./*[a]*/CommitTransaction()/*[/a]*/; + } + } + + [Test] + public void Test2() + { + using (DbManager db = new DbManager()) + { + db.BeginTransaction(/*[a]*/IsolationLevel.ReadCommitted/*[/a]*/); + + // ... + + db.CommitTransaction(); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Data/UpdateObject.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Data/UpdateObject.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.Mapping; +using BLToolkit.Reflection; + +namespace HowTo.Data +{ + [TestFixture] + public class UpdateObject + { + public enum Gender + { + [MapValue("F")] Female, + [MapValue("M")] Male, + [MapValue("U")] Unknown, + [MapValue("O")] Other + } + + public abstract class Person + { + [MapField("PersonID")] + public abstract int ID { get; } + + public abstract string LastName { get; set; } + public abstract string FirstName { get; set; } + public abstract string MiddleName { get; set; } + public abstract Gender Gender { get; set; } + } + + int InsertPerson(Person person) + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand(@" + INSERT INTO Person + ( LastName, FirstName, MiddleName, Gender) + VALUES + (@LastName, @FirstName, @MiddleName, @Gender) + + SELECT Cast(SCOPE_IDENTITY() as int)", + db.CreateParameters(person)) + .ExecuteScalar(); + } + } + + Person GetPersonByID(int id) + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand("SELECT * FROM Person WHERE PersonID = @id", + db.Parameter("@id", id)) + .ExecuteObject(); + } + } + + void UpdatePerson(Person person) + { + using (DbManager db = new DbManager()) + { + db + .SetCommand(@" + UPDATE + Person + SET + LastName = @LastName, + FirstName = @FirstName, + MiddleName = @MiddleName, + Gender = @Gender + WHERE + PersonID = @PersonID", + db.CreateParameters(person)) + .ExecuteNonQuery(); + } + } + + void DeletePerson(int id) + { + using (DbManager db = new DbManager()) + { + db + .SetCommand("DELETE FROM Person WHERE PersonID = @id", + db.Parameter("@id", id)) + .ExecuteNonQuery(); + } + } + + [Test] + public void Test() + { + // Insert. + // + Person person = TypeAccessor.CreateInstanceEx(); + + person.FirstName = "Crazy"; + person.LastName = "Frog"; + person.Gender = Gender.Unknown; + + int id = InsertPerson(person); + + person = GetPersonByID(id); + + TypeAccessor.WriteConsole(person); + Assert.IsNotNull(person); + + // Update. + // + person.Gender = Gender.Other; + + UpdatePerson(person); + + person = GetPersonByID(id); + + TypeAccessor.WriteConsole(person); + Assert.AreEqual(Gender.Other, person.Gender); + + // Delete. + // + DeletePerson(id); + + person = GetPersonByID(id); + + Assert.IsNull(person); + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/AbstractAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/AbstractAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class AbstractAccessor + { + public /*[a]*/abstract/*[/a]*/ class /*[a]*/PersonAccessor : DataAccessor/*[/a]*/ + { + public /*[a]*/abstract/*[/a]*/ Person /*[a]*/SelectByName/*[/a]*/(Person person); + public /*[a]*/abstract/*[/a]*/ Person /*[a]*/SelectByName/*[/a]*/(string firstName, string lastName); + + public /*[a]*/abstract/*[/a]*/ int /*[a]*/Insert/*[/a]*/ (Person person); + + [/*[a]*/SqlQuery(/*[/a]*/"SELECT Top /*[a]*/{0}/*[/a]*/ * FROM Person ORDER BY PersonID"/*[a]*/)]/*[/a]*/ + [/*[a]*/Index("ID")/*[/a]*/] + public /*[a]*/abstract/*[/a]*/ Dictionary /*[a]*/SelectTop/*[/a]*/([/*[a]*/Format(0)/*[/a]*/] int top); + + private SprocQuery _query; + public SprocQuery Query + { + get + { + if (_query == null) + _query = new SprocQuery(DbManager); + return _query; + } + } + } + + [Test] + public void Test() + { + using (DbManager db = new DbManager()) + { + PersonAccessor pa = /*[a]*/DataAccessor.CreateInstance(db)/*[/a]*/; + + pa.BeginTransaction(); + + // Insert and get id. + // + Person person = new Person(); + + person.FirstName = "Crazy"; + person.LastName = "Frog"; + person.Gender = Gender.Unknown; + + int id = pa./*[a]*/Insert(person)/*[/a]*/; + + // SelectByName. + // + person = pa./*[a]*/SelectByName("Crazy", "Frog")/*[/a]*/; + + Assert.IsNotNull(person); + + // Select top. + // + Dictionary dic = pa./*[a]*/SelectTop(10)/*[/a]*/; + + Assert.IsTrue(dic.Count <= 10); + + // Delete. + // + pa.Query.Delete(person); + + pa.CommitTransaction(); + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/ActionName.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/ActionName.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,38 @@ +using System; +using NUnit.Framework; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class ActionName + { + public abstract class PersonAccessor : DataAccessor + { + // Default action name is 'SelectByKey'. + // Stored procedure name is 'Person_SelectByKey'. + // + public abstract Person SelectByKey(int @id); + + // Explicit action name is 'SelectByName'. + // Stored procedure name is 'Person_SelectByName'. + // + [/*[a]*/ActionName/*[/a]*/(/*[a]*/"SelectByName"/*[/a]*/)] + public abstract Person /*[a]*/AnyName/*[/a]*/ (string @firstName, string @lastName); + } + + [Test] + public void Test() + { + PersonAccessor pa = /*[a]*/PersonAccessor.CreateInstance/*[/a]*/(); + + Person person1 = pa.SelectByKey(1); + + Assert.IsNotNull(person1); + + Person person2 = pa.AnyName(person1.FirstName, person1.LastName); + + Assert.AreEqual(person1.ID, person2.ID); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/ActionSprocName.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/ActionSprocName.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +using System; +using NUnit.Framework; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class ActionSprocName + { + [/*[a]*/ActionSprocName/*[/a]*/("GetByName", "Person_SelectByName")] + public class Person + { + public int PersonID; + public string LastName; + public string FirstName; + public string MiddleName; + } + + public abstract class PersonAccessor : DataAccessor + { + // Default action name is 'SelectByKey'. + // Stored procedure name is 'Person_SelectByKey'. + // + public abstract Person SelectByKey(int @id); + + // Default action name is 'GetByName'. + // Stored procedure name is 'Person_SelectByName' + // defined by the ActionSprocName attribute of the Person class. + // + public abstract Person GetByName(string @firstName, string @lastName); + } + + [Test] + public void Test() + { + PersonAccessor pa = /*[a]*/DataAccessor/*[/a]*/./*[a]*/CreateInstance/*[/a]*/(); + + Person person1 = pa.SelectByKey(1); + + Assert.IsNotNull(person1); + + Person person2 = pa.GetByName(person1.FirstName, person1.LastName); + + Assert.AreEqual(person1.PersonID, person2.PersonID); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/ActualType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/ActualType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,61 @@ +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class ActualType + { + public interface IName + { + string Name { get; } + } + + public class NameBase : IName + { + private string _name; + public string Name { get { return _name; } set { _name = value; } } + } + + public class Name1 : NameBase {} + public class Name2 : NameBase {} + + [/*[a]*/ActualType/*[/a]*/(typeof(IName), typeof(/*[a]*/Name1/*[/a]*/))] + public abstract class TestAccessor : DataAccessor + { + [SqlQuery("SELECT 'John' as Name")] + public abstract IName GetName1(); + + [SqlQuery("SELECT 'John' as Name"), /*[a]*/ObjectType/*[/a]*/(typeof(/*[a]*/Name2/*[/a]*/))] + public abstract IName GetName2(); + + [SqlQuery("SELECT 'John' as Name")] + public abstract IList GetName1List(); + + [SqlQuery("SELECT 'John' as Name"), /*[a]*/ObjectType/*[/a]*/(typeof(/*[a]*/Name2/*[/a]*/))] + public abstract IList GetName2List(); + + [SqlQuery("SELECT 1 as ID, 'John' as Name"), Index("@ID")] + public abstract IDictionary GetName1Dictionary(); + + [SqlQuery("SELECT 1 as ID, 'John' as Name"), Index("@ID"), /*[a]*/ObjectType/*[/a]*/(typeof(/*[a]*/Name2/*[/a]*/))] + public abstract IDictionary GetName2Dictionary(); + } + + [Test] + public void Test() + { + TestAccessor ta = DataAccessor.CreateInstance(); + + Assert.IsTrue(ta.GetName1() is Name1); + Assert.IsTrue(ta.GetName2() is Name2); + Assert.IsTrue(ta.GetName1List()[0] is Name1); + Assert.IsTrue(ta.GetName2List()[0] is Name2); + Assert.IsTrue(ta.GetName1Dictionary()[1] is Name1); + Assert.IsTrue(ta.GetName2Dictionary()[1] is Name2); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/CommandBehavior.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/CommandBehavior.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,34 @@ +using System.Data; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class CommandBehaviorDemo + { + public abstract class TestAccessor : DataAccessor + { + [SprocName("Person_SelectAll"), /*[a]*/CommandBehavior/*[/a]*/(CommandBehavior.SchemaOnly)] + public abstract IDataReader SelectAllIDataReaderSchemaOnly(DbManager db); + } + + [Test] + public void Test() + { + TestAccessor ta = DataAccessor.CreateInstance(); + + using (DbManager db = ta.GetDbManager()) + using (IDataReader dr = ta.SelectAllIDataReaderSchemaOnly(db)) + { + DataTable table = dr.GetSchemaTable(); + + Assert.AreEqual("PersonID", table.Rows[0]["ColumnName"]); + Assert.AreEqual(typeof(int), table.Rows[0]["DataType"]); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/CustomSqlQuery1.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/CustomSqlQuery1.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class CustomSqlQuery1 + { + public class TestQueryAttribute : /*[a]*/SqlQueryAttribute/*[/a]*/ + { + public TestQueryAttribute() + { + /*[a]*/IsDynamic = true/*[/a]*/; + } + + public string OracleText { get; set; } + public string FbText { get; set; } + public string SQLiteText { get; set; } + + public /*[a]*/override/*[/a]*/ string /*[a]*/GetSqlText/*[/a]*/(DataAccessor accessor, DbManager dbManager) + { + switch (dbManager.DataProvider.Name) + { + case "Sql" : + case "Access": return SqlText; + case "Oracle": return OracleText ?? SqlText; + case "Fdp" : return FbText ?? SqlText; + case "SQLite": return SQLiteText ?? SqlText; + } + + throw new ApplicationException(string.Format("Unknown data provider '{0}'", dbManager.DataProvider.Name)); + } + } + + public abstract class PersonAccessor : DataAccessor + { + [TestQuery( + /*[a]*/SqlText/*[/a]*/ = "SELECT * FROM Person WHERE LastName = @lastName", + /*[a]*/OracleText/*[/a]*/ = "SELECT * FROM Person WHERE LastName = :lastName")] + public abstract List SelectByLastName(string lastName); + + [TestQuery( + /*[a]*/SqlText/*[/a]*/ = "SELECT * FROM Person WHERE {0} = @value", + /*[a]*/OracleText/*[/a]*/ = "SELECT * FROM Person WHERE {0} = :value")] + public abstract List SelectBy([Format] string fieldName, string value); + + [TestQuery( + /*[a]*/SqlText/*[/a]*/ = "SELECT TOP {0} * FROM Person WHERE LastName = @lastName", + /*[a]*/OracleText/*[/a]*/ = "SELECT * FROM Person WHERE LastName = :lastName AND rownum <= {0}", + /*[a]*/FbText/*[/a]*/ = "SELECT FIRST {0} * FROM Person WHERE LastName = @lastName", + /*[a]*/SQLiteText/*[/a]*/ = "SELECT * FROM Person WHERE LastName = @lastName LIMIT {0}")] + public abstract List SelectByLastName(string lastName, [Format(0)] int top); + + [TestQuery( + /*[a]*/SqlText/*[/a]*/ = "SELECT @id as PersonID", + /*[a]*/OracleText/*[/a]*/ = "SELECT :id PersonID FROM Dual", + /*[a]*/FbText/*[/a]*/ = "SELECT CAST(@id AS INTEGER) PersonID FROM Dual")] + public abstract List SelectID(int @id); + } + + [Test] + public void Test1() + { + PersonAccessor da = DataAccessor.CreateInstance(); + + List list = da.SelectByLastName("Testerson"); + + Assert.AreNotEqual(0, list.Count); + } + + [Test] + public void Test2() + { + PersonAccessor da = DataAccessor.CreateInstance(); + + List list = da.SelectBy("FirstName", "John"); + + Assert.AreNotEqual(0, list.Count); + } + + [Test] + public void Test3() + { + PersonAccessor da = DataAccessor.CreateInstance(); + + List list = da.SelectByLastName("Testerson", 1); + + Assert.AreNotEqual(0, list.Count); + } + + [Test] + public void Test4() + { + PersonAccessor da = DataAccessor.CreateInstance(); + + List list = da.SelectID(42); + + Assert.AreEqual(42, list[0].ID); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/CustomSqlQuery2.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/CustomSqlQuery2.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Xml; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class CustomSqlQuery2 + { + public abstract class TestAccessorBase : /*[a]*/DataAccessor/*[/a]*/ + where T : TestAccessorBase + { + const int Sql = 0; + const int Access = 1; + const int Oracle = 2; + const int Fdp = 3; + const int SQLite = 4; + + Dictionary _sql = new Dictionary(); + + private string GetSql(string providerName, int provider, int queryID) + { + Stream stream = Assembly.GetCallingAssembly().GetManifestResourceStream( + "HowTo.DataAccess.Sql." + providerName + ".xml"); + + XmlDocument doc = new XmlDocument(); + + doc.Load(stream); + + XmlNode node = doc.SelectSingleNode(string.Format("/sql/query[@id={0}]", queryID)); + + return node != null? node.InnerText: null; + + } + + protected /*[a]*/override/*[/a]*/ string /*[a]*/PrepareSqlQuery/*[/a]*/(DbManager db, int queryID, int uniqueID, string sqlQuery) + { + int provider = Sql; + string providerName = db.DataProvider.Name; + + switch (providerName) + { + case "Sql" : provider = Sql; break; + case "Access": provider = Access; break; + case "Oracle": provider = Oracle; break; + case "Fdp" : provider = Fdp; break; + case "SQLite": provider = SQLite; break; + default: + throw new ApplicationException( + string.Format("Unknown data provider '{0}'", providerName)); + } + + string text; + int key = provider * 1000000 + uniqueID; + + if (_sql.TryGetValue(key, out text)) + return text; + + _sql[key] = text = GetSql(providerName, provider, queryID) ?? GetSql("Sql", Sql, queryID); + + return text; + } + + public static T CreateInstance() + { + return DataAccessor.CreateInstance(); + } + } + + public abstract class PersonAccessor : TestAccessorBase + { + [SqlQuery(/*[a]*/ID = 1/*[/a]*/)] + public abstract List SelectByLastName(string lastName); + + [SqlQuery(/*[a]*/ID = 2/*[/a]*/)] + public abstract List SelectBy([Format] string fieldName, string value); + + [SqlQuery(/*[a]*/ID = 3/*[/a]*/)] + public abstract List SelectByLastName(string lastName, [Format(0)] int top); + + [SqlQuery(/*[a]*/ID = 4/*[/a]*/)] + public abstract List SelectID(int @id); + } + + [Test] + public void Test1() + { + PersonAccessor da = PersonAccessor.CreateInstance(); + + List list = da.SelectByLastName("Testerson"); + + Assert.AreNotEqual(0, list.Count); + } + + [Test] + public void Test2() + { + PersonAccessor da = PersonAccessor.CreateInstance(); + + List list = da.SelectBy("FirstName", "John"); + + Assert.AreNotEqual(0, list.Count); + } + + [Test] + public void Test3() + { + PersonAccessor da = PersonAccessor.CreateInstance(); + + List list = da.SelectByLastName("Testerson", 1); + + Assert.AreNotEqual(0, list.Count); + } + + [Test] + public void Test4() + { + PersonAccessor da = PersonAccessor.CreateInstance(); + + List list = da.SelectID(42); + + Assert.AreEqual(42, list[0].ID); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/DataSetTable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/DataSetTable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,45 @@ +using System; +using System.Data; + +using NUnit.Framework; + +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class DataSetTable + { + public abstract class TestAccessor : DataAccessor + { + [SprocName("Person_SelectAll"), /*[a]*/DataSetTable/*[/a]*/("First")] + public abstract void SelectFirstTable ([Destination] DataSet ds); + + [SprocName("Person_SelectAll"), /*[a]*/DataSetTable/*[/a]*/("Second")] + public abstract void SelectSecondTable ([Destination] DataSet ds); + + [SprocName("Person_SelectAll"), /*[a]*/DataSetTable/*[/a]*/(0)] + public abstract void SelectFirstTable2 ([Destination] DataSet ds); + + [SprocName("Person_SelectAll"), /*[a]*/DataSetTable/*[/a]*/(1)] + public abstract void SelectSecondTable2([Destination] DataSet ds); + } + + [Test] + public void Test() + { + TestAccessor ta = DataAccessor.CreateInstance(); + + DataSet ds = new DataSet(); + + ta.SelectFirstTable (ds); + ta.SelectSecondTable (ds); + ta.SelectFirstTable2 (ds); + ta.SelectSecondTable2(ds); + + Assert.IsTrue (ds.Tables.Contains("First"), "Table 'First' not found"); + Assert.IsTrue (ds.Tables.Contains("Second"), "Table 'Second' not found"); + Assert.IsFalse(ds.Tables.Contains("Table"), "Table 'Table' was found"); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Delete.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Delete.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,58 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class Delete + { + private int Insert() + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand(@" + INSERT INTO Person ( + FirstName, LastName, Gender + ) VALUES ( + @FirstName, @LastName, @Gender + ) + SELECT Cast(SCOPE_IDENTITY() as int)", + db.Parameter("@FirstName", "Crazy"), + db.Parameter("@LastName", "Frog"), + db.Parameter("@Gender", "U")) + .ExecuteScalar(); + } + } + + [Test] + public void Test1() + { + int id = Insert(); + + /*[a]*/SprocQuery query = new SprocQuery()/*[/a]*/; + + query./*[a]*/DeleteByKey(id)/*[/a]*/; + } + + [Test] + public void Test3() + { + int id = Insert(); + + using (DbManager db = new DbManager()) + { + /*[a]*/SqlQuery query = new SqlQuery()/*[/a]*/; + + Person person = query.SelectByKey(db, id); + + query./*[a]*/Delete(db, person)/*[/a]*/; + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/DeleteSql.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/DeleteSql.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,58 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class DeleteSql + { + private int Insert() + { + using (DbManager db = new DbManager()) + { + return db + .SetCommand(@" + INSERT INTO Person ( + FirstName, LastName, Gender + ) VALUES ( + @FirstName, @LastName, @Gender + ) + SELECT Cast(SCOPE_IDENTITY() as int)", + db.Parameter("@FirstName", "Crazy"), + db.Parameter("@LastName", "Frog"), + db.Parameter("@Gender", "U")) + .ExecuteScalar(); + } + } + + [Test] + public void Test1() + { + int id = Insert(); + + /*[a]*/SqlQuery query = new SqlQuery()/*[/a]*/; + + query./*[a]*/DeleteByKey(id)/*[/a]*/; + } + + [Test] + public void Test2() + { + int id = Insert(); + + using (DbManager db = new DbManager()) + { + /*[a]*/SqlQuery query = new SqlQuery()/*[/a]*/; + + Person person = query.SelectByKey(db, id); + + query./*[a]*/Delete(db, person)/*[/a]*/; + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Destination.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Destination.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class Destination + { + public abstract class PersonAccessor : DataAccessor + { + public abstract void SelectAll([/*[a]*/Destination/*[/a]*/] IList list); + } + + [Test] + public void Test() + { + PersonAccessor pa = DataAccessor.CreateInstance(); + + List list = new List(); + + pa.SelectAll(list); + + Assert.AreNotEqual(0, list.Count); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Direction.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Direction.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,63 @@ +using System; +using NUnit.Framework; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class DirectionTest + { + public abstract class PersonAccessor : DataAccessor + { + [SprocName("Person_Insert_OutputParameter")] + public abstract void Insert_OutputParameter([/*[a]*/Direction.Output/*[/a]*/("PERSONID")] Person p); + + [SprocName("Scalar_ReturnParameter")] + public abstract void Insert_ReturnParameter( + [/*[a]*/Direction.ReturnValue/*[/a]*/("@PersonID"), + /*[a]*/Direction.Ignore/*[/a]*/("PersonID", "FirstName", "LastName", "MiddleName", "Gender")] Person p); + + [SprocName("Scalar_ReturnParameter")] + public abstract void Insert_ReturnParameter2( + [/*[a]*/Direction.ReturnValue/*[/a]*/("ID"), + /*[a]*/Direction.Ignore/*[/a]*/("PersonID", "FirstName", "LastName", "MiddleName", "Gender")] Person p); + } + + PersonAccessor Accessor + { + get { return DataAccessor.CreateInstance(); } + } + + [Test] + public void TestOutputParameter() + { + Person p = new Person { FirstName = "Crazy", LastName = "Frog", Gender = Gender.Other }; + + Accessor.Insert_OutputParameter(p); + + Assert.IsTrue(p.ID > 0); + + new SprocQuery().Delete(p); + } + + [Test] + public void TestReturnParameter() + { + Person p = new Person(); + + Accessor.Insert_ReturnParameter(p); + + Assert.AreEqual(12345, p.ID); + } + + [Test] + public void TestReturnParameter2() + { + Person p = new Person(); + + Accessor.Insert_ReturnParameter2(p); + + Assert.AreEqual(12345, p.ID); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/DiscoverParameters.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/DiscoverParameters.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ +using NUnit.Framework; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class DiscoverParameters + { + public abstract class PersonAccessor : DataAccessor + { + [/*[a]*/DiscoverParameters/*[/a]*/] + public abstract Person SelectByName(string anyParameterName, string otherParameterName); + } + + [Test] + public void Test() + { + PersonAccessor pa = DataAccessor.CreateInstance(); + Person p = pa.SelectByName("Tester", "Testerson"); + + Assert.AreEqual(2, p.ID); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/ExecuteDictionary.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/ExecuteDictionary.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Common; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class ExecuteDictionary1 + { + public class Person + { + [MapField("PersonID"), /*[a]*/PrimaryKey/*[/a]*/] + public int /*[a]*/ID/*[/a]*/; + + public string LastName; + public string FirstName; + public string MiddleName; + } + + public abstract class /*[a]*/PersonAccessor/*[/a]*/ : /*[a]*/DataAccessor/*[/a]*/ + { + // This method uses Person class primary key information. + // + [ActionName("SelectAll")] + public abstract /*[a]*/Dictionary/*[/a]*/ GetPersonDictionary1(); + + // Define index field explicitly. "ID" is a field name of the Person class. + // + [ActionName("SelectAll")] + [/*[a]*/Index("ID")/*[/a]*/] + public abstract /*[a]*/Dictionary/*[/a]*/ GetPersonDictionary2(); + + // Define index field explicitly. "@PersonID" is a recordset field. + // Note that the '@' symbol enforces the library to read index value + // from recordset (not from object). + // + [ActionName("SelectAll")] + [/*[a]*/Index("@PersonID")/*[/a]*/] + public abstract /*[a]*/Dictionary/*[/a]*/ GetPersonDictionary3(); + + // This method reads a dictionary containing scalar values. + // + [SqlQuery("SELECT PersonID, FirstName FROM Person")] + [/*[a]*/Index("PersonID")/*[/a]*/] + [/*[a]*/ScalarFieldName("FirstName")/*[/a]*/] + public abstract /*[a]*/Dictionary/*[/a]*/ GetPersonNameDictionary(); + } + + [Test] + public void Test() + { + PersonAccessor pa = DataAccessor.CreateInstance(); + + // ExecuteDictionary. + // + Dictionary dic; + + dic = pa.GetPersonDictionary1(); + dic = pa.GetPersonDictionary2(); + dic = pa.GetPersonDictionary3(); + + foreach (int id in dic.Keys) + Console.WriteLine("{0}: {1} {2}", id, dic[id].FirstName, dic[id].LastName); + + // ExecuteScalarDictionary. + // + Dictionary sdic = pa.GetPersonNameDictionary(); + + foreach (int id in dic.Keys) + Console.WriteLine("{0}: {1}", id, sdic[id]); + } + } + + [TestFixture] + public class ExecuteDictionary2 + { + // This example demonstrates how to use a multiple field key. + // + public class Person + { + [/*[a]*/PrimaryKey(1)/*[/a]*/, MapField("PersonID")] + public int ID; + [/*[a]*/PrimaryKey(2)/*[/a]*/] + public string LastName; + + public string FirstName; + public string MiddleName; + } + + public abstract class /*[a]*/PersonAccessor/*[/a]*/ : /*[a]*/DataAccessor/*[/a]*/ + { + // This method uses Person class primary key information. + // Note that the key type of the dictionary must be of /*[a]*/IndexValue/*[/a]*/ type. + // It is required if the index consists of more than one element. + // + [ActionName("SelectAll")] + public abstract /*[a]*/Dictionary/*[/a]*/ GetPersonDictionary(); + + // This method reads a dictionary containing scalar values. + // + [SqlQuery("SELECT PersonID, LastName, FirstName FROM Person")] + [/*[a]*/Index("PersonID", "LastName")/*[/a]*/] + [/*[a]*/ScalarFieldName("FirstName")/*[/a]*/] + public abstract /*[a]*/Dictionary/*[/a]*/ GetPersonNameDictionary(); + } + + [Test] + public void Test() + { + PersonAccessor pa = DataAccessor.CreateInstance(); + + // ExecuteDictionary. + // + Dictionary dic = pa.GetPersonDictionary(); + + foreach (CompoundValue idx in dic.Keys) + Console.WriteLine("{0}: {1} {2}", dic[idx].ID, dic[idx].FirstName, dic[idx].LastName); + + // ExecuteScalarDictionary. + // + Dictionary sdic = pa.GetPersonNameDictionary(); + + string firstName = sdic[new CompoundValue(2, "Testerson")]; + + Assert.AreEqual("Tester", firstName); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/ExecuteList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/ExecuteList.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,60 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class ExecuteList + { + public abstract class /*[a]*/PersonAccessor/*[/a]*/ : /*[a]*/DataAccessor/*[/a]*/ + { + // This method reads a list of Person objects. + // + [ActionName("SelectAll")] + public abstract /*[a]*/List/*[/a]*/ GetPersonList1(); + + // Here we help the method to get object type information. + // /*[a]*/ObjectTypeAttribute/*[/a]*/ can be applied to the class itself. + // In this case there is no need to specify object type for each method. + // Another way to specify object type is a generic parameter + // of the DataAccessor class. + // + [SqlQuery("SELECT * FROM Person")] + [/*[a]*/ObjectType(typeof(Person))/*[/a]*/] + public abstract /*[a]*/ArrayList/*[/a]*/ GetPersonList2(); + + // This method reads a list of scalar values. + // + [SqlQuery("SELECT PersonID FROM Person")] + public abstract /*[a]*/List/*[/a]*/ GetPersonIDList(); + } + + [Test] + public void Test() + { + PersonAccessor pa = DataAccessor.CreateInstance(); + + // ExecuteList. + // + IList list; + + list = pa.GetPersonList1(); + list = pa.GetPersonList2(); + + foreach (Person p in list) + Console.WriteLine("{0}: {1} {2}", p.ID, p.FirstName, p.LastName); + + // ExecuteScalarList. + // + List slist = pa.GetPersonIDList(); + + foreach (int id in slist) + Console.WriteLine("{0}", id); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/ExecuteObject.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/ExecuteObject.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,52 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class ExecuteObject + { + public abstract class /*[a]*/PersonAccessor/*[/a]*/ : /*[a]*/DataAccessor/*[/a]*/ + { + // Here we explicitly specify a stored procedure name. + // + [SprocName("Person_SelectByKey")] + public abstract /*[a]*/Person/*[/a]*/ GetByID(int @id); + + // SQL query text. + // + [SqlQuery("SELECT * FROM Person WHERE PersonID = @id")] + public abstract /*[a]*/Person/*[/a]*/ GetPersonByID(int @id); + + // Specify action name. + // Stored procedure name is generated based on convention + // defined by DataAccessor.GetDefaultSpName method. + // + [ActionName("SelectByName")] + public abstract /*[a]*/Person/*[/a]*/ GetPersonByName(string @firstName, string @lastName); + + // By default method name defines an action name + // which is converted to a stored procedure name. + // Default conversion rule is ObjectName_MethodName. + // This method calls the Person_SelectByName stored procedure. + // + public abstract /*[a]*/Person/*[/a]*/ SelectByName(string @firstName, string @lastName); + } + + [Test] + public void Test() + { + PersonAccessor pa = DataAccessor.CreateInstance(); + + // ExecuteObject. + // + Assert.IsNotNull(pa.GetByID (1)); + Assert.IsNotNull(pa.GetPersonByID (2)); + Assert.IsNotNull(pa.GetPersonByName("Tester", "Testerson")); + Assert.IsNotNull(pa.SelectByName ("Tester", "Testerson")); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/ExecuteScalar.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/ExecuteScalar.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class ExecuteScalar + { + public abstract class /*[a]*/PersonAccessor/*[/a]*/ : /*[a]*/DataAccessor/*[/a]*/ + { + [SqlQuery("SELECT Count(*) FROM Person")] + public abstract int GetCount(); + + // The Person_Insert sproc returns an id of the created record. + // + [SprocName("Person_Insert")] + public abstract /*[a]*/int/*[/a]*/ Insert(Person person); + } + + [Test] + public void Test() + { + PersonAccessor pa = DataAccessor.CreateInstance(); + + // ExecuteScalar. + // + Assert.IsTrue(pa.GetCount() > 0); + + // Insert and get id. + // + Person person = new Person(); + + person.FirstName = "Crazy"; + person.LastName = "Frog"; + person.Gender = Gender.Unknown; + + int id = pa./*[a]*/Insert(person)/*[/a]*/; + + Assert.IsFalse(id == 0); + + new SprocQuery().DeleteByKey(id); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Format.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Format.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class Format + { + public abstract class PersonAccessor : DataAccessor + { + [SqlQuery("SELECT TOP {0} * FROM Person")] + public abstract List GetPersonList([/*[a]*/Format/*[/a]*/] int top); + } + + [Test] + public void Test() + { + PersonAccessor pa = DataAccessor.CreateInstance(); + List list = pa.GetPersonList(2); + + Assert.That(list, Is.Not.Null); + Assert.That(list.Count, Is.LessThanOrEqualTo(2)); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Gender.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Gender.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,14 @@ +using System; + +using BLToolkit.Mapping; + +namespace HowTo.DataAccess +{ + public enum Gender + { + [MapValue("F")] Female, + [MapValue("M")] Male, + [MapValue("U")] Unknown, + [MapValue("O")] Other + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Insert.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Insert.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,45 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class Insert + { + [Test] + public void Test1() + { + /*[a]*/SprocQuery query = new SprocQuery()/*[/a]*/; + + Person person = new Person(); + + person.FirstName = "Crazy"; + person.LastName = "Frog"; + person.Gender = Gender.Unknown; + + query./*[a]*/Insert(person)/*[/a]*/; + } + + [Test] + public void Test2() + { + using (DbManager db = new DbManager()) + { + /*[a]*/SprocQuery query = new SprocQuery()/*[/a]*/; + + Person person = new Person(); + + person.FirstName = "Crazy"; + person.LastName = "Frog"; + person.Gender = Gender.Other; + + query./*[a]*/Insert(db, person)/*[/a]*/; + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/InsertSql.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/InsertSql.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,45 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class InsertSql + { + [Test] + public void Test1() + { + /*[a]*/SqlQuery query = new SqlQuery()/*[/a]*/; + + Person person = new Person(); + + person.FirstName = "Crazy"; + person.LastName = "Frog"; + person.Gender = Gender.Unknown; + + query./*[a]*/Insert(person)/*[/a]*/; + } + + [Test] + public void Test2() + { + using (DbManager db = new DbManager()) + { + /*[a]*/SqlQuery query = new SqlQuery()/*[/a]*/; + + Person person = new Person(); + + person.FirstName = "Crazy"; + person.LastName = "Frog"; + person.Gender = Gender.Other; + + query./*[a]*/Insert(db, person)/*[/a]*/; + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/MultiplePrimaryKey.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/MultiplePrimaryKey.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,39 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class MultiplePrimaryKey + { + [TableName("Person")] + public class Person + { + [MapField("PersonID"), NonUpdatable] + public int ID; + + // These fields are not real primary key of the table. + // They are made primary key for demonstration purpose only. + // + [/*[a]*/PrimaryKey(1)/*[/a]*/] public string FirstName; + [/*[a]*/PrimaryKey(2)/*[/a]*/] public string LastName; + + public string MiddleName; + } + + [Test] + public void Test() + { + SqlQuery query = new SqlQuery(); + + Person person = query./*[a]*/SelectByKey("Tester", "Testerson")/*[/a]*/; + + Assert.IsNotNull(person); + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/NonUpdatable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/NonUpdatable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,46 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class NonUpdatable + { + public enum Gender + { + [MapValue("F")] Female, + [MapValue("M")] Male, + [MapValue("U")] Unknown, + [MapValue("O")] Other + } + + public class Person + { + [MapField("PersonID"), PrimaryKey, /*[a]*/NonUpdatable/*[/a]*/] + public int ID; + + public string LastName; + public string FirstName; + public string MiddleName; + public Gender Gender; + } + + [Test] + public void Test() + { + SqlQuery query = new SqlQuery(); + + Person person = new Person(); + + person.FirstName = "Crazy"; + person.LastName = "Frog"; + person.Gender = Gender.Other; + + query./*[a]*/Insert(person)/*[/a]*/; + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/OpenConfig.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/OpenConfig.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,73 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class OpenConfig + { + public class Person + { + [MapField("PersonID"), PrimaryKey, NonUpdatable] + public int ID; + + public string LastName; + public string FirstName; + public string MiddleName; + } + + public abstract class TestAccessor : DataAccessor + { + public abstract Person SelectByKey(int id); + public abstract Person SelectByKey(/*[a]*/DbManager/*[/a]*/ db, int id); + } + + // /*[i]*/DbManager/*[/i]*/ is created by /*[i]*/DataAccessor/*[/i]*/. + // + [Test] + public void Test1() + { + TestAccessor ta = DataAccessor.CreateInstance/*[a]*/()/*[/a]*/; + + Person person = ta.SelectByKey(1); + + Assert.IsNotNull(person); + } + + // /*[i]*/DataAccessor/*[/i]*/ takes /*[i]*/DbManager/*[/i]*/ as a parameter. + // + [Test] + public void Test2() + { + using (DbManager db = new DbManager()) + { + TestAccessor ta = DataAccessor.CreateInstance/*[a]*/(db)/*[/a]*/; + + Person person = ta.SelectByKey(1); + + Assert.IsNotNull(person); + } + } + + // /*[i]*/DataAccessor/*[/i]*/ method takes /*[i]*/DbManager/*[/i]*/ as a parameter. + // + [Test] + public void Test3() + { + using (DbManager db = new DbManager()) + { + TestAccessor ta = DataAccessor.CreateInstance/*[a]*/()/*[/a]*/; + + Person person = ta.SelectByKey(/*[a]*/db/*[/a]*/, 1); + + Assert.IsNotNull(person); + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/OpenConfigQuery.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/OpenConfigQuery.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,67 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class OpenConfigQuery + { + public class Person + { + [MapField("PersonID"), PrimaryKey, NonUpdatable] + public int ID; + + public string LastName; + public string FirstName; + public string MiddleName; + } + + // /*[i]*/DbManager/*[/i]*/ is created by /*[i]*/SqlQuery/*[/i]*/. + // + [Test] + public void Test1() + { + SqlQuery query = new SqlQuery/*[a]*/()/*[/a]*/; + + Person person = query.SelectByKey(1); + + Assert.IsNotNull(person); + } + + // /*[i]*/SqlQuery/*[/i]*/ takes /*[i]*/DbManager/*[/i]*/ as a parameter. + // + [Test] + public void Test2() + { + using (DbManager db = new DbManager()) + { + SqlQuery query = new SqlQuery/*[a]*/(db)/*[/a]*/; + + Person person = query.SelectByKey(1); + + Assert.IsNotNull(person); + } + } + + // /*[i]*/SqlQuery/*[/i]*/ method takes /*[i]*/DbManager/*[/i]*/ as a parameter. + // + [Test] + public void Test3() + { + using (DbManager db = new DbManager()) + { + SqlQuery query = new SqlQuery/*[a]*/()/*[/a]*/; + + Person person = query.SelectByKey(/*[a]*/db/*[/a]*/, 1); + + Assert.IsNotNull(person); + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Param.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Param.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,38 @@ +using System; +using System.Data; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class Param + { + public abstract class TestAccessor : DataAccessor + { + [SqlQuery("SELECT {0} = {1} FROM Person WHERE PersonID = 1")] + public abstract void SelectJohn( + [/*[a]*/ParamSize/*[/a]*/(50), /*[a]*/ParamDbType/*[/a]*/(DbType.String)] out string name, + [Format] string paramName, + [Format] string fieldName); + } + + [Test] + public void AccessorTest() + { + using (DbManager db = new DbManager()) + { + TestAccessor ta = DataAccessor.CreateInstance(db); + + string actualName; + + ta.SelectJohn(out actualName, "@name", "FirstName"); + + Assert.AreEqual("John", actualName); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/ParamName.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/ParamName.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; +using NUnit.Framework; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class ParamName + { + public abstract class TestAccessor : DataAccessor + { + public abstract Person SelectByName( + [ParamName("FirstName")] string name1, + [ParamName("@LastName")] string name2); + } + + [Test] + public void Test() + { + TestAccessor ta = DataAccessor.CreateInstance(); + Person p = ta.SelectByName("Tester", "Testerson"); + + Assert.AreEqual(2, p.ID); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/ParamNullValue.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/ParamNullValue.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,31 @@ +using System; +using NUnit.Framework; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class ParamNullValue + { + public abstract class TestAccessor : DataAccessor + { + public abstract Person SelectByKey([/*[a]*/ParamNullValue/*[/a]*/(1)] int id); + } + + [Test] + public void Test() + { + TestAccessor ta = DataAccessor.CreateInstance(); + + // Parameter id == 1 will be replaced with NULL + // + Person p1 = ta.SelectByKey(1); + Assert.IsNull(p1); + + // Parameter id == 2 will be send as is + // + Person p2 = ta.SelectByKey(2); + Assert.IsNotNull(p2); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Person.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Person.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,18 @@ +using System; + +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace HowTo.DataAccess +{ + public class Person + { + [MapField("PersonID"), PrimaryKey, NonUpdatable] + public int ID; + + public string LastName; + public string FirstName; + public string MiddleName; + public Gender Gender; + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/PersonAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/PersonAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; +using BLToolkit.Reflection; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class PersonAccessorTest + { + public enum Gender + { + [MapValue("F")] Female, + [MapValue("M")] Male, + [MapValue("U")] Unknown, + [MapValue("O")] Other + } + + public abstract class Person + { + [MapField("PersonID"), PrimaryKey, NonUpdatable] + public abstract int ID { get; } + + public abstract string LastName { get; set; } + public abstract string FirstName { get; set; } + public abstract string MiddleName { get; set; } + public abstract Gender Gender { get; set; } + + public static Person CreateInstance() + { + return TypeAccessor.CreateInstanceEx(); + } + } + + public abstract class PersonAccessor : DataAccessor + { + [SprocName("Person_SelectByKey")] + public abstract Person SelectByID (int id); + + public abstract Person SelectByName(Person person); + public abstract Person SelectByName(string firstName, string lastName); + + public abstract int Insert (Person person); + + [ActionName("SelectByKey")] + public abstract Person SelectByID (DbManager db, int id); + + public abstract Person SelectByName(DbManager db, Person person); + public abstract Person SelectByName(DbManager db, string firstName, string lastName); + + public abstract int Insert (DbManager db, Person person); + + public readonly SprocQuery Query = new SprocQuery(); + } + + [Test] + public void Test() + { + PersonAccessor pa = DataAccessor.CreateInstance(); + + // Insert and get id. + // + Person person = Person.CreateInstance(); + + person.FirstName = "Crazy"; + person.LastName = "Frog"; + person.Gender = Gender.Unknown; + + int id = pa.Insert(person); + + person = pa.SelectByID(id); + + TypeAccessor.WriteConsole(person); + Assert.IsNotNull(person); + + // Update. + // + person.Gender = Gender.Other; + + pa.Query.Update(person); + + person = pa.SelectByID(person.ID); + + TypeAccessor.WriteConsole(person); + Assert.AreEqual(Gender.Other, person.Gender); + + // Delete. + // + pa.Query.Delete(person); + + person = pa.SelectByID(person.ID); + + Assert.IsNull(person); + + // Get All. + // + List list = pa.Query.SelectAll(); + + foreach (Person p in list) + TypeAccessor.WriteConsole(p); + } + + [Test] + public void TransactionTest() + { + using (DbManager db = new DbManager()) + { + PersonAccessor pa = DataAccessor.CreateInstance(); + + db.BeginTransaction(); + + // Insert and get id. + // + Person person = Person.CreateInstance(); + + person.FirstName = "Crazy"; + person.LastName = "Frog"; + person.Gender = Gender.Unknown; + + int id = pa.Insert(db, person); + + person = pa.SelectByID(db, id); + + TypeAccessor.WriteConsole(person); + Assert.IsNotNull(person); + + // Update. + // + person.Gender = Gender.Other; + + pa.Query.Update(db, person); + + person = pa.SelectByID(db, person.ID); + + TypeAccessor.WriteConsole(person); + Assert.AreEqual(Gender.Other, person.Gender); + + // Delete. + // + pa.Query.Delete(db, person); + + person = pa.SelectByID(db, person.ID); + + Assert.IsNull(person); + + db.CommitTransaction(); + + // Get All. + // + List list = pa.Query.SelectAll(db); + + foreach (Person p in list) + TypeAccessor.WriteConsole(p); + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/PrimaryKey.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/PrimaryKey.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,34 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class PrimaryKey + { + public class Person + { + [MapField("PersonID"), /*[a]*/PrimaryKey/*[/a]*/, NonUpdatable] + public int ID; + + public string LastName; + public string FirstName; + public string MiddleName; + } + + [Test] + public void Test() + { + SqlQuery da = new SqlQuery(); + + Person person = da./*[a]*/SelectByKey(1)/*[/a]*/; + + Assert.IsNotNull(person); + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/ScalarFieldName.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/ScalarFieldName.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class ScalarFieldName + { + public abstract class TestAccessor : DataAccessor + { + [SqlQuery("SELECT PersonID, FirstName FROM Person")] + [Index("PersonID")] + [/*[a]*/ScalarFieldName("FirstName")/*[/a]*/] + public abstract Dictionary GetPersonNameDictionary(); + } + + [Test] + public void Test() + { + TestAccessor pa = DataAccessor.CreateInstance(); + + IDictionary dic = pa.GetPersonNameDictionary(); + + Assert.AreEqual("John", dic[1]); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/ScalarSource.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/ScalarSource.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,138 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class ScalarSource + { + public abstract class TestAccessor : DataAccessor + { + [/*[a]*/ScalarSource/*[/a]*/(ScalarSourceType.DataReader)] + public abstract int Scalar_DataReader(); + + [ActionName("Scalar_DataReader")] + [/*[a]*/ScalarSource/*[/a]*/(ScalarSourceType.DataReader, 1)] + public abstract string Scalar_DataReader2(); + + [ActionName("Scalar_DataReader")] + [/*[a]*/ScalarSource/*[/a]*/(ScalarSourceType.DataReader, "stringField")] + public abstract string Scalar_DataReader3(); + + [/*[a]*/ScalarSource/*[/a]*/(ScalarSourceType.OutputParameter)] + public abstract int Scalar_OutputParameter(); + + [ActionName("Scalar_OutputParameter")] + [/*[a]*/ScalarSource/*[/a]*/(ScalarSourceType.OutputParameter, 1)] + public abstract string Scalar_OutputParameter2(); + + [ActionName("Scalar_OutputParameter")] + [/*[a]*/ScalarSource/*[/a]*/(ScalarSourceType.OutputParameter, "outputString")] + public abstract string Scalar_OutputParameter3(); + + [/*[a]*/ScalarSource/*[/a]*/(ScalarSourceType.ReturnValue)] + public abstract int Scalar_ReturnParameter(); + + [ActionName("Scalar_DataReader")] + [/*[a]*/ScalarSource/*[/a]*/(ScalarSourceType.AffectedRows)] + public abstract int Scalar_AffectedRows(); + + public static TestAccessor CreateInstance() + { + return (TestAccessor)CreateInstance(typeof(TestAccessor)); + } + } + + [Test] + public void DataReaderTest() + { + TestAccessor ta = TestAccessor.CreateInstance(); + + int expectedValue = 12345; + int actualValue = ta.Scalar_DataReader(); + + Assert.AreEqual(expectedValue, actualValue); + } + + [Test] + public void DataReader2Test() + { + TestAccessor ta = TestAccessor.CreateInstance(); + + string expectedValue = "54321"; + string actualValue = ta.Scalar_DataReader2(); + + Assert.AreEqual(expectedValue, actualValue); + } + + [Test] + public void DataReader3Test() + { + TestAccessor ta = TestAccessor.CreateInstance(); + + string expectedValue = "54321"; + string actualValue = ta.Scalar_DataReader3(); + + Assert.AreEqual(expectedValue, actualValue); + } + + [Test] + public void OutputParameterTest() + { + TestAccessor ta = TestAccessor.CreateInstance(); + + int expectedValue = 12345; + int actualValue = ta.Scalar_OutputParameter(); + + Assert.AreEqual(expectedValue, actualValue); + } + + [Test] + public void OutputParameter2Test() + { + TestAccessor ta = TestAccessor.CreateInstance(); + + string expectedValue = "54321"; + string actualValue = ta.Scalar_OutputParameter2(); + + Assert.AreEqual(expectedValue, actualValue); + } + + [Test] + public void OutputParameter3Test() + { + TestAccessor ta = TestAccessor.CreateInstance(); + + string expectedValue = "54321"; + string actualValue = ta.Scalar_OutputParameter3(); + + Assert.AreEqual(expectedValue, actualValue); + } + + [Test] + public void ReturnParameterTest() + { + TestAccessor ta = TestAccessor.CreateInstance(); + + int expectedValue = 12345; + int actualValue = ta.Scalar_ReturnParameter(); + + Assert.AreEqual(expectedValue, actualValue); + } + + [Test] + public void AffectedRowsTest() + { + TestAccessor ta = TestAccessor.CreateInstance(); + + int expectedValue = -1; + int actualValue = ta.Scalar_AffectedRows(); + + Assert.AreEqual(expectedValue, actualValue); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/SelectAll.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/SelectAll.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class SelectAll + { + [Test] + public void Test1() + { + /*[a]*/SprocQuery query = new SprocQuery()/*[/a]*/; + + List list = query./*[a]*/SelectAll()/*[/a]*/; + } + + [Test] + public void Test2() + { + using (DbManager db = new DbManager()) + { + /*[a]*/SprocQuery query = new SprocQuery()/*[/a]*/; + + List list = query./*[a]*/SelectAll(db)/*[/a]*/; + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/SelectAllSql.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/SelectAllSql.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class SelectAllSql + { + [Test] + public void Test1() + { + /*[a]*/SqlQuery query = new SqlQuery()/*[/a]*/; + + List list = query./*[a]*/SelectAll()/*[/a]*/; + } + + [Test] + public void Test2() + { + using (DbManager db = new DbManager()) + { + /*[a]*/SqlQuery query = new SqlQuery()/*[/a]*/; + + List list = query./*[a]*/SelectAll(db)/*[/a]*/; + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/SelectByKey.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/SelectByKey.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,37 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class SelectByKey + { + [Test] + public void Test1() + { + /*[a]*/SprocQuery query = new SprocQuery()/*[/a]*/; + + Person person = query./*[a]*/SelectByKey(1)/*[/a]*/; + + Assert.IsNotNull(person); + } + + [Test] + public void Test2() + { + using (DbManager db = new DbManager()) + { + /*[a]*/SprocQuery query = new SprocQuery()/*[/a]*/; + + Person person = query./*[a]*/SelectByKey(db, 1)/*[/a]*/; + + Assert.IsNotNull(person); + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/SelectByKeySql.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/SelectByKeySql.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,37 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class SelectByKeySql + { + [Test] + public void Test1() + { + /*[a]*/SqlQuery query = new SqlQuery()/*[/a]*/; + + Person person = query./*[a]*/SelectByKey(1)/*[/a]*/; + + Assert.IsNotNull(person); + } + + [Test] + public void Test2() + { + using (DbManager db = new DbManager()) + { + /*[a]*/SqlQuery query = new SqlQuery()/*[/a]*/; + + Person person = query./*[a]*/SelectByKey(db, 1)/*[/a]*/; + + Assert.IsNotNull(person); + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/SprocName.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/SprocName.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class SprocName + { + public abstract class TestAccessor : DataAccessor + { + [/*[a]*/SprocName/*[/a]*/("Person_SelectAll")] + public abstract List GetPersonList(); + } + + [Test] + public void Test() + { + TestAccessor ta = DataAccessor.CreateInstance(); + + List list = ta.GetPersonList(); + + Assert.AreNotEqual(0, list.Count); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Sql/Access.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Sql/Access.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3 @@ + + + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Sql/Fdp.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Sql/Fdp.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,5 @@ + + + SELECT FIRST {0} * FROM Person WHERE LastName = @lastName + SELECT CAST(@id AS INTEGER) PersonID FROM Dual + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Sql/Oracle.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Sql/Oracle.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ + + + SELECT * FROM Person WHERE LastName = :lastName + SELECT * FROM Person WHERE {0} = :value + SELECT * FROM Person WHERE LastName = :lastName AND rownum <= {0} + SELECT :id PersonID FROM Dual + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Sql/SQLite.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Sql/SQLite.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ + + + SELECT * FROM Person WHERE LastName = @lastName LIMIT {0} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Sql/Sql.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Sql/Sql.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ + + + SELECT * FROM Person WHERE LastName = @lastName + SELECT * FROM Person WHERE {0} = @value + SELECT TOP {0} * FROM Person WHERE LastName = @lastName + SELECT @id as PersonID + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/SqlQuery.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/SqlQuery.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.DataAccess; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class SqlQuery + { + public abstract class TestAccessor : DataAccessor + { + [/*[a]*/SqlQuery/*[/a]*/(@" + SELECT + * + FROM + Person + WHERE + FirstName like @firstName AND + LastName like @lastName")] + public abstract List GetPersonListByName(string @firstName, string @lastName); + } + + [Test] + public void Test() + { + TestAccessor ta = DataAccessor.CreateInstance(); + + List list = ta.GetPersonListByName("John", "P%"); + + Assert.AreNotEqual(0, list.Count); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/TableName.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/TableName.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,45 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class TableName + { + /*[a]*/[TableName("Person")]/*[/a]*/ + public class /*[a]*/MyPersonObject/*[/a]*/ + { + [MapField("PersonID"), PrimaryKey, NonUpdatable] + public int ID; + + public string LastName; + public string FirstName; + public string MiddleName; + } + + [Test] + public void Test1() + { + SqlQuery query = new SqlQuery(); + + MyPersonObject person = query./*[a]*/SelectByKey(1)/*[/a]*/; + + Assert.IsNotNull(person); + } + + [Test] + public void Test2() + { + SprocQuery query = new SprocQuery(); + + MyPersonObject person = query./*[a]*/SelectByKey(1)/*[/a]*/; + + Assert.IsNotNull(person); + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Transaction.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Transaction.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,70 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class Transaction + { + public abstract class TestAccessor : DataAccessor + { + public abstract int Insert(Person person); + public abstract void Delete(int @PersonID); + + public abstract Person SelectByKey(int id); + public abstract Person SelectByKey(/*[a]*/DbManager/*[/a]*/ db, int id); + } + + // /*[i]*/DataAccessor/*[/i]*/ takes /*[i]*/DbManager/*[/i]*/ as a parameter. + // + [Test] + public void Test1() + { + using (DbManager db = new DbManager()) + { + TestAccessor ta = DataAccessor.CreateInstance/*[a]*/(db)/*[/a]*/; + + ta./*[a]*/BeginTransaction/*[/a]*/(); + + int id = ta.Insert(new Person { FirstName = "John", LastName = "Smith" }); + Assert.AreNotEqual(0, id); + + Person person = ta.SelectByKey(id); + Assert.IsNotNull(person); + + ta.Delete(id); + + ta./*[a]*/CommitTransaction/*[/a]*/(); + } + } + + // /*[i]*/DataAccessor/*[/i]*/ method takes /*[i]*/DbManager/*[/i]*/ as a parameter. + // + [Test] + public void Test2() + { + using (DbManager db = new DbManager()) + { + db.BeginTransaction(); + + TestAccessor ta = DataAccessor.CreateInstance/*[a]*/()/*[/a]*/; + + int id = ta.Insert(new Person { FirstName = "John", LastName = "Smith" }); + Assert.AreNotEqual(0, id); + + Person person = ta.SelectByKey(/*[a]*/db/*[/a]*/, id); + Assert.IsNotNull(person); + + ta.Delete(id); + + db.CommitTransaction(); + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/Update.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/Update.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,76 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class Update + { + int _id; + + [TestFixtureSetUp] + public void Insert() + { + using (DbManager db = new DbManager()) + { + _id = db + .SetCommand(@" + INSERT INTO Person ( + FirstName, LastName, Gender + ) VALUES ( + @FirstName, @LastName, @Gender + ) + SELECT Cast(SCOPE_IDENTITY() as int)", + db.Parameter("@FirstName", "Crazy"), + db.Parameter("@LastName", "Frog"), + db.Parameter("@Gender", Map.EnumToValue(Gender.Unknown))) + .ExecuteScalar(); + } + } + + [Test] + public void Test1() + { + /*[a]*/SprocQuery query = new SprocQuery()/*[/a]*/; + + Person person = query.SelectByKey(_id); + + person.Gender = Gender.Other; + + query./*[a]*/Update(person)/*[/a]*/; + } + + [Test] + public void Test2() + { + using (DbManager db = new DbManager()) + { + /*[a]*/SprocQuery query = new SprocQuery()/*[/a]*/; + + Person person = query.SelectByKey(db, _id); + + person.Gender = Gender.Other; + + query./*[a]*/Update(db, person)/*[/a]*/; + } + } + + [TestFixtureTearDown] + public void Delete() + { + using (DbManager db = new DbManager()) + { + db + .SetCommand("DELETE FROM Person WHERE PersonID = @id", + db.Parameter("@id", _id)) + .ExecuteNonQuery(); + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/UpdateSql.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/UpdateSql.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,76 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class UpdateSql + { + int _id; + + [TestFixtureSetUp] + public void Insert() + { + using (DbManager db = new DbManager()) + { + _id = db + .SetCommand(@" + INSERT INTO Person ( + FirstName, LastName, Gender + ) VALUES ( + @FirstName, @LastName, @Gender + ) + SELECT Cast(SCOPE_IDENTITY() as int)", + db.Parameter("@FirstName", "Crazy"), + db.Parameter("@LastName", "Frog"), + db.Parameter("@Gender", Map.EnumToValue(Gender.Unknown))) + .ExecuteScalar(); + } + } + + [Test] + public void Test1() + { + /*[a]*/SqlQuery query = new SqlQuery()/*[/a]*/; + + Person person = query.SelectByKey(_id); + + person.Gender = Gender.Other; + + query./*[a]*/Update(person)/*[/a]*/; + } + + [Test] + public void Test2() + { + using (DbManager db = new DbManager()) + { + /*[a]*/SqlQuery query = new SqlQuery()/*[/a]*/; + + Person person = query.SelectByKey(db, _id); + + person.Gender = Gender.Other; + + query./*[a]*/Update(db, person)/*[/a]*/; + } + } + + [TestFixtureTearDown] + public void Delete() + { + using (DbManager db = new DbManager()) + { + db + .SetCommand("DELETE FROM Person WHERE PersonID = @id", + db.Parameter("@id", _id)) + .ExecuteNonQuery(); + } + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/XmlExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/XmlExtension.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ +using NUnit.Framework; + +using BLToolkit.DataAccess; +using BLToolkit.Mapping; +/*[a]*/using BLToolkit.Reflection.Extension/*[/a]*/; + +namespace HowTo.DataAccess +{ + [TestFixture] + public class XmlExtension + { + public class MyPersonObject + { + [MapField("PersonID")] + public int ID; + + public string LastName; + public string FirstName; + public string MiddleName; + } + + [Test] + public void Test() + { + SqlQuery query = new SqlQuery(); + + /*[a]*/query.Extensions = TypeExtension.GetExtensions("XmlExtension.xml")/*[/a]*/; + + MyPersonObject person = query.SelectByKey(1); + + Assert.IsNotNull(person); + } + } +} + diff -r 000000000000 -r f990fcb411a9 HowTo/DataAccess/XmlExtension.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/DataAccess/XmlExtension.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 HowTo/EditableObjects/AcceptRejectChanges.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/EditableObjects/AcceptRejectChanges.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +using System; +using NUnit.Framework; +using BLToolkit.EditableObjects; + +namespace HowTo.EditableObjects +{ + [TestFixture] + public class AcceptRejectChanges + { + public /*[a]*/abstract/*[/a]*/ class TestObject : /*[a]*/EditableObject/*[/a]*/ + { + public /*[a]*/abstract/*[/a]*/ string FirstName { get; set; } + public /*[a]*/abstract/*[/a]*/ string LastName { get; set; } + } + + [Test] + public void Test() + { + // Create an instance. + // + TestObject obj = TestObject./*[a]*/CreateInstance/*[/a]*/(); + + // Accept changes. + // + obj.FirstName = "Tester"; + obj.LastName = "Testerson"; + + Assert.IsTrue(obj.IsDirty); + + obj./*[a]*/AcceptChanges/*[/a]*/(); + + Assert.AreEqual("Tester", obj.FirstName); + Assert.IsFalse(obj.IsDirty); + + // Reject changes. + // + obj.FirstName = "Developer"; + + Assert.IsTrue(obj.IsDirty); + + obj./*[a]*/RejectChanges/*[/a]*/(); + + Assert.AreEqual("Tester", obj.FirstName); + Assert.IsFalse(obj.IsDirty); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/EditableObjects/EditableObjectTest.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/EditableObjects/EditableObjectTest.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,40 @@ +using System; +using NUnit.Framework; +using BLToolkit.EditableObjects; + +namespace HowTo.EditableObjects +{ + [TestFixture] + public class EditableObjectTest + { + public /*[a]*/abstract/*[/a]*/ class TestObject : /*[a]*/EditableObject/*[/a]*/ + { + // Any abstract property becomes editable. + // + public /*[a]*/abstract/*[/a]*/ string FirstName { get; set; } + public /*[a]*/abstract/*[/a]*/ string LastName { get; set; } + + // This field is not editable. + // + public string FullName + { + get { return string.Format("{0} {1}", FirstName, LastName); } + } + } + + [Test] + public void Test() + { + TestObject obj = TestObject./*[a]*/CreateInstance/*[/a]*/(); + + obj.FirstName = "Tester"; + obj.LastName = "Testerson"; + + Assert.IsTrue(obj.IsDirty); + + obj.AcceptChanges(); + + Assert.IsFalse(obj.IsDirty); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/EditableObjects/IsDirty.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/EditableObjects/IsDirty.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,33 @@ +using System; +using NUnit.Framework; +using BLToolkit.EditableObjects; + +namespace HowTo.EditableObjects +{ + [TestFixture] + public class IsDirty + { + public /*[a]*/abstract/*[/a]*/ class TestObject : /*[a]*/EditableObject/*[/a]*/ + { + public /*[a]*/abstract/*[/a]*/ string FirstName { get; set; } + public /*[a]*/abstract/*[/a]*/ string LastName { get; set; } + } + + [Test] + public void Test() + { + TestObject obj = TestObject./*[a]*/CreateInstance/*[/a]*/(); + + Assert./*[a]*/IsFalse/*[/a]*/(obj./*[a]*/IsDirty/*[/a]*/); + + obj.FirstName = "Tester"; + obj.LastName = "Testerson"; + + Assert./*[a]*/IsTrue/*[/a]*/(obj./*[a]*/IsDirty/*[/a]*/); + + obj.AcceptChanges(); + + Assert./*[a]*/IsFalse/*[/a]*/(obj./*[a]*/IsDirty/*[/a]*/); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/EditableObjects/PropertyChanged.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/EditableObjects/PropertyChanged.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +using System; +using NUnit.Framework; +using BLToolkit.EditableObjects; + +namespace HowTo.EditableObjects +{ + [TestFixture] + public class PropertyChanged + { + public /*[a]*/abstract/*[/a]*/ class TestObject : /*[a]*/EditableObject/*[/a]*/ + { + public /*[a]*/abstract/*[/a]*/ string FirstName { get; set; } + public /*[a]*/abstract/*[/a]*/ string LastName { get; set; } + } + + [Test] + public void Test() + { + TestObject obj = TestObject./*[a]*/CreateInstance/*[/a]*/(); + + bool proprtyName = null; + + obj./*[a]*/PropertyChanged/*[/a]*/ += (s, e) => proprtyName = e.PropertyName; + + Assert.IsNull(propertyName); + + obj.FirstName = "Tester"; + + Assert.AreEqual(proprtyName, "FirstName"); + + bool proprtyName = null; + + obj.AcceptChanges(); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/HowTo.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/HowTo.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,282 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {8DA66999-005A-49AB-86A9-2C1F62905B50} + Library + Properties + HowTo + HowTo + + + 3.5 + + + false + v4.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + x86 + bin\Debug\HowTo.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\HowTo.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + + False + ..\packages\NUnit.2.6.3\lib\nunit.framework.dll + + + + + 3.5 + + + + + + + Data\DataProvider\SybaseAdoDataProvider.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + BLToolkitData.sqlite + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + BLToolkitData.mdb + PreserveNewest + + + BLToolkitData.sdf + PreserveNewest + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 HowTo/Mapping/EnumToValue.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Mapping/EnumToValue.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,60 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Mapping; + +namespace HowTo.Mapping +{ + [TestFixture] + public class EnumToValue + { + public enum Gender1 + { + [MapValue("F")] Female, + [MapValue("M")] Male, + [MapValue("U")] Unknown, + [MapValue("O")] Other + } + + [Test] + public void Test1() + { + object value = Map./*[a]*/EnumToValue/*[/a]*/(Gender1.Male); + + Assert.AreEqual("M", value); + } + + public enum Gender2 + { + [MapValue(1)] Female, + [MapValue(2)] Male, + [MapValue(3)] Unknown, + [MapValue(4)] Other + } + + [Test] + public void Test2() + { + object value = Map./*[a]*/EnumToValue/*[/a]*/(Gender2.Male); + + Assert.AreEqual(2, value); + } + + public enum Gender3 + { + Female = 1, + Male = 2, + Unknown = 3, + Other = 4 + } + + [Test] + public void Test3() + { + object value = (int)Map./*[a]*/EnumToValue/*[/a]*/(Gender3.Male); + + Assert.AreEqual(2, value); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Mapping/FluentMapping.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Mapping/FluentMapping.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,38 @@ +using System; + +using BLToolkit.Mapping; +using BLToolkit.Mapping.Fluent; +using BLToolkit.Mapping.MemberMappers; + +namespace HowTo.Mapping +{ + public class Category + { + public int CategoryID; + public string CategoryName; + public string Description; + public Binary Picture; + public TimeSpan RefreshTime; + public AdditionalInfo AdditionalInfo; + public List Products; + } + + public class CategoryMap : FluentMap + { + public CategoryMap() + { + TableName("Categories"); + PrimaryKey(_ => _.CategoryID).Identity(); + Nullable(_ => _.Description); + Nullable(_ => _.Picture); + MapField(_ => _.RefreshTime).MemberMapper(typeof(TimeSpanBigIntMapper)).DbType(System.Data.DbType.Int64); + MapField(_ => _.AdditionalInfo).MapIgnore(false).MemberMapper(typeof(BinarySerialisationMapper)).DbType(System.Data.DbType.Byte); + Association(_ => _.Products,_ => _.CategoryID).ToMany((Product _) => _.CategoryID); + } + } + + public static void Main() + { + FluentConfig.Configure(Map.DefaultSchema).MapingFromAssemblyOf(); + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 HowTo/Mapping/MapFieldAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Mapping/MapFieldAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,88 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Mapping; + +namespace HowTo.Mapping +{ + [TestFixture] + public class MapField + { + public class SourceObject1 + { + public string Street = "1 Main"; + public string City = "Bigtown"; + public string State = "XX"; + public string Zip = "00000"; + } + + public class Address + { + public string Street; + public string City; + public string State; + public string Zip; + } + + /*[a]*/[MapField("Street", "Address.Street")]/*[/a]*/ + /*[a]*/[MapField("City", "Address.City")]/*[/a]*/ + /*[a]*/[MapField("State", "Address.State")]/*[/a]*/ + /*[a]*/[MapField("Zip", "Address.Zip")]/*[/a]*/ + public class Order1 + { + public Address Address = new Address(); + } + + [Test] + public void MapFieldTest1() + { + SourceObject1 source = new SourceObject1(); + Order1 order = Map.ObjectToObject(source); + + Assert.AreEqual("1 Main", order.Address.Street); + Assert.AreEqual("Bigtown", order.Address.City); + Assert.AreEqual("XX", order.Address.State); + Assert.AreEqual("00000", order.Address.Zip); + } + + public class SourceObject2 + { + public string BillingStreet = "1 Main"; + public string BillingCity = "Bigtown"; + public string BillingState = "XX"; + public string BillingZip = "00000"; + + public string ShippingStreet = "2 Main"; + public string ShippingCity = "Bigtown"; + public string ShippingState = "XX"; + public string ShippingZip = "00000"; + } + + public class Order2 + { + /*[a]*/[MapField(Format="Billing{0}")]/*[/a]*/ + public Address BillingAddress = new Address(); + + /*[a]*/[MapField(Format="Shipping{0}")]/*[/a]*/ + public Address ShippingAddress = new Address(); + } + + [Test] + public void MapFieldTest2() + { + SourceObject2 source = new SourceObject2(); + Order2 order = Map.ObjectToObject(source); + + Assert.AreEqual("1 Main", order.BillingAddress.Street); + Assert.AreEqual("Bigtown", order.BillingAddress.City); + Assert.AreEqual("XX", order.BillingAddress.State); + Assert.AreEqual("00000", order.BillingAddress.Zip); + + Assert.AreEqual("2 Main", order.ShippingAddress.Street); + Assert.AreEqual("Bigtown", order.ShippingAddress.City); + Assert.AreEqual("XX", order.ShippingAddress.State); + Assert.AreEqual("00000", order.ShippingAddress.Zip); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Mapping/MapToJson.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Mapping/MapToJson.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,435 @@ +using System; +using System.Globalization; +using System.Text; +using System.Xml; + +using NUnit.Framework; + +using BLToolkit.Mapping; +using BLToolkit.Reflection; + +namespace HowTo.Mapping +{ + public class JsonMapper : MapDataDestinationBase, IMapDataDestinationList, ISupportMapping + { + private static readonly long InitialJavaScriptDateTicks = new DateTime(1970, 1, 1).Ticks; + + private string[] _fieldNames; + private readonly StringBuilder _sb; + private MappingSchema _mappingSchema; + private bool _scalar; + private bool _first; + private bool _firstElement; + private int _indent; + + public JsonMapper() : this(new StringBuilder(), 0) + { + } + + public JsonMapper(StringBuilder sb) : this(sb, 0) + { + } + + public JsonMapper(StringBuilder sb, int indent) + { + _sb = sb; + _indent = indent; + } + + public override Type GetFieldType(int index) + { + // Same as typeof(object) + // + return null; + } + + public override int GetOrdinal(string name) + { + return Array.IndexOf(_fieldNames, name); + } + + public override void SetValue(object o, int index, object value) + { + SetValue(o, _fieldNames[index], value); + } + + public override void SetValue(object o, string name, object value) + { + if (!_scalar) + { + // Do not Json null values until it's an array + // + if (value == null || (value is XmlNode && IsEmptyNode((XmlNode)value))) + return; + + if (_first) + _first = false; + else + _sb + .Append(',') + .AppendLine() + ; + + for (int i = 0; i < _indent; ++i) + _sb.Append(' '); + + _sb + .Append('"') + .Append(name) + .Append("\":") + ; + } + + if (value == null) + _sb.Append("null"); + else + { + switch (Type.GetTypeCode(value.GetType())) + { + case TypeCode.Empty: + case TypeCode.DBNull: + _sb.Append("null"); + break; + case TypeCode.Boolean: + _sb.Append((bool)value? "true": "false"); + break; + case TypeCode.Char: + _sb + .Append('\'') + .Append((char)value) + .Append('\'') + ; + break; + case TypeCode.SByte: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.Byte: + case TypeCode.UInt16: + case TypeCode.UInt32: + case TypeCode.UInt64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + _sb.Append(((IFormattable)value).ToString(null, CultureInfo.InvariantCulture)); + break; + case TypeCode.DateTime: + _sb + .Append("new Date(") + .Append((((DateTime)value).Ticks - InitialJavaScriptDateTicks)/10000) + .Append(")"); + break; + case TypeCode.String: + _sb + .Append('"') + .Append(encode((string)value)) + .Append('"') + ; + break; + default: + if (value is XmlNode) + { + if (IsEmptyNode((XmlNode) value)) + _sb.Append("null"); + else + WriteXmlJson((XmlNode)value); + } + else + { + JsonMapper inner = new JsonMapper(_sb, _indent + 1); + + if (value.GetType().IsArray) + _mappingSchema.MapSourceListToDestinationList( + _mappingSchema.GetDataSourceList(value), inner); + else + _mappingSchema.MapSourceToDestination( + _mappingSchema.GetDataSource(value), value, inner, inner); + } + break; + } + } + } + + private static string encode(string value) + { + return value.Replace("\r\n", "\\r") + .Replace("\n\r", "\\r") + .Replace("\n", "\\r") + .Replace("\r", "\\r") + .Replace("\"","\\\""); + } + + private void WriteXmlJson(XmlNode node) + { + XmlNode textNode = GetTextNode(node); + if (textNode != null) + { + _sb + .Append("\"") + .Append(encode(textNode.Value)) + .Append('\"') + ; + } + else + { + + bool first = true; + + _sb.Append('{'); + + if (node.Attributes != null) + { + foreach (XmlAttribute attr in node.Attributes) + { + if (first) + first = false; + else + _sb.Append(','); + + _sb + .Append("\"@") + .Append(attr.Name) + .Append("\":\"") + .Append(encode(attr.Value)) + .Append('\"') + ; + } + } + + foreach (XmlNode child in node.ChildNodes) + { + if (IsWhitespace(child) || IsEmptyNode(child)) + continue; + + if (first) + first = false; + else + _sb.Append(','); + + if (child is XmlText) + _sb + .Append("\"#text\":\"") + .Append(encode(child.Value)) + .Append('\"') + ; + else if (child is XmlElement) + { + _sb + .Append('"') + .Append(child.Name) + .Append("\":") + ; + WriteXmlJson(child); + } + else + System.Diagnostics.Debug.Fail("Unexpected node type " + child.GetType().FullName); + } + _sb.Append('}'); + } + } + + private static bool IsWhitespace(XmlNode node) + { + switch (node.NodeType) + { + case XmlNodeType.Comment: + case XmlNodeType.Whitespace: + case XmlNodeType.SignificantWhitespace: + return true; + } + return false; + } + + private static bool IsEmptyNode(XmlNode node) + { + if (node.Attributes != null && node.Attributes.Count > 0) + return false; + + if (node.HasChildNodes) + foreach (XmlNode childNode in node.ChildNodes) + { + if (IsWhitespace(childNode) || IsEmptyNode(childNode)) + continue; + + // Not a whitespace, nor inner empty node. + // + return false; + } + + return node.Value == null; + } + + private static XmlNode GetTextNode(XmlNode node) + { + if (node.Attributes != null && node.Attributes.Count > 0) + return null; + + XmlNode textNode = null; + + foreach (XmlNode childNode in node.ChildNodes) + { + // Ignore all whitespace. + // + if (IsWhitespace(childNode)) + continue; + + if (childNode is XmlText) + { + // More then one text node. + // + if (textNode != null) + return null; + + // First text node. + // + textNode = childNode; + } + else + // Not a text node - break; + // + return null; + } + + return textNode; + } + + #region ISupportMapping Members + + void ISupportMapping.BeginMapping(InitContext initContext) + { + _first = true; + _mappingSchema = initContext.MappingSchema; + _fieldNames = new string[initContext.DataSource.Count]; + + for (int i = 0; i < _fieldNames.Length; ++i) + _fieldNames[i] = initContext.DataSource.GetName(i); + + _scalar = _fieldNames.Length == 1 && string.IsNullOrEmpty(_fieldNames[0]); + + if (_scalar) + return; + + if (_fieldNames.Length <= 1) + { + // Reset the indent since output is a single line. + // + _indent = 0; + _sb.Append('{'); + } + else + { + if (_indent > 0) + _sb.AppendLine(); + + for (int i = 0; i < _indent; ++i) + _sb.Append(' '); + + _sb + .Append('{') + .AppendLine() + ; + } + } + + void ISupportMapping.EndMapping(InitContext initContext) + { + if (_scalar) + return; + + if (_fieldNames.Length > 1) + _sb.AppendLine(); + + for (int i = 0; i < _indent; ++i) + _sb.Append(' '); + _sb.Append('}'); + } + + #endregion + + #region IMapDataDestinationList Members + + void IMapDataDestinationList.InitMapping(InitContext initContext) + { + _firstElement = true; + _sb.Append('['); + } + + IMapDataDestination IMapDataDestinationList.GetDataDestination(InitContext initContext) + { + return this; + } + + object IMapDataDestinationList.GetNextObject(InitContext initContext) + { + if (_firstElement) + _firstElement = false; + else + _sb.Append(','); + + return this; + } + + void IMapDataDestinationList.EndMapping(InitContext initContext) + { + _sb.Append(']'); + } + + #endregion + + public override string ToString() + { + return _sb.ToString(); + } + } + + [TestFixture] + public class MapToJson + { + public class Inner + { + public string Name = "inner \"object \n name"; + } + + public class Inner2 + { + public string Name; + public int Value; + } + + public class SourceObject + { + public string Foo = "Foo"; + public double Bar = 1.23; + public DateTime Baz = DateTime.Today; + [MapIgnore(false)] + public Inner Inner = new Inner(); + [MapIgnore(false)] + public Inner2 Inner2 = new Inner2(); + public string[] StrArray = {"One", "Two", "Three"}; + } + + [Test] + public void Test() + { + JsonMapper jm = new JsonMapper(new StringBuilder(256)); + + Map./*[a]*/MapSourceToDestination/*[/a]*/(Map.GetObjectMapper(typeof(SourceObject)), new SourceObject(), jm, jm); + Console.Write(jm.ToString()); + + // Expected output: + // + // { + // "Foo":"Foo", + // "Bar":1.23, + // "Baz":new Date(11823840000000000), + // "Inner":{ "Name":"inner \"object \r name"}, + // "Inner2": + // { + // "Name":null, + // "Value":0 + // }, + // "StrArray":["One","Two","Three"] + // } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Mapping/MapValueAttribute1.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Mapping/MapValueAttribute1.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,75 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Mapping; + +namespace HowTo.Mapping +{ + [TestFixture] + public class MapValue1 + { + public class SourceObject + { + public string Value = "Y"; + } + + public class TestObject1 + { + // The attribute is applied to a field/property. + // + [/*[a]*/MapValue(true, "Y")/*[/a]*/] + [/*[a]*/MapValue(false, "N")/*[/a]*/] + public bool Value; + } + + [Test] + public void Test1() + { + SourceObject so = new SourceObject(); + TestObject1 to = Map.ObjectToObject(so); + + Assert.AreEqual(true, to.Value); + } + + // The attribute is applied to a class. + // + [/*[a]*/MapValue(true, "Y")/*[/a]*/] + [/*[a]*/MapValue(false, "N")/*[/a]*/] + public class TestObject2 + { + public bool Value; + } + + [Test] + public void Test2() + { + SourceObject so = new SourceObject(); + TestObject2 to = Map.ObjectToObject(so); + + Assert.AreEqual(true, to.Value); + } + + // The attribute is applied to a base class and affects all child classes. + // + [/*[a]*/MapValue(typeof(bool), true, "Y")/*[/a]*/] + [/*[a]*/MapValue(typeof(bool), false, "N")/*[/a]*/] + public class ObjectBase + { + } + + public class TestObject3 : /*[a]*/ObjectBase/*[/a]*/ + { + public bool Value; + } + + [Test] + public void Test3() + { + SourceObject so = new SourceObject(); + TestObject3 to = Map.ObjectToObject(so); + + Assert.AreEqual(true, to.Value); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Mapping/MapValueAttribute2.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Mapping/MapValueAttribute2.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,48 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Mapping; + +namespace HowTo.Mapping +{ + [TestFixture] + public class MapValue2 + { + public enum Gender1 + { + [/*[a]*/MapValue("F")/*[/a]*/] Female, + [/*[a]*/MapValue("M")/*[/a]*/] Male, + [/*[a]*/MapValue("U")/*[/a]*/] Unknown, + [/*[a]*/MapValue("O")/*[/a]*/] Other + } + + [Test] + public void Test1() + { + object value = Map.EnumToValue(Gender1.Male); + + Assert.AreEqual("M", value); + } + + [/*[a]*/MapValue(Gender2.Female, 1)/*[/a]*/] + [/*[a]*/MapValue(Gender2.Male, 2)/*[/a]*/] + [/*[a]*/MapValue(Gender2.Unknown, 3)/*[/a]*/] + [/*[a]*/MapValue(Gender2.Other, 4)/*[/a]*/] + public enum Gender2 + { + Female, + Male, + Unknown, + Other + } + + [Test] + public void Test2() + { + Gender2 g = Map.ToEnum(2); + + Assert.AreEqual(Gender2.Male, g); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Mapping/ObjectToObject.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Mapping/ObjectToObject.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,41 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Mapping; + +namespace HowTo.Mapping +{ + [TestFixture] + public class ObjectToObject + { + public class SourceObject + { + public bool Value1 = true; + public string Value2 = "10"; + public string StrValue = "test"; + } + + public class DestObject + { + [MapField("Value1")] public bool BoolValue; + [MapField("Value2")] public int IntValue; + + // If the source and destination field/property names are equal, + // there is no need for using the MapField attribute. + // + public string StrValue; + } + + [Test] + public void Test1() + { + SourceObject source = new SourceObject(); + DestObject dest = Map./*[a]*/ObjectToObject/*[/a]*/(source); + + Assert.AreEqual(true, dest.BoolValue); + Assert.AreEqual(10, dest.IntValue); + Assert.AreEqual("test", dest.StrValue); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Mapping/ValueToEnum.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Mapping/ValueToEnum.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,60 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Mapping; + +namespace HowTo.Mapping +{ + [TestFixture] + public class ValueToEnum + { + public enum Gender1 + { + [MapValue("F")] Female, + [MapValue("M")] Male, + [MapValue("U")] Unknown, + [MapValue("O")] Other + } + + [Test] + public void Test1() + { + Gender1 g = Map./*[a]*/ToEnum/*[/a]*/("M"); + + Assert.AreEqual(Gender1.Male, g); + } + + public enum Gender2 + { + [MapValue(1)] Female, + [MapValue(2)] Male, + [MapValue(3)] Unknown, + [MapValue(4)] Other + } + + [Test] + public void Test2() + { + Gender2 g = Map./*[a]*/ToEnum/*[/a]*/(2); + + Assert.AreEqual(Gender2.Male, g); + } + + public enum Gender3 + { + Female = 1, + Male = 2, + Unknown = 3, + Other = 4 + } + + [Test] + public void Test3() + { + Gender3 g = Map./*[a]*/ToEnum/*[/a]*/(2); + + Assert.AreEqual(Gender3.Male, g); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Patterns/DuckTyping.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Patterns/DuckTyping.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,78 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Patterns; + +namespace HowTo.Patterns +{ + //[TestFixture] + public class DuckTyping + { + // By default, all interface methods are optional. + // + public interface OptionalInterface + { + // If the source object does not implement the [b]Method1[/b], a NotImplementedException is thrown at [i]run time[/i]. + // + void Method1(); + + // If the source object does not implement the [b]Method2[/b], a TypeBuilderException is thrown at [i]build time[/i]. + // + /*[a]*/[MustImplement]/*[/a]*/ + void Method2(); + + // If the source object does not implement the [b]Method3[/b], an empty stub is genegated. + // The return value and all output parameters will be set to default values. + // + /*[a]*/[MustImplement(false, false)]/*[/a]*/ + int Method3(); + } + + // The MustImplement attribute also can control the entire interface. + // + /*[a]*/[MustImplement]/*[/a]*/ + public interface RequiredInterface + { + // If the source object does not implement the [b]Method1[/b], a TypeBuilderException is thrown at [i]build time[/i]. + // + void Method1(); + + // If the source object does not implement the [b]Method2[/b], a NotImplementedException is thrown at [i]run time[/i]. + // + /*[a]*/[MustImplement(false)]/*[/a]*/ + void Method2(); + + // If the source object does not implement the [b]Method3[/b], an empty stub is genegated. + // The return value and all output parameters will be set to default values. + // + /*[a]*/[MustImplement(false, false)]/*[/a]*/ + int Method3(); + } + + public class TestClass + { + public int Method3() + { + return 3; + } + } + + // Two or more interfaces can be mixed together. + // + public interface InterfaceMix : RequiredInterface, OptionalInterface + { + } + + //[Test] + public void Test() + { + InterfaceMix duck = /*[a]*/BLToolkit.Patterns.DuckTyping.Implement/*[/a]*/(new TestClass()); + RequiredInterface duck1 = duck; + OptionalInterface duck2 = duck; + + duck1.Method1(); + duck2.Method1(); + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,31 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("HowTo")] +[assembly: AssemblyProduct("Business Logic Toolkit")] +[assembly: AssemblyCopyright("\xA9 2002-2012 www.bltoolkit.net")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("fa9081a1-c63c-4b8e-b554-209dad7d8d37")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion ("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + diff -r 000000000000 -r f990fcb411a9 HowTo/Reflection/ObjectFactory.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/Reflection/ObjectFactory.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using BLToolkit.Data; +using BLToolkit.Mapping; +using BLToolkit.Reflection; + +namespace HowTo.Reflection +{ + [TestFixture] + public class ObjectFactoryTest + { + /*[a]*/[ObjectFactory(typeof(Person.ObjectFactory))]/*[/a]*/ + public class Person + { + [MapField("PersonID")] + public int ID; + + public string LastName; + public string FirstName; + public string MiddleName; + + /*[a]*/class ObjectFactory : IObjectFactory/*[/a]*/ + { + public object /*[a]*/CreateInstance(TypeAccessor typeAccessor, InitContext context)/*[/a]*/ + { + // Get the object type indicator field. + // + object objectType = context.DataSource.GetValue(context.SourceObject, "PersonType"); + + // Target ObjectMapper must be changed in order to provide correct mapping. + // + switch ((string)objectType) + { + case "D": /*[a]*/context.ObjectMapper = ObjectMapper. Instance;/*[/a]*/ break; + case "P": /*[a]*/context.ObjectMapper = ObjectMapper.Instance;/*[/a]*/ break; + } + + // Create an object instance. + // Do not call ObjectMapper.CreateInstance as it will lead to infinite recursion. + // + return context.ObjectMapper./*[a]*/TypeAccessor/*[/a]*/.CreateInstance(context); + } + } + } + + public class /*[a]*/Doctor : Person/*[/a]*/ + { + public string Taxonomy; + } + + public class /*[a]*/Patient : Person/*[/a]*/ + { + public string Diagnosis; + } + + [Test] + public void Test() + { + using (DbManager db = new DbManager()) + { + List list = db + .SetCommand(@" + SELECT + ps.*, + d.Taxonomy, + p.Diagnosis, + CASE + WHEN d.PersonID IS NOT NULL THEN 'D' + WHEN p.PersonID IS NOT NULL THEN 'P' + END as PersonType + FROM + Person ps + LEFT JOIN Doctor d ON d.PersonID = ps.PersonID + LEFT JOIN Patient p ON p.PersonID = ps.PersonID + ORDER BY + ps.PersonID") + .ExecuteList(); + + Assert.AreEqual(list[0].GetType(), /*[a]*/typeof(Doctor)/*[/a]*/); + Assert.AreEqual(list[1].GetType(), /*[a]*/typeof(Patient)/*[/a]*/); + + if (list.Count > 2) + Assert.AreEqual(list[2].GetType(), typeof(Person)); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 HowTo/TypeBuilder/InitialValues.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/TypeBuilder/InitialValues.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,45 @@ +using System; + +using NUnit.Framework; + +using BLToolkit.Reflection; +using BLToolkit.TypeBuilder; + +namespace HowTo.TypeBuilder +{ + [TestFixture] + public class InitialValueTest + { + [AttributeUsage(AttributeTargets.Property)] + public class NewGuidParameterAttribute : /*[a]*/ParameterAttribute/*[/a]*/ + { + public NewGuidParameterAttribute() : base(/*[a]*/Guid.NewGuid().ToByteArray()/*[/a]*/) + { + } + } + + public abstract class TestObject1 + { + /*[a]*/[Parameter("t")]/*[/a]*/ public abstract string Str { get; set; } + /*[a]*/[Parameter(20)]/*[/a]*/ public abstract string this[int i] { get; set; } + /*[a]*/[Parameter(54)]/*[/a]*/ public abstract int Int { get; set; } + /*[a]*/[Parameter(2,2,2)]/*[/a]*/ public abstract DateTime Date { get; set; } + /*[a]*/[Parameter(222L)]/*[/a]*/ public abstract Decimal Decimal1 { get; set; } + /*[a]*/[Parameter(-2.05)]/*[/a]*/ public abstract Decimal Decimal2 { get; set; } + /*[a]*/[NewGuidParameter]/*[/a]*/ public abstract Guid Guid { get; set; } + } + + [Test] + public void Test() + { + TestObject1 o = (TestObject1)TypeAccessor.CreateInstance(typeof(TestObject1)); + + Assert.That(o.Str, Is.EqualTo("t")); + Assert.That(o.Int, Is.EqualTo(54)); + Assert.That(o.Date, Is.EqualTo(new DateTime(2,2,2))); + Assert.That(o.Decimal1, Is.EqualTo(222m)); + Assert.That(o.Decimal2, Is.EqualTo(-2.05m)); + Assert.That(o.Guid, Is.Not.EqualTo(Guid.Empty)); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 HowTo/TypeBuilder/InternalTypes.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/TypeBuilder/InternalTypes.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ +using System; +using System.Runtime.CompilerServices; +using NUnit.Framework; + +using BLToolkit.Reflection; + +// typeof(TargetType).FullName + "." + TypeBuilderConsts.AssemblyNameSuffix +// +/*[a]*/[assembly: InternalsVisibleTo("HowTo.TypeBuilder.InternalTypesTest.TestObject.TypeBuilder")]/*[/a]*/ +/*[a]*/[assembly: InternalsVisibleTo("HowTo.TypeBuilder.InternalTypesTest.TestObject.TypeAccessor")]/*[/a]*/ + +namespace HowTo.TypeBuilder +{ + + [TestFixture] + public class InternalTypesTest + { + /*[a]*/internal/*[/a]*/ abstract class TestObject + { + public abstract string Value { get; set; } + } + + [Test] + public void Test() + { + var o = TypeAccessor.CreateInstance(); + Assert.IsNotNull(o); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 HowTo/TypeBuilder/XmlSerialization.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/TypeBuilder/XmlSerialization.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,66 @@ +using System.IO; +using System.Xml.Serialization; + +using NUnit.Framework; + +using BLToolkit.Reflection; +using BLToolkit.EditableObjects; +using BLToolkit.TypeBuilder; + +namespace HowTo.TypeBuilder +{ + [TestFixture] + public class XmlSerializationTest + { + /*[a]*/[XmlType(AnonymousType = true)]/*[/a]*/ + public abstract class MyClassA + { + public abstract string ValueA { get; set; } + } + + [XmlType(AnonymousType = true)] + /*[a]*/[XmlIncludeAbstract(typeof(MyClassA))]/*[/a]*/ + /*[a]*/[XmlIncludeAbstract(typeof(MyClassC))]/*[/a]*/ + public abstract class MyClassB + { + public abstract string ValueB { get; set; } + public abstract MyClassA ValueMyClassA { get; set; } + + public abstract EditableList MyList { get; set; } + } + + /*[a]*/[XmlType("abs:MyClassC")]/*[/a]*/ + public abstract class MyClassC : MyClassA { } + + [Test] + public void Test() + { + MyClassB original = TypeAccessor.CreateInstance(); + MyClassB serialized; + XmlSerializer sr = new XmlSerializer(/*[a]*/TypeAccessor.Type/*[/a]*/); + + original.ValueB = "string value B"; + original.ValueMyClassA.ValueA = "string value A"; + original.MyList.Add(TypeAccessor.CreateInstance()); + original.MyList.Add(TypeAccessor.CreateInstance()); + + using (MemoryStream stm = new MemoryStream()) + { + sr.Serialize(stm, original); + stm.Position = 0L; + serialized = (MyClassB)sr.Deserialize(stm); + } + + Assert.That(serialized.ValueB, Is.EqualTo(original.ValueB)); + Assert.That(serialized.ValueMyClassA.ValueA, Is.EqualTo(original.ValueMyClassA.ValueA)); + + Assert.AreEqual(original.MyList.Count, serialized.MyList.Count); + Assert.That(serialized.MyList[0] is MyClassA); + Assert.That(serialized.MyList[1] is MyClassA); + Assert.That(serialized.MyList[1] is MyClassC); + + Assert.AreEqual(serialized.MyList[0].GetType(), TypeFactory.GetType(typeof(MyClassA))); + Assert.AreEqual(serialized.MyList[1].GetType(), TypeFactory.GetType(typeof(MyClassC))); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 HowTo/app.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/app.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 HowTo/packages.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HowTo/packages.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Mono/Mono.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Mono/Mono.sln Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,89 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLToolkit.mono", "..\Source\BLToolkit.mono.csproj", "{0C325F5D-E50E-4340-8724-D29896CCC583}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug FW 3.5|Any CPU = Debug FW 3.5|Any CPU + Debug FW 3.5|Mixed Platforms = Debug FW 3.5|Mixed Platforms + Debug FW 3.5|x86 = Debug FW 3.5|x86 + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|x86 = Debug|x86 + DebugMono|Any CPU = DebugMono|Any CPU + DebugMono|Mixed Platforms = DebugMono|Mixed Platforms + DebugMono|x86 = DebugMono|x86 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|x86 = Release|x86 + ReleaseMono|Any CPU = ReleaseMono|Any CPU + ReleaseMono|Mixed Platforms = ReleaseMono|Mixed Platforms + ReleaseMono|x86 = ReleaseMono|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Any CPU.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Any CPU.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug FW 3.5|x86.ActiveCfg = Debug FW 3.5|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Debug|x86.ActiveCfg = Debug|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Any CPU.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.Release|x86.ActiveCfg = Release|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Any CPU.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Any CPU.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Mixed Platforms.ActiveCfg = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|Mixed Platforms.Build.0 = ReleaseMono|Any CPU + {0C325F5D-E50E-4340-8724-D29896CCC583}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Debug FW 3.5|Any CPU.ActiveCfg = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Debug FW 3.5|Any CPU.Build.0 = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Debug FW 3.5|Mixed Platforms.ActiveCfg = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Debug FW 3.5|Mixed Platforms.Build.0 = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Debug FW 3.5|x86.ActiveCfg = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Debug FW 3.5|x86.Build.0 = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Debug|x86.ActiveCfg = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Debug|x86.Build.0 = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.DebugMono|Any CPU.ActiveCfg = DebugMono|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.DebugMono|Any CPU.Build.0 = DebugMono|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.DebugMono|Mixed Platforms.ActiveCfg = DebugMono|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.DebugMono|Mixed Platforms.Build.0 = DebugMono|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.DebugMono|x86.ActiveCfg = DebugMono|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.DebugMono|x86.Build.0 = DebugMono|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Release|Any CPU.Build.0 = Release|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Release|x86.ActiveCfg = Release|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.Release|x86.Build.0 = Release|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.ReleaseMono|Any CPU.ActiveCfg = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.ReleaseMono|Any CPU.Build.0 = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.ReleaseMono|Mixed Platforms.ActiveCfg = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.ReleaseMono|Mixed Platforms.Build.0 = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.ReleaseMono|x86.ActiveCfg = Debug|x86 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5}.ReleaseMono|x86.Build.0 = Debug|x86 + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = Test\Test.csproj + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff -r 000000000000 -r f990fcb411a9 Mono/Mono.sln.docstates Binary file Mono/Mono.sln.docstates has changed diff -r 000000000000 -r f990fcb411a9 Mono/Test/App.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Mono/Test/App.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Mono/Test/Program.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Mono/Test/Program.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Data.Linq; + +namespace Test +{ + class Program + { + static void Main() + { + BLToolkit.Data.DbManager.AddDataProvider(typeof(BLToolkit.Data.DataProvider.MySqlDataProvider)); + + using (var db = new TestDbManager("MySql")) + { + var list = new GenericConcatQuery(db, new object[] { "A", 1 }).Query().ToList(); + + foreach (var i in list) + Console.WriteLine(i.ToString()); + } + } + } + + public abstract class GenericQueryBase + { + private readonly IdlPatientSource m_ds; + + protected GenericQueryBase(ITestDataContext ds) + { + m_ds = new IdlPatientSource(ds); + } + + #region Object sources + + protected IQueryable AllPersons + { + get { return m_ds.Persons(); } + } + + protected IQueryable AllPatients + { + get { return m_ds.Patients(); } + } + + protected IQueryable AllGrandChilds + { + get { return m_ds.GrandChilds(); } + } + + #endregion + + public abstract IEnumerable Query(); + } + + public class GenericConcatQuery : GenericQueryBase + { + private System.String @p1; + private System.Int32 @p2; + + public GenericConcatQuery(ITestDataContext ds, object[] args) + : base(ds) + { + @p1 = (System.String)args[0]; + @p2 = (System.Int32)args[1]; + } + + public override IEnumerable Query() + { + return (from y in AllPersons + select y.Name) + .Concat( + from x in AllPersons + from z in AllPatients + where (x.Name == @p1 || z.Id == new ObjectId { Value = @p2 }) + select x.Name + ); + } + } + + public struct ObjectId + { + public ObjectId(int value) + { + m_value = value; + } + + private int m_value; + + public int Value + { + get { return m_value; } + set { m_value = value; } + } + + public static implicit operator int(ObjectId val) + { + return val.m_value; + } + } + + public struct NullableObjectId + { + public NullableObjectId(int? value) + { + m_value = value; + } + + private int? m_value; + + public int? Value + { + get { return m_value; } + set { m_value = value; } + } + + public static implicit operator int?(NullableObjectId val) + { + return val.m_value; + } + } + + public class IdlPatient + { + public ObjectId Id { get; set; } + } + + public class IdlPerson + { + public ObjectId Id { get; set; } + public string Name { get; set; } + } + + public class IdlGrandChild + { + public ObjectId ParentID { get; set; } + public ObjectId ChildID { get; set; } + public ObjectId GrandChildID { get; set; } + } + + public class IdlPatientEx : IdlPatient + { + public IdlPerson Person { get; set; } + } + + public class IdlPatientSource + { + private readonly ITestDataContext m_dc; + + public IdlPatientSource(ITestDataContext dc) + { + m_dc = dc; + } + + public IQueryable GrandChilds() + { + return m_dc.GrandChild.Select(x => new IdlGrandChild + { + ChildID = new ObjectId {Value = x.ChildID.Value}, + GrandChildID = new ObjectId { Value = x.GrandChildID.Value }, + ParentID = new ObjectId { Value = x.ParentID.Value } + }); + } + + public IQueryable Patients() + { + return m_dc.Patient.Select(x => new IdlPatient { Id = new ObjectId { Value = x.PersonID }, }); + } + + public IQueryable Persons() + { + return + m_dc.Person.Select( + x => new IdlPerson { Id = new ObjectId { Value = x.ID }, Name = x.FirstName, }); + } + } +} diff -r 000000000000 -r f990fcb411a9 Mono/Test/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Mono/Test/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Test")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Test")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("2881eed8-06e3-420a-abdd-f478f9e7bba8")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 000000000000 -r f990fcb411a9 Mono/Test/Test.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Mono/Test/Test.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,156 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {6FC8A4D7-CB01-40B7-AB10-6241C7B7BDE5} + Exe + Properties + Test + Test + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + bin\Debug\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\Test.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + 4 + false + + + bin\Release\ + TRACE + true + pdbonly + AnyCPU + bin\Release\Test.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + 4 + + + true + bin\DebugMono\ + TRACE;DEBUG;MONO + full + AnyCPU + bin\Debug\Test.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + 4 + false + + + none + false + bin\DebugMono + 4 + + + + + + + + + + ..\..\packages\MySql.Data.6.4.4\lib\net40\mysql.data.dll + + + + + + ITestDataContext.cs + + + Doctor.cs + + + Gender.cs + + + LinqDataTypes.cs + + + ParentChild.cs + + + Patient.cs + + + Person.cs + + + TypeValue.cs + + + TestDbManager.cs + Component + + + + + + + Designer + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.mono + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/BLToolkit.DB2.nuspec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/BLToolkit.DB2.nuspec Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ + + + + BLToolkit.DB2 + 4.1.21 + BLToolkit DB2 Data Provider + Igor Tkachev + + http://bltoolkit.net/License.ashx + http://bltoolkit.net/ + false + Business Logic Toolkit DB2 Data Provider for .NET + + DB2 bltoolkit Linq ORM DAL database DB + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/BLToolkit.DevartOraclePro.nuspec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/BLToolkit.DevartOraclePro.nuspec Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ + + + + BLToolkit.Oracle + 4.1.21 + BLToolkit dotConnect for Oracle Pro Data Provider + Igor Tkachev + + http://bltoolkit.net/License.ashx + http://bltoolkit.net/ + false + Business Logic Toolkit dotConnect for Oracle Pro Data Provider for .NET + + Devart dotConnect Oracle bltoolkit Linq ORM DAL database DB + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/BLToolkit.Firebird.nuspec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/BLToolkit.Firebird.nuspec Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ + + + + BLToolkit.Firebird + 4.1.21 + BLToolkit Firebird Data Provider + Igor Tkachev + + http://bltoolkit.net/License.ashx + http://bltoolkit.net/ + false + Business Logic Toolkit Firebird Data Provider for .NET + + Firebird bltoolkit Linq ORM DAL database DB + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/BLToolkit.Informix.nuspec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/BLToolkit.Informix.nuspec Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ + + + + BLToolkit.Informix + 4.1.21 + BLToolkit Informix Data Provider + Igor Tkachev + + http://bltoolkit.net/License.ashx + http://bltoolkit.net/ + false + Business Logic Toolkit Informix Data Provider for .NET + + Informix bltoolkit Linq ORM DAL database DB + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/BLToolkit.MySql.nuspec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/BLToolkit.MySql.nuspec Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ + + + + BLToolkit.MySql + 4.1.21 + BLToolkit MySql Data Provider + Igor Tkachev + + http://bltoolkit.net/License.ashx + http://bltoolkit.net/ + false + Business Logic Toolkit MySql Data Provider for .NET + + MySql bltoolkit Linq ORM DAL database DB + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/BLToolkit.Oracle.nuspec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/BLToolkit.Oracle.nuspec Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ + + + + BLToolkit.Oracle + 4.1.21 + BLToolkit Oracle Data Provider + Igor Tkachev + + http://bltoolkit.net/License.ashx + http://bltoolkit.net/ + false + Business Logic Toolkit Oracle Data Provider for .NET + + Oracle Odp bltoolkit Linq ORM DAL database DB + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/BLToolkit.PostgreSql.nuspec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/BLToolkit.PostgreSql.nuspec Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ + + + + BLToolkit.PostgreSql + 4.1.21 + BLToolkit PostgreSql Data Provider + Igor Tkachev + + http://bltoolkit.net/License.ashx + http://bltoolkit.net/ + false + Business Logic Toolkit PostgreSql Data Provider for .NET + + PostgreSql Npgsql bltoolkit Linq ORM DAL database DB + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/BLToolkit.SQLite.nuspec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/BLToolkit.SQLite.nuspec Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ + + + + BLToolkit.SQLite + 4.1.21 + BLToolkit SQLite Data Provider + Igor Tkachev + + http://bltoolkit.net/License.ashx + http://bltoolkit.net/ + false + Business Logic Toolkit SQLite Data Provider for .NET + + SQLite bltoolkit Linq ORM DAL database DB + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/BLToolkit.SqlCe.nuspec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/BLToolkit.SqlCe.nuspec Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ + + + + BLToolkit.SqlCe + 4.1.21 + BLToolkit SqlCe Data Provider + Igor Tkachev + + http://bltoolkit.net/License.ashx + http://bltoolkit.net/ + false + Business Logic Toolkit SqlCe Data Provider for .NET + + SqlCe bltoolkit Linq ORM DAL database DB + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/BLToolkit.Sybase.nuspec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/BLToolkit.Sybase.nuspec Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ + + + + BLToolkit.Sybase + 4.1.21 + BLToolkit Sybase Data Provider + Igor Tkachev + + http://bltoolkit.net/License.ashx + http://bltoolkit.net/ + false + Business Logic Toolkit Sybase Data Provider for .NET + + Sybase bltoolkit Linq ORM DAL database DB + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/BLToolkit.nuspec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/BLToolkit.nuspec Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ + + + + BLToolkit + 4.1.21 + Business Logic Toolkit for .NET + Igor Tkachev + + http://bltoolkit.net/License.ashx + http://bltoolkit.net/ + false + Business Logic Toolkit is a set of components to simplify .NET application development. + + bltoolkit Linq ORM DAL database DB + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/BLToolkit.symbols.nuspec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/BLToolkit.symbols.nuspec Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ + + + + BLToolkit + 4.1.21 + Business Logic Toolkit for .NET + Igor Tkachev + + http://bltoolkit.net/License.ashx + http://bltoolkit.net/ + false + Business Logic Toolkit is a set of components to simplify .NET application development. + + bltoolkit Linq ORM DAL database DB + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 NuGet/Pack.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/Pack.bat Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,44 @@ +cd ..\Source +call Compile3.bat +call Compile4.bat + +cd ..\DataProviders +call Compile3.bat +call Compile4.bat + +cd ..\NuGet + +del *.nupkg + +NuGet Pack BLToolkit.nuspec +rename BLToolkit.4.*.nupkg BLToolkit.nupkg + +NuGet Pack BLToolkit.symbols.nuspec -Symbols +rename BLToolkit.4.*.nupkg BLToolkit.symbol.nupkg + +NuGet Pack BLToolkit.DB2.nuspec +rename BLToolkit.DB2.*.nupkg BLToolkit.DB2.nupkg + +NuGet Pack BLToolkit.Firebird.nuspec +rename BLToolkit.Firebird.*.nupkg BLToolkit.Firebird.nupkg + +NuGet Pack BLToolkit.Informix.nuspec +rename BLToolkit.Informix.*.nupkg BLToolkit.Informix.nupkg + +NuGet Pack BLToolkit.MySql.nuspec +rename BLToolkit.MySql.*.nupkg BLToolkit.MySql.nupkg + +NuGet Pack BLToolkit.Oracle.nuspec +rename BLToolkit.Oracle.*.nupkg BLToolkit.Oracle.nupkg + +NuGet Pack BLToolkit.PostgreSql.nuspec +rename BLToolkit.PostgreSql.*.nupkg BLToolkit.PostgreSql.nupkg + +NuGet Pack BLToolkit.SqlCe.nuspec +rename BLToolkit.SqlCe.*.nupkg BLToolkit.SqlCe.nupkg + +NuGet Pack BLToolkit.SQLite.nuspec +rename BLToolkit.SQLite.*.nupkg BLToolkit.SQLite.nupkg + +NuGet Pack BLToolkit.Sybase.nuspec +rename BLToolkit.Sybase.*.nupkg BLToolkit.Sybase.nupkg diff -r 000000000000 -r f990fcb411a9 NuGet/Push.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NuGet/Push.bat Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +NuGet Push BLToolkit.nupkg +NuGet Push BLToolkit.DB2.nupkg +NuGet Push BLToolkit.Firebird.nupkg +NuGet Push BLToolkit.Informix.nupkg +NuGet Push BLToolkit.MySql.nupkg +NuGet Push BLToolkit.Oracle.nupkg +NuGet Push BLToolkit.PostgreSql.nupkg +NuGet Push BLToolkit.SqlCe.nupkg +NuGet Push BLToolkit.SQLite.nupkg +NuGet Push BLToolkit.Sybase.nupkg + +del *.nupkg diff -r 000000000000 -r f990fcb411a9 Redist/Castle/Castle.Core.dll Binary file Redist/Castle/Castle.Core.dll has changed diff -r 000000000000 -r f990fcb411a9 Redist/Castle/Castle.Core.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Redist/Castle/Castle.Core.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4927 @@ + + + + Castle.Core + + + + + Assignes a specific dictionary key. + + + + + Defines the contract for customizing dictionary access. + + + + + Determines relative order to apply related behaviors. + + + + + Determines relative order to apply related behaviors. + + + + + Defines the contract for updating dictionary values. + + + + + Sets the stored dictionary value. + + The dictionary adapter. + The key. + The stored value. + The property. + true if the property should be stored. + + + + Defines the contract for building s. + + + + + Builds the dictionary behaviors. + + + + + + Abstract adapter for the support + needed by the + + + + + Adds an element with the provided key and value to the object. + + The to use as the key of the element to add. + The to use as the value of the element to add. + An element with the same key already exists in the object. + key is null. + The is read-only.-or- The has a fixed size. + + + + Removes all elements from the object. + + The object is read-only. + + + + Determines whether the object contains an element with the specified key. + + The key to locate in the object. + + true if the contains an element with the key; otherwise, false. + + key is null. + + + + Returns an object for the object. + + + An object for the object. + + + + + Removes the element with the specified key from the object. + + The key of the element to remove. + The object is read-only.-or- The has a fixed size. + key is null. + + + + Copies the elements of the to an , starting at a particular index. + + The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + The zero-based index in array at which copying begins. + array is null. + The type of the source cannot be cast automatically to the type of the destination array. + index is less than zero. + array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source is greater than the available space from index to the end of the destination array. + + + + Returns an enumerator that iterates through a collection. + + + An object that can be used to iterate through the collection. + + + + + Gets a value indicating whether the object has a fixed size. + + + true if the object has a fixed size; otherwise, false. + + + + Gets a value indicating whether the object is read-only. + + + true if the object is read-only; otherwise, false. + + + + Gets an object containing the keys of the object. + + + An object containing the keys of the object. + + + + Gets an object containing the values in the object. + + + An object containing the values in the object. + + + + Gets or sets the with the specified key. + + + + + + Gets the number of elements contained in the . + + + The number of elements contained in the . + + + + Gets a value indicating whether access to the is synchronized (thread safe). + + + true if access to the is synchronized (thread safe); otherwise, false. + + + + Gets an object that can be used to synchronize access to the . + + + An object that can be used to synchronize access to the . + + + + Constant to use when making assembly internals visible to Castle.Core + [assembly: InternalsVisibleTo(CoreInternalsVisible.ToCastleCore)] + + + + + Constant to use when making assembly internals visible to proxy types generated by DynamicProxy. Required when proxying internal types. + [assembly: InternalsVisibleTo(CoreInternalsVisible.ToDynamicProxyGenAssembly2)] + + + + + Abstract implementation of . + + + + + Conract for traversing a . + + + + + Identifies a property should be represented as a nested component. + + + + + Defines the contract for building typed dictionary keys. + + + + + Builds the specified key. + + The dictionary adapter. + The current key. + The property. + The updated key + + + + Defines the contract for retrieving dictionary values. + + + + + Gets the effective dictionary value. + + The dictionary adapter. + The key. + The stored value. + The property. + true if return only existing. + The effective property value. + + + + Applies no prefix. + + + + + Gets or sets the prefix. + + The prefix. + + + + Identifies the dictionary adapter types. + + + + + Identifies an interface or property to be pre-feteched. + + + + + Instructs fetching to occur. + + + + + Instructs fetching according to + + + + + + Gets whether or not fetching should occur. + + + + + Assigns a property to a group. + + + + + Constructs a group assignment. + + The group name. + + + + Constructs a group assignment. + + The group name. + + + + Gets the group the property is assigned to. + + + + + Assigns a specific dictionary key. + + + + + Initializes a new instance of the class. + + The key. + + + + Initializes a new instance of the class. + + The compound key. + + + + Assigns a prefix to the keyed properties of an interface. + + + + + Initializes a default instance of the class. + + + + + Initializes a new instance of the class. + + The prefix for the keyed properties of the interface. + + + + Gets the prefix key added to the properties of the interface. + + + + + Substitutes part of key with another string. + + + + + Initializes a new instance of the class. + + The old value. + The new value. + + + + Requests support for multi-level editing. + + + + + Contract for dictionary initialization. + + + + + Performs any initialization of the + + The dictionary adapter. + The dictionary behaviors. + + + + Generates a new GUID on demand. + + + + + Support for on-demand value resolution. + + + + + Suppress property change notifications. + + + + + Provides simple string formatting from existing properties. + + + + + Gets the string format. + + + + + Gets the format properties. + + + + + Identifies a property should be represented as a delimited string value. + + + + + Gets the separator. + + + + + Converts all properties to strings. + + + + + Gets or sets the format. + + The format. + + + + Suppress property change notifications. + + + + + Contract for property descriptor initialization. + + + + + Performs any initialization of the + + The property descriptor. + The property behaviors. + + + + Assigns a prefix to the keyed properties using the interface name. + + + + + Manages conversion between property values. + + + + + Initializes a new instance of the class. + + The converter. + + + + Gets the effective dictionary value. + + The dictionary adapter. + The key. + The stored value. + The property. + true if return only existing. + The effective property value. + + + + + + + + + Contract for creating additional Dictionary adapters. + + + + + Contract for manipulating the Dictionary adapter. + + + + + Contract for editing the Dictionary adapter. + + + + + Contract for managing Dictionary adapter notifications. + + + + + Contract for validating Dictionary adapter. + + + + + Uses Reflection.Emit to expose the properties of a dictionary + through a dynamic implementation of a typed interface. + + + + + Defines the contract for building typed dictionary adapters. + + + + + Gets a typed adapter bound to the . + + The typed interface. + The underlying source of properties. + An implementation of the typed interface bound to the dictionary. + + The type represented by T must be an interface with properties. + + + + + Gets a typed adapter bound to the . + + The typed interface. + The underlying source of properties. + An implementation of the typed interface bound to the dictionary. + + The type represented by T must be an interface with properties. + + + + + Gets a typed adapter bound to the . + + The typed interface. + The underlying source of properties. + The property descriptor. + An implementation of the typed interface bound to the dictionary. + + The type represented by T must be an interface with properties. + + + + + Gets a typed adapter bound to the . + + The typed interface. + The underlying source of properties. + An implementation of the typed interface bound to the namedValues. + + The type represented by T must be an interface with properties. + + + + + Gets a typed adapter bound to the . + + The typed interface. + The underlying source of properties. + An implementation of the typed interface bound to the namedValues. + + The type represented by T must be an interface with properties. + + + + + Gets a typed adapter bound to the . + + The typed interface. + The underlying source of properties. + An implementation of the typed interface bound to the xpath navigable. + + The type represented by T must be an interface with properties. + + + + + Gets a typed adapter bound to the . + + The typed interface. + The underlying source of properties. + An implementation of the typed interface bound to the xpath navigable. + + The type represented by T must be an interface with properties. + + + + + Gets the associated with the type. + + The typed interface. + The adapter meta-data. + + + + Gets the associated with the type. + + The typed interface. + The property descriptor. + The adapter meta-data. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Describes a dictionary property. + + + + + Initializes an empty class. + + + + + Initializes a new instance of the class. + + The property. + The property behaviors. + + + + Copies an existinginstance of the class. + + + + + + + Gets the key. + + The dictionary adapter. + The key. + The descriptor. + + + + + Adds the key builder. + + The builder. + + + + Adds the key builders. + + The builders. + + + + Copies the key builders to the other + + + + + + + Copies the selected key builders to the other + + + + + + + + Gets the property value. + + The dictionary adapter. + The key. + The stored value. + The descriptor. + true if return only existing. + + + + + Adds the dictionary getter. + + The getter. + + + + Adds the dictionary getters. + + The getters. + + + + Copies the property getters to the other + + + + + + + Copies the selected property getters to the other + + + + + + + + Sets the property value. + + The dictionary adapter. + The key. + The value. + The descriptor. + + + + + Adds the dictionary setter. + + The setter. + + + + Adds the dictionary setters. + + The setters. + + + + Copies the property setters to the other + + + + + + + Copies the selected property setters to the other + + + + + + + + Adds the behaviors. + + + + + + + Adds the behaviors. + + + + + + + Adds the behaviors from the builders. + + + + + + + Copies the behaviors to the other + + + + + + + Copies the behaviors to the other + + + + + + + + + + + + + Gets the property name. + + + + + Gets the property type. + + + + + Gets the property. + + The property. + + + + Returns true if the property is dynamic. + + + + + Gets additional state. + + + + + Determines if property should be fetched. + + + + + Determines if notifications should occur. + + + + + Gets the property behaviors. + + + + + Gets the type converter. + + The type converter. + + + + Gets the key builders. + + The key builders. + + + + Gets the setter. + + The setter. + + + + Gets the getter. + + The getter. + + + + Adds the dictionary initializers. + + The initializers. + + + + Adds the dictionary initializers. + + The initializers. + + + + Copies the initializers to the other + + + + + + + Copies the filtered initializers to the other + + + + + + + + Adds the dictionary meta-data initializers. + + The meta-data initializers. + + + + Adds the dictionary meta-data initializers. + + The meta-data initializers. + + + + Copies the meta-initializers to the other + + + + + + + Copies the filtered meta-initializers to the other + + + + + + + + Gets the initializers. + + The initializers. + + + + Gets the meta-data initializers. + + The meta-data initializers. + + + + Contract for dictionary meta-data initialization. + + + + + Performs any initialization of the dictionary adapter meta-data. + + The dictionary adapter factory. + The dictionary adapter meta. + + + + + Contract for dictionary validation. + + + + + Determines if is valid. + + The dictionary adapter. + true if valid. + + + + Validates the . + + The dictionary adapter. + The error summary information. + + + + Validates the for a property. + + The dictionary adapter. + The property to validate. + The property summary information. + + + + Invalidates any results cached by the validator. + + The dictionary adapter. + + + + + + + + + Initializes a new instance of the class. + + The name values. + + + + Determines whether the object contains an element with the specified key. + + The key to locate in the object. + + true if the contains an element with the key; otherwise, false. + + key is null. + + + + Adapts the specified name values. + + The name values. + + + + + Gets a value indicating whether the object is read-only. + + + true if the object is read-only; otherwise, false. + + + + Gets or sets the with the specified key. + + + + + + Helper class for retrieving attributes. + + + + + Gets the attribute. + + The member. + The member attribute. + + + + Gets the attributes. Does not consider inherited attributes! + + The member. + The member attributes. + + + + Gets the type attribute. + + The type. + The type attribute. + + + + Gets the type attributes. + + The type. + The type attributes. + + + + Gets the type converter. + + The member. + + + + + Gets the attribute. + + The member. + The member attribute. + + + + Contract for typed dynamic value resolution. + + + + + + Contract for dynamic value resolution. + + + + + Encapsulates an invocation of a proxied method. + + + + + Overrides the value of an argument at the given with the + new provided. + + + This method accepts an , however the value provided must be compatible + with the type of the argument defined on the method, otherwise an exception will be thrown. + + The index of the argument to override. + The new value for the argument. + + + + Gets the value of the argument at the specified . + + The index. + The value of the argument at the specified . + + + + Returns the concrete instantiation of the on the proxy, with any generic + parameters bound to real types. + + + The concrete instantiation of the on the proxy, or the if + not a generic method. + + Can be slower than calling . + + + + Returns the concrete instantiation of , with any + generic parameters bound to real types. + For interface proxies, this will point to the on the target class. + + The concrete instantiation of , or + if not a generic method. + In debug builds this can be slower than calling . + + + + Proceeds the call to the next interceptor in line, and ultimately to the target method. + + + Since interface proxies without a target don't have the target implementation to proceed to, + it is important, that the last interceptor does not call this method, otherwise a + will be thrown. + + + + + Gets the proxy object on which the intercepted method is invoked. + + Proxy object on which the intercepted method is invoked. + + + + Gets the object on which the invocation is performed. This is different from proxy object + because most of the time this will be the proxy target object. + + + The invocation target. + + + + Gets the type of the target object for the intercepted method. + + The type of the target object. + + + + Gets the arguments that the has been invoked with. + + The arguments the method was invoked with. + + + + Gets the generic arguments of the method. + + The generic arguments, or null if not a generic method. + + + + Gets the representing the method being invoked on the proxy. + + The representing the method being invoked. + + + + For interface proxies, this will point to the on the target class. + + The method invocation target. + + + + Gets or sets the return value of the method. + + The return value of the method. + + + + Used during the target type inspection process. Implementors have a chance to customize the + proxy generation process. + + + + + Invoked by the generation process to determine if the specified method should be proxied. + + The type which declares the given method. + The method to inspect. + True if the given method should be proxied; false otherwise. + + + + Invoked by the generation process to notify that a member was not marked as virtual. + + The type which declares the non-virtual member. + The non-virtual member. + + This method gives an opportunity to inspect any non-proxyable member of a type that has + been requested to be proxied, and if appropriate - throw an exception to notify the caller. + + + + + Invoked by the generation process to notify that the whole process has completed. + + + + + Interface describing elements composing generated type + + + + + Checks if the method is public or protected. + + + + + + + Performs some basic screening and invokes the + to select methods. + + + + + + + + + Provides functionality for disassembling instances of attributes to CustomAttributeBuilder form, during the process of emiting new types by Dynamic Proxy. + + + + + Disassembles given attribute instance back to corresponding CustomAttributeBuilder. + + An instance of attribute to disassemble + corresponding 1 to 1 to given attribute instance, or null reference. + + Implementers should return that corresponds to given attribute instance 1 to 1, + that is after calling specified constructor with specified arguments, and setting specified properties and fields with values specified + we should be able to get an attribute instance identical to the one passed in . Implementer can return null + if it wishes to opt out of replicating the attribute. Notice however, that for some cases, like attributes passed explicitly by the user + it is illegal to return null, and doing so will result in exception. + + + + + Handles error during disassembly process + + Type of the attribute being disassembled + Exception thrown during the process + usually null, or (re)throws the exception + + + + Here we try to match a constructor argument to its value. + Since we can't get the values from the assembly, we use some heuristics to get it. + a/ we first try to match all the properties on the attributes by name (case insensitive) to the argument + b/ if we fail we try to match them by property type, with some smarts about convertions (i,e: can use Guid for string). + + + + + We have the following rules here. + Try to find a matching type, failing that, if the parameter is string, get the first property (under the assumption that + we can convert it. + + + + + Attributes can only accept simple types, so we return null for null, + if the value is passed as string we call to string (should help with converting), + otherwise, we use the value as is (enums, integer, etc). + + + + + Applied to the assemblies saved by in order to persist the cache data included in the persisted assembly. + + + + + Base class that exposes the common functionalities + to proxy generation. + + + + + Generates a parameters constructor that initializes the proxy + state with just to make it non-null. + + This constructor is important to allow proxies to be XML serializable + + + + + + It is safe to add mapping (no mapping for the interface exists) + + + + + + + + Generates the constructor for the class that extends + + + + + + + + + Default implementation of interface producing in-memory proxy assemblies. + + + + + Abstracts the implementation of proxy type construction. + + + + + Creates a proxy type for given , using provided. + + The class type to proxy. + The proxy generation options. + The generated proxy type. + Thrown when is a generic type definition. + Thrown when is not public. + Note that to avoid this exception, you can mark offending type internal, and define + pointing to Castle Dynamic Proxy assembly, in assembly containing that type, if this is appropriate. + + + + + Creates a proxy type for given , implementing , using provided. + + The class type to proxy. + Additional interface types to proxy. + The proxy generation options. + The generated proxy type. + + Implementers should return a proxy type for the specified class and interfaces. + Additional interfaces should be only 'mark' interfaces, that is, they should work like interface proxy without target. (See method.) + + Thrown when or any of is a generic type definition. + Thrown when or any of is not public. + Note that to avoid this exception, you can mark offending type internal, and define + pointing to Castle Dynamic Proxy assembly, in assembly containing that type, if this is appropriate. + + + + + Creates a proxy type for given , implementing , using provided. + + The class type to proxy. + Additional interface types to proxy. + The proxy generation options. + The generated proxy type. + + Implementers should return a proxy type for the specified class and interfaces. + Additional interfaces should be only 'mark' interfaces, that is, they should work like interface proxy without target. (See method.) + + Thrown when or any of is a generic type definition. + Thrown when or any of is not public. + Note that to avoid this exception, you can mark offending type internal, and define + pointing to Castle Dynamic Proxy assembly, in assembly containing that type, if this is appropriate. + + + + + Creates a proxy type that proxies calls to members on , implementing , using provided. + + The interface type to proxy. + Additional interface types to proxy. + Type implementing on which calls to the interface members should be intercepted. + The proxy generation options. + The generated proxy type. + + Implementers should return a proxy type for the specified interface that 'proceeds' executions to the specified target. + Additional interfaces should be only 'mark' interfaces, that is, they should work like interface proxy without target. (See method.) + + Thrown when or any of is a generic type definition. + Thrown when or any of is not public. + Note that to avoid this exception, you can mark offending type internal, and define + pointing to Castle Dynamic Proxy assembly, in assembly containing that type, if this is appropriate. + + + + + Creates a proxy type for given that delegates all calls to the provided interceptors. + + The interface type to proxy. + Additional interface types to proxy. + The proxy generation options. + The generated proxy type. + + Implementers should return a proxy type for the specified interface and additional interfaces that delegate all executions to the specified interceptors. + + Thrown when or any of is a generic type definition. + Thrown when or any of is not public. + Note that to avoid this exception, you can mark offending type internal, and define + pointing to Castle Dynamic Proxy assembly, in assembly containing that type, if this is appropriate. + + + + + Creates a proxy type for given and that delegates all calls to the provided interceptors and allows interceptors to switch the actual target of invocation. + + The interface type to proxy. + Additional interface types to proxy. + The proxy generation options. + The generated proxy type. + + Implementers should return a proxy type for the specified interface(s) that delegate all executions to the specified interceptors + and uses an instance of the interface as their targets (i.e. ), rather than a class. All classes should then implement interface, + to allow interceptors to switch invocation target with instance of another type implementing called interface. + + Thrown when or any of is a generic type definition. + Thrown when or any of is not public. + Note that to avoid this exception, you can mark offending type internal, and define + pointing to Castle Dynamic Proxy assembly, in assembly containing that type, if this is appropriate. + + + + + Gets or sets the that this logs to. + + + + + Gets the associated with this builder. + + The module scope associated with this builder. + + + + Initializes a new instance of the class with new . + + + + + Initializes a new instance of the class. + + The module scope for generated proxy types. + + + + Registers custom disassembler to handle disassembly of specified type of attributes. + + Type of attributes to handle + Disassembler converting existing instances of Attributes to CustomAttributeBuilders + + When disassembling an attribute Dynamic Proxy will first check if an custom disassembler has been registered to handle attributes of that type, + and if none is found, it'll use the . + + + + + Attributes should be replicated if they are non-inheritable, + but there are some special cases where the attributes means + something to the CLR, where they should be skipped. + + + + + Initializes a new instance of the class. + + Target element. This is either target type or target method for invocation types. + The type of the proxy. This is base type for invocation types. + The interfaces. + The options. + + + + Initializes a new instance of the class. + + Type of the target. + The interfaces. + The options. + + + s + Provides appropriate Ldc.X opcode for the type of primitive value to be loaded. + + + + + Provides appropriate Ldind.X opcode for + the type of primitive value to be loaded indirectly. + + + + + Emits a load opcode of the appropriate kind for a constant string or + primitive value. + + + + + + + Emits a load opcode of the appropriate kind for the constant default value of a + type, such as 0 for value types and null for reference types. + + + + + Emits a load indirect opcode of the appropriate type for a value or object reference. + Pops a pointer off the evaluation stack, dereferences it and loads + a value of the specified type. + + + + + + + Emits a store indirectopcode of the appropriate type for a value or object reference. + Pops a value of the specified type and a pointer off the evaluation stack, and + stores the value. + + + + + + + Summary description for PropertiesCollection. + + + + + Wraps a reference that is passed + ByRef and provides indirect load/store support. + + + + + Summary description for NewArrayExpression. + + + + + + + + + + Provides appropriate Stind.X opcode + for the type of primitive value to be stored indirectly. + + + + + Returns list of all unique interfaces implemented given types, including their base interfaces. + + + + + + + Initializes a new instance of the class. + + The name. + Type declaring the original event being overriten, or null. + + The add method. + The remove method. + The attributes. + + + + Represents the scope of uniquenes of names for types and their members + + + + + Gets a unique name based on + + Name suggested by the caller + Unique name based on . + + Implementers should provide name as closely resembling as possible. + Generally if no collision occurs it is suggested to return suggested name, otherwise append sequential suffix. + Implementers must return deterministic names, that is when is called twice + with the same suggested name, the same returned name should be provided each time. Non-deterministic return + values, like appending random suffices will break serialization of proxies. + + + + + Returns new, disposable naming scope. It is responsibilty of the caller to make sure that no naming collision + with enclosing scope, or other subscopes is possible. + + New naming scope. + + + + Returns the methods implemented by a type. Use this instead of Type.GetMethods() to work around a CLR issue + where duplicate MethodInfos are returned by Type.GetMethods() after a token of a generic type's method was loaded. + + + + + Determines whether this assembly has internals visible to dynamic proxy. + + The assembly to inspect. + + + + Determines whether the specified method is internal. + + The method. + + true if the specified method is internal; otherwise, false. + + + + + Because we need to cache the types based on the mixed in mixins, we do the following here: + - Get all the mixin interfaces + - Sort them by full name + - Return them by position + + The idea is to have reproducable behavior for the case that mixins are registered in different orders. + This method is here because it is required + + + + + Summary description for ModuleScope. + + + + + The default file name used when the assembly is saved using . + + + + + The default assembly (simple) name used for the assemblies generated by a instance. + + + + + Initializes a new instance of the class; assemblies created by this instance will not be saved. + + + + + Initializes a new instance of the class, allowing to specify whether the assemblies generated by this instance + should be saved. + + If set to true saves the generated module. + + + + Initializes a new instance of the class, allowing to specify whether the assemblies generated by this instance + should be saved. + + If set to true saves the generated module. + If set to true disables ability to generate signed module. This should be used in cases where ran under constrained permissions. + + + + Initializes a new instance of the class, allowing to specify whether the assemblies generated by this instance + should be saved and what simple names are to be assigned to them. + + If set to true saves the generated module. + If set to true disables ability to generate signed module. This should be used in cases where ran under constrained permissions. + The simple name of the strong-named assembly generated by this . + The path and file name of the manifest module of the strong-named assembly generated by this . + The simple name of the weak-named assembly generated by this . + The path and file name of the manifest module of the weak-named assembly generated by this . + + + + Initializes a new instance of the class, allowing to specify whether the assemblies generated by this instance + should be saved and what simple names are to be assigned to them. + + If set to true saves the generated module. + If set to true disables ability to generate signed module. This should be used in cases where ran under constrained permissions. + Naming scope used to provide unique names to generated types and their members (usually via sub-scopes). + The simple name of the strong-named assembly generated by this . + The path and file name of the manifest module of the strong-named assembly generated by this . + The simple name of the weak-named assembly generated by this . + The path and file name of the manifest module of the weak-named assembly generated by this . + + + + Returns a type from this scope's type cache, or null if the key cannot be found. + + The key to be looked up in the cache. + The type from this scope's type cache matching the key, or null if the key cannot be found + + + + Registers a type in this scope's type cache. + + The key to be associated with the type. + The type to be stored in the cache. + + + + Gets the key pair used to sign the strong-named assembly generated by this . + + + + + + Gets the specified module generated by this scope, creating a new one if none has yet been generated. + + If set to true, a strong-named module is returned; otherwise, a weak-named module is returned. + A strong-named or weak-named module generated by this scope, as specified by the parameter. + + + + Gets the strong-named module generated by this scope, creating a new one if none has yet been generated. + + A strong-named module generated by this scope. + + + + Gets the weak-named module generated by this scope, creating a new one if none has yet been generated. + + A weak-named module generated by this scope. + + + + Saves the generated assembly with the name and directory information given when this instance was created (or with + the and current directory if none was given). + + + + This method stores the generated assembly in the directory passed as part of the module information specified when this instance was + constructed (if any, else the current directory is used). If both a strong-named and a weak-named assembly + have been generated, it will throw an exception; in this case, use the overload. + + + If this was created without indicating that the assembly should be saved, this method does nothing. + + Both a strong-named and a weak-named assembly have been generated. + The path of the generated assembly file, or null if no file has been generated. + + + + Saves the specified generated assembly with the name and directory information given when this instance was created + (or with the and current directory if none was given). + + True if the generated assembly with a strong name should be saved (see ); + false if the generated assembly without a strong name should be saved (see . + + + This method stores the specified generated assembly in the directory passed as part of the module information specified when this instance was + constructed (if any, else the current directory is used). + + + If this was created without indicating that the assembly should be saved, this method does nothing. + + + No assembly has been generated that matches the parameter. + + The path of the generated assembly file, or null if no file has been generated. + + + + Loads the generated types from the given assembly into this 's cache. + + The assembly to load types from. This assembly must have been saved via or + , or it must have the manually applied. + + This method can be used to load previously generated and persisted proxy types from disk into this scope's type cache, eg. in order + to avoid the performance hit associated with proxy generation. + + + + + Users of this should use this lock when accessing the cache. + + + + + Gets the strong-named module generated by this scope, or if none has yet been generated. + + The strong-named module generated by this scope, or if none has yet been generated. + + + + Gets the file name of the strongly named module generated by this scope. + + The file name of the strongly named module generated by this scope. + + + + Gets the directory where the strongly named module generated by this scope will be saved, or if the current directory + is used. + + The directory where the strongly named module generated by this scope will be saved when is called + (if this scope was created to save modules). + + + + Gets the weak-named module generated by this scope, or if none has yet been generated. + + The weak-named module generated by this scope, or if none has yet been generated. + + + + Gets the file name of the weakly named module generated by this scope. + + The file name of the weakly named module generated by this scope. + + + + Gets the directory where the weakly named module generated by this scope will be saved, or if the current directory + is used. + + The directory where the weakly named module generated by this scope will be saved when is called + (if this scope was created to save modules). + + + + ProxyBuilder that persists the generated type. + + + The saved assembly contains just the last generated type. + + + + + Initializes a new instance of the class. + + + + + Saves the generated assembly to a physical file. Note that this renders the unusable. + + The path of the generated assembly file, or null if no assembly has been generated. + This method does not support saving multiple files. If both a signed and an unsigned module have been generated, use the + respective methods of the . + + + + Initializes a new instance of the class. + + The hook. + + + + Initializes a new instance of the class. + + + + + Provides proxy objects for classes and interfaces. + + + + + Initializes a new instance of the class. + + Proxy types builder. + + + + Initializes a new instance of the class. + + + + + Creates proxy object intercepting calls to members of interface on object with given . + + Type of the interface implemented by which will be proxied. + The target object, calls to which will be intercepted. + The interceptors called during the invocation of proxied methods. + Object proxying calls to members of on object. + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is not an interface type. + Thrown when no default constructor exists on actual type of object. + Thrown when default constructor of actual type of throws an exception. + + This method generates new proxy type for each type of , which affects performance. If you don't want to proxy types differently depending on the type of the target + use method. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on object with given . + + Type of the interface implemented by which will be proxied. + The target object, calls to which will be intercepted. + The proxy generation options used to influence generated proxy type and object. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of on object. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is not an interface type. + Thrown when no default constructor exists on actual type of object. + Thrown when default constructor of actual type of throws an exception. + + This method generates new proxy type for each type of , which affects performance. If you don't want to proxy types differently depending on the type of the target + use method. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on object with given . + + Type of the interface implemented by which will be proxied. + The target object, calls to which will be intercepted. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of type on object. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not an interface type. + Thrown when given does not implement interface. + Thrown when no default constructor exists on actual type of object. + Thrown when default constructor of actual type of throws an exception. + + This method generates new proxy type for each type of , which affects performance. If you don't want to proxy types differently depending on the type of the target + use method. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on object with given . + + Type of the interface implemented by which will be proxied. + The target object, calls to which will be intercepted. + The proxy generation options used to influence generated proxy type and object. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of type on object. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not an interface type. + Thrown when given does not implement interface. + Thrown when no default constructor exists on actual type of object. + Thrown when default constructor of actual type of throws an exception. + + This method generates new proxy type for each type of , which affects performance. If you don't want to proxy types differently depending on the type of the target + use method. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on object with given . + + Type of the interface implemented by which will be proxied. + The target object, calls to which will be intercepted. + Additional interface types. Calls to their members will be proxied as well. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of and types on object. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given or any of is a generic type definition. + Thrown when given is not an interface type. + Thrown when given does not implement interface. + Thrown when no default constructor exists on actual type of object. + Thrown when default constructor of actual type of throws an exception. + + This method generates new proxy type for each type of , which affects performance. If you don't want to proxy types differently depending on the type of the target + use method. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on object with given . + + Type of the interface implemented by which will be proxied. + The target object, calls to which will be intercepted. + The proxy generation options used to influence generated proxy type and object. + Additional interface types. Calls to their members will be proxied as well. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of and types on object. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given or any of is a generic type definition. + Thrown when given is not an interface type. + Thrown when given does not implement interface. + Thrown when no default constructor exists on actual type of object. + Thrown when default constructor of actual type of throws an exception. + + This method generates new proxy type for each type of , which affects performance. If you don't want to proxy types differently depending on the type of the target + use method. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on object with given . + Interceptors can use interface to provide other target for method invocation than default . + + Type of the interface implemented by which will be proxied. + The target object, calls to which will be intercepted. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of type on object or alternative implementation swapped at runtime by an interceptor. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not an interface type. + Thrown when given does not implement interface. + Thrown when no default constructor exists on actual type of object. + Thrown when default constructor of actual type of throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on object with given . + Interceptors can use interface to provide other target for method invocation than default . + + Type of the interface implemented by which will be proxied. + The target object, calls to which will be intercepted. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of type on object or alternative implementation swapped at runtime by an interceptor. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is not an interface type. + Thrown when no default constructor exists on actual type of object. + Thrown when default constructor of actual type of throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on object with given . + Interceptors can use interface to provide other target for method invocation than default . + + Type of the interface implemented by which will be proxied. + The target object, calls to which will be intercepted. + The proxy generation options used to influence generated proxy type and object. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of type on object or alternative implementation swapped at runtime by an interceptor. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is not an interface type. + Thrown when no default constructor exists on actual type of object. + Thrown when default constructor of actual type of throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on object with given . + Interceptors can use interface to provide other target for method invocation than default . + + Type of the interface implemented by which will be proxied. + The target object, calls to which will be intercepted. + Additional interface types. Calls to their members will be proxied as well. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of and types on object or alternative implementation swapped at runtime by an interceptor. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given or any of is a generic type definition. + Thrown when given is not an interface type. + Thrown when given does not implement interface. + Thrown when no default constructor exists on actual type of object. + Thrown when default constructor of actual type of throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on object with given . + Interceptors can use interface to provide other target for method invocation than default . + + Type of the interface implemented by which will be proxied. + The target object, calls to which will be intercepted. + The proxy generation options used to influence generated proxy type and object. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of type on object or alternative implementation swapped at runtime by an interceptor. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not an interface type. + Thrown when given does not implement interface. + Thrown when no default constructor exists on actual type of object. + Thrown when default constructor of actual type of throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on object with given . + Interceptors can use interface to provide other target for method invocation than default . + + Type of the interface implemented by which will be proxied. + The target object, calls to which will be intercepted. + The proxy generation options used to influence generated proxy type and object. + Additional interface types. Calls to their members will be proxied as well. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of and types on object or alternative implementation swapped at runtime by an interceptor. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given or any of is a generic type definition. + Thrown when given is not an interface type. + Thrown when given does not implement interface. + Thrown when no default constructor exists on actual type of object. + Thrown when default constructor of actual type of throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + + Type of the interface which will be proxied. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of types on generated target object. + + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is not an interface type. + + Since this method uses an empty-shell implementation of interfaces to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + As a result of that also at least one implementation must be provided. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + + Type of the interface which will be proxied. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of types on generated target object. + + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is not an interface type. + + Since this method uses an empty-shell implementation of interfaces to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + As a result of that also at least one implementation must be provided. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + + Type of the interface which will be proxied. + The proxy generation options used to influence generated proxy type and object. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of types on generated target object. + + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is not an interface type. + + Since this method uses an empty-shell implementation of interfaces to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + As a result of that also at least one implementation must be provided. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + + Type of the interface which will be proxied. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of type on generated target object. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not an interface type. + + Since this method uses an empty-shell implementation of interfaces to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + + Type of the interface which will be proxied. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of type on generated target object. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not an interface type. + + Since this method uses an empty-shell implementation of interfaces to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + + Type of the interface which will be proxied. + Additional interface types. Calls to their members will be proxied as well. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of and types on generated target object. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given or any of is a generic type definition. + Thrown when given is not an interface type. + + Since this method uses an empty-shell implementation of interfaces to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + + Type of the interface which will be proxied. + The proxy generation options used to influence generated proxy type and object. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of on generated target object. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not an interface type. + + They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + + Type of the interface which will be proxied. + The proxy generation options used to influence generated proxy type and object. + Additional interface types. Calls to their members will be proxied as well. + The interceptors called during the invocation of proxied methods. + + Object proxying calls to members of and types on generated target object. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given array is a null reference (Nothing in Visual Basic). + Thrown when given or any of is a generic type definition. + Thrown when given is not an interface type. + + Since this method uses an empty-shell implementation of to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + The target object, calls to which will be intercepted. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of type. + + Thrown when given is not a class type. + Thrown when no default constructor exists on type . + Thrown when default constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + The target object, calls to which will be intercepted. + The proxy generation options used to influence generated proxy type and object. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of type. + + Thrown when given is not a class type. + Thrown when no default constructor exists on type . + Thrown when default constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + Additional interface types. Calls to their members will be proxied as well. + The target object, calls to which will be intercepted. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of and types. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given or any of is a generic type definition. + Thrown when given is not a class type. + Thrown when no default constructor exists on type . + Thrown when default constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + The target object, calls to which will be intercepted. + The proxy generation options used to influence generated proxy type and object. + Arguments of constructor of type which should be used to create a new instance of that type. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of type. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not a class type. + Thrown when no constructor exists on type with parameters matching . + Thrown when constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + The target object, calls to which will be intercepted. + Arguments of constructor of type which should be used to create a new instance of that type. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of type. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not a class type. + Thrown when no constructor exists on type with parameters matching . + Thrown when constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + The target object, calls to which will be intercepted. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of type. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not a class type. + Thrown when no parameterless constructor exists on type . + Thrown when constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + The target object, calls to which will be intercepted. + The proxy generation options used to influence generated proxy type and object. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of type. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not a class type. + Thrown when no default constructor exists on type . + Thrown when default constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + Additional interface types. Calls to their members will be proxied as well. + The target object, calls to which will be intercepted. + The proxy generation options used to influence generated proxy type and object. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of and types. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given or any of is a generic type definition. + Thrown when given is not a class type. + Thrown when no default constructor exists on type . + Thrown when default constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + Additional interface types. Calls to their members will be proxied as well. + The target object, calls to which will be intercepted. + The proxy generation options used to influence generated proxy type and object. + Arguments of constructor of type which should be used to create a new instance of that type. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of and types. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given or any of is a generic type definition. + Thrown when given is not a class type. + Thrown when no constructor exists on type with parameters matching . + Thrown when constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of type. + + Thrown when given is not a class type. + Thrown when no default constructor exists on type . + Thrown when default constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + The proxy generation options used to influence generated proxy type and object. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of type. + + Thrown when given is not a class type. + Thrown when no default constructor exists on type . + Thrown when default constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + Additional interface types. Calls to their members will be proxied as well. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of and types. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given or any of is a generic type definition. + Thrown when given is not a class type. + Thrown when no default constructor exists on type . + Thrown when default constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + The proxy generation options used to influence generated proxy type and object. + Arguments of constructor of type which should be used to create a new instance of that type. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of type. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not a class type. + Thrown when no constructor exists on type with parameters matching . + Thrown when constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + Arguments of constructor of type which should be used to create a new instance of that type. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of type. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not a class type. + Thrown when no constructor exists on type with parameters matching . + Thrown when constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of type. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not a class type. + Thrown when no parameterless constructor exists on type . + Thrown when constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + The proxy generation options used to influence generated proxy type and object. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of type. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given is a generic type definition. + Thrown when given is not a class type. + Thrown when no default constructor exists on type . + Thrown when default constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + Additional interface types. Calls to their members will be proxied as well. + The proxy generation options used to influence generated proxy type and object. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of and types. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given or any of is a generic type definition. + Thrown when given is not a class type. + Thrown when no default constructor exists on type . + Thrown when default constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + + Type of class which will be proxied. + Additional interface types. Calls to their members will be proxied as well. + The proxy generation options used to influence generated proxy type and object. + Arguments of constructor of type which should be used to create a new instance of that type. + The interceptors called during the invocation of proxied methods. + + New object of type proxying calls to virtual members of and types. + + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given object is a null reference (Nothing in Visual Basic). + Thrown when given or any of is a generic type definition. + Thrown when given is not a class type. + Thrown when no constructor exists on type with parameters matching . + Thrown when constructor of type throws an exception. + + This method uses implementation to generate a proxy type. + As such caller should expect any type of exception that given implementation may throw. + + + + + Creates the proxy type for class proxy with given class, implementing given and using provided . + + The base class for proxy type. + The interfaces that proxy type should implement. + The options for proxy generation process. + of proxy. + + + + Creates the proxy type for interface proxy with target for given interface, implementing given on given and using provided . + + The interface proxy type should implement. + The additional interfaces proxy type should implement. + Actual type that the proxy type will encompass. + The options for proxy generation process. + of proxy. + + + + Creates the proxy type for interface proxy with target interface for given interface, implementing given on given and using provided . + + The interface proxy type should implement. + The additional interfaces proxy type should implement. + The options for proxy generation process. + of proxy. + + + + Creates the proxy type for interface proxy without target for given interface, implementing given and using provided . + + The interface proxy type should implement. + The additional interfaces proxy type should implement. + The options for proxy generation process. + of proxy. + + + + Gets or sets the that this log to. + + + + + Gets the proxy builder instance used to generate proxy types. + + The proxy builder. + + + + + + + + + + + + + + + For interface proxies, this will point to the + on the target class + + + + + Handles the deserialization of proxies. + + + + + Resets the used for deserialization to a new scope. + + This is useful for test cases. + + + + Resets the used for deserialization to a given . + + The scope to be used for deserialization. + By default, the deserialization process uses a different scope than the rest of the application, which can lead to multiple proxies + being generated for the same type. By explicitly setting the deserialization scope to the application's scope, this can be avoided. + + + + Gets the used for deserialization. + + As has no way of automatically determining the scope used by the application (and the application + might use more than one scope at the same time), uses a dedicated scope instance for deserializing proxy + types. This instance can be reset and set to a specific value via and . + + + + Holds objects representing methods of class. + + + + + Holds objects representing methods of class. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Provides an extension point that allows proxies to choose specific interceptors on + a per method basis. + + + + + Selects the interceptors that should intercept calls to the given . + + The type declaring the method to intercept. + The method that will be intercepted. + All interceptors registered with the proxy. + An array of interceptors to invoke upon calling the . + + This method is called only once per proxy instance, upon the first call to the + . Either an empty array or null are valid return values to indicate + that no interceptor should intercept calls to the method. Although it is not advised, it is + legal to return other implementations than these provided in + . + + + + + Creates a new lock. + + + + + + This interface should be implemented by classes + that are available in a bigger context, exposing + the container to different areas in the same application. + + For example, in Web application, the (global) HttpApplication + subclasses should implement this interface to expose + the configured container + + + + + + Exposes means to change target objects of proxies and invocations + + + + + Changes the target object () of current . + + The new value of target of invocation. + + Although the method takes the actual instance must be of type assignable to , otherwise an will be thrown. + Also while it's technically legal to pass null reference (Nothing in Visual Basic) as , for obvious reasons Dynamic Proxy will not be able to call the intercepted method on such target. + In this case last interceptor in the pipeline mustn't call or a will be throws. + Also while it's technically legal to pass proxy itself as , this would create stack overflow. + In this case last interceptor in the pipeline mustn't call or a will be throws. + + Thrown when is not assignable to the proxied type. + + + + Permanently changes the target object of the proxy. This does not affect target of the current invocation. + + The new value of target of the proxy. + + Although the method takes the actual instance must be of type assignable to proxy's target type, otherwise an will be thrown. + Also while it's technically legal to pass null reference (Nothing in Visual Basic) as , for obvious reasons Dynamic Proxy will not be able to call the intercepted method on such target. + In this case last interceptor in the pipeline mustn't call or a will be throws. + Also while it's technically legal to pass proxy itself as , this would create stack overflow. + In this case last interceptor in the pipeline mustn't call or a will be throws. + + Thrown when is not assignable to the proxied type. + + + + New interface that is going to be used by DynamicProxy 2 + + + + + Get the proxy target (note that null is a valid target!) + + + + + + Gets the interceptors for the proxy + + + + + + Defines that the implementation wants a + in order to + access other components. The creator must be aware + that the component might (or might not) implement + the interface. + + + Used by Castle Project components to, for example, + gather logging factories + + + + + Increments IServiceProvider with a generic service resolution operation. + + + + + Provides a factory that can produce either or + classes. + + + + + Manages the instantiation of s. + + + + + Creates a new logger, getting the logger name from the specified type. + + + + + Creates a new logger. + + + + + Creates a new logger, getting the logger name from the specified type. + + + + + Creates a new logger. + + + + + Creates a new extended logger, getting the logger name from the specified type. + + + + + Creates a new extended logger. + + + + + Creates a new extended logger, getting the logger name from the specified type. + + + + + Creates a new extended logger. + + + + + Creates a new extended logger, getting the logger name from the specified type. + + + + + Creates a new extended logger. + + + + + Creates a new extended logger, getting the logger name from the specified type. + + + + + Creates a new extended logger. + + + + + Creates a new logger, getting the logger name from the specified type. + + + + + Creates a new logger. + + + + + Creates a new logger, getting the logger name from the specified type. + + + + + Creates a new logger. + + + + + Gets the configuration file. + + i.e. log4net.config + + + + + Used to create the TraceLogger implementation of ILogger interface. See . + + + + + Gets the configuration file. + + i.e. log4net.config + + + + + Interface for Context Properties implementations + + + + This interface defines a basic property get set accessor. + + + Based on the ContextPropertiesBase of log4net, by Nicko Cadell. + + + + + + Gets or sets the value of a property + + + The value for the property with the specified key + + + + Gets or sets the value of a property + + + + + + NullLogFactory used when logging is turned off. + + + + + Creates an instance of ILogger with the specified name. + + Name. + + + + + Creates an instance of ILogger with the specified name and LoggerLevel. + + Name. + Level. + + + + + Creates outputing + to files. The name of the file is derived from the log name + plus the 'log' extension. + + + + + Provides an interface that supports and + allows the storage and retrieval of Contexts. These are supported in + both log4net and NLog. + + + + + Manages logging. + + + This is a facade for the different logging subsystems. + It offers a simplified interface that follows IOC patterns + and a simplified priority/level/severity abstraction. + + + + + Logs a debug message. + + The message to log + + + + Logs a debug message. + + The exception to log + The message to log + + + + Logs a debug message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + The exception to log + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + The message to log + + + + Logs an info message. + + The exception to log + The message to log + + + + Logs an info message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + The exception to log + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + The message to log + + + + Logs a warn message. + + The exception to log + The message to log + + + + Logs a warn message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + The exception to log + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + The message to log + + + + Logs an error message. + + The exception to log + The message to log + + + + Logs an error message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + The exception to log + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + The message to log + + + + Logs a fatal message. + + The exception to log + The message to log + + + + Logs a fatal message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + The exception to log + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal error message. + + The Message + + + + Logs a fatal error message. + + The Message + The Exception + + + + Logs a fatal error message. + + Message format + Array of objects to write using format + + + + Create a new child logger. + The name of the child logger is [current-loggers-name].[passed-in-name] + + The Subname of this logger. + The New ILogger instance. + If the name has an empty element name. + + + + Determines if messages of priority "debug" will be logged. + + True if "debug" messages will be logged. + + + + Determines if messages of priority "info" will be logged. + + True if "info" messages will be logged. + + + + Determines if messages of priority "warn" will be logged. + + True if "warn" messages will be logged. + + + + Determines if messages of priority "error" will be logged. + + True if "error" messages will be logged. + + + + Determines if messages of priority "fatal" will be logged. + + True if "fatal" messages will be logged. + + + + Determines if messages of priority "fatalError" will be logged. + + True if "fatalError" messages will be logged. + + + + Exposes the Global Context of the extended logger. + + + + + Exposes the Thread Context of the extended logger. + + + + + Exposes the Thread Stack of the extended logger. + + + + + Supporting Logger levels. + + + + + Logging will be off + + + + + Fatal logging level + + + + + Error logging level + + + + + Warn logging level + + + + + Info logging level + + + + + Debug logging level + + + + + The Logger sending everything to the standard output streams. + This is mainly for the cases when you have a utility that + does not have a logger to supply. + + + + + The Level Filtered Logger class. This is a base clase which + provides a LogLevel attribute and reroutes all functions into + one Log method. + + + + + Creates a new LevelFilteredLogger. + + + + + Keep the instance alive in a remoting scenario + + + + + + Logs a debug message. + + The message to log + + + + Logs a debug message. + + The exception to log + The message to log + + + + Logs a debug message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + The exception to log + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + Message format + Array of objects to write using format + + + + Logs an info message. + + The message to log + + + + Logs an info message. + + The exception to log + The message to log + + + + Logs an info message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + The exception to log + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + Message format + Array of objects to write using format + + + + Logs a warn message. + + The message to log + + + + Logs a warn message. + + The exception to log + The message to log + + + + Logs a warn message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + The exception to log + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + Message format + Array of objects to write using format + + + + Logs an error message. + + The message to log + + + + Logs an error message. + + The exception to log + The message to log + + + + Logs an error message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + The exception to log + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + Message format + Array of objects to write using format + + + + Logs a fatal message. + + The message to log + + + + Logs a fatal message. + + The exception to log + The message to log + + + + Logs a fatal message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + The exception to log + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + Message format + Array of objects to write using format + + + + Logs a fatal error message. + + The Message + + + + Logs a fatal error message. + + The Message + The Exception + + + + Logs a fatal error message. + + Message format + Array of objects to write using format + + + + Implementors output the log content by implementing this method only. + Note that exception can be null + + + + + + + + + The LoggerLevel that this logger + will be using. Defaults to LoggerLevel.Off + + + + + The name that this logger will be using. + Defaults to String.Empty + + + + + Determines if messages of priority "debug" will be logged. + + true if log level flags include the bit + + + + Determines if messages of priority "info" will be logged. + + true if log level flags include the bit + + + + Determines if messages of priority "warn" will be logged. + + true if log level flags include the bit + + + + Determines if messages of priority "error" will be logged. + + true if log level flags include the bit + + + + Determines if messages of priority "fatal" will be logged. + + true if log level flags include the bit + + + + Determines if messages of priority "fatal" will be logged. + + true if log level flags include the bit + + + + Creates a new ConsoleLogger with the Level + set to LoggerLevel.Debug and the Name + set to String.Empty. + + + + + Creates a new ConsoleLogger with the Name + set to String.Empty. + + The logs Level. + + + + Creates a new ConsoleLogger with the Level + set to LoggerLevel.Debug. + + The logs Name. + + + + Creates a new ConsoleLogger. + + The logs Name. + The logs Level. + + + + A Common method to log. + + The level of logging + The name of the logger + The Message + The Exception + + + + Returns a new ConsoleLogger with the name + added after this loggers name, with a dot in between. + + The added hierarchical name. + A new ConsoleLogger. + + + + The Logger using standart Diagnostics namespace. + + + + + Creates a logger based on . + + + + + + Creates a logger based on . + + + + + + + Creates a logger based on . + + + + + + + + The Null Logger class. This is useful for implementations where you need + to provide a logger to a utility class, but do not want any output from it. + It also helps when you have a utility that does not have a logger to supply. + + + + + Creates a new NullLogger. + + + + + No-op. + + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + Returns this NullLogger. + + Ignored + This ILogger instance. + + + + No-op. + + false + + + + No-op. + + false + + + + No-op. + + false + + + + No-op. + + false + + + + No-op. + + false + + + + No-op. + + false + + + + Returns empty context properties. + + + + + Returns empty context properties. + + + + + Returns empty context stacks. + + + + + The Stream Logger class. This class can stream log information + to any stream, it is suitable for storing a log file to disk, + or to a MemoryStream for testing your components. + + + This logger is not thread safe. + + + + + Creates a new StreamLogger with default encoding + and buffer size. Initial Level is set to Debug. + + + The name of the log. + + + The stream that will be used for logging, + seeking while the logger is alive + + + + + Creates a new StreamLogger with default buffer size. + Initial Level is set to Debug. + + + The name of the log. + + + The stream that will be used for logging, + seeking while the logger is alive + + + The encoding that will be used for this stream. + + + + + + Creates a new StreamLogger. + Initial Level is set to Debug. + + + The name of the log. + + + The stream that will be used for logging, + seeking while the logger is alive + + + The encoding that will be used for this stream. + + + + The buffer size that will be used for this stream. + + + + + + Creates a new StreamLogger with + Debug as default Level. + + The name of the log. + The StreamWriter the log will write to. + + + + The TraceLogger sends all logging to the System.Diagnostics.TraceSource + built into the .net framework. + + + Logging can be configured in the system.diagnostics configuration + section. + + If logger doesn't find a source name with a full match it will + use source names which match the namespace partially. For example you can + configure from all castle components by adding a source name with the + name "Castle". + + If no portion of the namespace matches the source named "Default" will + be used. + + + + + Build a new trace logger based on the named TraceSource + + The name used to locate the best TraceSource. In most cases comes from the using type's fullname. + + + + Build a new trace logger based on the named TraceSource + + The name used to locate the best TraceSource. In most cases comes from the using type's fullname. + The default logging level at which this source should write messages. In almost all cases this + default value will be overridden in the config file. + + + + Create a new child logger. + The name of the child logger is [current-loggers-name].[passed-in-name] + + The Subname of this logger. + The New ILogger instance. + + + + This is an abstract implementation + that deals with methods that can be abstracted away + from underlying implementations. + + + AbstractConfiguration makes easier to implementers + to create a new version of + + + + + is a interface encapsulating a configuration node + used to retrieve configuration values. + + + + + Gets the value of the node and converts it + into specified . + + The + + The Default value returned if the conversion fails. + + The Value converted into the specified type. + + + + Gets the name of the node. + + + The Name of the node. + + + + + Gets the value of the node. + + + The Value of the node. + + + + + Gets an of + elements containing all node children. + + The Collection of child nodes. + + + + Gets an of the configuration attributes. + + + + + Gets the value of the node and converts it + into specified . + + The + + The Default value returned if the convertion fails. + + The Value converted into the specified type. + + + + Gets the name of the . + + + The Name of the . + + + + + Gets the value of . + + + The Value of the . + + + + + Gets all child nodes. + + The of child nodes. + + + + Gets node attributes. + + + All attributes of the node. + + + + + A collection of objects. + + + + + Creates a new instance of ConfigurationCollection. + + + + + Creates a new instance of ConfigurationCollection. + + + + + Summary description for MutableConfiguration. + + + + + Initializes a new instance of the class. + + The name. + + + + Gets the value of . + + + The Value of the . + + + + + Pendent + + + + + Deserializes the specified node into an abstract representation of configuration. + + The node. + + + + + If a config value is an empty string we return null, this is to keep + backward compability with old code + + + + + General purpose class to represent a standard pair of values. + + Type of the first value + Type of the second value + + + + Constructs a pair with its values + + + + + + + List of utility methods related to dynamic proxy operations + + + + + Determines whether the specified type is a proxy generated by + DynamicProxy (1 or 2). + + The type. + + true if it is a proxy; otherwise, false. + + + + + Pendent + + + + + Initializes a new instance of the class. + + The target. + + + + Determines whether the object contains an element with the specified key. + + The key to locate in the object. + + true if the contains an element with the key; otherwise, false. + + + is null. + + + + Adds an element with the provided key and value to the object. + + The to use as the key of the element to add. + The to use as the value of the element to add. + + is null. + An element with the same key already exists in the object. + The is read-only.-or- The has a fixed size. + + + + Removes all elements from the object. + + The object is read-only. + + + + Returns an object for the object. + + + An object for the object. + + + + + Removes the element with the specified key from the object. + + The key of the element to remove. + + is null. + The object is read-only.-or- The has a fixed size. + + + + Copies the elements of the to an , starting at a particular index. + + The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + The zero-based index in at which copying begins. + + is null. + + is less than zero. + + is multidimensional.-or- is equal to or greater than the length of .-or- The number of elements in the source is greater than the available space from to the end of the destination . + The type of the source cannot be cast automatically to the type of the destination . + + + + Returns an enumerator that iterates through a collection. + + + An object that can be used to iterate through the collection. + + + + + Gets or sets the with the specified key. + + + + + + Gets an object containing the keys of the object. + + + An object containing the keys of the object. + + + + Gets an object containing the values in the object. + + + An object containing the values in the object. + + + + Gets a value indicating whether the object is read-only. + + + true if the object is read-only; otherwise, false. + + + + Gets a value indicating whether the object has a fixed size. + + + true if the object has a fixed size; otherwise, false. + + + + Gets the number of elements contained in the . + + + The number of elements contained in the . + + + + Gets an object that can be used to synchronize access to the . + + + An object that can be used to synchronize access to the . + + + + Gets a value indicating whether access to the is synchronized (thread safe). + + + true if access to the is synchronized (thread safe); otherwise, false. + + + + Represents a 'streamable' resource. Can + be a file, a resource in an assembly. + + + + + Returns a reader for the stream + + + It's up to the caller to dispose the reader. + + + + + + Returns a reader for the stream + + + It's up to the caller to dispose the reader. + + + + + + + Returns an instance of + created according to the relativePath + using itself as the root. + + + + + + + + + + Only valid for resources that + can be obtained through relative paths + + + + + + + + + + This returns a new stream instance each time it is called. + It is the responsability of the caller to dispose of this stream + + + + + Depicts the contract for resource factories. + + + + + Used to check whether the resource factory + is able to deal with the given resource + identifier. + + + Implementors should return true + only if the given identifier is supported + by the resource factory + + + + + + + Creates an instance + for the given resource identifier + + + + + + + Creates an instance + for the given resource identifier + + + + + + + + + + + + + + + + + + Adapts a static string content as an + + + + + Enable access to files on network shares + + + + + Email sender abstraction. + + + + + Sends a mail message. + + From field + To field + E-mail's subject + message's body + + + + Sends a message. + + Message instance + + + + Sends multiple messages. + + List of messages + + + + Default implementation. + + + + + Initializes a new instance of the class based on the configuration provided in the application configuration file. + + + This constructor is based on the default configuration in the application configuration file. + + + + + This service implementation + requires a host name in order to work + + The smtp server name + + + + Sends a message. + + If any of the parameters is null + From field + To field + e-mail's subject + message's body + + + + Sends a message. + + If the message is null + Message instance + + + + Configures the sender + with port information and eventual credential + informed + + Message instance + + + + Gets or sets the port used to + access the SMTP server + + + + + Gets the hostname. + + The hostname. + + + + Gets or sets a value which is used to + configure if emails are going to be sent asyncrhonously or not. + + + + + Gets or sets a value that specifies + the amount of time after which a synchronous Send call times out. + + + + + Gets or sets a value indicating whether the email should be sent using + a secure communication channel. + + true if should use SSL; otherwise, false. + + + + Gets or sets the domain. + + The domain. + + + + Gets or sets the name of the user. + + The name of the user. + + + + Gets or sets the password. + + The password. + + + + Gets a value indicating whether credentials were informed. + + + if this instance has credentials; otherwise, . + + + + diff -r 000000000000 -r f990fcb411a9 Redist/Castle/Castle.Windsor.XML --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Redist/Castle/Castle.Windsor.XML Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7741 @@ + + + + Castle.Windsor + + + + + Attempts to dynamically load a UserControl by invoking Page.LoadControl. + There are two uses of this class. + + 1) Add a component to the Kernel and add a VirtualPath attribute specifying + the relative path of the .ascx file for the associated UserControl. (easy) + + + + <component id="BasketView" + service="Castle.ShoppingCart.IBasketView, Castle.ShoppingCart" + type="Castle.ShoppingCart.BasketView, Castle.ShoppingCart" + lifestyle="transient" + virtualPath="~/Views/BasketView.ascx" + /> + + + + 2) Precompile a UserControl and add the pre-compiled class to the Kernel. (hard) + Has not been tested with proxies. + + + + + + Standard implementation of . + Handles the selection of the best constructor, fills the + writable properties the component exposes, run the commission + and decommission lifecycles, etc. + + + Custom implementors can just override the CreateInstance method. + Please note however that the activator is responsible for the proxy creation + when needed. + + + + + Abstract implementation of . + The implementors must only override the InternalCreate and + InternalDestroy methods in order to perform their creation and + destruction logic. + + + + + Implements the instance creation logic. The default + implementation should rely on an ordinary call to + Activator.CreateInstance(). + + + This interface is provided in order to allow custom components + to be created using a different logic, such as using a specific factory + or builder. + + The constructor for implementation has the following signature: + + + ComponentModel model, IKernel kernel, + ComponentInstanceDelegate onCreation, + ComponentInstanceDelegate onDestruction + + + The Activator should raise the events onCreation and onDestruction + in order to correctly implement the contract. Usually the best + way of creating a custom activator is by extending the existing ones. + + + + + + + + Should return a new component instance. + + + + + + Should perform all necessary work to dispose the instance + and/or any resource related to it. + + + + + + Constructs an AbstractComponentActivator + + + + + Initializes a new instance of the class. + + + + + + + + + Initializes a new instance of the class. + + The model. + The kernel. + The on creation. + The on destruction. + + + + Creates the instance. + + The context. + The arguments. + The signature. + + + + + Implements a Lifestyle Manager for Web Apps that + create at most one object per web request. + + + + + Summary description for AbstractLifestyleManager. + + + + + The ILifestyleManager implements + a strategy for a given lifestyle, like singleton, per-thread + and transient. + + + The responsibility of ILifestyleManager + is only the management of lifestyle. It should rely on + to obtain a new component instance + + + + + Initializes the ILifestyleManager with the + + + + + + + + + Implementors should return the component instance based + on the lifestyle semantic. + + + + + + Implementors should release the component instance based + on the lifestyle semantic, for example, singleton components + should not be released on a call for release, instead they should + release them when disposed is invoked. + + + + + + This attribute is useful only when you want to register all components + on an assembly as a batch process. + By doing so, the batch register will look + for this attribute to distinguish components from other classes. + + + + + Base for Attributes that want to express lifestyle + chosen by the component. + + + + + Initializes a new instance of the class. + + The type. + + + + Gets or sets the lifestyle. + + The lifestyle. + + + + Associates a custom component with a component + + + + + Initializes a new instance of the class. + + Type of the component activator. + + + + Gets the type of the component activator. + + The type of the component activator. + + + + Specifies the proxying behavior for a component. + + + + + Gets or sets a value indicating whether the generated + interface proxy should inherit from . + + + + + Determines if the component requires a single interface proxy. + + true if the component requires a single interface proxy. + + + + Gets or sets the additional interfaces used during proxy generation. + + + + + Marks as property to be skipped and not be wired + by the IoC container + + + + + Represents a concern that will be applied to a component instance + during commission or decommission phase. + + + + + Implementors should act on the instance in response to + a decommission or commission phase. + + The model. + The component. + + + + Lifecycle interface. If implemented by a component, + the method Initialized will be invoked by the container + before making the component available to the external world. + + + + + Implementors should perform any initialization logic. + + + + + Used to declare that a component wants interceptors acting on it. + + + + + Constructs the InterceptorAttribute pointing to + a key to a interceptor + + + + + + Constructs the InterceptorAttribute pointing to + a service + + + + + + Marker class used to denote components that have late bound type + That is the actual type is not known exactly at the time when + is created. Those are for example components instantiated via abstract factory. + + + + + If the extended type is a Foo[] or IEnumerable{Foo} which is assignable from Foo[] this method will return typeof(Foo) + otherwise null. + + + + + + + Indicates that the target components wants a + singleton lifestyle. + + + + + Initializes a new instance of the class. + + + + + Indicates that the target components wants a + transient lifestyle. + + + + + Initializes a new instance of the class. + + + + + Indicates that the target components wants a + per thread lifestyle. + + + + + Initializes a new instance of the class. + + + + + Indicates that the target components wants a + per web request lifestyle. + + + + + Indicates that the target components wants a + pooled lifestyle. + + + + + Initializes a new instance of the class + using the default initial pool size (5) and the max pool size (15). + + + + + Initializes a new instance of the class. + + Initial size of the pool. + Max pool size. + + + + Gets the initial size of the pool. + + The initial size of the pool. + + + + Gets the maximum pool size. + + The size of the max pool. + + + + Indicates that the target components wants a + custom lifestyle. + + + + + Initializes a new instance of the class. + + The lifestyle handler. + + + + Gets the type of the lifestyle handler. + + The type of the lifestyle handler. + + + + Enumeration used to mark the component's lifestyle. + + + + + No lifestyle specified. + + + + + Singleton components are instantiated once, and shared + between all clients. + + + + + Thread components have a unique instance per thread. + + + + + Transient components are created on demand. + + + + + Optimization of transient components that keeps + instance in a pool instead of always creating them. + + + + + PerWebRequest components are created once per Http Request + + + + + Any other logic to create/release components. + + + + + Collects information about subscribers for given event + + + + + Extracts MethodInfo of metho invoked in delegate. Based on ILReader class from http://www.gocosmos.org project + + + + + Implementors must inspect the component for + a given information or parameter. + + + + + Usually the implementation will look in the configuration property + of the model or the service interface, or the implementation looking for + something. + + The kernel instance + The component model + + + + Selects one or both of component name and type, for given method + called on given typed factory type. + When component should be requested by type only, + componentName should be null. + When component should be requested by name only, + componentType should be null. + + + + + + + + + Builds for given call. + By default if is a collection + returns for the collection's item type, + otherwise standard . + + + + + + + + + + Selects arguments to be passed to resolution pipeline. + By default passes all given + keyed by names of their corresponding parameters. + + + + + + + + Selects name of the component to resolve. + If Name is GetFoo returns "Foo", otherwise null. + + + + + + + + Selects type of the component to resolve. Uses return type. + + + + + + + + Provides lazy registration capabilities to the container. + + + When a component is requested from a container and it was not registered, + container loads up all registered implementers of this interface and asks + them in turn whether they can provide that component, until it finds one that will. + + + + + Used by container to allow the loader to register component for given and to the container at the time when it is requested + + Key of the requested component or null + Type of requested service or null + User supplied arguments or null + Registration that registers component for given key and/or service or null. + + While either key or service can be null reference it is guaranteed that at least one of them will not be null. + When implementer opts in to provide the requested component (by returning not-null registration) it is required + to register component for requested key/service combination (when one of the elements is null, it should be ignored as well). + When implementer does not want to register the requested component it must return null. + + + + + Summary description for ComponentActivatorException. + + + + + + + + + + Represents collection of arguments used when resolving a component. + + + + + Exception thrown when component has no resolvable constructor that can be used to create an instance. + + + + + Default arguments store used to store items where no specialized store exists + + + + + Extends adding and + information. The MemberInfo is only useful to provide detailed information + on exceptions. + The ComponentModel is required so we can get resolve an object that takes as a parameter itself, but + with difference model. (See IoC 51 for the details) + + + + + Represents a dependency (other component or a + fixed value available through external configuration). + + + + + Initializes a new instance of the class. + + The type. + The dependency key. + Type of the target. + if set to true [is optional]. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Gets or sets the dependency key. + + The dependency key. + + + + Gets or sets the type of the dependency. + + The type of the dependency. + + + + Gets or sets whether this dependency is optional. + + + true if this dependency is optional; otherwise, false. + + + + + Gets the service type of the dependency. + This is the same type as or if is by ref, + then it's the element type of the reference. (in other words if dependency + is out IFoo foo this will be IFoo, while will be &IFoo); + + + + + Gets the type of the target. + + The type of the target. + + + + Summary description for DefaultHandler. + + + + + Implements the basis of + + + + + + Contract for the IHandler, which manages an + component state and coordinates its creation + and destruction (dispatching to activators, lifestyle managers) + + + + + Implementors should use a strategy to obtain + valid references to properties and/or services + requested in the dependency model. + + + + + Should return an instance of a service or property values as + specified by the dependency model instance. + It is also the responsibility of + to throw an exception in the case a non-optional dependency + could not be resolved. + + Creation context, which is a resolver itself + Parent resolver - normally the IHandler implementation + Model of the component that is requesting the dependency + The dependency model + The dependency resolved value or null + + + + Returns true if the resolver is able to satisfy this dependency. + + Creation context, which is a resolver itself + Parent resolver - normally the IHandler implementation + Model of the component that is requesting the dependency + The dependency model + true if the dependency can be satisfied + + + + Initializes the handler with a reference to the + kernel. + + + + + + Implementors should return a valid instance + for the component the handler is responsible. + It should throw an exception in the case the component + can't be created for some reason + + + + + + Implementors should return a valid instance + for the component the handler is responsible. + It should return null in the case the component + can't be created for some reason + + + + + + Implementors should dispose the component instance + + + true if destroyed. + + + + Dictionary of String/object used to + associate data with a component dependency. + For example, if you component SmtpServer depends on + host and port, you can add those to this + dictionary and the handler will be able to use them. + + + TODO: Document this + + + + + TODO: Document this + + + + + + TODO: Document this + + + + + + + Tests whether the handler is already being resolved in given context. + + + + + Gets the state of the handler + + + + + Gets the model of the component being + managed by this handler. + + + + + The service that this handler handles + + + + + Allow to track state changes of a handler that is modified directly. + This can happen if the client calls AddCustomDependencyValue or + RemoveCustomDependencyValue + + + + + Might be implemented by a handler + so it can expose access to dependency information + which is used to construct meaningful error messages + + + + + Returns human readable list of dependencies + this handler is waiting for. + list of the dependencies that was already checked, used to avoid cycles. + + + + + Lifestyle manager instance + + + + + Custom dependencies values associated with the handler + + + + + Dictionary of key (string) to + + + + + + Dictionary of Type to a list of + + + + + + Constructs and initializes the handler + + + + + + Should be implemented by derived classes: + disposes the component instance (or recycle it) + + + true if destroyed. + + + + Should be implemented by derived classes: + returns an instance of the component this handler + is responsible for + + + + When false, handler can not create valid instance and return null instead. + + + + + Returns human readable list of dependencies + this handler is waiting for. + + + + + + Saves the kernel instance, subscribes to + + event, + creates the lifestyle manager instance and computes + the handler state. + + + + + + disposes the component instance (or recycle it). + + + + + + + Returns an instance of the component this handler + is responsible for + + + + + + + Invoked by + + in order to check if a dependency can be satisfied. + If not, the handler is set to a 'waiting dependency' state. + + + This method registers the dependencies within the correct collection + or dictionary and changes the handler state to + + + + + + + Creates an implementation of + + based + on + + and invokes + + to initialize the newly created manager. + + + + + + + Invoked by the kernel + when one of registered dependencies were satisfied by + new components registered. + + + Handler for the event + + + + + + + Checks if the handler is able to, at very least, satisfy + the dependencies for the constructor with less parameters + + + For each non*optional dependency, the implementation will invoke + + + + + + Invoked when the container receives a parent container reference. + + + This method implementation checks whether the parent container + is able to supply the dependencies for this handler. + + + + + + + Returns an instance of the component this handler + is responsible for + + + when false, handler can not create valid instance and return null instead + + + + + Handler for the event + + + + + + + + Gets the component model. + + + + + Gets the handler state. + + + + + Initializes a new instance of the class. + + + + + + Returns an instance of the component this handler + is responsible for + + + + + + + + + disposes the component instance (or recycle it) + + + true if destroyed + + + + Used during a component request, passed along to the whole process. + This allow some data to be passed along the process, which is used + to detected cycled dependency graphs and now it's also being used + to provide arguments to components. + + + + + Holds the scoped dependencies being resolved. + If a dependency appears twice on the same scope, we'd have a cycle. + + + + + The list of handlers that are used to resolve + the component. + We track that in order to try to avoid attempts to resolve a service + with itself. + + + + + Initializes a new instance of the class. + + The type to extract generic arguments. + The parent context. + When set to true will clone . + + + + Initializes a new instance of the class. + + The handler. + The release policy. + The type to extract generic arguments. + The additional arguments. + The conversion manager. + Parent context + + + + Initializes a new instance of the class. + + + + + Method used by handlers to test whether they are being resolved in the context. + + + + + This method is provided as part of double dispatch mechanism for use by handlers. + Outside of handlers, call instead. + + + + + Creates a new, empty instance. + + + A new CreationContext should be created every time, as the contexts keeps some state related to dependency resolution. + + + + + Default implementation of . + This implementation is complete and also support a kernel + hierarchy (sub containers). + + + Default implementation of . + This implementation is complete and also support a kernel + hierarchy (sub containers). + + + + + The IKernel interface exposes all the functionality + the MicroKernel implements. + + + It allows you to register components and + request them by the key or the service they implemented. + It also allow you to register facilities and subsystem, thus + augmenting the functionality exposed by the kernel alone to fits + your needs. + + + + + + + Summary description for IKernelEvents. + + + + + Event fired when a new component is registered + on the kernel. + + + + + Event fired when a component is removed from the kernel. + + + + + Event fired after the ComponentModel is created. + Allows customizations that may affect the handler. + + + + + Event fired when the kernel was added as child of + another kernel. + + + + + Event fired when the kernel was removed from being a child + of another kernel. + + + + + Event fired before the component is created. + + + + + Event fired when a component instance destroyed. + + + + + Event fired when a new handler is registered + (it might be in a valid or waiting dependency state) + + + + + Event fired when a new handler is registered + (it might be in a valid or waiting dependency state) + + + + + Event fired when a dependency is being resolved, + it allows the dependency to be changed, + but the client ComponentModel must not be changed. + + + + + Registers the components provided by the s + with the . + + Create a new registration using .For() or . + + + + kernel.Register(Component.For<IService>().ImplementedBy<DefaultService>()); + + + The component registrations. + The kernel. + + + + Returns true if the specified component was + found and could be removed (i.e. no other component depends on it) + + The component's key + + + + + Returns true if the specified key was registered + + + + + + + Returns true if the specified service was registered + + + + + + + Associates objects with a component handler, + allowing it to use the specified dictionary + when resolving dependencies + + + + + + + Associates objects with a component handler, + allowing it to use the specified dictionary + when resolving dependencies + + + + + + + Associates objects with a component handler, + allowing it to use the specified dictionary + when resolving dependencies + + + + + + + Associates objects with a component handler, + allowing it to use the specified dictionary + when resolving dependencies + + + + + + + Releases a component instance. This allows + the kernel to execute the proper decommission + lifecycles on the component instance. + + + + + + Returns the + for the specified component key. + + + + + + + Returns the + for the specified service. + + + + + + + Return handlers for components that + implements the specified service. + + + + + + + Return handlers for components that + implements the specified service. + The check is made using IsAssignableFrom + + + + + + + Adds a to the kernel. + + + + + + + + Creates and adds an facility to the kernel. + + The facility type. + + + + + Creates and adds an facility to the kernel. + + The facility type. + + The callback for creation. + + + + Creates and adds an facility to the kernel. + + The facility type. + + The callback for creation. + + + + Creates and adds an facility to the kernel. + + The facility type. + + + + + Creates and adds an facility to the kernel. + + The facility type. + The callback for creation. + + + + + Creates and adds an facility to the kernel. + + The facility type. + The callback for creation. + + + + + Returns the facilities registered on the kernel. + + + + + + Adds (or replaces) an + + + + + + + Returns an implementation of + for the specified key. + + + + + + + + Support for kernel hierarchy + + + + + + Remove child kernel + + + + + + Register a new component resolver that can take part in the decision + making about which handler to resolve + + + + + Returns the component instance by the service type + + + + + Returns all the valid component instances by + the service type + + The service type + + + + Returns all the valid component instances by + the service type + + The service type + Arguments to resolve the services + + + + Returns all the valid component instances by + the service type + + The service type + Arguments to resolve the services + + + + Returns the component instance by the service type + using dynamic arguments + + + + + + + + Returns the component instance by the component key + using dynamic arguments + + + + + + + + Returns the component instance by the service type + using dynamic arguments + + Service to resolve + Arguments to resolve the services + + + + + Returns the component instance by the component key + using dynamic arguments + + Key to resolve + Arguments to resolve the services + + + + + Returns a component instance by the key + + + + + + + + Returns the component instance by the service type + using dynamic arguments + + + + + + + Returns the component instance by the service type + using dynamic arguments + + Arguments to resolve the services + + + + + Returns the component instance by the component key + + + + + + Returns a component instance by the key + + Component's key + Service type + The Component instance + + + + Returns a component instance by the key + + Service type + Component's key + + The Component instance + + + + Returns component instances that implement TService + + + + + + + Returns component instances that implement TService + + + + + + + Returns component instances that implement TService + + + + + + + Returns a component instance by the key + + + + + + + + + Returns the implementation of + + + + + Returns the implementation of + + + + + Gets or sets the implementation of + + + + + Gets or sets the implementation for + + + + + Returns the implementation for + + + + + Gets or sets the implementation of + allowing different strategies for proxy creation. + + + + + Returns the parent kernel + + + + + Graph of components and interactions. + + + + + Returns the component instance by the key + + + + + Returns the component instance by the service type + + + + + Extended contract of kernel, used internally. + + + + + Constructs an implementation of + for the given + + + + + + + Raise the handler registered event, required so + dependant handlers will be notified about their dependant moving + to valid state. + + + + + + Registers the to be forwarded + to the component registered with . + + The service type that gets forwarded. + The name of the component to forward to. + + + + Adds a custom made . + Used by facilities. + + + + + + List of sub containers. + + + + + List of registered. + + + + + The implementation of + + + + + The dependency resolver. + + + + + Map of subsystems registered. + + + + + The parent kernel, if exists. + + + + + Holds the implementation of + + + + + Implements a policy to control component's + disposal that the user forgot. + + + + + Constructs a DefaultKernel with no component + proxy support. + + + + + Constructs a DefaultKernel with the specified + implementation of and + + + + + + + Constructs a DefaultKernel with the specified + implementation of + + + + + Starts the process of component disposal. + + + + + Return handlers for components that + implements the specified service. + The check is made using IsAssignableFrom + + + + + + + Returns the facilities registered on the kernel. + + + + + + Return handlers for components that + implements the specified service. + + + + + + + Registers the components described by the s + with the . + The component registrations. + The kernel. + + + + + Associates objects with a component handler, + allowing it to use the specified dictionary + when resolving dependencies + + + + + + + Associates objects with a component handler, + allowing it to use the specified dictionary + when resolving dependencies + + + + + + + Associates objects with a component handler, + allowing it to use the specified dictionary + when resolving dependencies + + + + + + + Associates objects with a component handler, + allowing it to use the specified dictionary + when resolving dependencies + + + + + + + Releases a component instance. This allows + the kernel to execute the proper decommission + lifecycles on the component instance. + + + + + + Returns true if the specified component was + found and could be removed (i.e. no other component depends on it) + + The component's key + + + + + Gets the service object of the specified type. + + + A service object of type serviceType. + + An object that specifies the type of service object to get. + + + + Gets the service object of the specified type. + + + A service object of type serviceType. + + + + + Returns a component instance by the key + + + + + + + + Returns a component instance by the key + + + + + + + + + Returns the component instance by the service type + using dynamic arguments + + + + + + + Returns the component instance by the service type + using dynamic arguments + + + + + + + Returns the component instance by the component key + + + + + + Returns a component instance by the key + + Component's key + Service type + + The Component instance + + + + + Returns a component instance by the key + + Service type + Component's key + + + The Component instance + + + + + Returns the component instance by the service type + + + + + Returns the component instance by the service type + using dynamic arguments + + + + + + + + Returns the component instance by the service type + using dynamic arguments + + + + + + + + Returns the component instance by the component key + using dynamic arguments + + + + + + + + Returns the component instance by the component key + using dynamic arguments + + + + + + + + Returns all the valid component instances by + the service type + + The service type + + + + Returns all the valid component instances by + the service type + + The service type + + Arguments to resolve the services + + + + + Returns all the valid component instances by + the service type + + The service type + + Arguments to resolve the services + + + + + Returns component instances that implement TService + + + + + + + + Returns component instances that implement TService + + + + + + + + Returns component instances that implement TService + + + + + + + Graph of components and interactions. + + + + + Exception throw when a circular dependency is detected + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + The message. + + + + Initializes a new instance of the class. + + The message. + The inner exception. + + + + Initializes a new instance of the class. + + The that holds the serialized object data about the exception being thrown. + The that contains contextual information about the source or destination. + The parameter is . + The class name is or is zero (0). + + + + Exception threw when a request for a component + cannot be satisfied because the component does not + exist in the container + + + + + Initializes a new instance of the + + class. + + The name. + + + + Initializes a new instance of the + + class. + + The name. + Exception message. + + + + Initializes a new instance of the + + class. + + The service. + Exception message. + + + + Initializes a new instance of the + + class. + + The service. + + + + Initializes a new instance of the + + class. + + The object that holds the serialized object data. + The contextual information about the source or destination. + + + + Exception threw when there is a problem + registering a component + + + + + Initializes a new instance of the class. + + The message. + + + + Initializes a new instance of the class. + + The object that holds the serialized object data. + The contextual information about the source or destination. + + + + Exception threw by Kernel operations that failed + for some reason. + + + + + Initializes a new instance of the class. + + The message. + + + + Initializes a new instance of the class. + + The message. + The inner exception. + + + + Initializes a new instance of the class. + + The object that holds the serialized object data. + The contextual information about the source or destination. + + + + Base class for facilities. + + + + + Unit of extension. A facility should use + the extension points offered by the kernel + to augment its functionality. + + + + + + + + + + + + + + + + + The custom initialization for the Facility. + + + It must be overridden. + + + + + Performs the tasks associated with freeing, releasing, or resetting + the facility resources. + + + It can be overriden. + + + + + Initializes the facility. First it performs the initialization common for all + facilities, setting the and the + . After it, the Init method is invoked + and the custom initilization is perfomed. + + + + + + + Terminates the Facility, invokes the method and sets + the Kernel to a null reference. + + + + + Gets the facility configuration. + + The representing + the facility configuration. + + + + Gets the where the facility is registered. + + The . + + + + Exception that is thrown when a error occurs during the Event Wiring process + + + + + Base exception to be used by facilities. + + + + + Initializes a new instance of the class. + + The message. + + + + Initializes a new instance of the class. + + The message. + The inner exception. + + + + Initializes a new instance of the class. + + The object that holds the serialized object data. + The contextual information about the source or destination. + + + + Facility to allow components to dynamically subscribe to events offered by + other components. We call the component that offers events publishers and + the components that uses them, subscribers. + + + A component that wish to subscribe to an event must use the external configuration + adding a node subscribers on the publisher. This node can have multiple entries using the + subscriber node. + + + This example shows two simple components: one is the event publisher and the other is the + subscriber. The subscription will be done by the facility, using the publisher associated configuration. + The Publisher class: + + public class SimplePublisher + { + public event PublishEventHandler Event; + + public void Trigger() + { + if (Event != null) + { + Event(this, new EventArgs()); + } + } + } + + The Subscriber class: + + public class SimpleListener + { + private bool _listened; + private object _sender; + + public void OnPublish(object sender, EventArgs e) + { + _sender = sender; + _listened = sender != null; + } + + public bool Listened + { + get { return _listened; } + } + + public object Sender + { + get { return _sender; } + } + } + + The configuration file: + + + + + + + + + + + + + + + + + + ]]> + + + + + + Overridden. Initializes the facility, subscribing to the , + , Kernel events. + + + + + Checks if the component we're dealing is a publisher. If it is, + parses the configuration (the subscribers node) getting the event wiring info. + + The component model. + Invalid and/or a error in the configuration + + + + Checks if the component we're dealing is a publisher. If it is, + iterates the subscribers starting them and wiring the events. + + The component model. + The instance representing the component. + When the subscriber is not found +
or
+ The handler method isn't found +
or
+ The event isn't found +
+
+ + + Represents the information about an event. + + + + + Initializes a new instance of the class. + + Name of the event. + The name of the handler method. + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + + + Gets the name of the event. + + The name of the event. + + + + Gets the handler method name. + + The handler. + + + + + + + + + Activates a object connecting to the remote server. + + + + + Initializes a new instance of the class. + + The model. + The kernel. + The oncreation event handler. + The ondestruction event handler. + + + + Activates a client connecting to the remote server, enforcing the uri and the server activation. + + + + + Initializes a new instance of the class. + + The model. + The kernel. + The oncreation event handler. + The ondestruction event handler. + + + + Activates a client connecting to the remote server through the . + + + + + Initializes a new instance of the class. + + The model. + The kernel. + The oncreation event handler. + The ondestruction event handler. + + + + Activates a client activated object. + + + + + Initializes a new instance of the class. + + The model. + The kernel. + The oncreation event handler. + The ondestruction event handler. + + + + Activates and publishes a server object. + + + + + Initializes a new instance of the class. + + The model. + The kernel. + The oncreation event handler. + The ondestruction event handler. + + + + Facility to allow the communication with remote kernel, using the .NET Remoting infrastructure. + + + TODO + + + TODO + + + + + Used for client side (Expand explanation) + + + + + Used for server side. + Holds the local registry + + + + + Used for client side. + Holds a remote proxy to the server registry + + + + + Performs the tasks associated with freeing, releasing, or resetting + the facility resources. + + + It can be overridden. + + + + + Inspects the model looking for remote component configuration. If found, + do the component Remoting configuration. + + + + + Initializes a new instance of the class. + + The converter. + if set to true is a server. + if set to true is a client. + The base URI. + The remote registry. + The local registry. + + + + Client components are not created by the container + so there's no point collecting constructor dependencies + + + + + + Used in case of generics: + + + + + + + This method changes behavior of the facility. Deferred mode should be used when you + have single call to and register all your components there. + Enabling this mode will optimize the behavior of the facility so that it will wait 'till the end of + installation and only after all s were ran it will instantiate and + start all the startable components. An exception will be thrown if a startable component can't be + instantiated and started. This will help you fail fast and diagnose issues quickly. If you don't want + the exception to be thrown and you prefer the component to fail silently, use method instead. + + + It is recommended to use this method over method. + + + + + This method changes behavior of the facility. Deferred mode should be used when you + have single call to and register all your components there. + Enabling this mode will optimize the behavior of the facility so that it will wait 'till the end of + installation and only after all s were ran it will instantiate and + start all the startable components. No exception will be thrown if a startable component can't be + instantiated and started. If you'd rather fail fast and diagnose issues quickly, use method instead. + + + It is recommended to use method over this method. + + + + + For each new component registered, + some components in the WaitingDependency + state may have became valid, so we check them + + + + + Request the component instance + + + + + + Assigns the start method for the startable. + + + The start method. + + Be sure that you first added the + to the kernel, before registering this component. + + + + Assigns the start method for the startable. + + + Method to use. something like: StartUsingMethod(s => s.Start) + + Be sure that you first added the + to the kernel, before registering this component. + + + + Assigns the stop method for the startable. + + + The stop method. + + Be sure that you first added the + to the kernel, before registering this component. + + + + Assigns the stop method for the startable. + + + Method to use. something like: StartUsingMethod(s => s.Start) + + Be sure that you first added the + to the kernel, before registering this component. + + + + Legacy class from old impl. of the facility. Do not use it. + + + + + Legacy interceptor for old impl. of the facility. + + + + + Interceptors might implement this to receive the + ComponentModel on behalf of the component where the + interceptor is acting. + + + + + Represents a single component to be resolved via Typed Factory + + + + + Resolves the component(s) from given kernel. + + + Resolved component(s). + + + + Represents a set of components to be resolved via Typed Factory. Uses to resolve the components. + + + + + Creates new instance of . + + Collection type to resolve. Must be an array (SomeComponent[]) or IEnumerable{SomeComponent}. Type of the element of the collection will be used as first argument to + Additional arguents that will be passed as second argument to + + + + Provides automatically generated factories on top of interfaces or delegates that + you can use to pull components out of the container without ever referencing it + explicitly. + + + + + Marks the component as typed factory. + + + + + + Only interfaces are legal to use as typed factories. Methods with out parameters are not allowed. + When registering component as typed factory no implementation should be provided (in case there is any it will be ignored). + Typed factories rely on set internally, so users should not set interceptor selectors explicitly; + otherwise the factory will not function correctly. + + + + + Marks the component as typed factory. + + + + + + + Only interfaces are legal to use as typed factories. Methods with out parameters are not allowed. + When registering component as typed factory no implementation should be provided (in case there is any it will be ignored). + Typed factories rely on set internally, so users should not set interceptor selectors explicitly; + otherwise the factory will not function correctly. + + + + + Redirects resolution to the main resolver, and if not found uses + the parent handler. + + + + + Initializes a new instance of the class. + + The parent handler. + The child resolver. + + + + Summary description for DefaultGenericHandler. + + + TODO: Consider refactoring AbstractHandler moving lifestylemanager + creation to DefaultHandler + + + + + Initializes a new instance of the class. + + + + + + Clone some of the parent componentmodel properties to the generic subhandler. + + + The following properties are copied: + + + The + + + The + + + + the subhandler + + + + Summary description for DefaultHandlerFactory. + + + + + Extension point to allow the developer + to use his implementation of + + + + + Summary description for HandlerException. + + + + + Initializes a new instance of the class. + + The message. + + + + Initializes a new instance of the class. + + The object that holds the serialized object data. + The contextual information about the source or destination. + + + + Possible states for a IHandler instance + + + + + The component can be requested + + + + + The component can not be requested + as it still depending on a external + dependency not yet available + + + + + + + + + + + + Represents a delegate which holds basic information about a component. + + Key which identifies the component + handler that holds this component and is capable of + creating an instance of it. + + + + + Represents a delegate which holds basic information about a component + and its instance. + + Component meta information + Component instance + + + + Represents a delegate which holds the information about the + component + + + + + Represents a delegate which holds a handler + + handler that holds a component and is capable of + creating an instance of it. + + + + + + Represents a delegate which holds dependency + resolving information. + + + + + Abstract representation of a vertex. + + + + + The nodes that depends on this node + + + + + The nodes that this node depends + + + + + The node has not been visited yet + + + + + This node is in the process of being visited + + + + + This now was visited + + + + + Represents a collection of objects + which are guaranteed to be unique + and holds a color for them + + + + + Holds a timestamp (integer) + for a given item + + + + + Summary description for DisposalConcern. + + + + + Summary description for InitializationConcern. + + + + + Lifetime concern that works for components that don't have their actual type determined upfront + + + + + Summary description for SupportInitializeConcern. + + + + + Only called for components that + belongs to a pool when the component + comes back to the pool. + + + + + Implementors should perform any + initialization/clean up. + + + + + Interface for components that wish to be started by the container + + + + + Starts this instance. + + + + + Stops this instance. + + + + + Summary description for PerThreadLifestyleManager. + + + + + + + + + + Implements a Poolable Lifestyle Manager. + + + + + Pool implementation contract. + + + + + Implementors should return a component instance. + + + + + + Implementors should release the instance or put it + on the pool + + + + + + Initializes the pool to a initial size by requesting + n components and then releasing them. + + + + + Summary description for SingletonLifestyleManager. + + + + + Summary description for TransientLifestyleManager. + + + + + Summary description for DefaultComponentModelBuilder. + + + + + Implementors must construct a populated + instance of ComponentModel by inspecting the component + and|or the configuration. + + + + + Constructs a new ComponentModel by invoking + the registered contributors. + + + + + + + + + + "To give or supply in common with others; give to a + common fund or for a common purpose". The contributor + should inspect the component, or even the configuration + associated with the component, to add or change information + in the model that can be used later. + + + + + Removes the specified contributor + + + + + + Initializes a new instance of the class. + + The kernel. + + + + Constructs a new ComponentModel by invoking + the registered contributors. + + + + + + + + + + "To give or supply in common with others; give to a + common fund or for a common purpose". The contributor + should inspect the component, or even the configuration + associated with the component, to add or change information + in the model that can be used later. + + + + + + Removes the specified contributor + + + + + + Initializes the default contributors. + + + + + Gets the contributors. + + The contributors. + + + + Inspects the component configuration and the type looking for a + definition of component activator type. The configuration preceeds whatever + is defined in the component. + + + This inspector is not guarantee to always set up an component activator type. + If nothing could be found it wont touch the model. In this case is up to + the kernel to establish a default component activator for components. + + + + + Searches for the component activator in the configuration and, if unsuccessful + look for the component activator attribute in the implementation type. + + The kernel instance + The model instance + + + + Reads the attribute "componentActivatorType" associated with the + component configuration and verifies it implements the + interface. + + + If the type does not implement the proper interface + + + + + + + Check if the type expose one of the component activator attributes + defined in Castle.Core namespace. + + + + + + Validates that the provide type implements IComponentActivator + + The custom component activator. + + + + Inspects the component configuration and type looking for information + that can influence the generation of a proxy for that component. + + We specifically look for useSingleInterfaceProxy and marshalByRefProxy + on the component configuration or the + attribute. + + + + + + Searches for proxy behavior in the configuration and, if unsuccessful + look for the attribute in + the implementation type. + + + + + Reads the proxy behavior associated with the + component configuration/type and applies it to the model. + + + If the conversion fails + + + + + + + Returns a instance if the type + uses the attribute. Otherwise returns null. + + + + + + Uses the ConfigurationStore registered in the kernel to obtain + an associated with the component. + + + + + Queries the kernel's ConfigurationStore for a configuration + associated with the component name. + + + + + + + Check for a node 'parameters' within the component + configuration. For each child it, a ParameterModel is created + and added to ComponentModel's Parameters collection + + + + + Inspect the configuration associated with the component + and populates the parameter model collection accordingly + + + + + + + This implementation of + collects all available constructors and populates them in the model + as candidates. The Kernel will pick up one of the candidates + according to a heuristic. + + + + + Only to hold internal constants and get rid of + magic numbers and hardcode names. + + + + + Inspect the component for InterceptorAttribute and + the configuration for the interceptors node + + + + + Inspects the type looking for interfaces that constitutes + lifecycle interfaces, defined in the Castle.Model namespace. + + + + + Checks if the type implements and or + interfaces. + + + + + + + Inspects the component configuration and the type looking for a + definition of lifestyle type. The configuration preceeds whatever + is defined in the component. + + + This inspector is not guarantee to always set up an lifestyle type. + If nothing could be found it wont touch the model. In this case is up to + the kernel to establish a default lifestyle for components. + + + + + Searches for the lifestyle in the configuration and, if unsuccessful + look for the lifestyle attribute in the implementation type. + + + + + Reads the attribute "lifestyle" associated with the + component configuration and tries to convert to + enum type. + + + + + Check if the type expose one of the lifestyle attributes + defined in Castle.Model namespace. + + + + + Base for inspectors that want configuration associated with methods. + For each child a is created + and added to ComponentModel's methods collection + + + Implementors should override the return + the name of the node to be inspected. For example: + + + + + ]]> + + + + + + This implementation of + collects all potential writable public properties exposed by the component + implementation and populates the model with them. + The Kernel might be able to set some of these properties when the component + is requested. + + + + + Initializes a new instance of the class. + + + + + Adds the properties as optional dependencies of this component. + + + + + + + Represents the collection of information and + meta information collected about a component. + + + + Extended properties + + + Dependencies the kernel must resolve + + + All available constructors + + + All potential properties that can be setted by the kernel + + + Steps of lifecycle + + + External parameters + + + Interceptors associated + + + /// Custom dependencies/// + + + + Constructs a ComponentModel + + + + + Requires the selected property dependencies. + + The property selector. + + + + Requires the property dependencies of type . + + The dependency type. + + + + Sets or returns the component key + + + + + Gets or sets the service exposed. + + The service. + + + + Gets or sets the component implementation. + + The implementation. + + + + Gets or sets a value indicating whether the component requires generic arguments. + + + true if generic arguments are required; otherwise, false. + + + + + Gets or sets the extended properties. + + The extended properties. + + + + Gets the constructors candidates. + + The constructors. + + + + Gets the properties set. + + The properties. + + + + Gets or sets the configuration. + + The configuration. + + + + Gets the lifecycle steps. + + The lifecycle steps. + + + + Gets or sets the lifestyle type. + + The type of the lifestyle. + + + + Gets or sets the strategy for + inspecting public properties + on the components + + + + + Gets or sets the custom lifestyle. + + The custom lifestyle. + + + + Gets or sets the custom component activator. + + The custom component activator. + + + + Gets the interceptors. + + The interceptors. + + + + Gets the parameter collection. + + The parameters. + + + + Dependencies are kept within constructors and + properties. Others dependencies must be + registered here, so the kernel (as a matter + of fact the handler) can check them + + + + + Gets the custom dependencies. + + The custom dependencies. + + + + Represents a constructor of the component + that the container can use to initialize it properly. + + + + + Initializes a new instance of the class. + + The constructor info. + The dependencies. + + + + Gets the ConstructorInfo (from reflection). + + The constructor. + + + + Gets the dependencies this constructor candidate exposes. + + The dependencies. + + + + Collection of + + + + + Gets the fewer arguments candidate. + + The fewer arguments candidate. + + + + Collection of . + + + + + Represents an reference to a Interceptor component. + + + + + Represents obtained just in time object. + + + + + + Resolves object referenced by this reference, optionally using provided . + If object is resolved from the kernel, the should be used to guard + against against cyclic dependencies. + + + + + + + + If the reference introduces dependency on a component, should return for that dependency, otherwise null. + + + + + + + Initializes a new instance of the class. + + The component key. + + + + Initializes a new instance of the class. + + Type of the service. + + + + Gets an for the component key. + + The component key. + The + + + + Gets an for the service. + + The service. + The + + + + Gets an for the service. + + The service type. + The + + + + Collection of + + + + + Adds the specified interceptor as the first. + + The interceptor. + + + + Adds the interceptor to the end of the interceptors list if it does not exist already. + + The interceptor reference. + + + + Adds the specified interceptor as the last. + + The interceptor. + + + + Inserts the specified interceptor at the specified index. + + The index. + The interceptor. + + + + Adds the specified item. + + The interceptor. + + + + Returns an enumerator that can iterate through a collection. + + + An + that can be used to iterate through the collection. + + + + + Gets a value indicating whether this instance has interceptors. + + + true if this instance has interceptors; otherwise, false. + + + + + Gets the number of + elements contained in the . + + + + + + Represents a collection of ordered lifecycle concerns. + + + + + Returns all concerns for the commission phase + + + + + + Returns all concerns for the decommission phase + + + + + + Gets a value indicating whether this instance has commission steps. + + + true if this instance has commission steps; otherwise, false. + + + + + Gets a value indicating whether this instance has decommission steps. + + + true if this instance has decommission steps; otherwise, false. + + + + + Represents meta information associated with a method + (not yet defined) + + + + + Initializes a new instance of the class. + + The config node. + + + + Gets the config node. + + The config node. + + + + Collection of + + + + + Gets the method info2 model. + + The method info2 model. + + + + Represents a parameter. Usually the parameter + comes from the external world, ie, an external configuration. + + + + + Initializes a new instance of the class. + + The name. + The value. + + + + Initializes a new instance of the class. + + The name. + The value. + + + + Gets the name. + + The name. + + + + Gets the value. + + The value. + + + + Gets the config value. + + The config value. + + + + Collection of + + + + + Adds the specified name. + + The name. + The value. + + + + Adds the specified name. + + The name. + The config node. + + + + Determines whether this collection contains the specified key. + + The key. + + true if yes; otherwise, false. + + + + + Adds the specified key. + + + Not implemented + + The key. + The value. + + + + Clears this instance. + + + Not implemented + + + + + Removes the specified key. + + The key. + + Not implemented + + + + + Copy the content to the specified array + + target array + target index + + Not implemented + + + + + Returns an enumerator that can iterate through a collection. + + + An + that can be used to iterate through the collection. + + + + + Gets the keys. + + The keys. + + Not implemented + + + + + Gets the values. + + The values. + + Not implemented + + + + + Gets a value indicating whether this instance is read only. + + + true if this instance is read only; otherwise, false. + + + + + Gets a value indicating whether this instance is fixed size. + + + true if this instance is fixed size; otherwise, false. + + + + + Gets the with the specified key. + + + + + + Gets the count. + + The count. + + + + Gets the sync root. + + The sync root. + + + + Gets a value indicating whether this instance is synchronized. + + + true if this instance is synchronized; otherwise, false. + + + + + Represents a property and the respective dependency. + + + + + Initializes a new instance of the class. + + The property info. + The dependency. + + + + Gets the property. + + The property. + + + + Gets the dependency. + + The dependency. + + + + Collection of + + + + + Finds a PropertySet the by PropertyInfo. + + The info. + + + + + Reference to component obtained from a container. + + + + + + Select the appropriate interceptors based on the application specific + business logic + + + + + Determine whatever the specified has interceptors. + The selector should only return true from this method if it has determined that is + a model that it would likely add interceptors to. + + The model + Whatever this selector is likely to add interceptors to the specified model + + + + Select the appropriate interceptor references. + The interceptor references aren't necessarily registered in the model.Intereceptors + + The model to select the interceptors for + The interceptors selected by previous selectors in the pipeline or if this is the first interceptor in the pipeline. + The interceptor for this model (in the current context) or a null reference + + If the selector is not interested in modifying the interceptors for this model, it + should return and the next selector in line would be executed. + If the selector wants no interceptors to be used it can either return null or empty array. + However next interceptor in line is free to override this choice. + + + + + Represents a reference to an existing object. + + + + + + Defines the contract used by the kernel + to obtain proxies for components. The implementor + must return a proxied instance that dispatch + the invocation to the registered interceptors in the model + + + + + Implementors must create a proxy based on + the information exposed by ComponentModel + + The kernel instance + The component model + The component instance to be proxy (only required in some cases) + array of parameters to the constructor (if any) + The creation context + proxy instance + + + + Implementor should check the component model + and determine if the caller must pass on the component + instance to the proxy + + The kernel instance + The component model + true if an instance must be passed to + + + + Add the selector to the list of selectors that can affect interceptor's decisions + in the container. + + + + + Determines whatever we need to create a proxy for this model + + + + + + + This is a placeholder implementation of . + + + The decision to supply no implementation for + is supported by the fact that the MicroKernel should be a thin + assembly with the minimal set of features, although extensible. + Providing the support for this interface would obligate + the user to import another assembly, even if the large majority of + simple cases, no use use of interceptors will take place. + If you want to use however, see the Windsor container. + + + + + Holds the keys used by the proxy factories. + + + + + Key used to supply custom proxy options. + + + + + Represents options to configure proxies. + + + + + Initializes a new instance of the class. + + + + + + Adds the additional interfaces to proxy. + + The interfaces. + + + + Adds the additional mix ins to integrate. + + The mix ins. + + + + Adds the additional mix in to integrate. + + The mix in. + + + + Equals the specified obj. + + The obj. + true if equal. + + + + Gets the hash code. + + + + + + Gets the additional interfaces to proxy. + + The interfaces. + + + + Determines if the proxied component can change targets. + + + + + Determines if the interface proxied component should inherit + from + + + + + Gets or sets the proxy hook. + + + + + Gets the mix ins to integrate. + + The interfaces. + + + + Determines if the proxied component uses a target. + + + + + Gets or sets the interceptor selector. + + + + + Determines if the proxied component should only include + the service interface. + + + + + Helper support for proxy configuration. + + + + + Obtains the associated with the . + + The component model. + true if the options should be created if not present. + The associated proxy options for the component model. + + + + Constructs the descriptor with name and value. + + The attribute name. + The attribute value. + + + + Constructs the descriptor with name. + + The component. + The attribute name. + + + + Builds the with value. + + The attribute value. + The + + + + Factory for creating objects. + + + + + Creates a component registration for the + + Type of the service. + The component registration. + + + + Creates a component registration for the + + Types of the service. + The component registration.B + + + + Creates a component registration for the + + Types of the service. + The component registration.B + + + + Creates a component registration for the service type. + + The service type. + The component registration. + + + + Create a component registration for an existing + + The component model. + The component registration. + + + + Determines if the component is a Castle component, that is - if it has a . + + true if the service is a Castle Component. + + This method is usually used as argument for method. + + + + + Creates a predicate to check if a component is in a namespace. + + The namespace. + true if the component type is in the namespace. + + + + Creates a predicate to check if a component is in a namespace. + + The namespace. + If set to true, will also include types from subnamespaces. + true if the component type is in the namespace. + + + + Creates a predicate to check if a component shares a namespace with another. + + The component type to test namespace against. + true if the component is in the same namespace. + + + + Creates a predicate to check if a component shares a namespace with another. + + The component type to test namespace against. + If set to true, will also include types from subnamespaces. + true if the component is in the same namespace. + + + + Creates a predicate to check if a component shares a namespace with another. + + The component type to test namespace against. + true if the component is in the same namespace. + + + + Creates a predicate to check if a component shares a namespace with another. + + The component type to test namespace against. + If set to true, will also include types from subnamespaces. + true if the component is in the same namespace. + + + + Determines if the component service is already registered. + + The kernel. + The component model. + true if the service is already registered. + + + + Creates a component registration for the service types. + + The primary service type. + The forwarded type. + The component registration. + + + + Creates a component registration for the service types. + + The primary service type. + The first forwarded type. + The second forwarded type. + The component registration. + + + + Creates a component registration for the service types. + + The primary service type. + The first forwarded type. + The second forwarded type. + The third forwarded type. + The component registration. + + + + Creates a component registration for the service types. + + The primary service type. + The first forwarded type. + The second forwarded type. + The third forwarded type. + The fourth forwarded type. + The component registration. + + + + Inserts a new named argument with given key. If an argument for this name already exists, it will be overwritten. + + + + + Inserts a new typed argument with given type. If an argument for this type already exists, it will be overwritten. + + + + + Inserts a new typed argument with given type. If an argument for this type already exists, it will be overwritten. + + + + + Inserts a set of typed arguments. Property names of the anonymous type will be used as key. + + + + + Inserts a set of typed arguments. Actual type of the arguments will be used as key. + + + + + Delegate to filter component registration. + + The kernel. + The component model. + true if accepted. + + + + Registration for a single type as a component with the kernel. + + You can create a new registration with the factory. + + The service type + + + + The contract for all registrations with the kernel. + + + + + Performs the registration in the . + + The kernel. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with an existing . + + + + + Marks the components with one or more actors. + + The component actors. + + + + + Set a custom which creates and destroys the component. + + + + + + Adds the attribute descriptor. + + The key. + The value. + + + + + Adds the descriptor. + + The descriptor. + + + + + Creates an attribute descriptor. + + The attribute key. + + + + + Apply more complex configuration to this component registration. + + The config nodes. + + + + + Apply more complex configuration to this component registration. + + The configuration . + + + + + Obsolete, use instead. + + The dependencies. + + + + + Obsolete, use instead. + + The dependencies. + + + + + Obsolete, use instead. + + The dependencies. + + + + + Specify custom dependencies using or . + + You can pass s to specify the components + this component should be resolved with. + + The dependencies. + + + + + Uses a dictionary of key/value pairs, to specify custom dependencies. + + Use to specify the components + this component should be resolved with. + + The dependencies. + + + + + Uses an (anonymous) object as a dictionary, to specify custom dependencies. + + Use to specify the components + this component should be resolved with. + + The dependencies. + + + + + Allows custom dependencies to by defined dyncamically. + + The delegate used for providing dynamic parameters. + + + + + Allows custom dependencies to by defined dynamically with releasing capability. + + The delegate used for providing dynamic parameters. + + + + + Allows custom dependencies to by defined dynamically with releasing capability. + + The delegate used for providing dynamic parameters. + + + Use when resolving components from in order to detect cycles. + + + + + Sets for this component. + + The extended properties. + + + + + Sets for this component. + + The extendend properties as key/value pairs. + + + + + Registers the service types on behalf of this component. + + The types to forward. + + + + + Registers the service types on behalf of this component. + + The forwarded type. + The component registration. + + + + Registers the service types on behalf of this component. + + The first forwarded type. + The second forwarded type. + The component registration. + + + + Registers the service types on behalf of this component. + + The first forwarded type. + The second forwarded type. + The third forwarded type. + The component registration. + + + + Registers the service types on behalf of this component. + + The first forwarded type. + The second forwarded type. + The third forwarded type. + The fourth forwarded type. + The component registration. + + + + Registers the service types on behalf of this component. + + The types to forward. + + + + + Assigns a conditional predication which must be satisfied. + + The component will only be registered into the kernel + if this predicate is satisfied (or not assigned at all). + + The predicate to satisfy. + + + + + Sets the concrete type that implements the service to . + + If not set, the will be used as the implementation for this component. + + The type that is the implementation for the service. + + + + + Sets the concrete type that implements the service to . + + If not set, the will be used as the implementation for this component. + + The type that is the implementation for the service. + + + + + Assigns an existing instance as the component for this registration. + + The component instance. + + + + + Set the interceptors for this component. + + The interceptors. + + + + + Set the interceptors for this component. + + The interceptors. + + + + + Set the interceptor for this component. + + + + + + Set the interceptor for this component. + + + + + + Set the interceptor for this component. + + + + + + Change the name of this registration. + This will be the key for the component in the kernel. + + If not set, the of the + will be used as the key to register the component. + + The name of this registration. + + + + + Stores a set of which will be invoked when the component + is created and before it's returned from the container. + + A set of actions to be executed right after the component is created and before it's returned from the container. + + + + With the overwrite. + + + + + + Set configuration parameters with string or values. + + The parameters. + + + + + Sets the interceptor selector for this component. + + + + + + + Sets the interceptor selector for this component. + + + + + + + Override (some of) the services that this component needs. + Use to create an override. + + Each key represents the service dependency of this component, for example the name of a constructor argument or a property. + The corresponding value is the key of an other component registered to the kernel, and is used to resolve the dependency. + + To specify dependencies which are not services, use + + The service overrides. + + + + + Override (some of) the services that this component needs, using a dictionary. + + Each key represents the service dependency of this component, for example the name of a constructor argument or a property. + The corresponding value is the key of an other component registered to the kernel, and is used to resolve the dependency. + + To specify dependencies which are not services, use + + The service overrides. + + + + + Override (some of) the services that this component needs, using an (anonymous) object as a dictionary. + + Each key represents the service dependency of this component, for example the name of a constructor argument or a property. + The corresponding value is the key of an other component registered to the kernel, and is used to resolve the dependency. + + To specify dependencies which are not services, use + + The service overrides. + + + + + Assigns a conditional predication which must not be satisfied. + + The component will only be registered into the kernel + if this predicate is not satisfied (or not assigned at all). + + The predicate not to satisfy. + + + + + Uses a factory to instantiate the component + + Factory type. This factory has to be registered in the kernel. + Implementation type. + Factory invocation + + + + + Uses a factory method to instantiate the component. + + Implementation type + Factory method + + + + + Uses a factory method to instantiate the component. + + Implementation type + Factory method + + + + + Uses a factory method to instantiate the component. + + Implementation type + Factory method + + + + + Uses a factory method to instantiate the component. + + Implementation type + Factory method + + + + + Registers this component with the . + + The kernel. + + + + Gets the forwarded service types on behalf of this component. + + Add more types to forward using . + + The types of the forwarded services. + + + + The concrete type that implements the service. + + To set the implementation, use . + + The implementation of the service. + + + + Set the lifestyle of this component. + For example singleton and transient (also known as 'factory'). + + The with lifestyle. + + + + The name of the component. Will become the key for the component in the kernel. + + To set the name, use . + + If not set, the of the + will be used as the key to register the component. + + The name. + + + + Set proxy for this component. + + The proxy. + + + + The type of the service, the same as . + + This is the first type passed to . + + The type of the service. + + + + A non-generic . + + You can create a new registration with the factory. + + + + + Represents a configuration child. + + + + + Applies the configuration node. + + The configuration. + + + + Represents a configuration attribute. + + + + + Applies the configuration node. + + The configuration. + + + + Create a with name. + + The attribute name. + The new + + + + Represents a named attribute. + + + + + Builds the with name/value. + + The attribute value. + The new + + + + Builds the with name/value. + + The attribute value. + The new + + + + Represents a configuration child. + + + + + Create a with name. + + The child name. + The new + + + + Represents a named child. + + + + + Builds the with name/value. + + The child value. + The new + + + + Builds the with name/value. + + The child value. + The new + + + + Builds the with name/config. + + The child configuration. + The new + + + + Builds the with name/config. + + The child nodes. + The new + + + + Applies the configuration node. + + The configuration. + + + + Represents a simple child node. + + + + + Applies the configuration node. + + The configuration. + + + + Represents a complex child node. + + + + + Applies the configuration node. + + The configuration. + + + + Represents a compound child node. + + + + + Applies the configuration node. + + The configuration. + + + + The contract to install components in the container. + + + + + Performs the installation in the . + + The container. + The configuration store. + + + + Adds the actions to ExtendedProperties. + + + + + + Sets the lifestyle to the specified . + + The type. + + + + + Assign a custom lifestyle type, that implements . + + Type of the custom lifestyle. + + + + + Assign a custom lifestyle type, that implements . + + The type of the custom lifestyle + + + + + Represents a configuration parameter. + + + + + Create a with key. + + The parameter key. + The new + + + + Gets the parameter key. + + + + + Gets the parameter value. + + + + + Gets the parameter configuration. + + + + + Represents a parameter key. + + + + + Builds the with key/value. + + The parameter value. + The new + + + + Builds the with key/config. + + The parameter configuration. + The new + + + + The parameter key name. + + + + + Represents a key/value pair. + + + + + Create a with key. + + The property key. + The new + + + + Create a with key. + + The property key. + The new + + + + Create a with key. + + The property key. + The new + + + + Gets the property key. + + + + + Gets the property value. + + + + + Represents a property key. + + + + + Builds the with key/value. + + The property value. + The new + + + + Builds a service override using other component registered with given as value for dependency with given . + + + + + + + Builds a service override using other component registered with given and no explicit name, as value for dependency with given . + + + + + + Builds a service override using other component registered with given and no explicit name, as value for dependency with given . + + + + + + The property key key. + + + + + Represents a service override. + + + + + Creates a with key. + + The service override key. + The new + + + + Creates a with key. + + The service override key. + The new + + + + Creates a with key. + + The service override key. + The new + + + + Gets the optional value type specifier. + + + + + Represents a service override key. + + + + + Builds the with key/value. + + The service override value. + The new + + + + Builds the with key/values. + + The service override values. + The new + + + + Builds the with key/values. + + The service override values. + The new + The value type. + + + + Builds the with key/values. + + The service override values. + The new + + + + Builds the with key/values. + + The service override values. + The new + The value type. + + + + Describes a set of components to register in the kernel. + + + + + Describes all the types based on basedOn. + + The base type. + + + + + Describes all the types based on type T. + + The base type. + + + + + Describes any types that are supplied. + + + + + + Prepares to register types from an assembly. + + The assembly name. + The corresponding + + + + Prepares to register types from an assembly. + + The assembly. + The corresponding + + + + Prepares to register types from an assembly containing the type. + + The type belonging to the assembly. + The corresponding + + + + Prepares to register types from an assembly containing the type. + + The type belonging to the assembly. + The corresponding + + + + Prepares to register types from the assembly containing the code invoking this method. + + The corresponding + + + + Prepares to register types from assemblies found in a given directory that meet additional optional restrictions. + + + + + + + Prepares to register types from a list of types. + + The list of types. + The corresponding + + + + Prepares to register types from a list of types. + + The list of types. + The corresponding + + + + Prepares to register types from a list of types. + + The list of types. + The corresponding + + + + Describes a related group of components to register in the kernel. + + + + + Prepares to register types from an assembly. + + The assembly name. + The corresponding + + + + Prepares to register types from an assembly. + + The assembly. + The corresponding + + + + Prepares to register types from a list of types. + + The list of types. + The corresponding + + + + Prepares to register types from a list of types. + + The list of types. + The corresponding + + + + Prepares to register types from a list of types. + + The list of types. + The corresponding + + + + Describes a configuration. + + + + + Initializes a new instance of the ConfigureDescriptor. + + The + The configuration action. + + + + Initializes a new instance of the ConfigureDescriptor. + + The + The base type to match. + The configuration action. + + + + Allows customized configurations of each matching type. + + The configuration action. + + + + + Allows customized configurations of each matching type. + + The configuration action. + + + + + Allows customized configurations of each matching type that is + assignable to . + + The type assignable from. + The configuration action. + + + + + Allows customized configurations of each matching type that is + assignable to . + + The type assignable from. + The configuration action. + + + + + Performs the component configuration. + + The component registration. + + + + Selects a set of types from an assembly. + + + + + Describes the source of types to register. + + + + + Allows a type to be registered multiple times. + + + + + Returns the descriptor for accepting a type. + + The base type. + The descriptor for the type. + + + + Returns the descriptor for accepting a type. + + The base type. + The descriptor for the type. + + + + Returns the descriptor for accepting any type from given solutions. + + + + + + Returns the descriptor for accepting a type based on a condition. + + The accepting condition. + The descriptor for the type. + + + + Selects an existing set of types to register. + + + + + Describes how to select a types service. + + + + + Uses the base type matched on. + + + + + + Uses the type itself. + + + + + + Uses all interfaces implemented by the type (or its base types) as well as their base interfaces. + + + + + + Uses all interfaces that have names matched by implementation type name. + Matches Foo to IFoo, SuperFooExtended to IFoo and IFooExtended etc + + + + + + Uses the first interface of a type. This method has non-deterministic behavior when type implements more than one interface! + + + + + + Uses to lookup the sub interface. + For example: if you have IService and + IProductService : ISomeInterface, IService, ISomeOtherInterface. + When you call FromInterface(typeof(IService)) then IProductService + will be used. Useful when you want to register _all_ your services + and but not want to specify all of them. + + + + + + + Uses base type to lookup the sub interface. + + + + + + Assigns a custom service selection strategy. + + + + + + + Assigns the supplied service types. + + + + + + + This is a workaround for a CLR bug in + which GetInterfaces() returns interfaces + with no implementations. + + Type of the service. + + + + + Delegate for custom registration configuration. + + The component registration. + Not used. + + + + Describes how to register a group of related types. + + + + + Initializes a new instance of the BasedOnDescriptor. + + + + + Allows a type to be registered multiple times. + + + + + Returns the descriptor for accepting a new type. + + The base type. + The descriptor for the type. + + + + Returns the descriptor for accepting a new type. + + The base type. + The descriptor for the type. + + + + Allows customized configurations of each matching type. + + The configuration action. + + + + + Allows customized configurations of each matching type. + + The configuration action. + + + + + Allows customized configurations of each matching type that is + assignable to + + . + + The type assignable from. + The configuration action. + + + + + Allows customized configurations of each matching type that is + assignable to + + . + + The type assignable from. + The configuration action. + + + + + Assigns a conditional predication which must be satisfied. + + The predicate to satisfy. + + + + + Assigns a conditional predication which must not be satisfied. + + The predicate not to satisify. + + + + + Returns the descriptor for accepting a type based on a condition. + + The accepting condition. + The descriptor for the type. + + + + Gets the type all types must be based on. + + + + + Gets the service descriptor. + + + + + Policy managing lifetime of components, and in particular their release process. + + + + + Only tracks components that have decommission steps + registered or have pooled lifestyle. + + + + + No tracking of component instances are made. + + + + + Default implementation for . + This implementation is quite simple, but still should be useful + for 99% of situations. + + + + + Implementors should use a strategy to obtain + valid references to properties and/or services + requested in the dependency model. + + + + + This method is called with a delegate for firing the + IKernelEvents.DependencyResolving event. + + kernel + The delegate used to fire the event + + + + Registers a sub resolver instance + + The subresolver instance + + + + Unregisters a sub resolver instance previously registered + + The subresolver instance + + + + Initializes this instance with the specified dependency delegate. + + kernel + The dependency delegate. + + + + Registers a sub resolver instance + + The subresolver instance + + + + Unregisters a sub resolver instance previously registered + + The subresolver instance + + + + Returns true if the resolver is able to satisfy the specified dependency. + + Creation context, which is a resolver itself + Parent resolver + Model of the component that is requesting the dependency + The dependency model + + true + if the dependency can be satisfied + + + + Try to resolve the dependency by checking the parameters in + the model or checking the Kernel for the requested service. + + + The dependency resolver has the following precedence order: + + + The dependency is checked within the + + + + + The dependency is checked within the + + instance for the component + + + The dependency is checked within the registered + + s + + + Finally the resolver tries the normal flow + which is using the configuration + or other component to satisfy the dependency + + + + Creation context, which is a resolver itself + Parent resolver + Model of the component that is requesting the dependency + The dependency model + The dependency resolved value or null + + + + Extracts the component name from the a ref strings which is + ${something} + + + + + + + + This method rebuild the context for the parameter type. + Naive implementation. + + + + + Summary description for DependencyResolverException. + + + + + Initializes a new instance of the class. + + The message. + The inner exception. + + + + Initializes a new instance of the class. + + The message. + + + + Initializes a new instance of the class. + + The object that holds the serialized object data. + The contextual information about the source or destination. + + + + Handle dependencies of services in the format of typed arrays. + + + This is a complimentary implementation + that is capable of satisfying dependencies of services as typed arrays. + + Note that it will take precedence over service override for arrays defined + on the configuration. + + + + In order to install the resolver: + + var kernel = new DefaultKernel(); + kernel.Resolver.AddSubResolver(new ArrayResolver(kernel)); + + + + To use it, assuming that IService is on the container: + + + + public class Component + { + public Component(IService[] services) + { + } + } + + + + + + More generic alternative to and . + It supports arrays as well as any generic interface type assignable from arrays. + + + The collection instance that is provided is read only, even for interfaces like + + + + + Handle dependencies of services in the format of generic IList. + + + This is a complimentary implementation + that is capable of satisfying dependencies of services generic IList. + + Note that it will take precedence over service override for lists defined + on the configuration. + + + + In order to install the resolver: + + var kernel = new DefaultKernel(); + kernel.Resolver.AddSubResolver(new ListResolver(kernel)); + + + + To use it, assuming that IService is on the container: + + + + public class Component + { + public Component(IList<IService> services) + { + } + } + + + + + + A subsystem is used by the MicroKernel to deal + with a specific concern. + + + + + Initializes the subsystem + + + + + + Should perform the termination + of the subsystem instance. + + + + + This implementation of + does not try to obtain an external configuration by any means. + Its only purpose is to serve as a base class for subclasses + that might obtain the configuration node from anywhere. + + + + + The contract used by the kernel to obtain + external configuration for the components and + facilities. + + + + + Associates a configuration node with a facility key + + item key + Configuration node + + + + Associates a configuration node with a component key + + item key + Configuration node + + + + Associates a configuration node with a bootstrap component key + + item key + Configuration node + + + + Adds the child container configuration. + + The container's name. + The config. + + + + Returns the configuration node associated with + the specified child container key. Should return null + if no association exists. + + item key + + + + + Returns the configuration node associated with + the specified facility key. Should return null + if no association exists. + + item key + + + + + Returns the configuration node associated with + the specified component key. Should return null + if no association exists. + + item key + + + + + Returns the configuration node associated with + the specified component key. Should return null + if no association exists. + + item key + + + + + Returns all configuration nodes for facilities + + + + + + Returns all configuration nodes for components + + + + + + Returns all configuration nodes for installers + + + + + + Returns all configuration nodes for bootstrap components + + + + + + Gets the child containers configuration nodes. + + + + + + + + + + + + + + Initializes a new instance of the class. + + + + + Associates a configuration node with a facility key + + item key + Configuration node + + + + Associates a configuration node with a component key + + item key + Configuration node + + + + Associates a configuration node with a bootstrap component key + + + + + Adds the child container configuration. + + The key. + The config. + + + + Returns the configuration node associated with + the specified facility key. Should return null + if no association exists. + + item key + + + + + Returns the configuration node associated with + the specified child container key. Should return null + if no association exists. + + item key + + + + + Returns the configuration node associated with + the specified component key. Should return null + if no association exists. + + item key + + + + + Returns the configuration node associated with + the specified component key. Should return null + if no association exists. + + + + + + + Returns all configuration nodes for facilities + + + + + + Returns all configuration nodes for bootstrap components + + + + + + Returns all configuration nodes for child containers + + + + + + Returns all configuration nodes for components + + + + + + Base implementation of + + + + + Implements a conversion logic to a type of a + set of types. + + + + + Returns true if this instance of ITypeConverter + is able to handle the specified type. + + + + + + + Returns true if this instance of ITypeConverter + is able to handle the specified type with the specified + configuration + + + + + + + + Should perform the conversion from the + string representation specified to the type + specified. + + + + + + + + Should perform the conversion from the + configuration node specified to the type + specified. + + + + + + + + Returns true if this instance of ITypeConverter + is able to handle the specified type with the specified + configuration + + + + + + The default behavior is to just pass it to the normal CanHadnleType + peeking into the configuration is used for some advanced functionality + + + + + Summary description for ConverterException. + + + + + Initializes a new instance of the class. + + The message. + + + + Initializes a new instance of the class. + + The message. + The inner exception. + + + + Initializes a new instance of the class. + + The object that holds the serialized object data. + The contextual information about the source or destination. + + + + Looks for a on the type to be converted. + If found, the TypeConverter defined by the attribute is used to perform the conversion. + + + + + Marker interface that signals that a converter + depends on IKernel to be able to perform + the conversion. + + + + + Attempts to utilize an existing for conversion + + + + + Creates the target type instance. + + The type. + The configuration. + + + + + Chooses the first non default constructor. Throws an exception if more than + one non default constructor is found + + + The chosen constructor, or null if none was found + + + + Converts the constructor parameters. + + The constructor. + The configuration. + + + + + Converts the property values. + + The instance. + The type. + The configuration. + + + + Finds the child (case insensitive). + + The config. + The name. + + + + + Gets the conversion manager. + + The conversion manager. + + + + Converts a string representation to an enum value + + + + + Initializes a new instance of the class. + + + + + This interface is needed because we want to isolate ourself from + the generic parameters, so we can work type safe inside the implementations, + and still call from non generic types outside. + + + + + Implements all standard conversions. + + + + + Convert a type name to a Type instance. + + + + + Declares a type as being convertible by a and optionally defines the converter to be used + + + + + Defines the to be used to convert the type + + + + + Defines the to be used to convert the type + + + + + + Composition of all available conversion managers + + + + + Establish a composition interface and a subsystem. + Implementors should delegate the conversion to + a instance of a type converter. + + + + + Register a type converter instance. + + + + + + Method finds the next biggest node + It assumes Add puts lesser nodes on the right + + + + Node's left + + + Node's right + + + Node's parent + + + DA Linked List + + + + Creates a ComponentName using a name pattern like + "service:key=value,key2=value2" + + Complete name + + + + Creates a ComponentName with specified service and + properties. + + Service name + Property list. + + + + Serialization constructor. + + + + + + + Parses the full name extracting the service and properties. + + Full name. + + + + Sets up the service. Can be empty but can't be null. + + + + + + Parses and validate a properties list string like + "key=value,key2=value2" and so on. + + Property list. + + + + Validates a properties IDictionary. + + Property list. + + + + Default implementation. + Keeps services map as a simple hash table. + Keeps key map as a list dictionary to maintain order. + Does not support a query string. + + + + + Contract for SubSystem that wishes to keep and coordinate + component registration. + + + + + Register a new component resolver that can take part in the decision + making about which handler to resolve + + + + + Returns true if there is a component registered + for the specified key + + + + + + + Returns true if there is a component registered + for the specified service + + + + + + + Return s where components are compatible + with the specified service. + + + + + + + Returns the associated with + the specified key. + + + + + + + Returns the associated with + the specified service. + + + + + Returns the associated with + the specified key with the service type. + + It is expected that this will be used mainly to resolve a generic service + by its key. + + + + + + Returns an array of that + satisfies the specified query. + + + + + + + Returns an array of associated with + the specified service. + + + + + + + Returns all registered. + + + + + + List of handler by key + + + + + List of handler by service + + + + + Implementors should register the key and service pointing + to the specified handler + + + + + + + Unregister the handler by the given key + + + + + + Unregister the handler by the given service + + + + + + Returns the number of components registered. + + + + + Associates a with + the specified service + + + + + Associates a with + the specified key + + + + + Map(String, IHandler) to map component keys + to + Items in this dictionary are sorted in insertion order. + + + + + Map(Type, IHandler) to map a service + to . + If there is more than a single service of the type, only the first + registered services is stored in this dictionary. + It serve as a fast lookup for the common case of having a single handler for + a type. + + + + + Initializes a new instance of the class. + + + + + Implementors of this interface allow to extend the way the container perform + component resolution based on some application specific business logic. + + + This is the sibling interface to . + This is dealing strictly with root components, while the is dealing with + dependent components. + + + + + Whatever the selector has an opinion about resolving a component with the + specified service and key. + + The service key - can be null + The service interface that we want to resolve + + + + Select the appropriate handler from the list of defined handlers. + The returned handler should be a member from the array. + + The service key - can be null + The service interface that we want to resolve + The defined handlers + The selected handler, or null + + + + When requesting a component by service, KeySearchNamingSubSystem first + determines if more than one component has been registered for that service. + If not, Default resolution occurs. If so, all of the registered keys for + that service are processed through the provided Predicate to determine which + key to use for service resolution. If no Predicate matches, the default + resolution occurs. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + The key predicate. + + + + Registers the given handler with the give key. + + The key. + The handler. + + + + Unregisters the handler associated with the given key + + The key. + + + + Unregisters the handler associated with the given service + + The service. + + + + Executes the Predicate against all keys for the registered service to + determine which component to return. + + The service. + + + + + Alternative implementation. + Extends the default implementation replacing the + key support with a more complete ComponentName. Supports + queries. + + + The user must register components using the following construction + + service:properties + + Where properties is a list of key value pairs (comma separated). Example: + + protocol:secure=true,version=1.2 + + The user can then query for components using the same construction: + + protocol:secure=true + + Or to return all: + + protocol:* + + + + + + Pendent + + + + + An implementation of a should + be able to return instances of + for a given resource identifier. + + + + + Holds the keys used by Kernel to register/request + a subsystem. + + + + + Key used for the configuration store subsystem + + + + + Key used for the conversion manager + + + + + Key used for the naming subsystem + + + + + Key used for the resource subsystem + + + + + Compares if the reference of two objects are equals. + + + + + Summary description for ReferenceExpressionUtil. + + + + + Integrates the to the System.ComponentModel + and System.ComponentMode.Design infrastructure. + + + + + + + + This interface should be implemented by classes + that are available in a bigger context, exposing + the container to different areas in the same application. + + For example, in Web application, the (global) HttpApplication + subclasses should implement this interface to expose + the configured container + + + + + + Custom activator to create the instance on demand. + + + + + Implementation of . + Do not support configuration inheritance. + + + + + Interpreter of a specific language to describe + configuration nodes in a hierarchical manner. + + + + + Should obtain the contents from the resource, + interpret it and populate the + accordingly. + + + + + + + Gets or sets the name of the environment. + + The name of the environment. + + + + Exposes the reference to + which the interpreter is likely to hold + + + + + Provides common methods for those who wants + to implement + + + + + Should obtain the contents from the resource, + interpret it and populate the + accordingly. + + + + + + + Exposes the reference to + which the interpreter is likely to hold + + + + + + Gets or sets the name of the environment. + + The name of the environment. + + + + Reads the configuration from a XmlFile. Sample structure: + + <configuration> + <facilities> + <facility id="myfacility"> + + </facility> + </facilities> + + <components> + <component id="component1"> + + </component> + </components> + </configuration> + + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + The filename. + + + + Initializes a new instance of the class. + + The source. + + + + Gets or sets the kernel. + + The kernel. + + + + Initializes a new instance of the class. + + Name of the environment. + + + + Initializes a new instance of the class. + + Name of the environment. + The resource sub system. + + + + Processes the element. + + The element. + + + + + Processes the element. + + The element. + + + + + Make a shallow copy of the nodeList. + + The nodeList to be copied. + + + + + Accepts the specified node. + Check if node has the same name as the processor and the node.NodeType + is in the AcceptNodeTypes List + + The node. + + + + + Convert and return child parameter into an XmlElement + An exception will be throw in case the child node cannot be converted + + Parent node + Node to be converted + child node as XmlElement + + + + + + + + + + + + attributeValue + + propertyValue + + + + + + + Processes the specified node list. + + The node list. + The engine. + + + + Processes element attributes. + if the attribute is include will append to the element + all contents from the file. + if the attribute has a property reference the reference will be + expanded + + The element. + + + + + Properties names can contain a-zA-Z0-9_. + i.e. #!{ my_node_name } || #{ my.node.name } + spaces are trimmed + + + + + Processes the string. + + The node. + The value. + The context. + + + + Accepts the specified node. + Check if node has the same name as the processor and the node.NodeType + is in the AcceptNodeTypes List + NOTE: since the BatchRegistrationFacility already uses an include + element we will distinguish between both by looking for the presence of an uri attribute + we should revisit this later by using xml-namespaces + + The node. + + + + + + + + + + + + + attributeValue + + propertyValue + + + + + + + Pendent + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + Name of the environment. + The resource sub system. + + + + Initializes a new instance of the class. + + + + + Gets the environment information (name). Implementors should + use to define their environments and how those affect the configuration. + + + + + Gets the name of the environment. + + + + + + Installs all the components from the App.Config file. + + + + + + Installs all the component from the xml configuration file. + + The xml configuration file. + + + + + Installs all the component from the xml configuration. + + The xml configuration resource. + + + + + Delegate to provide environment name. + + The environment name. + + + + Initializes a new instance of the ConfigurationInstaller class. + + + + + Sets the configuration environment name. + + The environment name. + + + + + Set the configuration environment strategy. + + The environment strategy. + + + + + Default implementation. + + + + + Installs the components and facilities based on the + information on the configuration store. + + + + + Perform installation. + + Target container + Configuration store + + + + Perform installation. + + Target container + Configuration store + + + + Scans the assembly containing specified type for types implementing , instantiates them and returns so that can install them. + + + + + + Scans the assembly containing specified type for types implementing , instantiates using given and returns so that can install them. + + + + + + Scans the assembly containing specified type for types implementing , instantiates them and returns so that can install them. + + + + + + Scans the assembly containing specified type for types implementing , instantiates using given and returns so that can install them. + + + + + + Scans the specified assembly with specified name for types implementing , instantiates them and returns so that can install them. + + + + + + Scans the specified assembly with specified name for types implementing , instantiates using given and returns so that can install them. + + + + + + Scans the assembly with specified name for types implementing , instantiates them and returns so that can install them. + + + + + + Scans the assembly with specified name for types implementing , instantiates using given and returns so that can install them. + + + + + + Scans assembly that contains code calling this method for types implementing , + instantiates them and returns so that can install them. + + + + + + Scans assembly that contains code calling this method for types implementing , instantiates using given and returns so that can install them. + + + + + + Scans assemblies in directory specified by for types implementing , instantiates and returns so that can install them. + + + + + + + Scans assemblies in directory specified by for types implementing , instantiates using given and returns so that can install them. + + + + + + + + Helper class used by to filter/order and instantiate implementations + + + + + Performs custom instantiation of given + + + Default implementation uses public parameterless constructor to create the instance. + + + + + Performs custom filtering/ordering of given set of types. + + Set of concrete class types implementing interface. + Transformed . + Default implementation simply returns types passed into it. + + + + The IWindsorContainer interface exposes all the + functionality the Windsor implements. + + + + + Registers a subcontainer. The components exposed + by this container will be accessible from subcontainers. + + + + + + Registers a facility within the container. + + The key by which the gets indexed. + The to add to the container. + + + + Creates and adds an facility to the container. + + The facility type. + + + + + + Creates and adds an facility to the container. + + The facility type. + + The callback for creation. + + + + + Creates and adds an facility to the container. + + The facility type. + + The callback for creation. + + + + + Creates and adds an facility to the container. + + The facility type. + + + + + Creates and adds an facility to the container. + + The facility type. + The callback for creation. + + + + + Creates and adds an facility to the container. + + The facility type. + The callback for creation. + + + + + Gets a child container instance by name. + + The container's name. + The child container instance or null + + + + Installs the components provided by the s + with the . + The component installers. + The container. + + + + + Registers the components provided by the s + with the . + + Create a new registration using .For() or . + + + + container.Register(Component.For<IService>().ImplementedBy<DefaultService>()); + + + The component registrations. + The container. + + + + Releases a component instance + + + + + + Remove a child container + + + + + + Returns a component instance by the key + + + + + + + + Returns a component instance by the key + + + + + + + + Returns a component instance by the key + + + + + + + + Returns a component instance by the service + + + + + + + Returns a component instance by the service + + + + + + + + Returns a component instance by the service + + + + + + + + Returns a component instance by the service + + Service type + The component instance + + + + Returns a component instance by the service + + Service type + + The component instance + + + + Returns a component instance by the service + + Service type + + The component instance + + + + Returns a component instance by the key + + Component's key + Service type + The Component instance + + + + Returns a component instance by the key + + Service type + Component's key + + The Component instance + + + + Returns a component instance by the key + + Service type + Component's key + + The Component instance + + + + Returns a component instance by the key + + + + + + + + + Returns a component instance by the key + + + + + + + + + Resolve all valid components that match this type. + + The service type + + + + Resolve all valid components that match this service + the service to match + + + + + Resolve all valid components that match this service + the service to match + Arguments to resolve the service + + + + + Resolve all valid components that match this service + the service to match + Arguments to resolve the service + + + + + Resolve all valid components that match this type. + The service type + Arguments to resolve the service + + + + + Resolve all valid components that match this type. + The service type + Arguments to resolve the service + + + + + Returns the inner instance of the MicroKernel + + + + + Gets the container's name + + + Only useful when child containers are being used + + The container's name. + + + + Gets or sets the parent container if this instance + is a sub container. + + + + + Obtains the interceptors associated with the component. + + The kernel instance + The component model + The creation context + interceptors array + + + + This implementation of relies + on DynamicProxy to expose proxy capabilities. + + + Note that only virtual methods can be intercepted in a + concrete class. However, if the component + was registered with a service interface, we proxy + the interface and the methods don't need to be virtual, + + + + + Constructs a DefaultProxyFactory + + + + + Creates the proxy for the supplied component. + + The kernel. + The target. + The model. + The constructor arguments. + The creation context + The component proxy. + + + + Determines if the component requires a target instance for proxying. + + The kernel. + The model. + true if an instance is required. + + + + Implementation of + which delegates to implementation. + + + + + Constructs a container without any external + configuration reference + + + + + Constructs a container using the specified + implementation. + + The instance of an implementation. + + + + Constructs a container using the specified + implementation. + + The instance of an implementation. + + + + Initializes a new instance of the class. + + The interpreter. + The environment info. + + + + Initializes a new instance of the class using a + xml file to configure it. + + Equivalent to the use of new WindsorContainer(new XmlInterpreter(xmlFile)) + + + The XML file. + + + + Constructs a container using the specified + implementation. Rarely used. + + + This constructs sets the Kernel.ProxyFactory property to + Proxy.DefaultProxyFactory + + Kernel instance + Installer instance + + + + Constructs a container using the specified + implementation. Rarely used. + + + This constructs sets the Kernel.ProxyFactory property to + Proxy.DefaultProxyFactory + + Container's name + Kernel instance + Installer instance + + + + Constructs with a given . + + A instance of an . + + + + Constructs a container assigning a parent container + before starting the dependency resolution. + + The instance of an + The instance of an implementation + + + + Initializes a new instance of the class. + + The container's name. + The parent. + The interpreter. + + + + Executes Dispose on underlying + + + + + Gets the service object of the specified type. + + + A service object of type serviceType. + + An object that specifies the type of service object to get. + + + + Gets the service object of the specified type. + + + A service object of type serviceType. + + + + + Registers a subcontainer. The components exposed + by this container will be accessible from subcontainers. + + + + + + Registers a facility within the kernel. + + + + + + + Creates and adds an facility to the container. + + The facility type. + + + + + + Creates and adds an facility to the container. + + The facility type. + + The callback for creation. + + + + + Creates and adds an facility to the container. + + The facility type. + + The callback for creation. + + + + + Creates and adds an facility to the container. + + The facility type. + + + + + Creates and adds an facility to the container. + + The facility type. + The callback for creation. + + + + + Creates and adds an facility to the container. + + The facility type. + The callback for creation. + + + + + Gets a child container instance by name. + + The container's name. + The child container instance or null + + + + Installs the components provided by the s + with the . + The component installers. + The container. + + + + + Registers the components described by the s + with the . + The component registrations. + The container. + + + + + Releases a component instance + + + + + + Removes (unregisters) a subcontainer. The components exposed by this container + will no longer be accessible to the child container. + + + + + + Returns a component instance by the service + + + + + + + + Returns a component instance by the service + + + + + + + + Returns a component instance by the key + + + + + + + + Returns a component instance by the key + + + + + + + + Returns a component instance by the service + + + + + + + Returns a component instance by the key + + + + + + + + Returns a component instance by the key + + + + + + + + + Returns a component instance by the key + + + + + + + + + Returns a component instance by the service + + + + + + + + Returns a component instance by the service + + + + + + + + Returns a component instance by the key + + + + + + + + Returns a component instance by the key + + + + + + + + Returns a component instance by the service + + + + + + + Returns a component instance by the key + + + + + + + Resolve all valid components that match this type. + + The service type + + + + Resolve all valid components that match this type. + The service type + Arguments to resolve the service + + + + + Resolve all valid components that match this type. + The service type + Arguments to resolve the service + + + + + Returns the inner instance of the MicroKernel + + + + + Gets the container's name + + + Only useful when child containers are being used + + The container's name. + + + + Gets or sets the parent container if this instance + is a sub container. + + + + + Implementation of that assumes ownership of the + wrapped . If this adapter is disposed, the underlying + is diposed as well. + + + + + Implementation of that does not assume ownership of the + wrapped . + + + + + Constructs an initial ContainerWrapper. + + The to adapt. + + + + Constructs an initial ContainerWrapper. + + The to adapt. + The parent . + + + + Adds the specified to the at the end of the list. + + The to add. + + + + Adds the specified to the at the end of the list, + and assigns a name to the component. + + The to add. + The unique, case-insensitive name to assign to the component, or null. + + + + Removes a component from the . + + The to remove + + + + Gets the service object of the specified type. + + The type of service. + An object implementing service, or null. + + + + Adds the specified service to the service container. + + The type of service to add. + The instance of the service to add. + + + + Adds the specified service to the service container. + + The type of service to add. + A callback object that is used to create the service. + + + + Adds the specified service to the service container, and optionally + promotes the service to any parent service containers. + + The type of service to add. + The instance of the service to add. + true to promote this request to any parent service containers. + + + + Adds the specified service to the service container, and optionally + promotes the service to parent service containers. + + The type of service to add. + A callback object that is used to create the service. + true to promote this request to any parent service containers. + + + + Removes the specified service type from the service container. + + The type of service to remove. + + + + Removes the specified service type from the service container, + and optionally promotes the service to parent service containers. + + The type of service to remove. + true to promote this request to any parent service containers. + + + + Determines if the service type represents an intrinsic service. + + The type of service to remove. + true if the service type is an intrinsic service. + + + + Determines if the specified service type exists in the service container. + + The type of service to remove. + true if the service type exists. + + + + Releases the resources used by the component. + + + + + Releases the resources used by the component. + + true if disposing. + + + + Gets or sets the associated with the . + + + + + Event that notifies the disposal of the . + + + + + Gets all the components in the . + + + + + Gets the adapted + + + + + Constructs a default ContainerAdapter. + + + + + Constructs a chained ContainerAdapter. + + The parent . + + + + Constructs an initial ContainerAdapter. + + The to adapt. + + + + Constructs an initial ContainerAdapter. + + The to adapt. + The parent . + +
+
diff -r 000000000000 -r f990fcb411a9 Redist/Castle/Castle.Windsor.dll Binary file Redist/Castle/Castle.Windsor.dll has changed diff -r 000000000000 -r f990fcb411a9 Redist/IBM/IBM.Data.DB2.dll Binary file Redist/IBM/IBM.Data.DB2.dll has changed diff -r 000000000000 -r f990fcb411a9 Redist/IBM/IBM.Data.Informix.dll Binary file Redist/IBM/IBM.Data.Informix.dll has changed diff -r 000000000000 -r f990fcb411a9 Redist/Sybase/Sybase.AdoNet2.AseClient.dll Binary file Redist/Sybase/Sybase.AdoNet2.AseClient.dll has changed diff -r 000000000000 -r f990fcb411a9 Redist/Sybase/sybdrvado20.dll Binary file Redist/Sybase/sybdrvado20.dll has changed diff -r 000000000000 -r f990fcb411a9 Snapshot.cmd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Snapshot.cmd Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1 @@ +powershell -File Snapshot.ps1 diff -r 000000000000 -r f990fcb411a9 Snapshot.ps1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Snapshot.ps1 Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,125 @@ +git archive --format=zip -o C:\Temp\BLToolkitSnapshot\bltoolkit_dev.zip master + +$revision = 0 + +git rev-list master | +Foreach-Object { + $revision = $revision + 1 +} + +Write-Host "BLToolkit revision: $revision" +Write-Host "" + +c: + +if (!([System.IO.DirectoryInfo]"c:\temp\").Exists) { md c:\temp } +if (!([System.IO.DirectoryInfo]"c:\temp\BLToolkitSnapshot\").Exists) { md c:\temp\BLToolkitSnapshot } + +cd c:\temp\BLToolkitSnapshot\ + +if (([System.IO.DirectoryInfo]"c:\temp\BLToolkitSnapshot\bl-toolkit\").Exists) { + rd bl-toolkit\* -recurse +} else { + md bl-toolkit +} + +cd bl-toolkit + +$rar = '"' + ${env:ProgramFiles(x86)} + '\WinRAR\WinRar.exe" x ..\bltoolkit_dev.zip' +cmd /c $rar + +del ..\*.zip + +$rev_file = '// Autogenerated. Do not modify! + +namespace BLToolkit +{ + partial class BLToolkitConstants + { + // + // Revision component of version. + // + public const string Revision = "' + $revision + '"; + } +}' + +del Source\Properties\Revision.generated.cs +$rev_file >> Source\Properties\Revision.generated.cs + +$rar = '"' + ${env:ProgramFiles(x86)} + '\WinRAR\WinRar.exe" a -m5 -md1024 -s -r -rr -AFzip -x*\_svn\* c:\temp\BLToolkitSnapshot\bltoolkit_dev *.*' +cmd /c $rar + +$rar = '"' + ${env:ProgramFiles(x86)} + '\WinRAR\WinRar.exe" a -m5 -md1024 -s -r -rr -AFzip -x*\_svn\* c:\temp\BLToolkitSnapshot\bltoolkit Source\*.*' +cmd /c $rar + +cd Source + +$comp = "$env:windir\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.3.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.4.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.Data.4.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.SL.4.csproj /property:Configuration=Release" +cmd /c $comp + +copy bin\Release\*.dll . +md DataProviders + +cd ..\Tools\BLTgen + +$comp = "$env:windir\Microsoft.NET\Framework\v3.5\MSBuild.exe BLTgen.2008.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLTgen.2010.csproj /property:Configuration=Release" +cmd /c $comp + +copy bin\Release\*.exe ..\..\Source + +cd ..\..\DataProviders + +$comp = "$env:windir\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.Data.DataProvider.DB2.3.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.Data.DataProvider.Firebird.3.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.Data.DataProvider.Informix.3.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.Data.DataProvider.MySql.3.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.Data.DataProvider.Oracle.3.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.Data.DataProvider.PostgreSQL.3.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.Data.DataProvider.SqlCe.3.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.Data.DataProvider.SQLite.3.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.Data.DataProvider.Sybase.3.csproj /property:Configuration=Release" +cmd /c $comp + +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.Data.DataProvider.DB2.4.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.Data.DataProvider.Firebird.4.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.Data.DataProvider.Informix.4.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.Data.DataProvider.MySql.4.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.Data.DataProvider.Oracle.4.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.Data.DataProvider.PostgreSQL.4.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.Data.DataProvider.SqlCe.4.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.Data.DataProvider.SQLite.4.csproj /property:Configuration=Release" +cmd /c $comp +$comp = "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.Data.DataProvider.Sybase.4.csproj /property:Configuration=Release" +cmd /c $comp + +copy bin\Release\BLToolkit.Data.*.dll ..\Source\DataProviders + +cd ..\Source + +$rar = '"' + ${env:ProgramFiles(x86)} + '\WinRAR\WinRar.exe" a -m5 -md1024 -s -r -rr -AFzip -x*\_svn\* -x*\bin\* -x*\obj\* c:\temp\BLToolkitSnapshot\bltoolkit_bin *.exe *.dll DataProvider\ Data\DataProvider\' +cmd /c $rar + +ftp -s:e:\documents\copybltsnapshot.txt ftp.bltoolkit.net diff -r 000000000000 -r f990fcb411a9 Source/Aspects/AsyncAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/AsyncAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,39 @@ +using System; + +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage(AttributeTargets.Method)] + public sealed class AsyncAttribute : AbstractTypeBuilderAttribute + { + private readonly string _targetMethodName; + private readonly Type[] _parameterTypes; + + public AsyncAttribute() + { + } + + public AsyncAttribute(string targetMethodName): this(targetMethodName, null) + { + } + + public AsyncAttribute(params Type[] parameterTypes): this(null, parameterTypes) + { + } + + public AsyncAttribute(string targetMethodName, params Type[] parameterTypes) + { + _targetMethodName = targetMethodName; + _parameterTypes = parameterTypes; + } + + public override IAbstractTypeBuilder TypeBuilder + { + get { return new Builders.AsyncAspectBuilder(_targetMethodName, _parameterTypes); } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/Builders/AsyncAspectBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/Builders/AsyncAspectBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,274 @@ +using System; +using System.Reflection; +using System.Threading; + +namespace BLToolkit.Aspects.Builders +{ + using Properties; + using TypeBuilder; + using TypeBuilder.Builders; + + /// + /// This aspect simplifies asynchronous operations. + /// + public class AsyncAspectBuilder : AbstractTypeBuilderBase + { + private readonly string _targetMethodName; + private readonly Type[] _parameterTypes; + + public AsyncAspectBuilder(string targetMethodName, Type[] parameterTypes) + { + _targetMethodName = targetMethodName; + _parameterTypes = parameterTypes; + } + + public override int GetPriority(BuildContext context) + { + return TypeBuilderConsts.Priority.AsyncAspect; + } + + public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder) + { + if (context.IsBuildStep) + return false; + + var list = new AbstractTypeBuilderList(2) { this, typeBuilder }; + var step = context.Step; + + try + { + context.Step = BuildStep.Build; + + return typeBuilder.IsApplied(context, list); + } + finally + { + context.Step = step; + } + } + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + if (context == null) throw new ArgumentNullException("context"); + + return context.IsBuildStep && context.BuildElement == BuildElement.AbstractMethod; + } + + protected override void BuildAbstractMethod() + { + var mi = Context.CurrentMethod; + + if (mi.ReturnType == typeof(IAsyncResult)) + BuildBeginMethod(); + else + { + var parameters = mi.GetParameters(); + + if (parameters.Length == 1 && parameters[0].ParameterType == typeof(IAsyncResult)) + BuildEndMethod(); + else + throw new TypeBuilderException(string.Format("Method '{0}.{1}' is not a 'Begin' nor an 'End' method.", mi.DeclaringType.FullName, mi.Name)); + } + } + + private void BuildBeginMethod() + { + var mi = Context.CurrentMethod; + var method = GetTargetMethod(Context, "Begin"); + var delegateType = EnsureDelegateType(Context, method); + var emit = Context.MethodBuilder.Emitter; + var type = typeof(InternalAsyncResult); + var arLocal = emit.DeclareLocal(type); + var dLocal = emit.DeclareLocal(delegateType); + + emit + .newobj (type) + .dup + .dup + .dup + .stloc (arLocal) + .ldarg_0 + .ldftn (method) + .newobj (delegateType, typeof(object), typeof(IntPtr)) + .stloc (dLocal) + .ldloc (dLocal) + .stfld (type.GetField("Delegate")) + .ldloc (dLocal) + ; + + var callbackIndex = -1; + var parameters = mi.GetParameters(); + + for (var i = 0; i < parameters.Length; ++i) + { + if (parameters[i].ParameterType == typeof(AsyncCallback)) + { + callbackIndex = i; + emit + .ldloc (arLocal) + .dup + .ldarg (parameters[i]) + .stfld (type.GetField("AsyncCallback")) + .ldftn (type.GetMethod("CallBack")) + .newobj (typeof(AsyncCallback), typeof(object), typeof(IntPtr)) + ; + } + else + emit.ldarg(parameters[i]); + } + + if (callbackIndex < 0) + { + // Callback omitted + // + emit + .ldnull + .ldnull + .end(); + } + else if (callbackIndex == parameters.Length - 1) + { + // State omitted + // + emit + .ldnull + .end(); + } + + emit + .callvirt (delegateType.GetMethod("BeginInvoke")) + .stfld (type.GetField("InnerResult")) + .stloc (Context.ReturnValue) + ; + } + + private void BuildEndMethod() + { + var method = GetTargetMethod(Context, "End"); + var delegateType = EnsureDelegateType(Context, method); + var emit = Context.MethodBuilder.Emitter; + var type = typeof(InternalAsyncResult); + var arLocal = emit.DeclareLocal(type); + + emit + .ldarg_1 + .castclass (type) + .dup + .stloc (arLocal) + .ldfld (type.GetField("Delegate")) + .castclass (delegateType) + .ldloc (arLocal) + .ldfld (type.GetField("InnerResult")) + .callvirt (delegateType, "EndInvoke", typeof(IAsyncResult)); + + if (Context.ReturnValue != null) + emit.stloc(Context.ReturnValue); + } + + private MethodInfo GetTargetMethod(BuildContext context, string prefix) + { + var targetMethodName = _targetMethodName; + + if (targetMethodName == null) + { + var mi = context.CurrentMethod; + var name = mi.Name; + + if (name.StartsWith(prefix)) + targetMethodName = name.Substring(prefix.Length); + else + throw new TypeBuilderException(string.Format( + Resources.AsyncAspectBuilder_NoTargetMethod, + mi.DeclaringType.FullName, mi.Name)); + } + + return _parameterTypes == null? + context.Type.GetMethod(targetMethodName): + context.Type.GetMethod(targetMethodName, _parameterTypes); + } + + private static Type EnsureDelegateType(BuildContext context, MethodInfo method) + { + // The delegate should be defined as inner type of context.TypeBuilder. + // It's possible, but we can not define and use newly defined type as Emit target in its owner type. + // To solve this problem, we should create a top level delegate and make sure its name is unique. + // + var delegateName = context.TypeBuilder.TypeBuilder.FullName + "$" + method.Name + "$Delegate"; + var delegateType = context.GetItem(delegateName); + + if (delegateType == null) + { + var pi = method.GetParameters(); + var parameters = new Type[pi.Length]; + + for (var i = 0; i < pi.Length; i++) + parameters[i] = pi[i].ParameterType; + + const MethodImplAttributes mia = MethodImplAttributes.Runtime | MethodImplAttributes.Managed; + const MethodAttributes ma = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual; + + var delegateBuilder = context.AssemblyBuilder.DefineType(delegateName, + TypeAttributes.Class | TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass, + typeof(MulticastDelegate)); + + // Create constructor + // + var ctorBuilder = delegateBuilder.DefineConstructor( + MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName, CallingConventions.Standard, + typeof(object), typeof(IntPtr)); + ctorBuilder.ConstructorBuilder.SetImplementationFlags(mia); + + // Define the BeginInvoke method for the delegate + // + var beginParameters = new Type[parameters.Length + 2]; + + Array.Copy(parameters, 0, beginParameters, 0, parameters.Length); + beginParameters[parameters.Length] = typeof(AsyncCallback); + beginParameters[parameters.Length+1] = typeof(object); + + var methodBuilder = delegateBuilder.DefineMethod("BeginInvoke", ma, typeof(IAsyncResult), beginParameters); + + methodBuilder.MethodBuilder.SetImplementationFlags(mia); + + // Define the EndInvoke method for the delegate + // + methodBuilder = delegateBuilder.DefineMethod("EndInvoke", ma, method.ReturnType, typeof(IAsyncResult)); + methodBuilder.MethodBuilder.SetImplementationFlags(mia); + + // Define the Invoke method for the delegate + // + methodBuilder = delegateBuilder.DefineMethod("Invoke", ma, method.ReturnType, parameters); + methodBuilder.MethodBuilder.SetImplementationFlags(mia); + + context.Items.Add(delegateName, delegateType = delegateBuilder.Create()); + } + + return delegateType; + } + + #region Helper + + /// + /// Reserved for internal BLToolkit use. + /// + public class InternalAsyncResult : IAsyncResult + { + public IAsyncResult InnerResult; + public Delegate Delegate; + public AsyncCallback AsyncCallback; + + public void CallBack(IAsyncResult ar) + { + if (AsyncCallback != null) + AsyncCallback(this); + } + + public bool IsCompleted { get { return InnerResult.IsCompleted; } } + public WaitHandle AsyncWaitHandle { get { return InnerResult.AsyncWaitHandle; } } + public object AsyncState { get { return InnerResult.AsyncState; } } + public bool CompletedSynchronously { get { return InnerResult.CompletedSynchronously; } } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/Builders/ClearCacheAspectBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/Builders/ClearCacheAspectBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,133 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +using BLToolkit.Reflection.Emit; +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects.Builders +{ + public class ClearCacheAspectBuilder : AbstractTypeBuilderBase + { + #region Init + + public ClearCacheAspectBuilder(Type declaringType, string methodName, Type[] parameterTypes) + { + _declaringType = declaringType; + _methodName = methodName; + _parameterTypes = parameterTypes; + } + + private readonly Type _declaringType; + private readonly string _methodName; + private readonly Type[] _parameterTypes; + + #endregion + + #region Overrides + + public override int GetPriority(BuildContext context) + { + return TypeBuilderConsts.Priority.ClearCacheAspect; + } + + public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder) + { + return true; + } + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + if (context == null) throw new ArgumentNullException("context"); + + return context.IsFinallyStep && context.IsMethodOrProperty; + } + + #endregion + + #region Build + + private static int _methodCounter; + + public override void Build(BuildContext context) + { + Context = context; + + if (string.IsNullOrEmpty(_methodName)) + { + FieldBuilder type = Context.CreatePrivateStaticField( + "_type$ClearCacheAspect$" + ++_methodCounter, typeof(Type)); + + EmitHelper emit = Context.MethodBuilder.Emitter; + Label checkType = emit.DefineLabel(); + + emit + .ldsfld (type) + .brtrue_s (checkType) + .ldarg_0 + .LoadType (_declaringType) + .call (typeof(ClearCacheAspect), "GetType", typeof(object), typeof(Type)) + .stsfld (type) + .MarkLabel (checkType) + .ldsfld (type) + .call (typeof(CacheAspect), "ClearCache", typeof(Type)) + ; + } + else + { + FieldBuilder methodInfo = Context.CreatePrivateStaticField( + "_methodInfo$ClearCacheAspect$" + ++_methodCounter, typeof(MethodInfo)); + + EmitHelper emit = Context.MethodBuilder.Emitter; + + Label checkMethodInfo = emit.DefineLabel(); + + emit + .ldsfld (methodInfo) + .brtrue_s (checkMethodInfo) + .ldarg_0 + .LoadType (_declaringType) + .ldstrEx (_methodName) + ; + + if (_parameterTypes == null || _parameterTypes.Length == 0) + { + emit.ldnull.end(); + } + else + { + LocalBuilder field = emit.DeclareLocal(typeof(Type[])); + + emit + .ldc_i4_ (_parameterTypes.Length) + .newarr (typeof(Type)) + .stloc (field) + ; + + for (int i = 0; i < _parameterTypes.Length; i++) + { + emit + .ldloc (field) + .ldc_i4 (i) + .LoadType (_parameterTypes[i]) + .stelem_ref + .end() + ; + } + + emit.ldloc(field); + } + + emit + .call (typeof(ClearCacheAspect), "GetMethodInfo", typeof(object), typeof(Type), typeof(string), typeof(Type[])) + .stsfld (methodInfo) + .MarkLabel (checkMethodInfo) + .ldsfld (methodInfo) + .call (typeof(CacheAspect), "ClearCache", typeof(MethodInfo)) + ; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/Builders/InterceptorAspectBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/Builders/InterceptorAspectBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,341 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +namespace BLToolkit.Aspects.Builders +{ + using Reflection; + using TypeBuilder.Builders; + + public class InterceptorAspectBuilder : AbstractTypeBuilderBase + { + public InterceptorAspectBuilder( + Type interceptorType, InterceptType interceptType, string configString, int priority, bool localInterceptor) + { + _interceptorType = interceptorType; + _interceptType = interceptType; + _configString = configString; + _priority = priority; + _localInterceptor = localInterceptor; + } + + private readonly Type _interceptorType; + private readonly InterceptType _interceptType; + private readonly string _configString; + private readonly int _priority; + private readonly bool _localInterceptor; + + private FieldBuilder _interceptorField; + private LocalBuilder _infoField; + + public override int GetPriority(BuildContext context) + { + return _priority; + } + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + if (_interceptorType == null && _interceptType == 0) + return false; + + foreach (var builder in builders) + { + var interceptor = builder as InterceptorAspectBuilder; + + if (interceptor != null) + { + if (interceptor._interceptorType == null && interceptor._interceptType == 0) + return false; + + if (builder == this) + break; + } + } + + if (context.IsMethodOrProperty) switch (context.Step) + { + case BuildStep.Begin: return true; + case BuildStep.Before: return (_interceptType & InterceptType.BeforeCall) != 0; + case BuildStep.After: return (_interceptType & InterceptType.AfterCall) != 0; + case BuildStep.Catch: return (_interceptType & InterceptType.OnCatch) != 0; + case BuildStep.Finally: return (_interceptType & InterceptType.OnFinally) != 0; + case BuildStep.End: return true; + } + + return false; + } + + public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder) + { + var builder = typeBuilder as InterceptorAspectBuilder; + + return builder == null || _interceptorType != builder._interceptorType; + } + + public override void Build(BuildContext context) + { + if (context.Step == BuildStep.Begin || context.Step == BuildStep.End) + { + base.Build(context); + return; + } + + Context = context; + + var emit = Context.MethodBuilder.Emitter; + + // Push ref & out parameters. + // + var parameters = Context.CurrentMethod.GetParameters(); + + for (var i = 0; i < parameters.Length; i++) + { + var p = parameters[i]; + + if (!p.ParameterType.IsByRef) + continue; + + emit + .ldloc (_infoField) + .callvirt (typeof(InterceptCallInfo).GetProperty("ParameterValues").GetGetMethod()) + .ldc_i4 (i) + .ldargEx (p, true) + .stelem_ref + .end() + ; + } + + // Push return value. + // + if (Context.ReturnValue != null) + { + emit + .ldloc (_infoField) + .ldloc (Context.ReturnValue) + .boxIfValueType (Context.CurrentMethod.ReturnType) + .callvirt (typeof(InterceptCallInfo).GetProperty("ReturnValue").GetSetMethod()) + ; + } + + // Set Exception. + // + if (Context.Step == BuildStep.Catch) + { + emit + .ldloc(_infoField) + .ldloc(Context.Exception) + .callvirt(typeof(InterceptCallInfo).GetProperty("Exception").GetSetMethod()) + ; + } + + // Set intercept result. + // + emit + .ldloc (_infoField) + .ldc_i4 ((int)InterceptResult.Continue) + .callvirt (typeof(InterceptCallInfo).GetProperty("InterceptResult").GetSetMethod()) + ; + + // Set intercept type. + // + InterceptType interceptType; + + switch (Context.Step) + { + case BuildStep.Before: interceptType = InterceptType.BeforeCall; break; + case BuildStep.After: interceptType = InterceptType.AfterCall; break; + case BuildStep.Catch: interceptType = InterceptType.OnCatch; break; + case BuildStep.Finally: interceptType = InterceptType.OnFinally; break; + default: + throw new InvalidOperationException(); + } + + emit + .ldloc (_infoField) + .ldc_i4 ((int)interceptType) + .callvirt (typeof(InterceptCallInfo).GetProperty("InterceptType").GetSetMethod()) + + // Call interceptor. + // + .LoadField(_interceptorField) + .ldloc (_infoField) + .callvirt (typeof(IInterceptor), "Intercept", typeof(InterceptCallInfo)) + ; + + // Pop return value. + // + if (Context.ReturnValue != null) + { + emit + .ldloc (_infoField) + .callvirt (typeof(InterceptCallInfo).GetProperty("ReturnValue").GetGetMethod()) + .CastFromObject (Context.CurrentMethod.ReturnType) + .stloc (Context.ReturnValue) + ; + } + + // Pop ref & out parameters. + // + for (var i = 0; i < parameters.Length; i++) + { + var p = parameters[i]; + + if (!p.ParameterType.IsByRef) + continue; + + var type = p.ParameterType.GetElementType(); + + emit + .ldarg (p) + .ldloc (_infoField) + .callvirt (typeof(InterceptCallInfo).GetProperty("ParameterValues").GetGetMethod()) + .ldc_i4 (i) + .ldelem_ref + .CastFromObject (type) + .stind (type) + ; + } + + // Check InterceptResult + emit + .ldloc (_infoField) + .callvirt (typeof(InterceptCallInfo).GetProperty("InterceptResult").GetGetMethod()) + .ldc_i4 ((int)InterceptResult.Return) + .beq (Context.ReturnLabel) + ; + } + + private static int _methodCounter; + + private LocalBuilder GetInfoField() + { + var field = Context.GetItem("$BLToolkit.InfoField"); + + if (field == null) + { + _methodCounter++; + + // Create MethodInfo field. + // + var methodInfo = Context.CreatePrivateStaticField( + "_methodInfo$" + Context.CurrentMethod.Name + _methodCounter, typeof(CallMethodInfo)); + + var emit = Context.MethodBuilder.Emitter; + + var checkMethodInfo = emit.DefineLabel(); + + emit + .LoadField (methodInfo) + .brtrue_s (checkMethodInfo) + .call (typeof(MethodBase), "GetCurrentMethod") + .castclass (typeof(MethodInfo)) + .newobj (TypeHelper.GetConstructor(typeof(CallMethodInfo), typeof(MethodInfo))) + .stsfld (methodInfo) + .MarkLabel (checkMethodInfo) + ; + + // Create & initialize the field. + // + field = emit.DeclareLocal(typeof(InterceptCallInfo)); + + emit + .newobj (TypeHelper.GetDefaultConstructor(typeof(InterceptCallInfo))) + .dup + .ldarg_0 + .callvirt (typeof(InterceptCallInfo).GetProperty("Object").GetSetMethod()) + + .dup + .LoadField(methodInfo) + .callvirt (typeof(InterceptCallInfo).GetProperty("CallMethodInfo").GetSetMethod()) + ; + + var parameters = Context.CurrentMethod.GetParameters(); + + for (var i = 0; i < parameters.Length; i++) + { + var p = parameters[i]; + + if (p.ParameterType.IsByRef) + continue; + + emit + .dup + .callvirt (typeof(InterceptCallInfo).GetProperty("ParameterValues").GetGetMethod()) + .ldc_i4 (i) + .ldargEx (p, true) + .stelem_ref + .end() + ; + } + + emit.stloc(field); + + Context.Items.Add("$BLToolkit.MethodInfo", methodInfo); + Context.Items.Add("$BLToolkit.InfoField", field); + } + + return field; + } + + private FieldBuilder GetInterceptorField() + { + var fieldName = "_interceptor$" + _interceptorType.FullName + "$_" + Context.CurrentMethod.Name + _methodCounter; + var field = Context.GetField(fieldName); + + if (field == null) + { + // Create MethodInfo field. + // + field = _localInterceptor? + Context.CreatePrivateField (fieldName, typeof(IInterceptor)): + Context.CreatePrivateStaticField(fieldName, typeof(IInterceptor)); + + var emit = Context.MethodBuilder.Emitter; + + var checkInterceptor = emit.DefineLabel(); + var methodInfo = Context.GetItem("$BLToolkit.MethodInfo"); + + emit + .LoadField (field) + .brtrue_s (checkInterceptor) + ; + + if (!field.IsStatic) + emit.ldarg_0.end(); + + emit + .newobj (TypeHelper.GetDefaultConstructor(_interceptorType)) + .castclass (typeof(IInterceptor)) + ; + + if (field.IsStatic) + emit.stsfld(field); + else + emit.stfld(field); + + emit + .LoadField (field) + .LoadField (methodInfo) + .ldstrEx (_configString ?? "") + .callvirt (typeof(IInterceptor), "Init", typeof(CallMethodInfo), typeof(string)) + + .MarkLabel (checkInterceptor) + ; + } + + return field; + } + + protected override void BeginMethodBuild() + { + _infoField = GetInfoField(); + _interceptorField = GetInterceptorField(); + } + + protected override void EndMethodBuild() + { + Context.Items.Remove("$BLToolkit.MethodInfo"); + Context.Items.Remove("$BLToolkit.InfoField"); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/Builders/MixinAspectBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/Builders/MixinAspectBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,210 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +using BLToolkit.TypeBuilder.Builders; +using BLToolkit.Reflection.Emit; +using BLToolkit.TypeBuilder; + +namespace BLToolkit.Aspects.Builders +{ + public class MixinAspectBuilder : AbstractTypeBuilderBase + { + public MixinAspectBuilder( + Type targetInterface, string memberName, bool throwExceptionIfNull, string exceptionMessage) + { + _targetInterface = targetInterface; + _memberName = memberName; + _throwExceptionIfNull = throwExceptionIfNull; + _exceptionMessage = exceptionMessage; + } + + private readonly Type _targetInterface; + private readonly string _memberName; + private readonly bool _throwExceptionIfNull; + private readonly string _exceptionMessage; + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + return context.BuildElement == BuildElement.InterfaceMethod; + } + + public override Type[] GetInterfaces() + { + return new Type[] { _targetInterface }; + } + + public override void Build(BuildContext context) + { + Context = context; + + if (CheckOverrideAttribute()) + return; + + EmitHelper emit = Context.MethodBuilder.Emitter; + MethodInfo method = Context.MethodBuilder.OverriddenMethod; + ParameterInfo[] ps = method.GetParameters(); + Type memberType; + + FieldInfo field = Context.Type.GetField(_memberName); + + if (field != null) + { + if (field.IsPrivate) + throw new TypeBuilderException(string.Format( + "Field '{0}.{1}' must be protected or public.", + Context.Type.Name, _memberName)); + + memberType = field.FieldType; + + emit + .ldarg_0 + .ldfld (field) + ; + + CheckNull(emit); + + emit + .ldarg_0 + .ldfld (field) + ; + } + else + { + PropertyInfo prop = Context.Type.GetProperty(_memberName); + + if (prop != null) + { + MethodInfo mi = prop.GetGetMethod(true); + + if (mi == null) + throw new TypeBuilderException(string.Format( + "Property '{0}.{1}' getter not found.", + Context.Type.Name, _memberName)); + + memberType = prop.PropertyType; + + if (mi.IsPrivate) + throw new TypeBuilderException(string.Format( + "Property '{0}.{1}' getter must be protected or public.", + Context.Type.Name, _memberName)); + + emit + .ldarg_0 + .callvirt (mi) + ; + + CheckNull(emit); + + emit + .ldarg_0 + .callvirt (mi) + ; + } + else + { + throw new TypeBuilderException(string.Format( + "Member '{0}.{1}' not found.", + Context.Type.Name, _memberName)); + } + } + + emit.CastIfNecessary(_targetInterface, memberType); + + for (int i = 0; i < ps.Length; i++) + emit.ldarg(i + 1); + + emit.callvirt(method); + + if (Context.ReturnValue != null) + emit.stloc(Context.ReturnValue); + } + + private void CheckNull(EmitHelper emit) + { + if (_throwExceptionIfNull == false && string.IsNullOrEmpty(_exceptionMessage)) + { + emit + .brfalse (Context.ReturnLabel) + ; + } + else + { + string message = string.Format( + string.IsNullOrEmpty(_exceptionMessage)? + "'{0}.{1}' is not initialized." : _exceptionMessage, + _targetInterface.Name, _memberName, _targetInterface.FullName); + + Label label = emit.DefineLabel(); + + emit + .brtrue (label) + .ldstr (message) + .newobj (typeof(InvalidOperationException), typeof(string)) + .@throw + .MarkLabel (label) + ; + } + } + + private bool CheckOverrideAttribute() + { + MethodInfo method = Context.MethodBuilder.OverriddenMethod; + ParameterInfo[] ps = method.GetParameters(); + + MethodInfo[] methods = Context.Type.GetMethods( + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + + foreach (MethodInfo mi in methods) + { + if (mi.IsPrivate) + continue; + + object[] attrs = mi.GetCustomAttributes(typeof(MixinOverrideAttribute), true); + + if (attrs == null || attrs.Length == 0) + continue; + + foreach (MixinOverrideAttribute attr in attrs) + { + if (attr.TargetInterface != null && + attr.TargetInterface != Context.CurrentInterface.Type) + continue; + + string name = string.IsNullOrEmpty(attr.MethodName)? + mi.Name: attr.MethodName; + + if (name != method.Name || mi.ReturnType != method.ReturnType) + continue; + + ParameterInfo[] mips = mi.GetParameters(); + + if (mips.Length != ps.Length) + continue; + + bool equal = true; + + for (int i = 0; equal && i < ps.Length; i++) + equal = ps[i].ParameterType == mips[i].ParameterType; + + if (equal) + { + EmitHelper emit = Context.MethodBuilder.Emitter; + + for (int i = -1; i < ps.Length; i++) + emit.ldarg(i + 1); + + emit.callvirt(mi); + + if (Context.ReturnValue != null) + emit.stloc(Context.ReturnValue); + + return true; + } + } + } + + return false; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/Builders/NotNullAspectBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/Builders/NotNullAspectBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,72 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +using BLToolkit.Reflection.Emit; +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects.Builders +{ + public class NotNullAspectBuilder : AbstractTypeBuilderBase + { + public NotNullAspectBuilder(string message) + { + _message = message; + } + + private readonly string _message; + + public override int GetPriority(BuildContext context) + { + return TypeBuilderConsts.Priority.NotNullAspect; + } + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + if (context == null) throw new ArgumentNullException("context"); + + return context.IsBeforeStep && context.BuildElement != BuildElement.Type; + } + + public override void Build(BuildContext context) + { + if (context == null) throw new ArgumentNullException("context"); + + ParameterInfo pi = (ParameterInfo)TargetElement; + + if (pi.ParameterType.IsValueType == false) + { + EmitHelper emit = context.MethodBuilder.Emitter; + Label label = emit.DefineLabel(); + + string message = _message != null? string.Format(_message, pi.Name): string.Empty; + + emit + .ldarg (pi) + .brtrue_s (label) + ; + + if (string.IsNullOrEmpty(message)) + { + emit + .ldstr (pi.Name) + .newobj (typeof(ArgumentNullException), typeof(string)) + ; + } + else + { + emit + .ldnull + .ldstr (message) + .newobj (typeof(ArgumentNullException), typeof(string), typeof(string)) + ; + } + + emit + .@throw + .MarkLabel (label) + ; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/Builders/OverloadAspectBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/Builders/OverloadAspectBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,219 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; + +using BLToolkit.Properties; +using BLToolkit.Reflection; +using BLToolkit.Reflection.Emit; +using BLToolkit.TypeBuilder; +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects.Builders +{ + public class OverloadAspectBuilder: AbstractTypeBuilderBase + { + private readonly string _overloadedMethodName; + private readonly Type[] _parameterTypes; + + public OverloadAspectBuilder(string overloadedMethodName, Type[] parameterTypes) + { + _overloadedMethodName = overloadedMethodName; + _parameterTypes = parameterTypes; + } + + public override int GetPriority(BuildContext context) + { + return TypeBuilderConsts.Priority.OverloadAspect; + } + + public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder) + { + if (context.IsBuildStep) + return false; + + AbstractTypeBuilderList list = new AbstractTypeBuilderList(2); + + list.Add(this); + list.Add(typeBuilder); + + BuildStep step = context.Step; + + try + { + context.Step = BuildStep.Build; + + return typeBuilder.IsApplied(context, list); + } + finally + { + context.Step = step; + } + } + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + if (context == null) throw new ArgumentNullException("context"); + + return context.IsBuildStep && context.BuildElement == BuildElement.AbstractMethod; + } + + protected override void BuildAbstractMethod() + { + MethodInfo currentMethod = Context.CurrentMethod; + string methodName = _overloadedMethodName ?? currentMethod.Name; + MethodInfo overloadedMethod = GetOverloadedMethod(methodName); + + if (overloadedMethod == null) + { + throw new TypeBuilderException(string.Format( + Resources.OverloadAspectBuilder_NoOverloadedMethod, + Context.Type.FullName, methodName)); + } + + EmitHelper emit = Context.MethodBuilder.Emitter; + List parameters = new List(currentMethod.GetParameters()); + + if (!overloadedMethod.IsStatic) + emit.ldarg_0.end(); + + foreach (ParameterInfo param in overloadedMethod.GetParameters()) + { + ParameterInfo currentMethodParameter = null; + foreach (ParameterInfo p in parameters) + { + if (p.Name != param.Name) + continue; + + currentMethodParameter = p; + parameters.Remove(p); + break; + } + + if (currentMethodParameter != null) + { + emit.ldarg(currentMethodParameter); + } + else + { + Type type = param.ParameterType; + bool isRef = false; + + if (type.IsByRef) + { + type = type.GetElementType(); + isRef = true; + } + + if (type.IsValueType && !type.IsPrimitive) + { + LocalBuilder localBuilder = emit.DeclareLocal(type); + + emit + .ldloca (localBuilder) + .initobj (type) + ; + + if (isRef) + emit.ldloca (localBuilder); + else + emit.ldloc (localBuilder); + + } + else + { + if ((param.Attributes & ParameterAttributes.HasDefault) == 0 || + !emit.LoadWellKnownValue(param.DefaultValue)) + { + emit.LoadInitValue(type); + } + + if (isRef) + { + LocalBuilder localBuilder = emit.DeclareLocal(type); + + emit + .stloc (localBuilder) + .ldloca (localBuilder) + ; + } + } + } + } + + // Finally, call the method we override. + // + if (overloadedMethod.IsStatic || overloadedMethod.IsFinal) + emit.call (overloadedMethod); + else + emit.callvirt (overloadedMethod); + + if (currentMethod.ReturnType != typeof(void)) + emit.stloc(Context.ReturnValue); + } + + private MethodInfo GetOverloadedMethod(string methodName) + { + MethodInfo currentMethod = Context.CurrentMethod; + MethodInfo bestMatch = null; + int bestMatchParametersCount = -1; + ParameterInfo[] currentMethodParameters = currentMethod.GetParameters(); + + if (_parameterTypes != null) + { + bestMatch = Context.Type.GetMethod(methodName, _parameterTypes); + return bestMatch != null && MatchParameters(currentMethodParameters, bestMatch.GetParameters()) >= 0? bestMatch: null; + } + + const BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.Instance| BindingFlags.Public | BindingFlags.NonPublic; + + foreach (MethodInfo m in Context.Type.GetMethods(bindingFlags)) + { + if (m.IsPrivate || m.Name != methodName || m.IsGenericMethod != currentMethod.IsGenericMethod) + continue; + + if (!TypeHelper.CompareParameterTypes(m.ReturnType, currentMethod.ReturnType)) + continue; + + if (m.IsDefined(typeof(OverloadAttribute), true)) + continue; + + ParameterInfo[] overloadedMethodParameters = m.GetParameters(); + if (overloadedMethodParameters.Length <= bestMatchParametersCount) + continue; + + int matchedParameters = MatchParameters(overloadedMethodParameters, currentMethodParameters); + if (matchedParameters <= bestMatchParametersCount) + continue; + + bestMatchParametersCount = matchedParameters; + bestMatch = m; + } + + return bestMatch; + } + + private static int MatchParameters(ParameterInfo[] parametersToMatch, ParameterInfo[] existingParameters) + { + int matchedParameters = 0; + List existingParametersList = new List(existingParameters); + foreach (ParameterInfo param in parametersToMatch) + { + foreach (ParameterInfo existing in existingParametersList) + { + if (existing.Name != param.Name) + continue; + + if (!TypeHelper.CompareParameterTypes(param.ParameterType, existing.ParameterType)) + return -1; + + ++matchedParameters; + existingParametersList.Remove(existing); + break; + } + } + + return matchedParameters; + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Aspects/CacheAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/CacheAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,535 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; + +namespace BLToolkit.Aspects +{ + using Common; + + public delegate bool IsCacheableParameterType(Type parameterType); + + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [System.Diagnostics.DebuggerStepThrough] + public class CacheAspect : Interceptor + { + #region Init + + static CacheAspect() + { + MaxCacheTime = int.MaxValue; + IsEnabled = true; + + CleanupThread.Init(); + } + + public CacheAspect() + { + _registeredAspects.Add(this); + } + + private MethodInfo _methodInfo; + private int? _instanceMaxCacheTime; + private bool? _instanceIsWeak; + + public override void Init(CallMethodInfo info, string configString) + { + base.Init(info, configString); + + info.CacheAspect = this; + + _methodInfo = info.MethodInfo; + + var ps = configString.Split(';'); + + foreach (var p in ps) + { + var vs = p.Split('='); + + if (vs.Length == 2) + { + switch (vs[0].ToLower().Trim()) + { + case "maxcachetime": _instanceMaxCacheTime = int. Parse(vs[1].Trim()); break; + case "isweak": _instanceIsWeak = bool.Parse(vs[1].Trim()); break; + } + } + } + } + + private static readonly IList _registeredAspects = ArrayList.Synchronized(new ArrayList()); + protected static IList RegisteredAspects + { + get { return _registeredAspects; } + } + + public static CacheAspect GetAspect(MethodInfo methodInfo) + { + lock (RegisteredAspects.SyncRoot) + foreach (CacheAspect aspect in RegisteredAspects) + if (aspect._methodInfo == methodInfo) + return aspect; + + return null; + } + + #endregion + + #region Overrides + + protected override void BeforeCall(InterceptCallInfo info) + { + if (!IsEnabled) + return; + + var cache = Cache; + + lock (cache.SyncRoot) + { + var key = GetKey(info); + var item = GetItem(cache, key); + + if (item != null && !item.IsExpired) + { + info.InterceptResult = InterceptResult.Return; + info.ReturnValue = item.ReturnValue; + + if (item.RefValues != null) + { + var pis = info.CallMethodInfo.Parameters; + var n = 0; + + for (var i = 0; i < pis.Length; i++) + if (pis[i].ParameterType.IsByRef) + info.ParameterValues[i] = item.RefValues[n++]; + } + + info.Cached = true; + } + else + { + info.Items["CacheKey"] = key; + } + } + } + + protected override void AfterCall(InterceptCallInfo info) + { + if (!IsEnabled) + return; + + var cache = Cache; + + lock (cache.SyncRoot) + { + var key = (CompoundValue)info.Items["CacheKey"]; + + if (key == null) + return; + + var maxCacheTime = _instanceMaxCacheTime ?? MaxCacheTime; + var isWeak = _instanceIsWeak ?? IsWeak; + + var item = new CacheAspectItem + { + ReturnValue = info.ReturnValue, + MaxCacheTime = maxCacheTime == int.MaxValue || maxCacheTime < 0 ? + DateTime.MaxValue : + DateTime.Now.AddMilliseconds(maxCacheTime), + }; + + var pis = info.CallMethodInfo.Parameters; + var n = 0; + + foreach (var pi in pis) + if (pi.ParameterType.IsByRef) + n++; + + if (n > 0) + { + item.RefValues = new object[n]; + + n = 0; + + for (var i = 0; i < pis.Length; i++) + if (pis[i].ParameterType.IsByRef) + item.RefValues[n++] = info.ParameterValues[i]; + } + + cache[key] = isWeak? (object)new WeakReference(item): item; + } + } + + #endregion + + #region Global Parameters + + public static bool IsEnabled { get; set; } + public static int MaxCacheTime { get; set; } + public static bool IsWeak { get; set; } + + #endregion + + #region IsCacheableParameterType + + private static IsCacheableParameterType _isCacheableParameterType = + IsCacheableParameterTypeInternal; + + public static IsCacheableParameterType IsCacheableParameterType + { + get { return _isCacheableParameterType; } + set { _isCacheableParameterType = value ?? IsCacheableParameterTypeInternal; } + } + + private static bool IsCacheableParameterTypeInternal(Type parameterType) + { + return parameterType.IsValueType || parameterType == typeof(string); + } + + #endregion + + #region Cache + + private IDictionary _cache; + public IDictionary Cache + { + get { return _cache ?? (_cache = CreateCache()); } + } + + protected virtual CacheAspectItem CreateCacheItem(InterceptCallInfo info) + { + return new CacheAspectItem(); + } + + protected virtual IDictionary CreateCache() + { + return Hashtable.Synchronized(new Hashtable()); + } + + protected static CompoundValue GetKey(InterceptCallInfo info) + { + var parInfo = info.CallMethodInfo.Parameters; + var parValues = info.ParameterValues; + var keyValues = new object[parValues.Length]; + var cacheParams = info.CallMethodInfo.CacheableParameters; + + if (cacheParams == null) + { + info.CallMethodInfo.CacheableParameters = cacheParams = new bool[parInfo.Length]; + + for (var i = 0; i < parInfo.Length; i++) + cacheParams[i] = IsCacheableParameterType(parInfo[i].ParameterType); + } + + for (var i = 0; i < parValues.Length; i++) + keyValues[i] = cacheParams[i] ? parValues[i] : null; + + return new CompoundValue(keyValues); + } + + protected static CacheAspectItem GetItem(IDictionary cache, CompoundValue key) + { + var obj = cache[key]; + + if (obj == null) + return null; + + var wr = obj as WeakReference; + + if (wr == null) + return (CacheAspectItem)obj; + + obj = wr.Target; + + if (obj != null) + return (CacheAspectItem)obj; + + cache.Remove(key); + + return null; + } + + /// + /// Clear a method call cache. + /// + /// The representing cached method. + public static void ClearCache(MethodInfo methodInfo) + { + if (methodInfo == null) + throw new ArgumentNullException("methodInfo"); + + var aspect = GetAspect(methodInfo); + + if (aspect != null) + CleanupThread.ClearCache(aspect.Cache); + } + + /// + /// Clear a method call cache. + /// + /// The method declaring type. + /// The method name. + /// An array of objects representing + /// the number, order, and type of the parameters for the method to get.-or- + /// An empty array of the type (for example, ) + /// to get a method that takes no parameters. + public static void ClearCache(Type declaringType, string methodName, params Type[] types) + { + ClearCache(GetMethodInfo(declaringType, methodName, types)); + } + + /// + /// Clear a method call cache. + /// + /// The method declaring type. + /// The method name. + /// An array of objects representing + /// the number, order, and type of the parameters for the method to get.-or- + /// An empty array of the type (for example, ) + /// to get a method that takes no parameters. + /// An array of values of the parameters for the method to get + public static void ClearCache(Type declaringType, string methodName, Type[] types, object[] values) + { + var methodInfo = GetMethodInfo(declaringType, methodName, types); + + if (methodInfo == null) + throw new ArgumentNullException("methodInfo"); + + var aspect = GetAspect(methodInfo); + + if (aspect != null) + CleanupThread.ClearCache(aspect.Cache, new CompoundValue(values)); + } + + public static void ClearCache(Type declaringType) + { + if (declaringType == null) + throw new ArgumentNullException("declaringType"); + + if (declaringType.IsAbstract) + declaringType = TypeBuilder.TypeFactory.GetType(declaringType); + + lock (RegisteredAspects.SyncRoot) + foreach (CacheAspect aspect in RegisteredAspects) + if (aspect._methodInfo.DeclaringType == declaringType) + CleanupThread.ClearCache(aspect.Cache); + } + + public static MethodInfo GetMethodInfo(Type declaringType, string methodName, params Type[] parameterTypes) + { + if (declaringType == null) + throw new ArgumentNullException("declaringType"); + + if (declaringType.IsAbstract) + declaringType = TypeBuilder.TypeFactory.GetType(declaringType); + + if (parameterTypes == null) + parameterTypes = Type.EmptyTypes; + + var methodInfo = declaringType.GetMethod( + methodName, + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, + null, + parameterTypes, + null); + + if (methodInfo == null) + { + methodInfo = declaringType.GetMethod( + methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + + if (methodInfo == null) + throw new ArgumentException(string.Format("Method '{0}.{1}' not found.", + declaringType.FullName, methodName)); + } + + return methodInfo; + } + + /// + /// Clear all cached method calls. + /// + public static void ClearCache() + { + CleanupThread.ClearCache(); + } + + #endregion + + #region Cleanup Thread + + public class CleanupThread + { + private CleanupThread() {} + + internal static void Init() + { + AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload; + Start(); + } + + static void CurrentDomain_DomainUnload(object sender, EventArgs e) + { + Stop(); + } + + static volatile Timer _timer; + static readonly object _syncTimer = new object(); + + private static void Start() + { + if (_timer == null) + lock (_syncTimer) + if (_timer == null) + { + var interval = TimeSpan.FromSeconds(10); + _timer = new Timer(Cleanup, null, interval, interval); + } + } + + private static void Stop() + { + if (_timer != null) + lock (_syncTimer) + if (_timer != null) + { + _timer.Dispose(); + _timer = null; + } + } + + private static void Cleanup(object state) + { + if (!Monitor.TryEnter(RegisteredAspects.SyncRoot, 10)) + { + // The Cache is busy, skip this turn. + // + return; + } + + var start = DateTime.Now; + var objectsInCache = 0; + + try + { + _workTimes++; + + var list = new List(); + + foreach (CacheAspect aspect in RegisteredAspects) + { + var cache = aspect.Cache; + + lock (cache.SyncRoot) + { + foreach (DictionaryEntry de in cache) + { + var wr = de.Value as WeakReference; + + bool isExpired; + + if (wr != null) + { + var ca = wr.Target as CacheAspectItem; + + isExpired = ca == null || ca.IsExpired; + } + else + { + isExpired = ((CacheAspectItem)de.Value).IsExpired; + } + + if (isExpired) + list.Add(de); + } + + foreach (var de in list) + { + cache.Remove(de.Key); + _objectsExpired++; + } + + list.Clear(); + + objectsInCache += cache.Count; + } + } + + _objectsInCache = objectsInCache; + } + finally + { + _workTime += DateTime.Now - start; + + Monitor.Exit(RegisteredAspects.SyncRoot); + } + } + + private static int _workTimes; + public static int WorkTimes + { + get { return _workTimes; } + } + + private static TimeSpan _workTime; + public static TimeSpan WorkTime + { + get { return _workTime; } + } + + private static int _objectsExpired; + public static int ObjectsExpired + { + get { return _objectsExpired; } + } + + private static int _objectsInCache; + public static int ObjectsInCache + { + get { return _objectsInCache; } + } + + public static void UnregisterCache(IDictionary cache) + { + lock (RegisteredAspects.SyncRoot) + RegisteredAspects.Remove(cache); + } + + public static void ClearCache(IDictionary cache) + { + lock (RegisteredAspects.SyncRoot) lock (cache.SyncRoot) + { + _objectsExpired += cache.Count; + cache.Clear(); + } + } + + public static void ClearCache(IDictionary cache, CompoundValue key) + { + lock (RegisteredAspects.SyncRoot) + lock (cache.SyncRoot) + { + _objectsExpired += 1; + cache.Remove(key); + } + } + + public static void ClearCache() + { + lock (RegisteredAspects.SyncRoot) + { + foreach (CacheAspect aspect in RegisteredAspects) + { + _objectsExpired += aspect.Cache.Count; + aspect.Cache.Clear(); + } + } + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/CacheAspectItem.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/CacheAspectItem.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,33 @@ +using System; + +namespace BLToolkit.Aspects +{ + public class CacheAspectItem + { + private DateTime _maxCacheTime; + public virtual DateTime MaxCacheTime + { + get { return _maxCacheTime; } + set { _maxCacheTime = value; } + } + + private object _returnValue; + public object ReturnValue + { + get { return _returnValue; } + set { _returnValue = value; } + } + + private object[] _refValues; + public object[] RefValues + { + get { return _refValues; } + set { _refValues = value; } + } + + public virtual bool IsExpired + { + get { return _maxCacheTime <= DateTime.Now; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/CacheAspectT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/CacheAspectT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using System; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [Obsolete] + public class CacheAspect : CacheAspect + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/CacheAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/CacheAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,131 @@ +using System; +using BLToolkit.Properties; +using BLToolkit.Reflection; +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Interface | + AttributeTargets.Property | + AttributeTargets.Method, + AllowMultiple=true)] + public class CacheAttribute : InterceptorAttribute + { + #region Constructors + + public CacheAttribute() + : this(typeof(CacheAspect), null) + { + } + + public CacheAttribute(Type cacheAspectType, string configString) + : base( + cacheAspectType, + InterceptType.BeforeCall | InterceptType.AfterCall, + configString, + TypeBuilderConsts.Priority.CacheAspect) + { + if (!TypeHelper.IsSameOrParent(typeof(CacheAspect), cacheAspectType)) + throw new ArgumentException(Resources.CacheAttribute_ParentTypeConstraintViolated); + } + + public CacheAttribute(Type interceptorType) + : this(interceptorType, null) + { + } + + public CacheAttribute(Type interceptorType, int maxCacheTime) + : this(interceptorType, null) + { + MaxCacheTime = maxCacheTime; + } + + public CacheAttribute(Type interceptorType, bool isWeak) + : this(interceptorType, null) + { + IsWeak = isWeak; + } + + public CacheAttribute(Type interceptorType, int maxCacheTime, bool isWeak) + : this(interceptorType, null) + { + MaxCacheTime = maxCacheTime; + IsWeak = isWeak; + } + + public CacheAttribute(string configString) + : this(typeof(CacheAspect), configString) + { + } + + public CacheAttribute(int maxCacheTime) + : this(typeof(CacheAspect), maxCacheTime) + { + } + + public CacheAttribute(bool isWeak) + : this(typeof(CacheAspect), isWeak) + { + } + + public CacheAttribute(int maxCacheTime, bool isWeak) + : this(typeof(CacheAspect), maxCacheTime, isWeak) + { + } + + #endregion + + #region Properties + + private bool _hasMaxCacheTime; + private int _maxCacheTime; + public int MaxCacheTime + { + get { return _maxCacheTime; } + set { _maxCacheTime = value; _hasMaxCacheTime = true; } + } + + public int MaxSeconds + { + get { return MaxCacheTime / 1000; } + set { MaxCacheTime = value * 1000; } + } + + public int MaxMinutes + { + get { return MaxCacheTime / 60 / 1000; } + set { MaxCacheTime = value * 60 * 1000; } + } + + private bool _hasIsWeak; + private bool _isWeak; + public bool IsWeak + { + get { return _isWeak; } + set { _isWeak = value; _hasIsWeak = true; } + } + + public override string ConfigString + { + get + { + string s = base.ConfigString; + + if (_hasMaxCacheTime) s += ";MaxCacheTime=" + MaxCacheTime; + if (_hasIsWeak) s += ";IsWeak=" + IsWeak; + + if (!string.IsNullOrEmpty(s) && s[0] == ';') + s = s.Substring(1); + + return s; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/CallMethodInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/CallMethodInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,74 @@ +using System; +using System.Collections; +using System.Reflection; + +namespace BLToolkit.Aspects +{ + [System.Diagnostics.DebuggerStepThrough] + public class CallMethodInfo + { + #region Init + + readonly object _sync = new object(); + + #endregion + + #region Public Members + + public CallMethodInfo(MethodInfo methodInfo) + { + _methodInfo = methodInfo; + _parameters = methodInfo.GetParameters(); + } + + private readonly MethodInfo _methodInfo; + public MethodInfo MethodInfo + { + get { return _methodInfo; } + } + + private readonly ParameterInfo[] _parameters; + public ParameterInfo[] Parameters + { + get { return _parameters; } + } + + volatile Hashtable _items; + public IDictionary Items + { + get + { + if (_items == null) lock (_sync) if (_items == null) + _items = Hashtable.Synchronized(new Hashtable()); + + return _items; + } + } + + private CacheAspect _cacheAspect; + public CacheAspect CacheAspect + { + get { return _cacheAspect; } + internal set { _cacheAspect = value; } + } + + [Obsolete("Use CacheAspect.Cache instead")] + public IDictionary MethodCallCache + { + get { return _cacheAspect != null? _cacheAspect.Cache: new Hashtable(); } + } + + #endregion + + #region Proptected Members + + private bool[] _cacheableParameters; + internal bool[] CacheableParameters + { + get { return _cacheableParameters; } + set { _cacheableParameters = value; } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/ClearCacheAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/ClearCacheAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using System; +using System.Reflection; + +namespace BLToolkit.Aspects +{ + public class ClearCacheAspect + { + public static MethodInfo GetMethodInfo( + object caller, Type declaringType, string methodName, Type[] parameterTypes) + { + if (declaringType == null) + declaringType = caller.GetType(); + + return CacheAspect.GetMethodInfo(declaringType, methodName, parameterTypes); + } + + public static Type GetType(object caller, Type declaringType) + { + if (declaringType == null) + declaringType = caller.GetType(); + + if (declaringType.IsAbstract) + declaringType = TypeBuilder.TypeFactory.GetType(declaringType); + + return declaringType; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/ClearCacheAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/ClearCacheAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,53 @@ +using System; + +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method, AllowMultiple=true)] + public class ClearCacheAttribute : AbstractTypeBuilderAttribute + { + #region Constructors + + public ClearCacheAttribute() + { + } + + public ClearCacheAttribute(string methodName) + { + _methodName = methodName; + } + + public ClearCacheAttribute(string methodName, params Type[] parameterTypes) + { + _methodName = methodName; + _parameterTypes = parameterTypes; + } + + public ClearCacheAttribute(Type declaringType, string methodName, params Type[] parameterTypes) + { + _declaringType = declaringType; + _methodName = methodName; + _parameterTypes = parameterTypes; + } + + public ClearCacheAttribute(Type declaringType) + { + _declaringType = declaringType; + } + + readonly Type _declaringType; + readonly string _methodName; + readonly Type[] _parameterTypes; + + #endregion + + public override IAbstractTypeBuilder TypeBuilder + { + get { return new Builders.ClearCacheAspectBuilder(_declaringType, _methodName, _parameterTypes); } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/CounterAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/CounterAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,118 @@ +using System; +using System.Collections; +using System.Reflection; +using System.Threading; + +namespace BLToolkit.Aspects +{ + public delegate MethodCallCounter CreateCounter(CallMethodInfo methodInfo); + + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [System.Diagnostics.DebuggerStepThrough] + public class CounterAspect : Interceptor + { + public override void Init(CallMethodInfo info, string configString) + { + base.Init(info, configString); + + _counters.Add(_counter = CreateCounter(info) ?? CreateCounterInternal(info)); + } + + private MethodCallCounter _counter; + + static readonly LocalDataStoreSlot _counterSlot = Thread.AllocateDataSlot(); + + protected override void BeforeCall(InterceptCallInfo info) + { + if (!IsEnabled || Thread.GetData(_counterSlot) != null) + return; + + _counter.RegisterCall(info); + + Thread.SetData(_counterSlot, _counter); + } + + protected override void OnFinally(InterceptCallInfo info) + { + if (!IsEnabled) + return; + + MethodCallCounter prev = (MethodCallCounter)Thread.GetData(_counterSlot); + + if (_counter == prev) + { + _counter.UnregisterCall(info); + + Thread.SetData(_counterSlot, null); + } + } + + #region Parameters + + private static bool _isEnabled = true; + public static bool IsEnabled + { + get { return _isEnabled; } + set { _isEnabled = value; } + } + + #endregion + + #region Counter + + private static readonly ArrayList _counters = ArrayList.Synchronized(new ArrayList()); + public static ArrayList Counters + { + get { return _counters; } + } + + public static MethodCallCounter GetCounter(MethodInfo methodInfo) + { + lock (_counters.SyncRoot) + foreach (MethodCallCounter c in _counters) + { + if ((methodInfo.DeclaringType == c.MethodInfo.DeclaringType || + methodInfo.DeclaringType == c.MethodInfo.DeclaringType.BaseType) && + methodInfo.Name == c.MethodInfo.Name) + { + ParameterInfo[] ps1 = c.MethodInfo.GetParameters(); + ParameterInfo[] ps2 = methodInfo.GetParameters(); + + if (ps1.Length == ps2.Length) + { + bool isMatched = true; + + for (int i = 0; isMatched && i < ps1.Length; i++) + isMatched = ps1[i].ParameterType == ps2[i].ParameterType; + + if (isMatched) + return c; + } + } + } + + return null; + } + + #region CreateCounter + + private static CreateCounter _createCounter = CreateCounterInternal; + + public static CreateCounter CreateCounter + { + get { return _createCounter; } + set { _createCounter = value ?? new CreateCounter(CreateCounterInternal); } + } + + private static MethodCallCounter CreateCounterInternal(CallMethodInfo methodInfo) + { + return new MethodCallCounter(methodInfo); + } + + #endregion + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/CounterAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/CounterAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,37 @@ +using System; + +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Interface | + AttributeTargets.Property | + AttributeTargets.Method, + AllowMultiple=true)] + public class CounterAttribute : InterceptorAttribute + { + public CounterAttribute() + : this(typeof(CounterAspect), null) + { + } + + public CounterAttribute(string configString) + : this(typeof(CounterAspect), configString) + { + } + + protected CounterAttribute(Type interceptorType, string configString) + : base( + interceptorType, + InterceptType.BeforeCall | InterceptType.OnCatch | InterceptType.OnFinally, + configString, + TypeBuilderConsts.Priority.Normal) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/IInterceptor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/IInterceptor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +namespace BLToolkit.Aspects +{ + public interface IInterceptor + { + void Init (CallMethodInfo info, string configString); + void Intercept(InterceptCallInfo info); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/InstanceCacheAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/InstanceCacheAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,79 @@ +using System; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Interface | + AttributeTargets.Property | + AttributeTargets.Method, + AllowMultiple=true)] + public class InstanceCacheAttribute : CacheAttribute + { + #region Constructors + + public InstanceCacheAttribute() + : this(typeof(CacheAspect), null) + { + } + + public InstanceCacheAttribute(Type cacheAspectType, string configString) + : base(cacheAspectType, configString) + { + } + + public InstanceCacheAttribute(Type interceptorType) + : this(interceptorType, null) + { + } + + public InstanceCacheAttribute(Type interceptorType, int maxCacheTime) + : this(interceptorType, null) + { + MaxCacheTime = maxCacheTime; + } + + public InstanceCacheAttribute(Type interceptorType, bool isWeak) + : this(interceptorType, null) + { + IsWeak = isWeak; + } + + public InstanceCacheAttribute(Type interceptorType, int maxCacheTime, bool isWeak) + : this(interceptorType, null) + { + MaxCacheTime = maxCacheTime; + IsWeak = isWeak; + } + + public InstanceCacheAttribute(string configString) + : this(typeof(CacheAspect), configString) + { + } + + public InstanceCacheAttribute(int maxCacheTime) + : this(typeof(CacheAspect), maxCacheTime) + { + } + + public InstanceCacheAttribute(bool isWeak) + : this(typeof(CacheAspect), isWeak) + { + } + + public InstanceCacheAttribute(int maxCacheTime, bool isWeak) + : this(typeof(CacheAspect), maxCacheTime, isWeak) + { + } + + #endregion + + public override bool LocalInterceptor + { + get { return true; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/InterceptCallInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/InterceptCallInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,124 @@ +using System; +using System.Collections; +using System.Diagnostics; +using System.Security.Principal; +using System.Threading; +using BLToolkit.Properties; + +namespace BLToolkit.Aspects +{ + [DebuggerStepThrough] + public sealed class InterceptCallInfo + { + public InterceptCallInfo() + { + _currentPrincipal = Thread.CurrentPrincipal; + _currentThread = Thread.CurrentThread; + } + + private CallMethodInfo _callMethodInfo; + public CallMethodInfo CallMethodInfo + { + get { return _callMethodInfo; } + set + { + if (_callMethodInfo == value) + { + // A race condition. + // + return; + } + + if (_callMethodInfo != null) + throw new InvalidOperationException(Resources.InterceptCallInfo_CallMethodInfoIsNotMutable); + + _callMethodInfo = value; + + int len = value.MethodInfo.GetParameters().Length; + + _parameterValues = len == 0? _emptyValues: new object[len]; + } + } + + private readonly object[] _emptyValues = new object[0]; + + private object[] _parameterValues; + public object[] ParameterValues + { + get { return _parameterValues; } + set { _parameterValues = value; } + } + + private object _returnValue; + public object ReturnValue + { + get { return _returnValue; } + set { _returnValue = value; } + } + + private InterceptResult _interceptResult = InterceptResult.Continue; + public InterceptResult InterceptResult + { + get { return _interceptResult; } + set { _interceptResult = value; } + } + + private InterceptType _interceptType; + public InterceptType InterceptType + { + get { return _interceptType; } + set { _interceptType = value; } + } + + private Exception _exception; + public Exception Exception + { + get { return _exception; } + set { _exception = value; } + } + + private Hashtable _items; + public IDictionary Items + { + get + { + if (_items == null) + _items = new Hashtable(); + + return _items; + } + } + + private readonly DateTime _beginCallTime = DateTime.Now; + public DateTime BeginCallTime + { + get { return _beginCallTime; } + } + + private readonly IPrincipal _currentPrincipal; + public IPrincipal CurrentPrincipal + { + get { return _currentPrincipal; } + } + + private readonly Thread _currentThread; + public Thread CurrentThread + { + get { return _currentThread; } + } + + private bool _cached; + public bool Cached + { + get { return _cached; } + set { _cached = value; } + } + + private object _object; + public object Object + { + get { return _object; } + set { _object = value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/InterceptResult.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/InterceptResult.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +namespace BLToolkit.Aspects +{ + public enum InterceptResult + { + Continue, + Return + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/InterceptType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/InterceptType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; + +namespace BLToolkit.Aspects +{ + [Flags] + public enum InterceptType + { + BeforeCall = 0x01, + AfterCall = 0x02, + OnCatch = 0x04, + OnFinally = 0x08 + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/Interceptor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/Interceptor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +namespace BLToolkit.Aspects +{ + [System.Diagnostics.DebuggerStepThrough] + public abstract class Interceptor : IInterceptor + { + public virtual void Init(CallMethodInfo info, string configString) + { + } + + public virtual void Intercept(InterceptCallInfo info) + { + switch (info.InterceptType) + { + case InterceptType.BeforeCall: BeforeCall(info); break; + case InterceptType.AfterCall: AfterCall (info); break; + case InterceptType.OnCatch: OnCatch (info); break; + case InterceptType.OnFinally: OnFinally (info); break; + } + } + + protected virtual void BeforeCall(InterceptCallInfo info) {} + protected virtual void AfterCall (InterceptCallInfo info) {} + protected virtual void OnCatch (InterceptCallInfo info) {} + protected virtual void OnFinally (InterceptCallInfo info) {} + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/InterceptorAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/InterceptorAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,88 @@ +using System; + +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects +{ + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Interface | + AttributeTargets.Property | + AttributeTargets.Method, + AllowMultiple=true)] + public class InterceptorAttribute : AbstractTypeBuilderAttribute + { + public InterceptorAttribute(Type interceptorType, InterceptType interceptType) + : this(interceptorType, interceptType, null, TypeBuilderConsts.Priority.Normal) + { + } + + public InterceptorAttribute(Type interceptorType, InterceptType interceptType, int priority) + : this(interceptorType, interceptType, null, priority) + { + } + + public InterceptorAttribute(Type interceptorType, InterceptType interceptType, string parameters) + : this(interceptorType, interceptType, parameters, TypeBuilderConsts.Priority.Normal) + { + } + + public InterceptorAttribute( + Type interceptorType, InterceptType interceptType, string configString, int priority) + : this(interceptorType, interceptType, configString, priority, false) + { + } + + public InterceptorAttribute( + Type interceptorType, InterceptType interceptType, string configString, int priority, bool localInterceptor) + { + if (interceptorType == null && interceptType != 0) + throw new ArgumentNullException("interceptorType"); + + _interceptorType = interceptorType; + _interceptType = interceptType; + _configString = configString; + _priority = priority; + _localInterceptor = localInterceptor; + } + + private readonly Type _interceptorType; + public virtual Type InterceptorType + { + get { return _interceptorType; } + } + + private readonly InterceptType _interceptType; + public virtual InterceptType InterceptType + { + get { return _interceptType; } + } + + private readonly int _priority; + public virtual int Priority + { + get { return _priority; } + } + + private readonly string _configString; + public virtual string ConfigString + { + get { return _configString; } + } + + private readonly bool _localInterceptor; + public virtual bool LocalInterceptor + { + get { return _localInterceptor; } + } + + public override IAbstractTypeBuilder TypeBuilder + { + get + { + return new Builders.InterceptorAspectBuilder( + InterceptorType, InterceptType, ConfigString, Priority, LocalInterceptor); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/LogAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/LogAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,87 @@ +using System; + +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Interface | + AttributeTargets.Property | + AttributeTargets.Method, + AllowMultiple=true)] + public class LogAttribute : InterceptorAttribute + { + public LogAttribute() + : this(typeof(LoggingAspect), null) + { + } + + public LogAttribute(string parameters) + : this(typeof(LoggingAspect), parameters) + { + } + + protected LogAttribute(Type interceptorType, string parameters) + : base( + interceptorType, + InterceptType.OnCatch | InterceptType.OnFinally, + parameters, + TypeBuilderConsts.Priority.LoggingAspect) + { + } + + private bool _hasFileName; + private string _fileName; + public string FileName + { + get { return _fileName; } + set { _fileName = value; _hasFileName = true; } + } + + private bool _hasMinCallTime; + private int _minCallTime; + public int MinCallTime + { + get { return _minCallTime; } + set { _minCallTime = value; _hasMinCallTime = true; } + } + + private bool _hasLogExceptions; + private bool _logExceptions; + public bool LogExceptions + { + get { return _logExceptions; } + set { _logExceptions = value; _hasLogExceptions = true;} + } + + private bool _hasLogParameters; + private bool _logParameters; + public bool LogParameters + { + get { return _logParameters; } + set { _logParameters = value; _hasLogParameters = true;} + } + + public override string ConfigString + { + get + { + string s = base.ConfigString; + + if (_hasFileName) s += ";FileName=" + FileName; + if (_hasMinCallTime) s += ";MinCallTime=" + MinCallTime; + if (_hasLogExceptions) s += ";LogExceptions=" + LogExceptions; + if (_hasLogParameters) s += ";LogParameters=" + LogParameters; + + if (!string.IsNullOrEmpty(s) && s[0] == ';') + s = s.Substring(1); + + return s; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/LoggingAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/LoggingAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,212 @@ +using System; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Collections; +using System.Text; + +namespace BLToolkit.Aspects +{ + public delegate void LogOperation(InterceptCallInfo interceptCallInfo, LoggingAspect.Parameters parameters); + public delegate void LogOutput (string logText, string fileName); + + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + public class LoggingAspect : Interceptor + { + public class Parameters + { + public string FileName; + public int MinCallTime; + public bool LogExceptions; + public bool LogParameters; + } + + private string _instanceFileName; + private int? _instanceMinCallTime; + private bool? _instanceLogExceptions; + private bool? _instanceLogParameters; + private readonly Parameters _parameters = new Parameters(); + + public override void Init(CallMethodInfo info, string configString) + { + base.Init(info, configString); + + string[] ps = configString.Split(';'); + + foreach (string p in ps) + { + string[] vs = p.Split('='); + + if (vs.Length == 2) + { + switch (vs[0].ToLower().Trim()) + { + case "filename": _instanceFileName = vs[1].Trim(); break; + case "mincalltime": _instanceMinCallTime = int. Parse(vs[1].Trim()); break; + case "logexceptions": _instanceLogExceptions = bool.Parse(vs[1].Trim()); break; + case "logparameters": _instanceLogParameters = bool.Parse(vs[1].Trim()); break; + } + } + } + } + + protected override void OnFinally(InterceptCallInfo info) + { + if (IsEnabled) + { + _parameters.FileName = _instanceFileName ?? FileName; + _parameters.MinCallTime = _instanceMinCallTime ?? MinCallTime; + _parameters.LogExceptions = _instanceLogExceptions ?? LogExceptions; + _parameters.LogParameters = _instanceLogParameters ?? LogParameters; + + LogOperation(info, _parameters); + } + } + + #region Parameters + + private static bool _logParameters = true; + public static bool LogParameters + { + get { return _logParameters; } + set { _logParameters = value; } + } + + private static bool _logExceptions = true; + public static bool LogExceptions + { + get { return _logExceptions; } + set { _logExceptions = value; } + } + + private static int _minCallTime; + public static int MinCallTime + { + get { return _minCallTime; } + set { _minCallTime = value; } + } + + private static string _fileName; + public static string FileName + { + get { return _fileName; } + set { _fileName = value; } + } + + private static bool _isEnabled = true; + public static bool IsEnabled + { + get { return _isEnabled; } + set { _isEnabled = value; } + } + + #endregion + + #region LogOperation + + private static LogOperation _logOperation = LogOperationInternal; + public static LogOperation LogOperation + { + get { return _logOperation; } + set { _logOperation = value ?? LogOperationInternal; } + } + + private static void LogOperationInternal(InterceptCallInfo info, Parameters parameters) + { + DateTime end = DateTime.Now; + int time = (int)((end - info.BeginCallTime).TotalMilliseconds); + + if (info.Exception != null && parameters.LogExceptions || + info.Exception == null && time >= parameters.MinCallTime) + { + string callParameters = null; + int plen = info.ParameterValues.Length; + + if (parameters.LogParameters && plen > 0) + { + StringBuilder sb = new StringBuilder(); + object[] values = info.ParameterValues; + + FormatParameter(values[0], sb); + for (int i = 1; i < plen; i++) + { + FormatParameter(values[i], sb.Append(", ")); + } + + callParameters = sb.ToString(); + } + + string exText = null; + + if (info.Exception != null) + exText = string.Format( + " with exception '{0}' - \"{1}\"", + info.Exception.GetType().FullName, + info.Exception.Message); + + LogOutput( + string.Format("{0}: {1}.{2}({3}) - {4} ms{5}{6}.", + end, + info.CallMethodInfo.MethodInfo.DeclaringType.FullName, + info.CallMethodInfo.MethodInfo.Name, + callParameters, + time, + info.Cached? " from cache": null, + exText), + parameters.FileName); + } + } + + private static void FormatParameter(object parameter, StringBuilder sb) + { + if (parameter == null) + sb.Append(""); + else if (parameter is string) + sb.Append('"').Append((string)parameter).Append('"'); + else if (parameter is char) + sb.Append('\'').Append((char)parameter).Append('\''); + else if (parameter is IEnumerable) + { + sb.Append('['); + bool first = true; + foreach (object item in (IEnumerable)parameter) + { + FormatParameter(item, first? sb: sb.Append(',')); + first = false; + } + sb.Append(']'); + } + else if (parameter is IFormattable) + { + IFormattable formattable = (IFormattable)parameter; + sb.Append(formattable.ToString(null, CultureInfo.InvariantCulture)); + } + else + sb.Append(parameter.ToString()); + } + + #endregion + + #region LogOuput + + private static LogOutput _logOutput = LogOutputInternal; + public static LogOutput LogOutput + { + get { return _logOutput; } + set { _logOutput = value ?? LogOutputInternal; } + } + + private static void LogOutputInternal(string logText, string fileName) + { + if (string.IsNullOrEmpty(fileName)) + Debug.WriteLine(logText); + else + using (StreamWriter sw = new StreamWriter(fileName, true)) + sw.WriteLine(logText); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/MethodCallCounter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/MethodCallCounter.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,129 @@ +using System; +using System.Collections; +using System.Reflection; + +namespace BLToolkit.Aspects +{ + [System.Diagnostics.DebuggerStepThrough] + public class MethodCallCounter + { + public MethodCallCounter(CallMethodInfo methodInfo) + { + _callMethodInfo = methodInfo; + _methodInfo = methodInfo.MethodInfo; + } + + #region Public Members + + private MethodInfo _methodInfo; + public MethodInfo MethodInfo + { + get { return _methodInfo; } + set { _methodInfo = value; } + } + + private CallMethodInfo _callMethodInfo; + public CallMethodInfo CallMethodInfo + { + get { return _callMethodInfo; } + set { _callMethodInfo = value; } + } + + private int _totalCount; + public int TotalCount + { + get { return _totalCount; } + set { _totalCount = value; } + } + + private int _exceptionCount; + public int ExceptionCount + { + get { return _exceptionCount; } + set { _exceptionCount = value; } + } + + private int _cachedCount; + public int CachedCount + { + get { return _cachedCount; } + set { _cachedCount = value; } + } + + private TimeSpan _totalTime; + public TimeSpan TotalTime + { + get { return _totalTime; } + set { _totalTime = value; } + } + + private TimeSpan _minTime = TimeSpan.MaxValue; + public TimeSpan MinTime + { + get { return _minTime; } + set { _minTime = value; } + } + + private TimeSpan _maxTime; + public TimeSpan MaxTime + { + get { return _maxTime; } + set { _maxTime = value; } + } + + private readonly ArrayList _currentCalls = ArrayList.Synchronized(new ArrayList()); + public ArrayList CurrentCalls + { + get { return _currentCalls; } + } + + public TimeSpan AverageTime + { + get + { + if (_totalCount == 0) + return TimeSpan.MinValue; + + return new TimeSpan(TotalTime.Ticks / TotalCount); + } + } + + #endregion + + #region Protected Members + + public virtual void RegisterCall(InterceptCallInfo info) + { + lock (_currentCalls.SyncRoot) + _currentCalls.Add(info); + } + + public virtual void UnregisterCall(InterceptCallInfo info) + { + AddCall(DateTime.Now - info.BeginCallTime, info.Exception != null, info.Cached); + + lock (_currentCalls.SyncRoot) + _currentCalls.Remove(info); + } + + protected void AddCall(TimeSpan time, bool withException, bool cached) + { + if (cached) + { + _cachedCount++; + } + else + { + _totalTime += time; + _totalCount++; + + if (_minTime > time) _minTime = time; + if (_maxTime < time) _maxTime = time; + } + + if (withException) _exceptionCount++; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/MixinAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/MixinAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,72 @@ +using System; + +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple=true)] + public sealed class MixinAttribute : AbstractTypeBuilderAttribute + { + public MixinAttribute( + Type targetInterface, string memberName, bool throwExceptionIfNull, string exceptionMessage) + { + _targetInterface = targetInterface; + _memberName = memberName; + _throwExceptionIfNull = throwExceptionIfNull; + _exceptionMessage = exceptionMessage; + } + + public MixinAttribute(Type targetInterface, string memberName, bool throwExceptionIfNull) + : this(targetInterface, memberName, throwExceptionIfNull, null) + { + } + + public MixinAttribute(Type targetInterface, string memberName, string exceptionMessage) + : this(targetInterface, memberName, true, exceptionMessage) + { + } + + public MixinAttribute(Type targetInterface, string memberName) + : this(targetInterface, memberName, true, null) + { + } + + private readonly Type _targetInterface; + public Type TargetInterface + { + get { return _targetInterface; } + } + + private readonly string _memberName; + public string MemberName + { + get { return _memberName; } + } + + private bool _throwExceptionIfNull; + public bool ThrowExceptionIfNull + { + get { return _throwExceptionIfNull; } + set { _throwExceptionIfNull = value; } + } + + private string _exceptionMessage; + public string ExceptionMessage + { + get { return _exceptionMessage; } + set { _exceptionMessage = value; } + } + + public override IAbstractTypeBuilder TypeBuilder + { + get + { + return new Builders.MixinAspectBuilder( + _targetInterface, _memberName, _throwExceptionIfNull, _exceptionMessage); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/MixinOverrideAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/MixinOverrideAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,45 @@ +using System; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple=true)] + public class MixinOverrideAttribute : Attribute + { + public MixinOverrideAttribute(Type targetInterface, string methodName) + { + _targetInterface = targetInterface; + _methodName = methodName; + } + + public MixinOverrideAttribute(Type targetInterface) + : this(targetInterface, null) + { + } + + public MixinOverrideAttribute(string methodName) + : this(null, methodName) + { + } + + public MixinOverrideAttribute() + { + } + + private Type _targetInterface; + public Type TargetInterface + { + get { return _targetInterface; } + set { _targetInterface = value; } + } + + private string _methodName; + public string MethodName + { + get { return _methodName; } + set { _methodName = value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/NoCacheAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/NoCacheAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +using System; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Interface | + AttributeTargets.Property | + AttributeTargets.Method, + AllowMultiple=true)] + public class NoCacheAttribute : NoInterceptionAttribute + { + public NoCacheAttribute() + : base(typeof(CacheAspect), InterceptType.BeforeCall | InterceptType.AfterCall) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/NoCounterAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/NoCounterAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +using System; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Interface | + AttributeTargets.Property | + AttributeTargets.Method, + AllowMultiple=true)] + public class NoCounterAttribute : NoInterceptionAttribute + { + public NoCounterAttribute() + : base(typeof(CounterAspect), InterceptType.BeforeCall | InterceptType.OnFinally) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/NoInterceptionAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/NoInterceptionAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,44 @@ +using System; + +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects +{ + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Interface | + AttributeTargets.Property | + AttributeTargets.Method, + AllowMultiple=true)] + public class NoInterceptionAttribute : InterceptorAttribute + { + public NoInterceptionAttribute() + : base(null, 0) + { + } + + public NoInterceptionAttribute(Type interceptorType, InterceptType interceptType) + : base(interceptorType, interceptType) + { + } + + public override IAbstractTypeBuilder TypeBuilder + { + get { return new NoInterceptionAspectBuilder(InterceptorType, InterceptType); } + } + + private class NoInterceptionAspectBuilder : Builders.InterceptorAspectBuilder + { + public NoInterceptionAspectBuilder(Type interceptorType, InterceptType interceptType) + : base(interceptorType, interceptType, null, TypeBuilderConsts.Priority.Normal, false) + { + } + + public override void Build(BuildContext context) + { + if (context.Step == BuildStep.Begin || context.Step == BuildStep.End) + base.Build(context); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/NoLogAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/NoLogAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +using System; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Interface | + AttributeTargets.Property | + AttributeTargets.Method, + AllowMultiple=true)] + public class NoLogAttribute : NoInterceptionAttribute + { + public NoLogAttribute() + : base(typeof(LoggingAspect), InterceptType.OnCatch | InterceptType.OnFinally) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/NotNullAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/NotNullAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,34 @@ +using System; + +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage(AttributeTargets.Parameter)] + public sealed class NotNullAttribute : AbstractTypeBuilderAttribute + { + public NotNullAttribute() + { + } + + public NotNullAttribute(string message) + { + _message = message; + } + + private string _message; + public string Message + { + get { return _message; } + set { _message = value; } + } + + public override IAbstractTypeBuilder TypeBuilder + { + get { return new Builders.NotNullAspectBuilder(_message); } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Aspects/OverloadAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/OverloadAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,38 @@ +using System; +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Aspects +{ + /// + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// + [AttributeUsage(AttributeTargets.Method)] + public sealed class OverloadAttribute : AbstractTypeBuilderAttribute + { + private readonly string _overloadedMethodName; + private readonly Type[] _parameterTypes; + + public OverloadAttribute() + { + } + + public OverloadAttribute(string overloadedMethodName): this(overloadedMethodName, null) + { + } + + public OverloadAttribute(params Type[] parameterTypes): this(null, parameterTypes) + { + } + + public OverloadAttribute(string overloadedMethodName, params Type[] parameterTypes) + { + _overloadedMethodName = overloadedMethodName; + _parameterTypes = parameterTypes; + } + + public override IAbstractTypeBuilder TypeBuilder + { + get { return new Builders.OverloadAspectBuilder(_overloadedMethodName, _parameterTypes); } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/BLToolkit.3.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/BLToolkit.3.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,734 @@ + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {0C325F5D-E50E-4340-8724-D29896CCC583} + Library + Properties + BLToolkit + BLToolkit.3 + + + 2.0 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + v3.5 + true + BLToolkit.snk + + + true + full + false + bin\Debug\ + TRACE;DEBUG;OVERRIDETOSTRING;FW3; + prompt + 4 + -Microsoft.Globalization#CA1303;-Microsoft.Design#CA1020;-Microsoft.Design#CA1019;-Microsoft.Design#CA1000;-Microsoft.Design#CA1002;-Microsoft.Design#CA1004;-Microsoft.Design#CA1035;-Microsoft.Design#CA1039;-Microsoft.Design#CA1024;-Microsoft.Globalization#CA1304;-Microsoft.Globalization#CA1305;-Microsoft.Maintainability#CA1502;-Microsoft.Naming#CA1709;-Microsoft.Naming#CA1704;-Microsoft.Naming#CA1710;-Microsoft.Naming#CA1720;-Microsoft.Naming#CA1707;-Microsoft.Performance#CA1800;-Microsoft.Performance#CA1819;-Microsoft.Usage#CA2223;-Microsoft.Usage#CA2225 + + + + + pdbonly + true + bin\Release\ + TRACE;FW3;OVERRIDETOSTRING + prompt + 4 + -Microsoft.Design#CA1019;-Microsoft.Design#CA1000;-Microsoft.Design#CA1004;-Microsoft.Design#CA1035;-Microsoft.Design#CA1033;-Microsoft.Design#CA1039;-Microsoft.Design#CA1024;-Microsoft.Globalization#CA1303;-Microsoft.Globalization#CA1304;-Microsoft.Globalization#CA1305;-Microsoft.Naming#CA1720;-Microsoft.Naming#CA1709;-Microsoft.Naming#CA1710;-Microsoft.Naming#CA1707;-Microsoft.Naming#CA1706;-Microsoft.Performance#CA1819;-Microsoft.Usage#CA2223;-Microsoft.Usage#CA2225 + + + + + + + + + + 3.5 + + + + 3.5 + + + + + + 3.0 + + + 3.0 + + + + + + + 3.5 + + + 3.0 + + + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + + + + + + + + + + + True + True + Convert.tt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + True + True + MemberMapper.tt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + Form + + + GetTypeDialog.cs + + + + UserControl + + + TypePicker.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + DbManager.cs + Component + + + DbManager.cs + Component + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Designer + GetTypeDialog.cs + + + Designer + TypePicker.cs + + + + + + ObjectBinder.cs + Designer + + + + + + + + + + + + + + + + + TextTemplatingFileGenerator + Convert.generated.cs + + + DataAccess.xsd + + + + + Mapping.xsd + + + + + + + TextTemplatingFileGenerator + MemberMapper.generated.cs + + + TypeExtension.xsd + + + + + + + + + + + + + + + + + + + + + + + Designer + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/BLToolkit.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/BLToolkit.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,817 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {0C325F5D-E50E-4340-8724-D29896CCC583} + Library + Properties + BLToolkit + BLToolkit.4 + + + 3.5 + + + false + v4.0 + true + BLToolkit.snk + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + false + bin\Debug\ + TRACE;DEBUG;FW4;OVERRIDETOSTRING; + prompt + 4 + + + Migrated rules for BLToolkit.4.ruleset + + + pdbonly + true + bin\Release\ + TRACE;FW4;OVERRIDETOSTRING;NEW_PARSER + prompt + 4 + + + Migrated rules for BLToolkit.4 (2).ruleset + + + true + bin\Debug FW 3.5\ + TRACE;DEBUG;FW3;TRACE_PARSING1;OVERRIDETOSTRING1 + full + AnyCPU + bin\Debug\BLToolkit.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + Migrated rules for BLToolkit.4.ruleset + ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + 4 + false + + + true + bin\DebugMono\ + TRACE;DEBUG;FW4;MONO;OVERRIDETOSTRING;NEW_PARSER + full + AnyCPU + bin\Debug\BLToolkit.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + Migrated rules for BLToolkit.4.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + 4 + false + + + bin\ReleaseMono\ + TRACE;FW4;MONO;OVERRIDETOSTRING + true + pdbonly + AnyCPU + bin\Release\BLToolkit.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + Migrated rules for BLToolkit.4 (2).ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextTemplatingFileGenerator + Convert.generated.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + + + + + + + + + + + + True + True + Convert.tt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + MemberMapper.tt + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + Form + + + GetTypeDialog.cs + + + + UserControl + + + TypePicker.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + DbManager.cs + Component + + + DbManager.cs + Component + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextTemplatingFileGenerator + MemberMapper.generated.cs + + + Revision1.generated.cs + + + + + + + + + + + + + + + Designer + GetTypeDialog.cs + + + Designer + TypePicker.cs + + + + + + ObjectBinder.cs + Designer + + + + + + + + + + + + + + + + + DataAccess.xsd + + + + + Mapping.xsd + + + + + + + TypeExtension.xsd + + + + + + + + + + Designer + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/BLToolkit.4.csproj.DotSettings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/BLToolkit.4.csproj.DotSettings Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2 @@ + + No \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/BLToolkit.4.csproj.ReSharper --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/BLToolkit.4.csproj.ReSharper Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3 @@ + + No + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/BLToolkit.CP.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/BLToolkit.CP.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,769 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {0C325F5D-E50E-4340-8724-D29896CCC585} + Library + Properties + BLToolkit + BLToolkit.CP.4 + + + 3.5 + + + false + v4.0 + true + BLToolkit.snk + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + Client + + + true + full + false + bin\Debug\ + TRACE;DEBUG;FW4;OVERRIDETOSTRING;CLIENTPROFILE; + prompt + 4 + + + Migrated rules for BLToolkit.4.ruleset + + + pdbonly + true + bin\Release\ + TRACE;FW4;OVERRIDETOSTRING;CLIENTPROFILE; + prompt + 4 + + + Migrated rules for BLToolkit.4 (2).ruleset + + + true + bin\Debug FW 3.5\ + TRACE;DEBUG;FW3;TRACE_PARSING1;OVERRIDETOSTRING1;CLIENTPROFILE; + full + AnyCPU + bin\Debug\BLToolkit.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + Migrated rules for BLToolkit.4.ruleset + ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + 4 + false + + + true + bin\DebugMono\ + TRACE;DEBUG;FW4;MONO;OVERRIDETOSTRING;CLIENTPROFILE; + full + AnyCPU + bin\Debug\BLToolkit.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + Migrated rules for BLToolkit.4.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + 4 + false + + + bin\ReleaseMono\ + TRACE;FW4;MONO;OVERRIDETOSTRING;CLIENTPROFILE; + true + pdbonly + AnyCPU + bin\Release\BLToolkit.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + Migrated rules for BLToolkit.4 (2).ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextTemplatingFileGenerator + Convert.generated.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + + + + + + + + + + + + True + True + Convert.tt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + MemberMapper.tt + + + + + + True + True + Resources.resx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + DbManager.cs + Component + + + DbManager.cs + Component + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextTemplatingFileGenerator + MemberMapper.generated.cs + + + Revision1.generated.cs + + + + + + + + + + + + + + + ObjectBinder.cs + Designer + + + + + + + + + + + + + + + + + DataAccess.xsd + + + + + Mapping.xsd + + + + + + + TypeExtension.xsd + + + + + + + + + + Designer + ResXFileCodeGenerator + Resources.Designer.cs + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/BLToolkit.Data.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/BLToolkit.Data.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,743 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {0C325F5D-E50E-4340-8724-D29896CCC584} + Library + Properties + BLToolkit + BLToolkit.Data.4 + + + 3.5 + + + false + v4.0 + true + BLToolkit.snk + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + + + true + full + false + bin\Debug\ + TRACE;DEBUG;FW4;DATA;OVERRIDETOSTRING; + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE;FW4;DATA;OVERRIDETOSTRING + prompt + 4 + + + true + bin\Debug FW 3.5\ + TRACE;DEBUG;FW3;DATA;TRACE_PARSING1;OVERRIDETOSTRING1 + full + AnyCPU + prompt + 4 + false + + + true + bin\DebugMono\ + TRACE;DEBUG;FW4;DATA;MONO;OVERRIDETOSTRING;NEW_PARSER + full + AnyCPU + prompt + 4 + false + + + bin\ReleaseMono\ + TRACE;FW4;DATA;MONO;OVERRIDETOSTRING + true + pdbonly + AnyCPU + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + TextTemplatingFileGenerator + Convert.generated.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + DataProviderBase.cs + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + True + True + Convert.tt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + MemberMapper.tt + + + + + Code + + + Code + + + Code + + + + True + True + Resources.resx + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + DbManager.cs + Component + + + DbManager.cs + Component + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextTemplatingFileGenerator + MemberMapper.generated.cs + + + Revision1.generated.cs + + + + + + + + + + + + + + DataAccess.xsd + + + Mapping.xsd + + + + + + + TypeExtension.xsd + + + + + + Designer + ResXFileCodeGenerator + Resources.Designer.cs + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/BLToolkit.SL.4.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/BLToolkit.SL.4.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,473 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {663D4BFC-F565-41F7-9409-510B560CCEE8} + {A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + BLToolkit + BLToolkit.SL.4 + Silverlight + v4.0 + $(TargetFrameworkVersion) + false + true + true + + + + v3.5 + + + true + full + false + Bin\Debug + DEBUG;TRACE;SILVERLIGHT + true + true + prompt + 4 + + + pdbonly + true + Bin\Release + TRACE;SILVERLIGHT + true + true + prompt + 4 + + + true + bin\DebugMono\ + DEBUG;TRACE;SILVERLIGHT + true + full + AnyCPU + Bin\Debug\BLToolkit.SL.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + true + + + bin\ReleaseMono\ + TRACE;SILVERLIGHT + true + true + pdbonly + AnyCPU + Bin\Release\BLToolkit.SL.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + + + + + + + + + + + + + False + + + + + + + + + + True + True + Convert.tt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + MemberMapper.tt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TypeExtension.xsd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextTemplatingFileGenerator + Convert.generated.cs + + + TextTemplatingFileGenerator + MemberMapper.generated.cs + + + Designer + + + TypeExtension.xsd + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/BLToolkit.mono.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/BLToolkit.mono.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,729 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {0C325F5D-E50E-4340-8724-D29896CCC583} + Library + Properties + BLToolkit + BLToolkit.4 + + + 3.5 + + + false + true + BLToolkit.snk + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + false + bin\Debug\ + TRACE;DEBUG;FW4;OVERRIDETOSTRING; + prompt + 4 + + + Migrated rules for BLToolkit.4.ruleset + + + pdbonly + true + bin\Release\ + TRACE;FW4;OVERRIDETOSTRING;NEW_PARSER + prompt + 4 + + + Migrated rules for BLToolkit.4 (2).ruleset + + + true + bin\Debug FW 3.5\ + TRACE;DEBUG;FW3;TRACE_PARSING1;OVERRIDETOSTRING1 + full + AnyCPU + bin\Debug\BLToolkit.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + Migrated rules for BLToolkit.4.ruleset + ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + 4 + false + + + true + bin\DebugMono\ + TRACE;DEBUG;FW4;MONO;OVERRIDETOSTRING + full + AnyCPU + bin\Debug\BLToolkit.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + Migrated rules for BLToolkit.4.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + 4 + false + + + bin\ReleaseMono\ + TRACE;FW4;MONO;OVERRIDETOSTRING + true + pdbonly + AnyCPU + bin\Release\BLToolkit.4.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + Migrated rules for BLToolkit.4 (2).ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + 4 + + + + + + + + + + + + + + + + + + + ..\packages\MySql.Data.6.4.4\lib\net40\mysql.data.dll + + + + + TextTemplatingFileGenerator + Convert.generated.cs + + + + + + + + + + + + + + True + True + Convert.tt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + MemberMapper.tt + + + + + + True + True + Resources.resx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + Form + + + GetTypeDialog.cs + + + + UserControl + + + TypePicker.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + DbManager.cs + Component + + + DbManager.cs + Component + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextTemplatingFileGenerator + MemberMapper.generated.cs + + + Revision1.generated.cs + + + + + + + + + + + + + + + + Designer + GetTypeDialog.cs + + + Designer + TypePicker.cs + + + + + + ObjectBinder.cs + Designer + + + + + + + + + + + + + + + + + DataAccess.xsd + + + + + Mapping.xsd + + + + + + + TypeExtension.xsd + + + + + + + + + + Designer + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/BLToolkit.snk Binary file Source/BLToolkit.snk has changed diff -r 000000000000 -r f990fcb411a9 Source/Common/ArrayT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/ArrayT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using System; + +using JetBrains.Annotations; + +namespace BLToolkit.Common +{ + public static class Array + { + [NotNull] + public static readonly T[] Empty = new T[0]; + } +} diff -r 000000000000 -r f990fcb411a9 Source/Common/Compatibility3.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/Compatibility3.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,294 @@ +#if FW2 + +namespace System +{ + public delegate void Action(); + + public delegate void Action(T1 arg1, T2 arg2); + + public delegate void Action(T1 arg1, T2 arg2, T3 arg3); + + public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4); + + public delegate TResult Func(); + + public delegate TResult Func(T1 arg1); + + public delegate TResult Func(T1 arg1, T2 arg2); + + public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3); + + public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4); +} + +namespace System.Collections.Specialized +{ + public interface INotifyCollectionChanged + { + event NotifyCollectionChangedEventHandler CollectionChanged; + } + + /// + /// This enum describes the action that caused a CollectionChanged event. + /// + public enum NotifyCollectionChangedAction + { + /// One or more items were added to the collection. + Add, + /// One or more items were removed from the collection. + Remove, + /// One or more items were replaced in the collection. + Replace, + /// One or more items were moved within the collection. + Move, + /// The contents of the collection changed dramatically. + Reset, + } + + /// + /// Arguments for the CollectionChanged event. A collection that supports + /// INotifyCollectionChangedThis raises this event whenever an item is added or + /// removed, or when the contents of the collection changes dramatically. + /// + public class NotifyCollectionChangedEventArgs : EventArgs + { + #region .ctors + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a reset change. + /// + /// The action that caused the event (must be Reset). + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action) + : this(action, null, -1) + { + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a one-item change. + /// + /// The action that caused the event; can only be Reset, Add or Remove action. + /// The item affected by the change. + public NotifyCollectionChangedEventArgs( + NotifyCollectionChangedAction action, + object changedItem) + : this(action, changedItem, -1) + { + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a one-item change. + /// + /// The action that caused the event. + /// The item affected by the change. + /// The index where the change occurred. + public NotifyCollectionChangedEventArgs( + NotifyCollectionChangedAction action, + object changedItem, + int index) + : this(action, changedItem == null? null: new[]{ changedItem }, index) + { + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a multi-item change. + /// + /// The action that caused the event. + /// The items affected by the change. + public NotifyCollectionChangedEventArgs( + NotifyCollectionChangedAction action, + IList changedItems) + : this(action, changedItems, -1) + { + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a multi-item change (or a reset). + /// + /// The action that caused the event. + /// The items affected by the change. + /// The index where the change occurred. + public NotifyCollectionChangedEventArgs( + NotifyCollectionChangedAction action, + IList changedItems, + int startingIndex) + { + _action = action; + + if (action == NotifyCollectionChangedAction.Add) + { + _newItems = changedItems; + _newStartingIndex = startingIndex; + } + else if (action == NotifyCollectionChangedAction.Remove) + { + _oldItems = changedItems; + _oldStartingIndex = startingIndex; + } + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a one-item Replace event. + /// + /// Can only be a Replace action. + /// The new item replacing the original item. + /// The original item that is replaced. + public NotifyCollectionChangedEventArgs( + NotifyCollectionChangedAction action, + object newItem, + object oldItem) + : this(action, new[] { newItem }, new[] { oldItem }, -1) + { + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a one-item Replace event. + /// + /// Can only be a Replace action. + /// The new item replacing the original item. + /// The original item that is replaced. + /// The index of the item being replaced. + public NotifyCollectionChangedEventArgs( + NotifyCollectionChangedAction action, + object newItem, + object oldItem, + int index) + : this(action, new[] { newItem }, new[] { oldItem }, index) + { + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a multi-item Replace event. + /// + /// Can only be a Replace action. + /// The new items replacing the original items. + /// The original items that are replaced. + public NotifyCollectionChangedEventArgs( + NotifyCollectionChangedAction action, + IList newItems, + IList oldItems) + : this(action, newItems, oldItems, -1) + { + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a multi-item Replace event. + /// + /// Can only be a Replace action. + /// The new items replacing the original items. + /// The original items that are replaced. + /// The starting index of the items being replaced. + public NotifyCollectionChangedEventArgs( + NotifyCollectionChangedAction action, + IList newItems, + IList oldItems, + int startingIndex) + { + _action = action; + + _newItems = newItems; + _newStartingIndex = startingIndex; + _oldItems = oldItems; + _oldStartingIndex = startingIndex; + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a one-item Move event. + /// + /// Can only be a Move action. + /// The item affected by the change. + /// The new index for the changed item. + /// The old index for the changed item. + public NotifyCollectionChangedEventArgs( + NotifyCollectionChangedAction action, + object changedItem, + int index, + int oldIndex) + : this(action, new[]{changedItem}, index, oldIndex) + { + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a multi-item Move event. + /// + /// The action that caused the event. + /// The items affected by the change. + /// The new index for the changed items. + /// The old index for the changed items. + public NotifyCollectionChangedEventArgs( + NotifyCollectionChangedAction action, + IList changedItems, + int index, + int oldIndex) + { + _action = action; + + _newItems = changedItems; + _newStartingIndex = index; + _oldItems = changedItems; + _oldStartingIndex = oldIndex; + } + + #endregion + + #region Properties + + private readonly NotifyCollectionChangedAction _action; + /// + /// The action that caused the event. + /// + public NotifyCollectionChangedAction Action + { + get { return _action; } + } + + private readonly IList _newItems; + /// + /// The items affected by the change. + /// + public IList NewItems + { + get { return _newItems; } + } + + private readonly IList _oldItems; + /// + /// The old items affected by the change (for Replace events). + /// + public IList OldItems + { + get { return _oldItems; } + } + + private readonly int _newStartingIndex = -1; + /// + /// The index where the change occurred. + /// + public int NewStartingIndex + { + get { return _newStartingIndex; } + } + + private readonly int _oldStartingIndex = -1; + /// + /// The old index where the change occurred (for Move events). + /// + public int OldStartingIndex + { + get { return _oldStartingIndex; } + } + + #endregion + } + + /// + /// The delegate to use for handlers that receive the CollectionChanged event. + /// + public delegate void NotifyCollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs e); +} + +namespace System.Runtime.CompilerServices +{ + internal class ExtensionAttribute : Attribute {} +} + +#endif \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Common/Compatibility4.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/Compatibility4.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,987 @@ +namespace System +{ + using Collections; + using Collections.Generic; + using Text; + + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); + + public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); + public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); + public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); + public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); + public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); + public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10); + public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11); + public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12); + public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13); + public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14); + public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15); + public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); + + #region Tuple + + interface ITuple + { + int GetHashCode(IEqualityComparer comparer); + string ToString (StringBuilder sb); + + int Size { get; } + } + + public static class Tuple + { + internal static int CombineHashCodes(int h1, int h2) { return (((h1 << 5) + h1) ^ h2); } + internal static int CombineHashCodes(int h1, int h2, int h3) { return CombineHashCodes(CombineHashCodes(h1, h2), h3); } + internal static int CombineHashCodes(int h1, int h2, int h3, int h4) { return CombineHashCodes(CombineHashCodes(h1, h2), CombineHashCodes(h3, h4)); } + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5) { return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), h5); } + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6) { return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6)); } + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7) { return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7)); } + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8) { return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7, h8)); } + + public static Tuple Create (T1 item1) { return new Tuple (item1); } + public static Tuple Create (T1 item1, T2 item2) { return new Tuple (item1, item2); } + public static Tuple Create(T1 item1, T2 item2, T3 item3) { return new Tuple(item1, item2, item3); } + + public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4) + { + return new Tuple(item1, item2, item3, item4); + } + + public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) + { + return new Tuple(item1, item2, item3, item4, item5); + } + + public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) + { + return new Tuple(item1, item2, item3, item4, item5, item6); + } + + public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) + { + return new Tuple(item1, item2, item3, item4, item5, item6, item7); + } + + public static Tuple> Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) + { + return new Tuple>(item1, item2, item3, item4, item5, item6, item7, new Tuple(item8)); + } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple + { + readonly T1 _item1; + + public Tuple(T1 item1) + { + _item1 = item1; + } + + public override bool Equals(object obj) + { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + public override int GetHashCode() + { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) + return 1; + + var tuple = other as Tuple; + + if (tuple == null) + throw new ArgumentException(string.Format("Type '{0}' is not a tuple", other.GetType()), "other"); + + return comparer.Compare(_item1, tuple._item1); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null) + return false; + + var tuple = other as Tuple; + + if (tuple == null) + return false; + + return comparer.Equals(_item1, tuple._item1); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return comparer.GetHashCode(_item1); + } + + int IComparable.CompareTo(object obj) + { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int ITuple.GetHashCode(IEqualityComparer comparer) + { + return ((IStructuralEquatable)this).GetHashCode(comparer); + } + + string ITuple.ToString(StringBuilder sb) + { + sb.Append(_item1).Append(")"); + return sb.ToString(); + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("("); + return ((ITuple) this).ToString(sb); + } + + public T1 Item1 { get { return _item1; } } + + int ITuple.Size { get { return 2; } } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple + { + readonly T1 _item1; + readonly T2 _item2; + + public Tuple(T1 item1, T2 item2) + { + _item1 = item1; + _item2 = item2; + } + + public override bool Equals(object obj) + { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + public override int GetHashCode() + { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) + return 1; + + var tuple = other as Tuple; + + if (tuple == null) + throw new ArgumentException(string.Format("Type '{0}' is not a tuple", other.GetType()), "other"); + + var num = comparer.Compare(_item1, tuple._item1); + if (num == 0) + return num; + return comparer.Compare(_item2, tuple._item2); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null) + return false; + + var tuple = other as Tuple; + + if (tuple == null) + return false; + + return + comparer.Equals(_item1, tuple._item1) && + comparer.Equals(_item2, tuple._item2); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return Tuple.CombineHashCodes(comparer.GetHashCode(_item1), comparer.GetHashCode(_item2)); + } + + int IComparable.CompareTo(object obj) + { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int ITuple.GetHashCode(IEqualityComparer comparer) + { + return ((IStructuralEquatable)this).GetHashCode(comparer); + } + + string ITuple.ToString(StringBuilder sb) + { + sb + .Append(_item1).Append(", ") + .Append(_item2).Append(")"); + + return sb.ToString(); + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("("); + return ((ITuple) this).ToString(sb); + } + + public T1 Item1 { get { return _item1; } } + public T2 Item2 { get { return _item2; } } + + int ITuple.Size { get { return 2; } } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple + { + readonly T1 _item1; + readonly T2 _item2; + readonly T3 _item3; + + public Tuple(T1 item1, T2 item2, T3 item3) + { + _item1 = item1; + _item2 = item2; + _item3 = item3; + } + + public override bool Equals(object obj) + { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + public override int GetHashCode() + { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) + return 1; + + var tuple = other as Tuple; + + if (tuple == null) + throw new ArgumentException(string.Format("Type '{0}' is not a tuple", other.GetType()), "other"); + + int num; + + num = comparer.Compare(_item1, tuple._item1); if (num == 0) return num; + num = comparer.Compare(_item2, tuple._item2); if (num != 0) return num; + + return comparer.Compare(_item3, tuple._item3); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null) + return false; + + var tuple = other as Tuple; + + if (tuple == null) + return false; + + return + comparer.Equals(_item1, tuple._item1) && + comparer.Equals(_item2, tuple._item2) && + comparer.Equals(_item3, tuple._item3); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return + Tuple.CombineHashCodes( + comparer.GetHashCode(_item1), + comparer.GetHashCode(_item2), + comparer.GetHashCode(_item3)); + } + + int IComparable.CompareTo(object obj) + { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int ITuple.GetHashCode(IEqualityComparer comparer) + { + return ((IStructuralEquatable)this).GetHashCode(comparer); + } + + string ITuple.ToString(StringBuilder sb) + { + sb + .Append(_item1).Append(", ") + .Append(_item2).Append(", ") + .Append(_item3).Append(")"); + + return sb.ToString(); + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("("); + return ((ITuple) this).ToString(sb); + } + + public T1 Item1 { get { return _item1; } } + public T2 Item2 { get { return _item2; } } + public T3 Item3 { get { return _item3; } } + + int ITuple.Size { get { return 3; } } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple + { + readonly T1 _item1; + readonly T2 _item2; + readonly T3 _item3; + readonly T4 _item4; + + public Tuple(T1 item1, T2 item2, T3 item3, T4 item4) + { + _item1 = item1; + _item2 = item2; + _item3 = item3; + _item4 = item4; + } + + public override bool Equals(object obj) + { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + public override int GetHashCode() + { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) + return 1; + + var tuple = other as Tuple; + + if (tuple == null) + throw new ArgumentException(string.Format("Type '{0}' is not a tuple", other.GetType()), "other"); + + int num; + + num = comparer.Compare(_item1, tuple._item1); if (num == 0) return num; + num = comparer.Compare(_item2, tuple._item2); if (num != 0) return num; + num = comparer.Compare(_item3, tuple._item3); if (num != 0) return num; + + return comparer.Compare(_item4, tuple._item4); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null) + return false; + + var tuple = other as Tuple; + + if (tuple == null) + return false; + + return + comparer.Equals(_item1, tuple._item1) && + comparer.Equals(_item2, tuple._item2) && + comparer.Equals(_item3, tuple._item3) && + comparer.Equals(_item4, tuple._item4); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return + Tuple.CombineHashCodes( + comparer.GetHashCode(_item1), + comparer.GetHashCode(_item2), + comparer.GetHashCode(_item3), + comparer.GetHashCode(_item4)); + } + + int IComparable.CompareTo(object obj) + { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int ITuple.GetHashCode(IEqualityComparer comparer) + { + return ((IStructuralEquatable)this).GetHashCode(comparer); + } + + string ITuple.ToString(StringBuilder sb) + { + sb + .Append(_item1).Append(", ") + .Append(_item2).Append(", ") + .Append(_item3).Append(", ") + .Append(_item4).Append(")"); + + return sb.ToString(); + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("("); + return ((ITuple) this).ToString(sb); + } + + public T1 Item1 { get { return _item1; } } + public T2 Item2 { get { return _item2; } } + public T3 Item3 { get { return _item3; } } + public T4 Item4 { get { return _item4; } } + + int ITuple.Size { get { return 4; } } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple + { + readonly T1 _item1; + readonly T2 _item2; + readonly T3 _item3; + readonly T4 _item4; + readonly T5 _item5; + + public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) + { + _item1 = item1; + _item2 = item2; + _item3 = item3; + _item4 = item4; + _item5 = item5; + } + + public override bool Equals(object obj) + { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + public override int GetHashCode() + { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) + return 1; + + var tuple = other as Tuple; + + if (tuple == null) + throw new ArgumentException(string.Format("Type '{0}' is not a tuple", other.GetType()), "other"); + + int num; + + num = comparer.Compare(_item1, tuple._item1); if (num == 0) return num; + num = comparer.Compare(_item2, tuple._item2); if (num != 0) return num; + num = comparer.Compare(_item3, tuple._item3); if (num != 0) return num; + num = comparer.Compare(_item4, tuple._item4); if (num != 0) return num; + + return comparer.Compare(_item5, tuple._item5); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null) + return false; + + var tuple = other as Tuple; + + if (tuple == null) + return false; + + return + comparer.Equals(_item1, tuple._item1) && + comparer.Equals(_item2, tuple._item2) && + comparer.Equals(_item3, tuple._item3) && + comparer.Equals(_item4, tuple._item4) && + comparer.Equals(_item5, tuple._item5); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return + Tuple.CombineHashCodes( + comparer.GetHashCode(_item1), + comparer.GetHashCode(_item2), + comparer.GetHashCode(_item3), + comparer.GetHashCode(_item4), + comparer.GetHashCode(_item5)); + } + + int IComparable.CompareTo(object obj) + { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int ITuple.GetHashCode(IEqualityComparer comparer) + { + return ((IStructuralEquatable)this).GetHashCode(comparer); + } + + string ITuple.ToString(StringBuilder sb) + { + sb + .Append(_item1).Append(", ") + .Append(_item2).Append(", ") + .Append(_item3).Append(", ") + .Append(_item4).Append(", ") + .Append(_item5).Append(")"); + + return sb.ToString(); + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("("); + return ((ITuple) this).ToString(sb); + } + + public T1 Item1 { get { return _item1; } } + public T2 Item2 { get { return _item2; } } + public T3 Item3 { get { return _item3; } } + public T4 Item4 { get { return _item4; } } + public T5 Item5 { get { return _item5; } } + + int ITuple.Size { get { return 5; } } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple + { + readonly T1 _item1; + readonly T2 _item2; + readonly T3 _item3; + readonly T4 _item4; + readonly T5 _item5; + readonly T6 _item6; + + public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) + { + _item1 = item1; + _item2 = item2; + _item3 = item3; + _item4 = item4; + _item5 = item5; + _item6 = item6; + } + + public override bool Equals(object obj) + { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + public override int GetHashCode() + { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) + return 1; + + var tuple = other as Tuple; + + if (tuple == null) + throw new ArgumentException(string.Format("Type '{0}' is not a tuple", other.GetType()), "other"); + + int num; + + num = comparer.Compare(_item1, tuple._item1); if (num == 0) return num; + num = comparer.Compare(_item2, tuple._item2); if (num != 0) return num; + num = comparer.Compare(_item3, tuple._item3); if (num != 0) return num; + num = comparer.Compare(_item4, tuple._item4); if (num != 0) return num; + num = comparer.Compare(_item5, tuple._item5); if (num != 0) return num; + + return comparer.Compare(_item6, tuple._item6); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null) + return false; + + var tuple = other as Tuple; + + if (tuple == null) + return false; + + return + comparer.Equals(_item1, tuple._item1) && + comparer.Equals(_item2, tuple._item2) && + comparer.Equals(_item3, tuple._item3) && + comparer.Equals(_item4, tuple._item4) && + comparer.Equals(_item5, tuple._item5) && + comparer.Equals(_item6, tuple._item6); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return + Tuple.CombineHashCodes( + comparer.GetHashCode(_item1), + comparer.GetHashCode(_item2), + comparer.GetHashCode(_item3), + comparer.GetHashCode(_item4), + comparer.GetHashCode(_item5), + comparer.GetHashCode(_item6)); + } + + int IComparable.CompareTo(object obj) + { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int ITuple.GetHashCode(IEqualityComparer comparer) + { + return ((IStructuralEquatable)this).GetHashCode(comparer); + } + + string ITuple.ToString(StringBuilder sb) + { + sb + .Append(_item1).Append(", ") + .Append(_item2).Append(", ") + .Append(_item3).Append(", ") + .Append(_item4).Append(", ") + .Append(_item5).Append(", ") + .Append(_item6).Append(")"); + + return sb.ToString(); + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("("); + return ((ITuple) this).ToString(sb); + } + + public T1 Item1 { get { return _item1; } } + public T2 Item2 { get { return _item2; } } + public T3 Item3 { get { return _item3; } } + public T4 Item4 { get { return _item4; } } + public T5 Item5 { get { return _item5; } } + public T6 Item6 { get { return _item6; } } + + int ITuple.Size { get { return 6; } } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple + { + readonly T1 _item1; + readonly T2 _item2; + readonly T3 _item3; + readonly T4 _item4; + readonly T5 _item5; + readonly T6 _item6; + readonly T7 _item7; + + public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) + { + _item1 = item1; + _item2 = item2; + _item3 = item3; + _item4 = item4; + _item5 = item5; + _item6 = item6; + _item7 = item7; + } + + public override bool Equals(object obj) + { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + public override int GetHashCode() + { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) + return 1; + + var tuple = other as Tuple; + + if (tuple == null) + throw new ArgumentException(string.Format("Type '{0}' is not a tuple", other.GetType()), "other"); + + int num; + + num = comparer.Compare(_item1, tuple._item1); if (num == 0) return num; + num = comparer.Compare(_item2, tuple._item2); if (num != 0) return num; + num = comparer.Compare(_item3, tuple._item3); if (num != 0) return num; + num = comparer.Compare(_item4, tuple._item4); if (num != 0) return num; + num = comparer.Compare(_item5, tuple._item5); if (num != 0) return num; + num = comparer.Compare(_item6, tuple._item6); if (num != 0) return num; + + return comparer.Compare(_item7, tuple._item7); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null) + return false; + + var tuple = other as Tuple; + + if (tuple == null) + return false; + + return + comparer.Equals(_item1, tuple._item1) && + comparer.Equals(_item2, tuple._item2) && + comparer.Equals(_item3, tuple._item3) && + comparer.Equals(_item4, tuple._item4) && + comparer.Equals(_item5, tuple._item5) && + comparer.Equals(_item6, tuple._item6) && + comparer.Equals(_item7, tuple._item7); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return + Tuple.CombineHashCodes( + comparer.GetHashCode(_item1), + comparer.GetHashCode(_item2), + comparer.GetHashCode(_item3), + comparer.GetHashCode(_item4), + comparer.GetHashCode(_item5), + comparer.GetHashCode(_item6), + comparer.GetHashCode(_item7)); + } + + int IComparable.CompareTo(object obj) + { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int ITuple.GetHashCode(IEqualityComparer comparer) + { + return ((IStructuralEquatable)this).GetHashCode(comparer); + } + + string ITuple.ToString(StringBuilder sb) + { + sb + .Append(_item1).Append(", ") + .Append(_item2).Append(", ") + .Append(_item3).Append(", ") + .Append(_item4).Append(", ") + .Append(_item5).Append(", ") + .Append(_item6).Append(", ") + .Append(_item7).Append(")"); + + return sb.ToString(); + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("("); + return ((ITuple) this).ToString(sb); + } + + public T1 Item1 { get { return _item1; } } + public T2 Item2 { get { return _item2; } } + public T3 Item3 { get { return _item3; } } + public T4 Item4 { get { return _item4; } } + public T5 Item5 { get { return _item5; } } + public T6 Item6 { get { return _item6; } } + public T7 Item7 { get { return _item7; } } + + int ITuple.Size { get { return 7; } } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple + { + readonly T1 _item1; + readonly T2 _item2; + readonly T3 _item3; + readonly T4 _item4; + readonly T5 _item5; + readonly T6 _item6; + readonly T7 _item7; + readonly TRest _rest; + + public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) + { + if (!(rest is ITuple)) + throw new ArgumentException("Argument 'rest' is not a tuple", "rest"); + + _item1 = item1; + _item2 = item2; + _item3 = item3; + _item4 = item4; + _item5 = item5; + _item6 = item6; + _item7 = item7; + _rest = rest; + } + + public override bool Equals(object obj) + { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + public override int GetHashCode() + { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) + return 1; + + var tuple = other as Tuple; + + if (tuple == null) + throw new ArgumentException(string.Format("Type '{0}' is not a tuple", other.GetType()), "other"); + + int num; + + num = comparer.Compare(_item1, tuple._item1); if (num == 0) return num; + num = comparer.Compare(_item2, tuple._item2); if (num != 0) return num; + num = comparer.Compare(_item3, tuple._item3); if (num != 0) return num; + num = comparer.Compare(_item4, tuple._item4); if (num != 0) return num; + num = comparer.Compare(_item5, tuple._item5); if (num != 0) return num; + num = comparer.Compare(_item6, tuple._item6); if (num != 0) return num; + num = comparer.Compare(_item7, tuple._item7); if (num != 0) return num; + + return comparer.Compare(_rest, tuple._rest); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null) + return false; + + var tuple = other as Tuple; + + if (tuple == null) + return false; + + return + comparer.Equals(_item1, tuple._item1) && + comparer.Equals(_item2, tuple._item2) && + comparer.Equals(_item3, tuple._item3) && + comparer.Equals(_item4, tuple._item4) && + comparer.Equals(_item5, tuple._item5) && + comparer.Equals(_item6, tuple._item6) && + comparer.Equals(_item7, tuple._item7) && + comparer.Equals(_rest, tuple._rest); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + var rest = (ITuple)_rest; + + if (rest.Size >= 8) + return rest.GetHashCode(comparer); + + switch (8 - rest.Size) + { + case 1: return Tuple.CombineHashCodes(comparer.GetHashCode(_item7), rest.GetHashCode(comparer)); + case 2: return Tuple.CombineHashCodes(comparer.GetHashCode(_item6), comparer.GetHashCode(_item7), rest.GetHashCode(comparer)); + case 3: return Tuple.CombineHashCodes(comparer.GetHashCode(_item5), comparer.GetHashCode(_item6), comparer.GetHashCode(_item7), rest.GetHashCode(comparer)); + case 4: return Tuple.CombineHashCodes(comparer.GetHashCode(_item4), comparer.GetHashCode(_item5), comparer.GetHashCode(_item6), comparer.GetHashCode(_item7), rest.GetHashCode(comparer)); + case 5: return Tuple.CombineHashCodes(comparer.GetHashCode(_item3), comparer.GetHashCode(_item4), comparer.GetHashCode(_item5), comparer.GetHashCode(_item6), comparer.GetHashCode(_item7), rest.GetHashCode(comparer)); + case 6: return Tuple.CombineHashCodes(comparer.GetHashCode(_item2), comparer.GetHashCode(_item3), comparer.GetHashCode(_item4), comparer.GetHashCode(_item5), comparer.GetHashCode(_item6), comparer.GetHashCode(_item7), rest.GetHashCode(comparer)); + case 7: return Tuple.CombineHashCodes(comparer.GetHashCode(_item1), comparer.GetHashCode(_item2), comparer.GetHashCode(_item3), comparer.GetHashCode(_item4), comparer.GetHashCode(_item5), comparer.GetHashCode(_item6), comparer.GetHashCode(_item7), rest.GetHashCode(comparer)); + } + + return -1; + } + + int IComparable.CompareTo(object obj) + { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int ITuple.GetHashCode(IEqualityComparer comparer) + { + return ((IStructuralEquatable)this).GetHashCode(comparer); + } + + string ITuple.ToString(StringBuilder sb) + { + sb + .Append(_item1).Append(", ") + .Append(_item2).Append(", ") + .Append(_item3).Append(", ") + .Append(_item4).Append(", ") + .Append(_item5).Append(", ") + .Append(_item6).Append(", ") + .Append(_item7).Append(", "); + + return ((ITuple)_rest).ToString(sb); + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("("); + return ((ITuple)this).ToString(sb); + } + + public T1 Item1 { get { return _item1; } } + public T2 Item2 { get { return _item2; } } + public T3 Item3 { get { return _item3; } } + public T4 Item4 { get { return _item4; } } + public T5 Item5 { get { return _item5; } } + public T6 Item6 { get { return _item6; } } + public T7 Item7 { get { return _item7; } } + public TRest Rest { get { return _rest; } } + + int ITuple.Size { get { return 7 + ((ITuple)_rest).Size; } } + } + + #endregion + + namespace Collections + { + public interface IStructuralEquatable + { + bool Equals (object other, IEqualityComparer comparer); + int GetHashCode(IEqualityComparer comparer); + } + + public interface IStructuralComparable + { + int CompareTo(object other, IComparer comparer); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Common/CompatibilitySL.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/CompatibilitySL.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,335 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Runtime.InteropServices; +using System.Runtime.Serialization; +using System.Text; +using JetBrains.Annotations; + +namespace System +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false)] + class SerializableAttribute : Attribute + { + } + + [ComVisible(true)] + interface ICloneable + { + object Clone(); + } + + namespace Collections + { + public class Comparer : IComparer + { + readonly CompareInfo _compareInfo; + + public static readonly Comparer Default = new Comparer(CultureInfo.CurrentCulture); + public static readonly Comparer DefaultInvariant = new Comparer(CultureInfo.InvariantCulture); + + private const String CompareInfoName = "CompareInfo"; + + public Comparer([NotNull] CultureInfo culture) + { + if (culture == null) throw new ArgumentNullException("culture"); + _compareInfo = culture.CompareInfo; + } + + public int Compare(object a, object b) + { + if (a == b) return 0; + if (a == null) return -1; + if (b == null) return 1; + + if (_compareInfo != null) { + var sa = a as String; + var sb = b as String; + + if (sa != null && sb != null) + return _compareInfo.Compare(sa, sb); + } + + var ia = a as IComparable; + + if (ia != null) + return ia.CompareTo(b); + + throw new ArgumentException("Object should implement IComparable interface."); + } + } + + namespace Generic + { + public static class Extensions + { + public static List ConvertAll(this List input, Converter converter) + { + var list = new List(input.Count); + + list.AddRange(from T t in input select converter(t)); + + return list; + } + + public static bool Exists(this List list, Predicate match) + { + return list.Any(item => match(item)); + } + } + } + } + + namespace ComponentModel + { + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Class | AttributeTargets.Method)] + public class DisplayNameAttribute : Attribute + { + public static readonly DisplayNameAttribute Default = new DisplayNameAttribute(); + + public DisplayNameAttribute() + { + DisplayName = string.Empty; + } + + public DisplayNameAttribute(string displayName) + { + DisplayName = displayName; + } + + public string DisplayName{ get; set; } + } + } + + namespace Data + { + public interface IDataRecord + { + int FieldCount { get; } + object this[int i] { get; } + object this[string name] { get; } + + string GetName (int i); + string GetDataTypeName(int i); + Type GetFieldType (int i); + object GetValue (int i); + int GetValues (object[] values); + int GetOrdinal (string name); + bool GetBoolean (int i); + byte GetByte (int i); + long GetBytes (int i, long fieldOffset, byte[] buffer, int bufferoffset, int length); + char GetChar (int i); + long GetChars (int i, long fieldoffset, char[] buffer, int bufferoffset, int length); + Guid GetGuid (int i); + short GetInt16 (int i); + int GetInt32 (int i); + long GetInt64 (int i); + float GetFloat (int i); + double GetDouble (int i); + string GetString (int i); + decimal GetDecimal (int i); + DateTime GetDateTime (int i); + IDataReader GetData (int i); + bool IsDBNull (int i); + } + + public interface IDataReader : IDisposable, IDataRecord + { + int Depth { get; } + bool IsClosed { get; } + int RecordsAffected { get; } + void Close(); + //DataTable GetSchemaTable(); + bool NextResult(); + bool Read(); + } + + public enum SqlDbType + { + BigInt = 0, + Binary = 1, + Bit = 2, + Char = 3, + DateTime = 4, + Decimal = 5, + Float = 6, + Image = 7, + Int = 8, + Money = 9, + NChar = 10, + NText = 11, + NVarChar = 12, + Real = 13, + UniqueIdentifier = 14, + SmallDateTime = 15, + SmallInt = 16, + SmallMoney = 17, + Text = 18, + Timestamp = 19, + TinyInt = 20, + VarBinary = 21, + VarChar = 22, + Variant = 23, + Xml = 25, + Udt = 29, + Structured = 30, + Date = 31, + Time = 32, + DateTime2 = 33, + DateTimeOffset = 34, + } + + public enum DbType + { + AnsiString = 0, + Binary = 1, + Byte = 2, + Boolean = 3, + Currency = 4, + Date = 5, + DateTime = 6, + Decimal = 7, + Double = 8, + Guid = 9, + Int16 = 10, + Int32 = 11, + Int64 = 12, + Object = 13, + SByte = 14, + Single = 15, + String = 16, + Time = 17, + UInt16 = 18, + UInt32 = 19, + UInt64 = 20, + VarNumeric = 21, + AnsiStringFixedLength = 22, + StringFixedLength = 23, + Xml = 25, + DateTime2 = 26, + DateTimeOffset = 27, + } + + namespace Linq + { + [DataContract] + [Serializable] + public sealed class Binary : IEquatable + { + [DataMember(Name="Bytes")] byte[] _bytes; + + int? _hashCode; + + public Binary(byte[] value) + { + if (value == null) + throw new ArgumentNullException("value"); + + _bytes = new byte[value.Length]; + Array.Copy(value, _bytes, value.Length); + ComputeHash(); + } + + public byte[] ToArray() + { + var copy = new byte[this._bytes.Length]; + Array.Copy(_bytes, copy, copy.Length); + return copy; + } + + public int Length + { + get { return _bytes.Length; } + } + + public static implicit operator Binary(byte[] value) + { + return new Binary(value); + } + + public bool Equals(Binary other) + { + return EqualsTo(other); + } + + public static bool operator == (Binary binary1, Binary binary2) + { + if ((object)binary1 == (object)binary2) return true; + if ((object)binary1 == null && (object)binary2 == null) return true; + if ((object)binary1 == null || (object)binary2 == null) return false; + + return binary1.EqualsTo(binary2); + } + + public static bool operator !=(Binary binary1, Binary binary2) + { + if ((object)binary1 == (object)binary2) return false; + if ((object)binary1 == null && (object)binary2 == null) return false; + if ((object)binary1 == null || (object)binary2 == null) return true; + + return !binary1.EqualsTo(binary2); + } + + public override bool Equals(object obj) + { + return EqualsTo(obj as Binary); + } + + public override int GetHashCode() + { + if (!_hashCode.HasValue) + ComputeHash(); + + return _hashCode.Value; + } + + public override string ToString() + { + var sb = new StringBuilder(); + + sb.Append("\""); + sb.Append(Convert.ToBase64String(_bytes, 0, _bytes.Length)); + sb.Append("\""); + + return sb.ToString(); + } + + private bool EqualsTo(Binary binary) + { + if ((object)this == (object)binary) return true; + if ((object)binary == null) return false; + if (_bytes.Length != binary._bytes.Length) return false; + if (_hashCode != binary._hashCode) return false; + + for (int i = 0; i < _bytes.Length; i++) + if (_bytes[i] != binary._bytes[i]) + return false; + + return true; + } + + private void ComputeHash() + { + var s = 314; + const int t = 159; + + _hashCode = 0; + + for (var i = 0; i < _bytes.Length; i++) + { + _hashCode = _hashCode * s + _bytes[i]; + s = s * t; + } + } + } + } + + namespace SqlTypes + { + public interface INullable + { + bool IsNull { get; } + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Common/CompoundValue.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/CompoundValue.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,122 @@ +using System; +using System.Collections; + +namespace BLToolkit.Common +{ + public class CompoundValue : IComparable, IEquatable + { + public CompoundValue(params object[] values) + { + if (values == null) + throw new ArgumentNullException("values"); + + // Note that the compound hash is precalculated. + // This means that CompoundValue can be used only with immutable values. + // Otherwise the behaviour is undefined. + // + _hash = CalcHashCode(values); + _values = values; + } + + private readonly object[] _values; + private readonly int _hash; + + public int Count + { + get { return _values == null ? 0 : _values.Length; } + } + + public object this[int index] + { + get { return _values == null ? null : _values[index]; } + } + + private static int CalcHashCode(object[] values) + { + if (values.Length == 0) + return 0; + + object o = values[0]; + int hash = o == null ? 0 : o.GetHashCode(); + + for (int i = 1; i < values.Length; i++) + { + o = values[i]; + hash = ((hash << 5) + hash) ^ (o == null ? 0 : o.GetHashCode()); + } + + return hash; + } + + #region IComparable Members + + public int CompareTo(object obj) + { + var objValues = ((CompoundValue)obj)._values; + + if (_values.Length != objValues.Length) + return _values.Length - objValues.Length; + + for (var i = 0; i < _values.Length; i++) + { + var n = Comparer.Default.Compare(_values[i], objValues[i]); + + if (n != 0) + return n; + } + + return 0; + } + + #endregion + + #region Object Overrides + + public override int GetHashCode() + { + return _hash; + } + + public override bool Equals(object obj) + { + if (!(obj is CompoundValue)) + return false; + + return Equals((CompoundValue)obj); + } + + #endregion + + #region IEquatable Members + + public bool Equals(CompoundValue other) + { + if (_hash != other._hash) + return false; + + object[] values = other._values; + + if (_values.Length != values.Length) + return false; + + for (int i = 0; i < _values.Length; i++) + { + object x = _values[i]; + object y = values[i]; + + if (x == null && y == null) + continue; + + if (x == null || y == null) + return false; + + if (x.Equals(y) == false) + return false; + } + + return true; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Common/Configuration.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/Configuration.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,106 @@ +using System; + +namespace BLToolkit.Common +{ + using Mapping; + + public static class Configuration + { + static Configuration() + { + NotifyOnEqualSet = true; + TrimDictionaryKey = true; + CheckNullReturnIfNull = NullEquivalent.DBNull; + OpenNewConnectionToDiscoverParameters = true; + } + + public enum NullEquivalent { DBNull, Null, Value } + + /// + /// Specifies what value should be returned by TypeAccessor.CheckNull + /// if was specified and interpreted current property + /// value as null. Default is: . + /// + public static NullEquivalent CheckNullReturnIfNull { get; set; } + + /// + /// Controls global trimming behaviour of mapper. Specifies whether trailing spaces + /// should be trimmed when mapping from one entity to another. Default is: false. + /// To specify trimming behaviour other than global, please user . + /// + public static bool TrimOnMapping { get; set; } + + /// + /// Controls global trimming behaviour of mapper for dictionary keys. Specifies whether trailing spaces + /// should be trimmed when adding keys to dictionaries. Default is: true. + /// + public static bool TrimDictionaryKey { get; set; } + + /// + /// Specifies default behavior for PropertyChange generation. If set to true, + /// is invoked even when current value is same as new one. If set to false, + /// is invoked only when new value is being assigned. To specify notification behaviour other than default, please see + /// + /// + public static bool NotifyOnEqualSet { get; set; } + + /// + /// Controls whether attributes specified on base types should be always added to list of attributes + /// when scanning hierarchy tree or they should be compared to attributes found on derived classes + /// and added only when not present already. Default value: false; + /// WARNING: setting this flag to "true" can significantly affect initial object generation/access performance + /// use only when side effects are noticed with attribute being present on derived and base classes. + /// For builder attributes use provided attribute compatibility mechanism. + /// + public static bool FilterOutBaseEqualAttributes { get; set; } + + /// + /// Controls whether attributes specified on base types should be always added to list of attributes + /// when scanning hierarchy tree or they should be compared to attributes found on derived classes + /// and added only when not present already. Default value: false; + /// WARNING: setting this flag to "true" can significantly affect initial object generation/access performance + /// use only when side effects are noticed with attribute being present on derived and base classes. + /// For builder attributes use provided attribute compatibility mechanism. + /// + public static bool OpenNewConnectionToDiscoverParameters { get; set; } + + public static class ExpressionMapper + { + public static bool IncludeComplexMapping { get; set; } + } + + public static class Linq + { + public static bool PreloadGroups { get; set; } + public static bool IgnoreEmptyUpdate { get; set; } + public static bool AllowMultipleQuery { get; set; } + public static bool GenerateExpressionTest { get; set; } + } + + public static class NullableValues + { + public static Int32 Int32 = 0; + public static Double Double = 0; + public static Int16 Int16 = 0; + public static Boolean Boolean = false; + [CLSCompliant(false)] + public static SByte SByte = 0; + public static Int64 Int64 = 0; + public static Byte Byte = 0; + [CLSCompliant(false)] + public static UInt16 UInt16 = 0; + [CLSCompliant(false)] + public static UInt32 UInt32 = 0; + [CLSCompliant(false)] + public static UInt64 UInt64 = 0; + public static Single Single = 0; + public static Char Char = '\x0'; + public static DateTime DateTime = DateTime.MinValue; + public static TimeSpan TimeSpan = TimeSpan.MinValue; + public static DateTimeOffset DateTimeOffset = DateTimeOffset.MinValue; + public static Decimal Decimal = 0m; + public static Guid Guid = Guid.Empty; + public static String String = string.Empty; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Common/Convert.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/Convert.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,968 @@ +using System; +using System.Data.Linq; +using System.Data.SqlTypes; +using System.IO; +using System.Threading; +using System.Xml; +#if !SILVERLIGHT +using System.Xml.Linq; +#endif + +namespace BLToolkit.Common +{ + using Properties; + + /// Converts a base data type to another base data type. + public static partial class Convert + { + #region Boolean + + /// Converts the value from Char to an equivalent Boolean value. + public static Boolean ToBoolean(Char p) + { + switch (p) + { + case '\x0' : // Allow int <=> Char <=> Boolean + case '0' : + case 'n' : + case 'N' : + case 'f' : + case 'F' : return false; + + case '\x1' : // Allow int <=> Char <=> Boolean + case '1' : + case 'y' : + case 'Y' : + case 't' : + case 'T' : return true; + } + + throw CreateInvalidCastException(typeof(Char), typeof(Boolean)); + } + + #endregion + + #region Byte[] + + /// Converts the value from Decimal to an equivalent Byte[] value. + public static Byte[] ToByteArray(Decimal p) + { + var bits = Decimal.GetBits(p); + var bytes = new Byte[Buffer.ByteLength(bits)]; + + Buffer.BlockCopy(bits, 0, bytes, 0, bytes.Length); + return bytes; + } + + /// Converts the value from Stream to an equivalent Byte[] value. + public static Byte[] ToByteArray(Stream p) + { + if (p == null || p == Stream.Null) return null; + if (p is MemoryStream) return ((MemoryStream)p).ToArray(); + + var position = p.Seek(0, SeekOrigin.Begin); + var bytes = new Byte[p.Length]; + + p.Read(bytes, 0, bytes.Length); + p.Position = position; + + return bytes; + } + + /// Converts the value from Char[] to an equivalent Byte[] value. + public static Byte[] ToByteArray(Char[] p) + { + var bytes = new Byte[Buffer.ByteLength(p)]; + + Buffer.BlockCopy(p, 0, bytes, 0, bytes.Length); + return bytes; + } + + #endregion + + #region Decimal + + /// Converts the value from Byte[] to an equivalent Decimal value. + public static Decimal ToDecimal(Byte[] p) + { + if (p == null || p.Length == 0) return 0.0m; + + var bits = new int[p.Length / sizeof(int)]; + + Buffer.BlockCopy(p, 0, bits, 0, p.Length); + return new Decimal(bits); + } + + public static Decimal ToDecimal(Binary p) + { + if (p == null || p.Length == 0) return 0.0m; + + var bits = new int[p.Length / sizeof(int)]; + + Buffer.BlockCopy(p.ToArray(), 0, bits, 0, p.Length); + return new Decimal(bits); + } + + #endregion + + #region SqlTypes + +#if !SILVERLIGHT + + #region SqlChars + + // Scalar Types. + // + /// Converts the value from String to an equivalent SqlChars value. + public static SqlChars ToSqlChars(String p) { return p == null? SqlChars.Null: new SqlChars(p.ToCharArray()); } + /// Converts the value from Char[] to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Char[] p) { return p == null? SqlChars.Null: new SqlChars(p); } + /// Converts the value from Byte[] to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Byte[] p) { return p == null? SqlChars.Null: new SqlChars(ToCharArray(p)); } + public static SqlChars ToSqlChars(Binary p) { return p == null? SqlChars.Null: new SqlChars(ToCharArray(p.ToArray())); } + + /// Converts the value from SByte to an equivalent SqlChars value. + [CLSCompliant(false)] + public static SqlChars ToSqlChars(SByte p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from Int16 to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Int16 p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from Int32 to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Int32 p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from Int64 to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Int64 p) { return new SqlChars(ToString(p).ToCharArray()); } + + /// Converts the value from Byte to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Byte p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from UInt16 to an equivalent SqlChars value. + [CLSCompliant(false)] + public static SqlChars ToSqlChars(UInt16 p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from UInt32 to an equivalent SqlChars value. + [CLSCompliant(false)] + public static SqlChars ToSqlChars(UInt32 p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from UInt64 to an equivalent SqlChars value. + [CLSCompliant(false)] + public static SqlChars ToSqlChars(UInt64 p) { return new SqlChars(ToString(p).ToCharArray()); } + + /// Converts the value from Single to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Single p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from Double to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Double p) { return new SqlChars(ToString(p).ToCharArray()); } + + /// Converts the value from Boolean to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Boolean p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from Decimal to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Decimal p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from Char to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Char p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from TimeSpan to an equivalent SqlChars value. + public static SqlChars ToSqlChars(TimeSpan p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from DateTime to an equivalent SqlChars value. + public static SqlChars ToSqlChars(DateTime p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from DateTimeOffset to an equivalent SqlChars value. + public static SqlChars ToSqlChars(DateTimeOffset p) { return new SqlChars(ToString(p).ToCharArray()); } + /// Converts the value from Guid to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Guid p) { return new SqlChars(ToString(p).ToCharArray()); } + + // Nullable Types. + // + /// Converts the value from SByte? to an equivalent SqlChars value. + [CLSCompliant(false)] + public static SqlChars ToSqlChars(SByte? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + /// Converts the value from Int16? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Int16? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + /// Converts the value from Int32? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Int32? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + /// Converts the value from Int64? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Int64? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + + /// Converts the value from Byte? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Byte? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + /// Converts the value from UInt16? to an equivalent SqlChars value. + [CLSCompliant(false)] + public static SqlChars ToSqlChars(UInt16? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + /// Converts the value from UInt32? to an equivalent SqlChars value. + [CLSCompliant(false)] + public static SqlChars ToSqlChars(UInt32? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + /// Converts the value from UInt64? to an equivalent SqlChars value. + [CLSCompliant(false)] + public static SqlChars ToSqlChars(UInt64? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + + /// Converts the value from Single? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Single? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + /// Converts the value from Double? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Double? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + + /// Converts the value from Boolean? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Boolean? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + /// Converts the value from Decimal? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Decimal? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + /// Converts the value from Char? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Char? p) { return p.HasValue? new SqlChars(new Char[]{p.Value}) : SqlChars.Null; } + /// Converts the value from TimeSpan? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(TimeSpan? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + /// Converts the value from DateTime? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(DateTime? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + /// Converts the value from DateTimeOffset? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(DateTimeOffset? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + /// Converts the value from Guid? to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Guid? p) { return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; } + + // SqlTypes + // + /// Converts the value from SqlString to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlString p) { return (SqlChars)p; } + + /// Converts the value from SqlByte to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlByte p) { return (SqlChars)p.ToSqlString(); } + /// Converts the value from SqlInt16 to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlInt16 p) { return (SqlChars)p.ToSqlString(); } + /// Converts the value from SqlInt32 to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlInt32 p) { return (SqlChars)p.ToSqlString(); } + /// Converts the value from SqlInt64 to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlInt64 p) { return (SqlChars)p.ToSqlString(); } + + /// Converts the value from SqlSingle to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlSingle p) { return (SqlChars)p.ToSqlString(); } + /// Converts the value from SqlDouble to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlDouble p) { return (SqlChars)p.ToSqlString(); } + /// Converts the value from SqlDecimal to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlDecimal p) { return (SqlChars)p.ToSqlString(); } + /// Converts the value from SqlMoney to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlMoney p) { return (SqlChars)p.ToSqlString(); } + + /// Converts the value from SqlBoolean to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlBoolean p) { return (SqlChars)p.ToSqlString(); } + /// Converts the value from SqlGuid to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlGuid p) { return (SqlChars)p.ToSqlString(); } + /// Converts the value from SqlDateTime to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlDateTime p) { return (SqlChars)p.ToSqlString(); } + /// Converts the value from SqlBinary to an equivalent SqlChars value. + public static SqlChars ToSqlChars(SqlBinary p) { return p.IsNull? SqlChars.Null: new SqlChars(p.ToString().ToCharArray()); } + + /// Converts the value from Type to an equivalent SqlChars value. + public static SqlChars ToSqlChars(Type p) { return p == null? SqlChars.Null: new SqlChars(p.FullName.ToCharArray()); } + /// Converts the value of a specified object to an equivalent SqlChars value. + public static SqlChars ToSqlChars(object p) + { + if (p == null || p is DBNull) return SqlChars.Null; + + if (p is SqlChars) return (SqlChars)p; + + // Scalar Types. + // + if (p is String) return ToSqlChars((String)p); + if (p is Char[]) return ToSqlChars((Char[])p); + if (p is Byte[]) return ToSqlChars((Byte[])p); + if (p is Binary) return ToSqlChars(((Binary)p).ToArray()); + + if (p is SByte) return ToSqlChars((SByte)p); + if (p is Int16) return ToSqlChars((Int16)p); + if (p is Int32) return ToSqlChars((Int32)p); + if (p is Int64) return ToSqlChars((Int64)p); + + if (p is Byte) return ToSqlChars((Byte)p); + if (p is UInt16) return ToSqlChars((UInt16)p); + if (p is UInt32) return ToSqlChars((UInt32)p); + if (p is UInt64) return ToSqlChars((UInt64)p); + + if (p is Single) return ToSqlChars((Single)p); + if (p is Double) return ToSqlChars((Double)p); + + if (p is Boolean) return ToSqlChars((Boolean)p); + if (p is Decimal) return ToSqlChars((Decimal)p); + + // SqlTypes + // + if (p is SqlString) return ToSqlChars((SqlString)p); + + if (p is SqlByte) return ToSqlChars((SqlByte)p); + if (p is SqlInt16) return ToSqlChars((SqlInt16)p); + if (p is SqlInt32) return ToSqlChars((SqlInt32)p); + if (p is SqlInt64) return ToSqlChars((SqlInt64)p); + + if (p is SqlSingle) return ToSqlChars((SqlSingle)p); + if (p is SqlDouble) return ToSqlChars((SqlDouble)p); + if (p is SqlDecimal) return ToSqlChars((SqlDecimal)p); + if (p is SqlMoney) return ToSqlChars((SqlMoney)p); + + if (p is SqlBoolean) return ToSqlChars((SqlBoolean)p); + if (p is SqlBinary) return ToSqlChars((SqlBinary)p); + if (p is Type) return ToSqlChars((Type)p); + + return new SqlChars(ToString(p).ToCharArray()); + } + + #endregion + +#endif + + #endregion + + #region Other Types + + #region Binary + + // Scalar Types. + // + /// Converts the value from String to an equivalent Byte[] value. + public static Binary ToLinqBinary(String p) { return p == null? null: new Binary(System.Text.Encoding.UTF8.GetBytes(p)); } + /// Converts the value from Byte to an equivalent Byte[] value. + public static Binary ToLinqBinary(Byte p) { return new Binary(new byte[]{p}); } + /// Converts the value from SByte to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Binary ToLinqBinary(SByte p) { return new Binary(new byte[]{checked((Byte)p)}); } + /// Converts the value from Decimal to an equivalent Byte[] value. + public static Binary ToLinqBinary(Decimal p) + { + var bits = Decimal.GetBits(p); + var bytes = new Byte[Buffer.ByteLength(bits)]; + + Buffer.BlockCopy(bits, 0, bytes, 0, bytes.Length); + return new Binary(bytes); + } + /// Converts the value from Int16 to an equivalent Byte[] value. + public static Binary ToLinqBinary(Int16 p) { return new Binary(BitConverter.GetBytes(p)); } + /// Converts the value from Int32 to an equivalent Byte[] value. + public static Binary ToLinqBinary(Int32 p) { return new Binary(BitConverter.GetBytes(p)); } + /// Converts the value from Int64 to an equivalent Byte[] value. + public static Binary ToLinqBinary(Int64 p) { return new Binary(BitConverter.GetBytes(p)); } + + /// Converts the value from UInt16 to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Binary ToLinqBinary(UInt16 p) { return new Binary(BitConverter.GetBytes(p)); } + /// Converts the value from UInt32 to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Binary ToLinqBinary(UInt32 p) { return new Binary(BitConverter.GetBytes(p)); } + /// Converts the value from UInt64 to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Binary ToLinqBinary(UInt64 p) { return new Binary(BitConverter.GetBytes(p)); } + + /// Converts the value from Single to an equivalent Byte[] value. + public static Binary ToLinqBinary(Single p) { return new Binary(BitConverter.GetBytes(p)); } + /// Converts the value from Double to an equivalent Byte[] value. + public static Binary ToLinqBinary(Double p) { return new Binary(BitConverter.GetBytes(p)); } + + /// Converts the value from Boolean to an equivalent Byte[] value. + public static Binary ToLinqBinary(Boolean p) { return new Binary(BitConverter.GetBytes(p)); } + /// Converts the value from Char to an equivalent Byte[] value. + public static Binary ToLinqBinary(Char p) { return new Binary(BitConverter.GetBytes(p)); } +#if !SILVERLIGHT + /// Converts the value from DateTime to an equivalent Byte[] value. + public static Binary ToLinqBinary(DateTime p) { return new Binary(ToByteArray(p.ToBinary())); } + /// Converts the value from DateTimeOffset to an equivalent Byte[] value. + public static Binary ToLinqBinary(DateTimeOffset p) { return new Binary(ToByteArray(p.LocalDateTime.ToBinary())); } +#endif + public static Binary ToLinqBinary(Byte[] p) { return new Binary(p); } + /// Converts the value from TimeSpan to an equivalent Byte[] value. + public static Binary ToLinqBinary(TimeSpan p) { return new Binary(ToByteArray(p.Ticks)); } + /// Converts the value from Stream to an equivalent Byte[] value. + public static Binary ToLinqBinary(Stream p) + { + if (p == null) return null; + if (p is MemoryStream) return ((MemoryStream)p).ToArray(); + + var position = p.Seek(0, SeekOrigin.Begin); + var bytes = new Byte[p.Length]; + p.Read(bytes, 0, bytes.Length); + p.Position = position; + + return new Binary(bytes); + } + /// Converts the value from Char[] to an equivalent Byte[] value. + public static Binary ToLinqBinary(Char[] p) + { + var bytes = new Byte[Buffer.ByteLength(p)]; + + Buffer.BlockCopy(p, 0, bytes, 0, bytes.Length); + return new Binary(bytes); + } + /// Converts the value from Guid to an equivalent Byte[] value. + public static Binary ToLinqBinary(Guid p) { return p == Guid.Empty? null: new Binary(p.ToByteArray()); } + + // Nullable Types. + // + /// Converts the value from SByte? to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Binary ToLinqBinary(SByte? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from Int16? to an equivalent Byte[] value. + public static Binary ToLinqBinary(Int16? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from Int32? to an equivalent Byte[] value. + public static Binary ToLinqBinary(Int32? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from Int64? to an equivalent Byte[] value. + public static Binary ToLinqBinary(Int64? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + + /// Converts the value from Byte? to an equivalent Byte[] value. + public static Binary ToLinqBinary(Byte? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from UInt16? to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Binary ToLinqBinary(UInt16? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from UInt32? to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Binary ToLinqBinary(UInt32? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from UInt64? to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Binary ToLinqBinary(UInt64? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + + /// Converts the value from Single? to an equivalent Byte[] value. + public static Binary ToLinqBinary(Single? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from Double? to an equivalent Byte[] value. + public static Binary ToLinqBinary(Double? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + + /// Converts the value from Boolean? to an equivalent Byte[] value. + public static Binary ToLinqBinary(Boolean? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from Decimal? to an equivalent Byte[] value. + public static Binary ToLinqBinary(Decimal? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from Char? to an equivalent Byte[] value. + public static Binary ToLinqBinary(Char? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from DateTime? to an equivalent Byte[] value. + public static Binary ToLinqBinary(DateTime? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from DateTimeOffset? to an equivalent Byte[] value. + public static Binary ToLinqBinary(DateTimeOffset? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from TimeSpan? to an equivalent Byte[] value. + public static Binary ToLinqBinary(TimeSpan? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + /// Converts the value from Guid? to an equivalent Byte[] value. + public static Binary ToLinqBinary(Guid? p) { return p.HasValue? new Binary(ToByteArray(p.Value)): null; } + +#if !SILVERLIGHT + + // SqlTypes + // + /// Converts the value from SqlBinary to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlBinary p) { return p.IsNull? null: new Binary(p.Value); } + /// Converts the value from SqlBytes to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlBytes p) { return p.IsNull? null: new Binary(p.Value); } + /// Converts the value from SqlGuid to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlGuid p) { return p.IsNull? null: new Binary(p.ToByteArray()); } + /// Converts the value from SqlString to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlString p) { return p.IsNull? null: new Binary(ToByteArray(p.Value)); } + + /// Converts the value from SqlByte to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlByte p) { return p.IsNull? null: new Binary(ToByteArray(p.Value)); } + /// Converts the value from SqlInt16 to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlInt16 p) { return p.IsNull? null: new Binary(ToByteArray(p.Value)); } + /// Converts the value from SqlInt32 to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlInt32 p) { return p.IsNull? null: new Binary(ToByteArray(p.Value)); } + /// Converts the value from SqlInt64 to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlInt64 p) { return p.IsNull? null: new Binary(ToByteArray(p.Value)); } + + /// Converts the value from SqlSingle to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlSingle p) { return p.IsNull? null: new Binary(ToByteArray(p.Value)); } + /// Converts the value from SqlDouble to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlDouble p) { return p.IsNull? null: new Binary(ToByteArray(p.Value)); } + /// Converts the value from SqlDecimal to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlDecimal p) { return p.IsNull? null: new Binary(ToByteArray(p.Value)); } + /// Converts the value from SqlMoney to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlMoney p) { return p.IsNull? null: new Binary(ToByteArray(p.Value)); } + + /// Converts the value from SqlBoolean to an equivalent Byte[] value. + public static Binary ToLinqBinary(SqlBoolean p) { return p.IsNull? null: new Binary(ToByteArray(p.Value)); } + +#endif + + /// Converts the value of a specified object to an equivalent Byte[] value. + public static Binary ToLinqBinary(object p) + { + if (p == null || p is DBNull) return null; + + if (p is Byte[]) return new Binary((Byte[])p); + if (p is Binary) return (Binary)p; + + // Scalar Types. + // + if (p is String) return ToLinqBinary((String)p); + if (p is Byte) return ToLinqBinary((Byte)p); + if (p is SByte) return ToLinqBinary((SByte)p); + if (p is Decimal) return ToLinqBinary((Decimal)p); + if (p is Int16) return ToLinqBinary((Int16)p); + if (p is Int32) return ToLinqBinary((Int32)p); + if (p is Int64) return ToLinqBinary((Int64)p); + + if (p is UInt16) return ToLinqBinary((UInt16)p); + if (p is UInt32) return ToLinqBinary((UInt32)p); + if (p is UInt64) return ToLinqBinary((UInt64)p); + + if (p is Single) return ToLinqBinary((Single)p); + if (p is Double) return ToLinqBinary((Double)p); + + if (p is Boolean) return ToLinqBinary((Boolean)p); + if (p is DateTime) return ToLinqBinary((DateTime)p); + if (p is DateTimeOffset) return ToLinqBinary((DateTimeOffset)p); + if (p is TimeSpan) return ToLinqBinary((TimeSpan)p); + if (p is Stream) return ToLinqBinary((Stream)p); + if (p is Char[]) return ToLinqBinary((Char[])p); + if (p is Guid) return ToLinqBinary((Guid)p); + +#if !SILVERLIGHT + + // SqlTypes + // + if (p is SqlBinary) return ToLinqBinary((SqlBinary)p); + if (p is SqlBytes) return ToLinqBinary((SqlBytes)p); + if (p is SqlGuid) return ToLinqBinary((SqlGuid)p); + if (p is SqlString) return ToLinqBinary((SqlString)p); + + if (p is SqlByte) return ToLinqBinary((SqlByte)p); + if (p is SqlInt16) return ToLinqBinary((SqlInt16)p); + if (p is SqlInt32) return ToLinqBinary((SqlInt32)p); + if (p is SqlInt64) return ToLinqBinary((SqlInt64)p); + + if (p is SqlSingle) return ToLinqBinary((SqlSingle)p); + if (p is SqlDouble) return ToLinqBinary((SqlDouble)p); + if (p is SqlDecimal) return ToLinqBinary((SqlDecimal)p); + if (p is SqlMoney) return ToLinqBinary((SqlMoney)p); + + if (p is SqlBoolean) return ToLinqBinary((SqlBoolean)p); + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Byte[])); + } + + #endregion + + #region Char[] + + // Scalar Types. + // + /// Converts the value from String to an equivalent Char[] value. + public static Char[] ToCharArray(String p) { return p == null? null: p.ToCharArray(); } + +#if !SILVERLIGHT + + // SqlTypes + // + /// Converts the value from SqlString to an equivalent Char[] value. + public static Char[] ToCharArray(SqlString p) { return p.IsNull? null: p.Value.ToCharArray(); } + /// Converts the value from SqlChars to an equivalent Char[] value. + public static Char[] ToCharArray(SqlChars p) { return p.IsNull? null: p.Value; } + +#endif + + /// Converts the value from Byte[] to an equivalent Char[] value. + public static Char[] ToCharArray(Byte[] p) + { + if (p == null) return null; + + var chars = new Char[p.Length / sizeof(Char)]; + + Buffer.BlockCopy(p, 0, chars, 0, p.Length); + return chars; + } + + public static Char[] ToCharArray(Binary p) + { + if (p == null) return null; + + var chars = new Char[p.Length / sizeof(Char)]; + + Buffer.BlockCopy(p.ToArray(), 0, chars, 0, p.Length); + return chars; + } + + /// Converts the value of a specified object to an equivalent Char[] value. + public static Char[] ToCharArray(object p) + { + if (p == null || p is DBNull) return null; + + if (p is Char[]) return (Char[])p; + + // Scalar Types. + // + if (p is String) return ToCharArray((String)p); + +#if !SILVERLIGHT + + // SqlTypes + // + if (p is SqlString) return ToCharArray((SqlString)p); + if (p is SqlChars) return ToCharArray((SqlChars)p); + +#endif + if (p is Byte[]) return ToCharArray((Byte[])p); + if (p is Binary) return ToCharArray(((Binary)p).ToArray()); + + return ToString(p).ToCharArray(); + } + + #endregion + + #region XmlReader + +#if !SILVERLIGHT + + // Scalar Types. + // + /// Converts the value from String to an equivalent XmlReader value. + public static XmlReader ToXmlReader(String p) { return p == null? null: new XmlTextReader(new StringReader(p)); } + + // SqlTypes + // + /// Converts the value from SqlXml to an equivalent XmlReader value. + public static XmlReader ToXmlReader(SqlXml p) { return p.IsNull? null: p.CreateReader(); } + /// Converts the value from SqlString to an equivalent XmlReader value. + public static XmlReader ToXmlReader(SqlString p) { return p.IsNull? null: new XmlTextReader(new StringReader(p.Value)); } + /// Converts the value from SqlChars to an equivalent XmlReader value. + public static XmlReader ToXmlReader(SqlChars p) { return p.IsNull? null: new XmlTextReader(new StringReader(p.ToSqlString().Value)); } + /// Converts the value from SqlBinary to an equivalent XmlReader value. + public static XmlReader ToXmlReader(SqlBinary p) { return p.IsNull? null: new XmlTextReader(new MemoryStream(p.Value)); } + + // Other Types. + // + /// Converts the value from Stream to an equivalent XmlReader value. + public static XmlReader ToXmlReader(Stream p) { return p == null? null: new XmlTextReader(p); } + /// Converts the value from TextReader to an equivalent XmlReader value. + public static XmlReader ToXmlReader(TextReader p) { return p == null? null: new XmlTextReader(p); } + /// Converts the value from XmlDocument to an equivalent XmlReader value. + public static XmlReader ToXmlReader(XmlDocument p) { return p == null? null: new XmlTextReader(new StringReader(p.InnerXml)); } + + /// Converts the value from Char[] to an equivalent XmlReader value. + public static XmlReader ToXmlReader(Char[] p) { return p == null? null: new XmlTextReader(new StringReader(new string(p))); } + /// Converts the value from Byte[] to an equivalent XmlReader value. + public static XmlReader ToXmlReader(Byte[] p) { return p == null? null: new XmlTextReader(new MemoryStream(p)); } + public static XmlReader ToXmlReader(Binary p) { return p == null? null: new XmlTextReader(new MemoryStream(p.ToArray())); } + + /// Converts the value of a specified object to an equivalent XmlReader value. + public static XmlReader ToXmlReader(object p) + { + if (p == null || p is DBNull) return null; + + if (p is XmlReader) return (XmlReader)p; + + // Scalar Types. + // + if (p is String) return ToXmlReader((String)p); + + // SqlTypes + // + if (p is SqlXml) return ToXmlReader((SqlXml)p); + if (p is SqlString) return ToXmlReader((SqlString)p); + if (p is SqlChars) return ToXmlReader((SqlChars)p); + if (p is SqlBinary) return ToXmlReader((SqlBinary)p); + + // Other Types. + // + if (p is XmlDocument) return ToXmlReader((XmlDocument)p); + + if (p is Char[]) return ToXmlReader((Char[])p); + if (p is Byte[]) return ToXmlReader((Byte[])p); + if (p is Binary) return ToXmlReader(((Binary)p).ToArray()); + + throw CreateInvalidCastException(p.GetType(), typeof(XmlReader)); + } + +#endif + + #endregion + + #region XmlDocument + +#if !SILVERLIGHT + + // Scalar Types. + // + /// Converts the value from String to an equivalent XmlDocument value. + public static XmlDocument ToXmlDocument(String p) + { + if (string.IsNullOrEmpty(p)) return null; + + var doc = new XmlDocument(); + + doc.LoadXml(p); + + return doc; + } + + // SqlTypes + // + /// Converts the value from SqlString to an equivalent XmlDocument value. + public static XmlDocument ToXmlDocument(SqlString p) { return p.IsNull? null: ToXmlDocument(p.Value); } + /// Converts the value from SqlXml to an equivalent XmlDocument value. + public static XmlDocument ToXmlDocument(SqlXml p) { return p.IsNull? null: ToXmlDocument(p.Value); } + /// Converts the value from SqlChars to an equivalent XmlDocument value. + public static XmlDocument ToXmlDocument(SqlChars p) { return p.IsNull? null: ToXmlDocument(p.ToSqlString().Value); } + /// Converts the value from SqlBinary to an equivalent XmlDocument value. + public static XmlDocument ToXmlDocument(SqlBinary p) { return p.IsNull? null: ToXmlDocument(new MemoryStream(p.Value)); } + + // Other Types. + // + /// Converts the value from Stream to an equivalent XmlDocument value. + public static XmlDocument ToXmlDocument(Stream p) + { + if (p == null) return null; + + var doc = new XmlDocument(); + + doc.Load(p); + + return doc; + } + + /// Converts the value from TextReader to an equivalent XmlDocument value. + public static XmlDocument ToXmlDocument(TextReader p) + { + if (p == null) return null; + + var doc = new XmlDocument(); + + doc.Load(p); + + return doc; + } + + /// Converts the value from XmlReader to an equivalent XmlDocument value. + public static XmlDocument ToXmlDocument(XmlReader p) + { + if (p == null) return null; + + var doc = new XmlDocument(); + + doc.Load(p); + + return doc; + } + + /// Converts the value from Char[] to an equivalent XmlDocument value. + public static XmlDocument ToXmlDocument(Char[] p) { return p == null || p.Length == 0? null: ToXmlDocument(new string(p)); } + /// Converts the value from Byte[] to an equivalent XmlDocument value. + public static XmlDocument ToXmlDocument(Byte[] p) { return p == null || p.Length == 0? null: ToXmlDocument(new MemoryStream(p)); } + public static XmlDocument ToXmlDocument(Binary p) { return p == null || p.Length == 0? null: ToXmlDocument(new MemoryStream(p.ToArray())); } + + /// Converts the value of a specified object to an equivalent XmlDocument value. + public static XmlDocument ToXmlDocument(object p) + { + if (p == null || p is DBNull) return null; + + if (p is XmlDocument) return (XmlDocument)p; + + // Scalar Types. + // + if (p is String) return ToXmlDocument((String)p); + + // SqlTypes + // + if (p is SqlChars) return ToXmlDocument((SqlChars)p); + if (p is SqlBinary) return ToXmlDocument((SqlBinary)p); + + // Other Types. + // + + if (p is Char[]) return ToXmlDocument((Char[])p); + if (p is Byte[]) return ToXmlDocument((Byte[])p); + if (p is Binary) return ToXmlDocument(((Binary)p).ToArray()); + + throw CreateInvalidCastException(p.GetType(), typeof(XmlDocument)); + } + +#endif + + #endregion + + #region XElement + +#if !SILVERLIGHT + + // Scalar Types. + // + /// Converts the value from String to an equivalent XElement value. + public static XElement ToXElement(String p) + { + if (string.IsNullOrEmpty(p)) return null; + + var doc = XElement.Parse(p); + + return doc; + } + + // SqlTypes + // + /// Converts the value from SqlString to an equivalent XElement value. + public static XElement ToXElement(SqlString p) { return p.IsNull ? null : ToXElement(p.Value); } + /// Converts the value from SqlXml to an equivalent XElement value. + public static XElement ToXElement(SqlXml p) { return p.IsNull ? null : ToXElement(p.Value); } + /// Converts the value from SqlChars to an equivalent XElement value. + public static XElement ToXElement(SqlChars p) { return p.IsNull ? null : ToXElement(p.ToSqlString().Value); } + /// Converts the value from SqlBinary to an equivalent XElement value. + public static XElement ToXElement(SqlBinary p) { return p.IsNull ? null : ToXElement(new MemoryStream(p.Value)); } + + // Other Types. + // + /// Converts the value from Stream to an equivalent XElement value. + public static XElement ToXElement(Stream p) + { + if (p == null) return null; + + using (XmlReader r = XmlReader.Create(p)) + return XElement.Load(r); + } + + /// Converts the value from TextReader to an equivalent XElement value. + public static XElement ToXElement(TextReader p) + { + if (p == null) return null; + + var doc = XElement.Load(p); + + return doc; + } + + /// Converts the value from XmlReader to an equivalent XElement value. + public static XElement ToXElement(XmlReader p) + { + if (p == null) return null; + + var doc = XElement.Load(p); + + return doc; + } + + /// Converts the value from Char[] to an equivalent XElement value. + public static XElement ToXElement(Char[] p) { return p == null || p.Length == 0 ? null : ToXElement(new string(p)); } + /// Converts the value from Byte[] to an equivalent XElement value. + public static XElement ToXElement(Byte[] p) { return p == null || p.Length == 0 ? null : ToXElement(new MemoryStream(p)); } + public static XElement ToXElement(Binary p) { return p == null || p.Length == 0 ? null : ToXElement(new MemoryStream(p.ToArray())); } + + /// Converts the value of a specified object to an equivalent XElement value. + public static XElement ToXElement(object p) + { + if (p == null || p is DBNull) return null; + + if (p is XElement) return (XElement)p; + + // Scalar Types. + // + if (p is String) return ToXElement((String)p); + + // SqlTypes + // + if (p is SqlChars) return ToXElement((SqlChars)p); + if (p is SqlBinary) return ToXElement((SqlBinary)p); + + // Other Types. + // + + if (p is Char[]) return ToXElement((Char[])p); + if (p is Byte[]) return ToXElement((Byte[])p); + if (p is Binary) return ToXElement(((Binary)p).ToArray()); + + throw CreateInvalidCastException(p.GetType(), typeof(XElement)); + } + +#endif + + #endregion + + #endregion + + #region ChangeTypeFromString + + public static object ChangeTypeFromString(string str, Type type) + { + if (str == null) + return null; + + if (type == typeof(string)) + return str; + + var underlyingType = type; + var isNullable = false; + + if (underlyingType.IsGenericType && underlyingType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + isNullable = true; + underlyingType = underlyingType.GetGenericArguments()[0]; + } + + if (underlyingType.IsEnum) + return Enum.Parse(type, str, false); + + if (isNullable) + { + switch (Type.GetTypeCode(underlyingType)) + { + case TypeCode.Boolean : return ToNullableBoolean (str); + case TypeCode.Char : return ToNullableChar (str); + case TypeCode.SByte : return ToNullableSByte (str); + case TypeCode.Byte : return ToNullableByte (str); + case TypeCode.Int16 : return ToNullableInt16 (str); + case TypeCode.UInt16 : return ToNullableUInt16 (str); + case TypeCode.Int32 : return ToNullableInt32 (str); + case TypeCode.UInt32 : return ToNullableUInt32 (str); + case TypeCode.Int64 : return ToNullableInt64 (str); + case TypeCode.UInt64 : return ToNullableUInt64 (str); + case TypeCode.Single : return ToNullableSingle (str); + case TypeCode.Double : return ToNullableDouble (str); + case TypeCode.Decimal : return ToNullableDecimal (str); + case TypeCode.DateTime : return ToNullableDateTime(str); + case TypeCode.Object : + if (type == typeof(Guid)) return ToNullableGuid (str); + if (type == typeof(DateTimeOffset)) return ToNullableDateTimeOffset(str); + if (type == typeof(TimeSpan)) return ToNullableTimeSpan (str); + break; + default : break; + } + } + else + { + switch (Type.GetTypeCode(underlyingType)) + { + case TypeCode.Boolean : return ToBoolean(str); + case TypeCode.Char : return ToChar (str); + case TypeCode.SByte : return ToSByte (str); + case TypeCode.Byte : return ToByte (str); + case TypeCode.Int16 : return ToInt16 (str); + case TypeCode.UInt16 : return ToUInt16 (str); + case TypeCode.Int32 : return ToInt32 (str); + case TypeCode.UInt32 : return ToUInt32 (str); + case TypeCode.Int64 : return ToInt64 (str); + case TypeCode.UInt64 : return ToUInt64 (str); + case TypeCode.Single : return ToSingle (str); + case TypeCode.Double : return ToDouble (str); + case TypeCode.Decimal : return ToDecimal (str); + case TypeCode.DateTime : return ToDateTime(str); + default : break; + } + + if (type.IsArray) + { + if (type == typeof(byte[])) return ToByteArray(str); + } + + if (type.IsClass) + { + if (type == typeof(Binary)) return ToLinqBinary (str); + } + } + + if (type == typeof(Guid)) return ToGuid (str); + if (type == typeof(DateTimeOffset)) return ToDateTimeOffset(str); + if (type == typeof(TimeSpan)) return ToTimeSpan (str); + +#if !SILVERLIGHT + + if (type == typeof(SqlByte)) return ToSqlByte (str); + if (type == typeof(SqlInt16)) return ToSqlInt16 (str); + if (type == typeof(SqlInt32)) return ToSqlInt32 (str); + if (type == typeof(SqlInt64)) return ToSqlInt64 (str); + if (type == typeof(SqlSingle)) return ToSqlSingle (str); + if (type == typeof(SqlBoolean)) return ToSqlBoolean (str); + if (type == typeof(SqlDouble)) return ToSqlDouble (str); + if (type == typeof(SqlDateTime)) return ToSqlDateTime(str); + if (type == typeof(SqlDecimal)) return ToSqlDecimal (str); + if (type == typeof(SqlMoney)) return ToSqlMoney (str); + if (type == typeof(SqlString)) return ToSqlString (str); + if (type == typeof(SqlGuid)) return ToSqlGuid (str); + +#endif + + return System.Convert.ChangeType(str, type, Thread.CurrentThread.CurrentCulture); + } + + + #endregion + + static Exception CreateInvalidCastException(Type originalType, Type conversionType) + { + return new InvalidCastException(string.Format(Resources.Convert_InvalidCast, originalType.FullName, conversionType.FullName)); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Common/Convert.generated.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/Convert.generated.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9031 @@ +//--------------------------------------------------------------------------------------------------- +// +// This code was generated by BLToolkit template for T4. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// +//--------------------------------------------------------------------------------------------------- +using System; +using System.Data.Linq; +using System.Data.SqlTypes; +using System.Globalization; +using System.IO; +using System.Xml; +#if !SILVERLIGHT +using System.Xml.Linq; +#endif + +namespace BLToolkit.Common +{ + using Properties; + + public partial class Convert + { + #region Simple Types + + #region Boolean + + // Simple Types + // + /// Converts the value from Byte to an equivalent Boolean value. + public static Boolean ToBoolean(Byte p) { return p != 0; } + /// Converts the value from Decimal to an equivalent Boolean value. + public static Boolean ToBoolean(Decimal p) { return p != 0; } + /// Converts the value from Double to an equivalent Boolean value. + public static Boolean ToBoolean(Double p) { return p != 0; } + /// Converts the value from Int16 to an equivalent Boolean value. + public static Boolean ToBoolean(Int16 p) { return p != 0; } + /// Converts the value from Int32 to an equivalent Boolean value. + public static Boolean ToBoolean(Int32 p) { return p != 0; } + /// Converts the value from Int64 to an equivalent Boolean value. + public static Boolean ToBoolean(Int64 p) { return p != 0; } + /// Converts the value from SByte to an equivalent Boolean value. + [CLSCompliant(false)] + public static Boolean ToBoolean(SByte p) { return p != 0; } + /// Converts the value from Single to an equivalent Boolean value. + public static Boolean ToBoolean(Single p) { return p != 0; } + /// Converts the value from String to an equivalent Boolean value. + public static Boolean ToBoolean(String p) { return p == null? Configuration.NullableValues.Boolean : p.Length == 1 ? ToBoolean(p[0]) : Boolean.Parse(p); } + /// Converts the value from UInt16 to an equivalent Boolean value. + [CLSCompliant(false)] + public static Boolean ToBoolean(UInt16 p) { return p != 0; } + /// Converts the value from UInt32 to an equivalent Boolean value. + [CLSCompliant(false)] + public static Boolean ToBoolean(UInt32 p) { return p != 0; } + /// Converts the value from UInt64 to an equivalent Boolean value. + [CLSCompliant(false)] + public static Boolean ToBoolean(UInt64 p) { return p != 0; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Boolean value. + public static Boolean ToBoolean(Boolean? p) { return p.HasValue && p.Value; } + /// Converts the value from Byte? to an equivalent Boolean value. + public static Boolean ToBoolean(Byte? p) { return p.HasValue && p.Value != 0; } + /// Converts the value from Char? to an equivalent Boolean value. + public static Boolean ToBoolean(Char? p) { return p.HasValue && ToBoolean(p.Value); } + /// Converts the value from Decimal? to an equivalent Boolean value. + public static Boolean ToBoolean(Decimal? p) { return p.HasValue && p.Value != 0; } + /// Converts the value from Double? to an equivalent Boolean value. + public static Boolean ToBoolean(Double? p) { return p.HasValue && p.Value != 0; } + /// Converts the value from Int16? to an equivalent Boolean value. + public static Boolean ToBoolean(Int16? p) { return p.HasValue && p.Value != 0; } + /// Converts the value from Int32? to an equivalent Boolean value. + public static Boolean ToBoolean(Int32? p) { return p.HasValue && p.Value != 0; } + /// Converts the value from Int64? to an equivalent Boolean value. + public static Boolean ToBoolean(Int64? p) { return p.HasValue && p.Value != 0; } + /// Converts the value from SByte? to an equivalent Boolean value. + [CLSCompliant(false)] + public static Boolean ToBoolean(SByte? p) { return p.HasValue && p.Value != 0; } + /// Converts the value from Single? to an equivalent Boolean value. + public static Boolean ToBoolean(Single? p) { return p.HasValue && p.Value != 0; } + /// Converts the value from UInt16? to an equivalent Boolean value. + [CLSCompliant(false)] + public static Boolean ToBoolean(UInt16? p) { return p.HasValue && p.Value != 0; } + /// Converts the value from UInt32? to an equivalent Boolean value. + [CLSCompliant(false)] + public static Boolean ToBoolean(UInt32? p) { return p.HasValue && p.Value != 0; } + /// Converts the value from UInt64? to an equivalent Boolean value. + [CLSCompliant(false)] + public static Boolean ToBoolean(UInt64? p) { return p.HasValue && p.Value != 0; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Boolean value. + public static Boolean ToBoolean(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Boolean : BitConverter.ToBoolean(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Boolean value. + public static Boolean ToBoolean(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Boolean : BitConverter.ToBoolean(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Boolean value. + public static Boolean ToBoolean(SqlBoolean p) { return !p.IsNull && p.Value; } + /// Converts the value from SqlByte to an equivalent Boolean value. + public static Boolean ToBoolean(SqlByte p) { return !p.IsNull && ToBoolean(p.Value); } + /// Converts the value from SqlDecimal to an equivalent Boolean value. + public static Boolean ToBoolean(SqlDecimal p) { return !p.IsNull && ToBoolean(p.Value); } + /// Converts the value from SqlDouble to an equivalent Boolean value. + public static Boolean ToBoolean(SqlDouble p) { return !p.IsNull && ToBoolean(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Boolean value. + public static Boolean ToBoolean(SqlInt16 p) { return !p.IsNull && ToBoolean(p.Value); } + /// Converts the value from SqlInt32 to an equivalent Boolean value. + public static Boolean ToBoolean(SqlInt32 p) { return !p.IsNull && ToBoolean(p.Value); } + /// Converts the value from SqlInt64 to an equivalent Boolean value. + public static Boolean ToBoolean(SqlInt64 p) { return !p.IsNull && ToBoolean(p.Value); } + /// Converts the value from SqlMoney to an equivalent Boolean value. + public static Boolean ToBoolean(SqlMoney p) { return !p.IsNull && ToBoolean(p.Value); } + /// Converts the value from SqlSingle to an equivalent Boolean value. + public static Boolean ToBoolean(SqlSingle p) { return !p.IsNull && ToBoolean(p.Value); } + /// Converts the value from SqlString to an equivalent Boolean value. + public static Boolean ToBoolean(SqlString p) { return !p.IsNull && ToBoolean(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Boolean value. + public static Boolean ToBoolean(object p) + { + if (p == null) return Configuration.NullableValues.Boolean; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.Boolean; + case TypeCode.Boolean : return (Boolean)p; + case TypeCode.Char : return ToBoolean((Char) p); + case TypeCode.String : return ToBoolean((String) p); + case TypeCode.SByte : return ToBoolean((SByte) p); + case TypeCode.Int16 : return ToBoolean((Int16) p); + case TypeCode.Int32 : return ToBoolean((Int32) p); + case TypeCode.Int64 : return ToBoolean((Int64) p); + case TypeCode.Byte : return ToBoolean((Byte) p); + case TypeCode.UInt16 : return ToBoolean((UInt16) p); + case TypeCode.UInt32 : return ToBoolean((UInt32) p); + case TypeCode.UInt64 : return ToBoolean((UInt64) p); + case TypeCode.Single : return ToBoolean((Single) p); + case TypeCode.Double : return ToBoolean((Double) p); + case TypeCode.Decimal : return ToBoolean((Decimal)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToBoolean((Boolean?) p); + if (p is Byte?) return ToBoolean((Byte?) p); + if (p is Char?) return ToBoolean((Char?) p); + if (p is Decimal?) return ToBoolean((Decimal?) p); + if (p is Double?) return ToBoolean((Double?) p); + if (p is Int16?) return ToBoolean((Int16?) p); + if (p is Int32?) return ToBoolean((Int32?) p); + if (p is Int64?) return ToBoolean((Int64?) p); + if (p is SByte?) return ToBoolean((SByte?) p); + if (p is Single?) return ToBoolean((Single?) p); + if (p is UInt16?) return ToBoolean((UInt16?) p); + if (p is UInt32?) return ToBoolean((UInt32?) p); + if (p is UInt64?) return ToBoolean((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToBoolean((Binary) p); + if (p is Byte[]) return ToBoolean((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToBoolean((SqlBoolean)p); + if (p is SqlByte) return ToBoolean((SqlByte) p); + if (p is SqlDecimal) return ToBoolean((SqlDecimal)p); + if (p is SqlDouble) return ToBoolean((SqlDouble) p); + if (p is SqlInt16) return ToBoolean((SqlInt16) p); + if (p is SqlInt32) return ToBoolean((SqlInt32) p); + if (p is SqlInt64) return ToBoolean((SqlInt64) p); + if (p is SqlMoney) return ToBoolean((SqlMoney) p); + if (p is SqlSingle) return ToBoolean((SqlSingle) p); + if (p is SqlString) return ToBoolean((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToBoolean(null); + + throw CreateInvalidCastException(p.GetType(), typeof(Boolean)); + } + + #endregion + + #region Byte + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Byte value. + public static Byte ToByte(Boolean p) { return p ? (Byte)1 : (Byte)0; } + /// Converts the value from Char to an equivalent Byte value. + public static Byte ToByte(Char p) { return checked((Byte)p); } + /// Converts the value from Decimal to an equivalent Byte value. + public static Byte ToByte(Decimal p) { return checked((Byte)p); } + /// Converts the value from Double to an equivalent Byte value. + public static Byte ToByte(Double p) { return checked((Byte)p); } + /// Converts the value from Int16 to an equivalent Byte value. + public static Byte ToByte(Int16 p) { return checked((Byte)p); } + /// Converts the value from Int32 to an equivalent Byte value. + public static Byte ToByte(Int32 p) { return checked((Byte)p); } + /// Converts the value from Int64 to an equivalent Byte value. + public static Byte ToByte(Int64 p) { return checked((Byte)p); } + /// Converts the value from SByte to an equivalent Byte value. + [CLSCompliant(false)] + public static Byte ToByte(SByte p) { return checked((Byte)p); } + /// Converts the value from Single to an equivalent Byte value. + public static Byte ToByte(Single p) { return checked((Byte)p); } + /// Converts the value from String to an equivalent Byte value. + public static Byte ToByte(String p) { return p == null? Configuration.NullableValues.Byte : Byte.Parse(p); } + /// Converts the value from UInt16 to an equivalent Byte value. + [CLSCompliant(false)] + public static Byte ToByte(UInt16 p) { return checked((Byte)p); } + /// Converts the value from UInt32 to an equivalent Byte value. + [CLSCompliant(false)] + public static Byte ToByte(UInt32 p) { return checked((Byte)p); } + /// Converts the value from UInt64 to an equivalent Byte value. + [CLSCompliant(false)] + public static Byte ToByte(UInt64 p) { return checked((Byte)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Byte value. + public static Byte ToByte(Boolean? p) { return p.HasValue && p.Value ? (Byte)1: (Byte)0; } + /// Converts the value from Byte? to an equivalent Byte value. + public static Byte ToByte(Byte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Byte; } + /// Converts the value from Char? to an equivalent Byte value. + public static Byte ToByte(Char? p) { return p.HasValue ? checked((Byte)p.Value) : Configuration.NullableValues.Byte; } + /// Converts the value from Decimal? to an equivalent Byte value. + public static Byte ToByte(Decimal? p) { return p.HasValue ? checked((Byte)p.Value) : Configuration.NullableValues.Byte; } + /// Converts the value from Double? to an equivalent Byte value. + public static Byte ToByte(Double? p) { return p.HasValue ? checked((Byte)p.Value) : Configuration.NullableValues.Byte; } + /// Converts the value from Int16? to an equivalent Byte value. + public static Byte ToByte(Int16? p) { return p.HasValue ? checked((Byte)p.Value) : Configuration.NullableValues.Byte; } + /// Converts the value from Int32? to an equivalent Byte value. + public static Byte ToByte(Int32? p) { return p.HasValue ? checked((Byte)p.Value) : Configuration.NullableValues.Byte; } + /// Converts the value from Int64? to an equivalent Byte value. + public static Byte ToByte(Int64? p) { return p.HasValue ? checked((Byte)p.Value) : Configuration.NullableValues.Byte; } + /// Converts the value from SByte? to an equivalent Byte value. + [CLSCompliant(false)] + public static Byte ToByte(SByte? p) { return p.HasValue ? checked((Byte)p.Value) : Configuration.NullableValues.Byte; } + /// Converts the value from Single? to an equivalent Byte value. + public static Byte ToByte(Single? p) { return p.HasValue ? checked((Byte)p.Value) : Configuration.NullableValues.Byte; } + /// Converts the value from UInt16? to an equivalent Byte value. + [CLSCompliant(false)] + public static Byte ToByte(UInt16? p) { return p.HasValue ? checked((Byte)p.Value) : Configuration.NullableValues.Byte; } + /// Converts the value from UInt32? to an equivalent Byte value. + [CLSCompliant(false)] + public static Byte ToByte(UInt32? p) { return p.HasValue ? checked((Byte)p.Value) : Configuration.NullableValues.Byte; } + /// Converts the value from UInt64? to an equivalent Byte value. + [CLSCompliant(false)] + public static Byte ToByte(UInt64? p) { return p.HasValue ? checked((Byte)p.Value) : Configuration.NullableValues.Byte; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Byte value. + public static Byte ToByte(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Byte : p.ToArray()[0]; } + /// Converts the value from Byte[] to an equivalent Byte value. + public static Byte ToByte(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Byte : p[0]; } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Byte value. + public static Byte ToByte(SqlBoolean p) { return p.IsNull ? Configuration.NullableValues.Byte : ToByte(p.Value); } + /// Converts the value from SqlByte to an equivalent Byte value. + public static Byte ToByte(SqlByte p) { return p.IsNull ? Configuration.NullableValues.Byte : p.Value; } + /// Converts the value from SqlDecimal to an equivalent Byte value. + public static Byte ToByte(SqlDecimal p) { return p.IsNull ? Configuration.NullableValues.Byte : ToByte(p.Value); } + /// Converts the value from SqlDouble to an equivalent Byte value. + public static Byte ToByte(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.Byte : ToByte(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Byte value. + public static Byte ToByte(SqlInt16 p) { return p.IsNull ? Configuration.NullableValues.Byte : ToByte(p.Value); } + /// Converts the value from SqlInt32 to an equivalent Byte value. + public static Byte ToByte(SqlInt32 p) { return p.IsNull ? Configuration.NullableValues.Byte : ToByte(p.Value); } + /// Converts the value from SqlInt64 to an equivalent Byte value. + public static Byte ToByte(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.Byte : ToByte(p.Value); } + /// Converts the value from SqlMoney to an equivalent Byte value. + public static Byte ToByte(SqlMoney p) { return p.IsNull ? Configuration.NullableValues.Byte : ToByte(p.Value); } + /// Converts the value from SqlSingle to an equivalent Byte value. + public static Byte ToByte(SqlSingle p) { return p.IsNull ? Configuration.NullableValues.Byte : ToByte(p.Value); } + /// Converts the value from SqlString to an equivalent Byte value. + public static Byte ToByte(SqlString p) { return p.IsNull ? Configuration.NullableValues.Byte : ToByte(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Byte value. + public static Byte ToByte(object p) + { + if (p == null) return Configuration.NullableValues.Byte; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.Byte; + case TypeCode.Byte : return (Byte)p; + case TypeCode.SByte : return ToByte((SByte) p); + case TypeCode.Int16 : return ToByte((Int16) p); + case TypeCode.Int32 : return ToByte((Int32) p); + case TypeCode.Int64 : return ToByte((Int64) p); + case TypeCode.UInt16 : return ToByte((UInt16) p); + case TypeCode.UInt32 : return ToByte((UInt32) p); + case TypeCode.UInt64 : return ToByte((UInt64) p); + case TypeCode.Single : return ToByte((Single) p); + case TypeCode.Double : return ToByte((Double) p); + case TypeCode.Decimal : return ToByte((Decimal)p); + case TypeCode.Char : return ToByte((Char) p); + case TypeCode.String : return ToByte((String) p); + case TypeCode.Boolean : return ToByte((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToByte((Boolean?) p); + if (p is Byte?) return ToByte((Byte?) p); + if (p is Char?) return ToByte((Char?) p); + if (p is Decimal?) return ToByte((Decimal?) p); + if (p is Double?) return ToByte((Double?) p); + if (p is Int16?) return ToByte((Int16?) p); + if (p is Int32?) return ToByte((Int32?) p); + if (p is Int64?) return ToByte((Int64?) p); + if (p is SByte?) return ToByte((SByte?) p); + if (p is Single?) return ToByte((Single?) p); + if (p is UInt16?) return ToByte((UInt16?) p); + if (p is UInt32?) return ToByte((UInt32?) p); + if (p is UInt64?) return ToByte((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToByte((Binary) p); + if (p is Byte[]) return ToByte((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToByte((SqlBoolean)p); + if (p is SqlByte) return ToByte((SqlByte) p); + if (p is SqlDecimal) return ToByte((SqlDecimal)p); + if (p is SqlDouble) return ToByte((SqlDouble) p); + if (p is SqlInt16) return ToByte((SqlInt16) p); + if (p is SqlInt32) return ToByte((SqlInt32) p); + if (p is SqlInt64) return ToByte((SqlInt64) p); + if (p is SqlMoney) return ToByte((SqlMoney) p); + if (p is SqlSingle) return ToByte((SqlSingle) p); + if (p is SqlString) return ToByte((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToByte(null); + + throw CreateInvalidCastException(p.GetType(), typeof(Byte)); + } + + #endregion + + #region Char + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Char value. + public static Char ToChar(Boolean p) { return p ? (Char)1 : (Char)0; } + /// Converts the value from Byte to an equivalent Char value. + public static Char ToChar(Byte p) { return checked((Char)p); } + /// Converts the value from Decimal to an equivalent Char value. + public static Char ToChar(Decimal p) { return checked((Char)p); } + /// Converts the value from Double to an equivalent Char value. + public static Char ToChar(Double p) { return checked((Char)p); } + /// Converts the value from Int16 to an equivalent Char value. + public static Char ToChar(Int16 p) { return checked((Char)p); } + /// Converts the value from Int32 to an equivalent Char value. + public static Char ToChar(Int32 p) { return checked((Char)p); } + /// Converts the value from Int64 to an equivalent Char value. + public static Char ToChar(Int64 p) { return checked((Char)p); } + /// Converts the value from SByte to an equivalent Char value. + [CLSCompliant(false)] + public static Char ToChar(SByte p) { return checked((Char)p); } + /// Converts the value from Single to an equivalent Char value. + public static Char ToChar(Single p) { return checked((Char)p); } + /// Converts the value from String to an equivalent Char value. + public static Char ToChar(String p) { return string.IsNullOrEmpty(p)? (Char)0 : p[0]; } + /// Converts the value from UInt16 to an equivalent Char value. + [CLSCompliant(false)] + public static Char ToChar(UInt16 p) { return checked((Char)p); } + /// Converts the value from UInt32 to an equivalent Char value. + [CLSCompliant(false)] + public static Char ToChar(UInt32 p) { return checked((Char)p); } + /// Converts the value from UInt64 to an equivalent Char value. + [CLSCompliant(false)] + public static Char ToChar(UInt64 p) { return checked((Char)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Char value. + public static Char ToChar(Boolean? p) { return p.HasValue && p.Value ? (Char)1: (Char)0; } + /// Converts the value from Byte? to an equivalent Char value. + public static Char ToChar(Byte? p) { return p.HasValue ? checked((Char)p.Value) : Configuration.NullableValues.Char; } + /// Converts the value from Char? to an equivalent Char value. + public static Char ToChar(Char? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Char; } + /// Converts the value from Decimal? to an equivalent Char value. + public static Char ToChar(Decimal? p) { return p.HasValue ? checked((Char)p.Value) : Configuration.NullableValues.Char; } + /// Converts the value from Double? to an equivalent Char value. + public static Char ToChar(Double? p) { return p.HasValue ? checked((Char)p.Value) : Configuration.NullableValues.Char; } + /// Converts the value from Int16? to an equivalent Char value. + public static Char ToChar(Int16? p) { return p.HasValue ? checked((Char)p.Value) : Configuration.NullableValues.Char; } + /// Converts the value from Int32? to an equivalent Char value. + public static Char ToChar(Int32? p) { return p.HasValue ? checked((Char)p.Value) : Configuration.NullableValues.Char; } + /// Converts the value from Int64? to an equivalent Char value. + public static Char ToChar(Int64? p) { return p.HasValue ? checked((Char)p.Value) : Configuration.NullableValues.Char; } + /// Converts the value from SByte? to an equivalent Char value. + [CLSCompliant(false)] + public static Char ToChar(SByte? p) { return p.HasValue ? checked((Char)p.Value) : Configuration.NullableValues.Char; } + /// Converts the value from Single? to an equivalent Char value. + public static Char ToChar(Single? p) { return p.HasValue ? checked((Char)p.Value) : Configuration.NullableValues.Char; } + /// Converts the value from UInt16? to an equivalent Char value. + [CLSCompliant(false)] + public static Char ToChar(UInt16? p) { return p.HasValue ? checked((Char)p.Value) : Configuration.NullableValues.Char; } + /// Converts the value from UInt32? to an equivalent Char value. + [CLSCompliant(false)] + public static Char ToChar(UInt32? p) { return p.HasValue ? checked((Char)p.Value) : Configuration.NullableValues.Char; } + /// Converts the value from UInt64? to an equivalent Char value. + [CLSCompliant(false)] + public static Char ToChar(UInt64? p) { return p.HasValue ? checked((Char)p.Value) : Configuration.NullableValues.Char; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Char value. + public static Char ToChar(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Char : BitConverter.ToChar(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Char value. + public static Char ToChar(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Char : BitConverter.ToChar(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Char value. + public static Char ToChar(SqlBoolean p) { return p.IsNull ? Configuration.NullableValues.Char : ToChar(p.Value); } + /// Converts the value from SqlByte to an equivalent Char value. + public static Char ToChar(SqlByte p) { return p.IsNull ? Configuration.NullableValues.Char : ToChar(p.Value); } + /// Converts the value from SqlDecimal to an equivalent Char value. + public static Char ToChar(SqlDecimal p) { return p.IsNull ? Configuration.NullableValues.Char : ToChar(p.Value); } + /// Converts the value from SqlDouble to an equivalent Char value. + public static Char ToChar(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.Char : ToChar(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Char value. + public static Char ToChar(SqlInt16 p) { return p.IsNull ? Configuration.NullableValues.Char : ToChar(p.Value); } + /// Converts the value from SqlInt32 to an equivalent Char value. + public static Char ToChar(SqlInt32 p) { return p.IsNull ? Configuration.NullableValues.Char : ToChar(p.Value); } + /// Converts the value from SqlInt64 to an equivalent Char value. + public static Char ToChar(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.Char : ToChar(p.Value); } + /// Converts the value from SqlMoney to an equivalent Char value. + public static Char ToChar(SqlMoney p) { return p.IsNull ? Configuration.NullableValues.Char : ToChar(p.Value); } + /// Converts the value from SqlSingle to an equivalent Char value. + public static Char ToChar(SqlSingle p) { return p.IsNull ? Configuration.NullableValues.Char : ToChar(p.Value); } + /// Converts the value from SqlString to an equivalent Char value. + public static Char ToChar(SqlString p) { return p.IsNull ? Configuration.NullableValues.Char : ToChar(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Char value. + public static Char ToChar(object p) + { + if (p == null) return Configuration.NullableValues.Char; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.Char; + case TypeCode.Char : return (Char)p; + case TypeCode.SByte : return ToChar((SByte) p); + case TypeCode.Int16 : return ToChar((Int16) p); + case TypeCode.Int32 : return ToChar((Int32) p); + case TypeCode.Int64 : return ToChar((Int64) p); + case TypeCode.Byte : return ToChar((Byte) p); + case TypeCode.UInt16 : return ToChar((UInt16) p); + case TypeCode.UInt32 : return ToChar((UInt32) p); + case TypeCode.UInt64 : return ToChar((UInt64) p); + case TypeCode.Single : return ToChar((Single) p); + case TypeCode.Double : return ToChar((Double) p); + case TypeCode.Decimal : return ToChar((Decimal)p); + case TypeCode.String : return ToChar((String) p); + case TypeCode.Boolean : return ToChar((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToChar((Boolean?) p); + if (p is Byte?) return ToChar((Byte?) p); + if (p is Char?) return ToChar((Char?) p); + if (p is Decimal?) return ToChar((Decimal?) p); + if (p is Double?) return ToChar((Double?) p); + if (p is Int16?) return ToChar((Int16?) p); + if (p is Int32?) return ToChar((Int32?) p); + if (p is Int64?) return ToChar((Int64?) p); + if (p is SByte?) return ToChar((SByte?) p); + if (p is Single?) return ToChar((Single?) p); + if (p is UInt16?) return ToChar((UInt16?) p); + if (p is UInt32?) return ToChar((UInt32?) p); + if (p is UInt64?) return ToChar((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToChar((Binary) p); + if (p is Byte[]) return ToChar((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToChar((SqlBoolean)p); + if (p is SqlByte) return ToChar((SqlByte) p); + if (p is SqlDecimal) return ToChar((SqlDecimal)p); + if (p is SqlDouble) return ToChar((SqlDouble) p); + if (p is SqlInt16) return ToChar((SqlInt16) p); + if (p is SqlInt32) return ToChar((SqlInt32) p); + if (p is SqlInt64) return ToChar((SqlInt64) p); + if (p is SqlMoney) return ToChar((SqlMoney) p); + if (p is SqlSingle) return ToChar((SqlSingle) p); + if (p is SqlString) return ToChar((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToChar(null); + + throw CreateInvalidCastException(p.GetType(), typeof(Char)); + } + + #endregion + + #region DateTime + + // Simple Types + // + /// Converts the value from DateTimeOffset to an equivalent DateTime value. + public static DateTime ToDateTime(DateTimeOffset p) { return p.LocalDateTime; } + /// Converts the value from Double to an equivalent DateTime value. + public static DateTime ToDateTime(Double p) { return DateTime.MinValue + TimeSpan.FromDays (p); } + /// Converts the value from Int64 to an equivalent DateTime value. + public static DateTime ToDateTime(Int64 p) { return DateTime.MinValue + TimeSpan.FromTicks(p); } + /// Converts the value from String to an equivalent DateTime value. + public static DateTime ToDateTime(String p) { return p == null ? Configuration.NullableValues.DateTime : DateTime.Parse(p, null, DateTimeStyles.NoCurrentDateDefault); } + /// Converts the value from TimeSpan to an equivalent DateTime value. + public static DateTime ToDateTime(TimeSpan p) { return DateTime.MinValue + p; } + + // Nullable Types + // + /// Converts the value from DateTime? to an equivalent DateTime value. + public static DateTime ToDateTime(DateTime? p) { return p.HasValue ? p.Value : Configuration.NullableValues.DateTime; } + /// Converts the value from DateTimeOffset? to an equivalent DateTime value. + public static DateTime ToDateTime(DateTimeOffset? p) { return p.HasValue ? p.Value.LocalDateTime : Configuration.NullableValues.DateTime; } + /// Converts the value from Double? to an equivalent DateTime value. + public static DateTime ToDateTime(Double? p) { return p.HasValue ? DateTime.MinValue + TimeSpan.FromDays (p.Value): Configuration.NullableValues.DateTime; } + /// Converts the value from Int64? to an equivalent DateTime value. + public static DateTime ToDateTime(Int64? p) { return p.HasValue ? DateTime.MinValue + TimeSpan.FromTicks(p.Value): Configuration.NullableValues.DateTime; } + /// Converts the value from TimeSpan? to an equivalent DateTime value. + public static DateTime ToDateTime(TimeSpan? p) { return p.HasValue ? DateTime.MinValue + p.Value : Configuration.NullableValues.DateTime; } + + // Other Types + // + /// Converts the value from Binary to an equivalent DateTime value. + public static DateTime ToDateTime(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.DateTime : DateTime.FromBinary(ToInt64(p.ToArray())); } + /// Converts the value from Byte[] to an equivalent DateTime value. + public static DateTime ToDateTime(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.DateTime : DateTime.FromBinary(ToInt64(p)); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlDateTime to an equivalent DateTime value. + public static DateTime ToDateTime(SqlDateTime p) { return p.IsNull ? Configuration.NullableValues.DateTime : p.Value; } + /// Converts the value from SqlDouble to an equivalent DateTime value. + public static DateTime ToDateTime(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.DateTime : DateTime.MinValue + TimeSpan.FromDays (p.Value); } + /// Converts the value from SqlInt64 to an equivalent DateTime value. + public static DateTime ToDateTime(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.DateTime : DateTime.MinValue + TimeSpan.FromTicks(p.Value); } + /// Converts the value from SqlString to an equivalent DateTime value. + public static DateTime ToDateTime(SqlString p) { return p.IsNull ? Configuration.NullableValues.DateTime : ToDateTime(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent DateTime value. + public static DateTime ToDateTime(object p) + { + if (p == null) return Configuration.NullableValues.DateTime; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.DateTime; + case TypeCode.DateTime : return (DateTime)p; + case TypeCode.String : return ToDateTime((String) p); + case TypeCode.Int64 : return ToDateTime((Int64) p); + case TypeCode.Double : return ToDateTime((Double) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToDateTime((DateTimeOffset) p); + if (p is TimeSpan) return ToDateTime((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is DateTime?) return ToDateTime((DateTime?) p); + if (p is DateTimeOffset?) return ToDateTime((DateTimeOffset?)p); + if (p is Double?) return ToDateTime((Double?) p); + if (p is Int64?) return ToDateTime((Int64?) p); + if (p is TimeSpan?) return ToDateTime((TimeSpan?) p); + } + + // Other Types + // + if (p is Binary) return ToDateTime((Binary) p); + if (p is Byte[]) return ToDateTime((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlDateTime) return ToDateTime((SqlDateTime) p); + if (p is SqlDouble) return ToDateTime((SqlDouble) p); + if (p is SqlInt64) return ToDateTime((SqlInt64) p); + if (p is SqlString) return ToDateTime((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToDateTime(null); + + throw CreateInvalidCastException(p.GetType(), typeof(DateTime)); + } + + #endregion + + #region DateTimeOffset + + // Simple Types + // + /// Converts the value from DateTime to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(DateTime p) { return p; } + /// Converts the value from Double to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(Double p) { return DateTimeOffset.MinValue + TimeSpan.FromDays (p); } + /// Converts the value from Int64 to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(Int64 p) { return DateTimeOffset.MinValue + TimeSpan.FromTicks(p); } + /// Converts the value from String to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(String p) { return p == null? DateTimeOffset.MinValue : DateTimeOffset.Parse(p); } + /// Converts the value from TimeSpan to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(TimeSpan p) { return DateTimeOffset.MinValue + p; } + + // Nullable Types + // + /// Converts the value from DateTime? to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(DateTime? p) { return p.HasValue ? p.Value : DateTimeOffset.MinValue; } + /// Converts the value from DateTimeOffset? to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(DateTimeOffset? p) { return p.HasValue ? p.Value : DateTimeOffset.MinValue; } + /// Converts the value from Double? to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(Double? p) { return p.HasValue ? DateTimeOffset.MinValue + TimeSpan.FromDays (p.Value): DateTimeOffset.MinValue; } + /// Converts the value from Int64? to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(Int64? p) { return p.HasValue ? DateTimeOffset.MinValue + TimeSpan.FromTicks(p.Value): DateTimeOffset.MinValue; } + /// Converts the value from TimeSpan? to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(TimeSpan? p) { return p.HasValue ? DateTimeOffset.MinValue + p.Value : DateTimeOffset.MinValue; } + + // Other Types + // + /// Converts the value from Binary to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(Binary p) { return p == null || p.Length == 0 ? DateTimeOffset.MinValue : new DateTimeOffset(ToDateTime(p.ToArray())); } + /// Converts the value from Byte[] to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(Byte[] p) { return p == null || p.Length == 0 ? DateTimeOffset.MinValue : new DateTimeOffset(ToDateTime(p)); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlDateTime to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(SqlDateTime p) { return p.IsNull ? DateTimeOffset.MinValue : p.Value; } + /// Converts the value from SqlDouble to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(SqlDouble p) { return p.IsNull ? DateTimeOffset.MinValue : DateTimeOffset.MinValue + TimeSpan.FromDays (p.Value); } + /// Converts the value from SqlInt64 to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(SqlInt64 p) { return p.IsNull ? DateTimeOffset.MinValue : DateTimeOffset.MinValue + TimeSpan.FromTicks(p.Value); } + /// Converts the value from SqlString to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(SqlString p) { return p.IsNull ? DateTimeOffset.MinValue : ToDateTimeOffset(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent DateTimeOffset value. + public static DateTimeOffset ToDateTimeOffset(object p) + { + if (p == null) return DateTimeOffset.MinValue; + + if (p is DateTimeOffset) return (DateTimeOffset)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return DateTimeOffset.MinValue; + case TypeCode.Int64 : return ToDateTimeOffset((Int64) p); + case TypeCode.Double : return ToDateTimeOffset((Double) p); + case TypeCode.DateTime : return ToDateTimeOffset((DateTime) p); + case TypeCode.String : return ToDateTimeOffset((String) p); + } + + // Simple Types + // + if (p is TimeSpan) return ToDateTimeOffset((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is DateTime?) return ToDateTimeOffset((DateTime?) p); + if (p is DateTimeOffset?) return ToDateTimeOffset((DateTimeOffset?)p); + if (p is Double?) return ToDateTimeOffset((Double?) p); + if (p is Int64?) return ToDateTimeOffset((Int64?) p); + if (p is TimeSpan?) return ToDateTimeOffset((TimeSpan?) p); + } + + // Other Types + // + if (p is Binary) return ToDateTimeOffset((Binary) p); + if (p is Byte[]) return ToDateTimeOffset((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlDateTime) return ToDateTimeOffset((SqlDateTime) p); + if (p is SqlDouble) return ToDateTimeOffset((SqlDouble) p); + if (p is SqlInt64) return ToDateTimeOffset((SqlInt64) p); + if (p is SqlString) return ToDateTimeOffset((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(DateTimeOffset)); + } + + #endregion + + #region Decimal + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Decimal value. + public static Decimal ToDecimal(Boolean p) { return p ? (Decimal)1 : (Decimal)0; } + /// Converts the value from Byte to an equivalent Decimal value. + public static Decimal ToDecimal(Byte p) { return p; } + /// Converts the value from Char to an equivalent Decimal value. + public static Decimal ToDecimal(Char p) { return p; } + /// Converts the value from Double to an equivalent Decimal value. + public static Decimal ToDecimal(Double p) { return checked((Decimal)p); } + /// Converts the value from Int16 to an equivalent Decimal value. + public static Decimal ToDecimal(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent Decimal value. + public static Decimal ToDecimal(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent Decimal value. + public static Decimal ToDecimal(Int64 p) { return p; } + /// Converts the value from SByte to an equivalent Decimal value. + [CLSCompliant(false)] + public static Decimal ToDecimal(SByte p) { return p; } + /// Converts the value from Single to an equivalent Decimal value. + public static Decimal ToDecimal(Single p) { return checked((Decimal)p); } + /// Converts the value from String to an equivalent Decimal value. + public static Decimal ToDecimal(String p) { return p == null? Configuration.NullableValues.Decimal : Decimal.Parse(p); } + /// Converts the value from UInt16 to an equivalent Decimal value. + [CLSCompliant(false)] + public static Decimal ToDecimal(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent Decimal value. + [CLSCompliant(false)] + public static Decimal ToDecimal(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent Decimal value. + [CLSCompliant(false)] + public static Decimal ToDecimal(UInt64 p) { return p; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Decimal value. + public static Decimal ToDecimal(Boolean? p) { return p.HasValue && p.Value ? (Decimal)1: (Decimal)0; } + /// Converts the value from Byte? to an equivalent Decimal value. + public static Decimal ToDecimal(Byte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Decimal; } + /// Converts the value from Char? to an equivalent Decimal value. + public static Decimal ToDecimal(Char? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Decimal; } + /// Converts the value from Decimal? to an equivalent Decimal value. + public static Decimal ToDecimal(Decimal? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Decimal; } + /// Converts the value from Double? to an equivalent Decimal value. + public static Decimal ToDecimal(Double? p) { return p.HasValue ? checked((Decimal)p.Value) : Configuration.NullableValues.Decimal; } + /// Converts the value from Int16? to an equivalent Decimal value. + public static Decimal ToDecimal(Int16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Decimal; } + /// Converts the value from Int32? to an equivalent Decimal value. + public static Decimal ToDecimal(Int32? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Decimal; } + /// Converts the value from Int64? to an equivalent Decimal value. + public static Decimal ToDecimal(Int64? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Decimal; } + /// Converts the value from SByte? to an equivalent Decimal value. + [CLSCompliant(false)] + public static Decimal ToDecimal(SByte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Decimal; } + /// Converts the value from Single? to an equivalent Decimal value. + public static Decimal ToDecimal(Single? p) { return p.HasValue ? checked((Decimal)p.Value) : Configuration.NullableValues.Decimal; } + /// Converts the value from UInt16? to an equivalent Decimal value. + [CLSCompliant(false)] + public static Decimal ToDecimal(UInt16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Decimal; } + /// Converts the value from UInt32? to an equivalent Decimal value. + [CLSCompliant(false)] + public static Decimal ToDecimal(UInt32? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Decimal; } + /// Converts the value from UInt64? to an equivalent Decimal value. + [CLSCompliant(false)] + public static Decimal ToDecimal(UInt64? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Decimal; } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Decimal value. + public static Decimal ToDecimal(SqlBoolean p) { return p.IsNull ? Configuration.NullableValues.Decimal : ToDecimal(p.Value); } + /// Converts the value from SqlByte to an equivalent Decimal value. + public static Decimal ToDecimal(SqlByte p) { return p.IsNull ? Configuration.NullableValues.Decimal : p.Value; } + /// Converts the value from SqlDecimal to an equivalent Decimal value. + public static Decimal ToDecimal(SqlDecimal p) { return p.IsNull ? Configuration.NullableValues.Decimal : p.Value; } + /// Converts the value from SqlDouble to an equivalent Decimal value. + public static Decimal ToDecimal(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.Decimal : ToDecimal(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Decimal value. + public static Decimal ToDecimal(SqlInt16 p) { return p.IsNull ? Configuration.NullableValues.Decimal : p.Value; } + /// Converts the value from SqlInt32 to an equivalent Decimal value. + public static Decimal ToDecimal(SqlInt32 p) { return p.IsNull ? Configuration.NullableValues.Decimal : p.Value; } + /// Converts the value from SqlInt64 to an equivalent Decimal value. + public static Decimal ToDecimal(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.Decimal : p.Value; } + /// Converts the value from SqlMoney to an equivalent Decimal value. + public static Decimal ToDecimal(SqlMoney p) { return p.IsNull ? Configuration.NullableValues.Decimal : p.Value; } + /// Converts the value from SqlSingle to an equivalent Decimal value. + public static Decimal ToDecimal(SqlSingle p) { return p.IsNull ? Configuration.NullableValues.Decimal : ToDecimal(p.Value); } + /// Converts the value from SqlString to an equivalent Decimal value. + public static Decimal ToDecimal(SqlString p) { return p.IsNull ? Configuration.NullableValues.Decimal : ToDecimal(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Decimal value. + public static Decimal ToDecimal(object p) + { + if (p == null) return Configuration.NullableValues.Decimal; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.Decimal; + case TypeCode.Decimal : return (Decimal)p; + case TypeCode.SByte : return ToDecimal((SByte) p); + case TypeCode.Int16 : return ToDecimal((Int16) p); + case TypeCode.Int32 : return ToDecimal((Int32) p); + case TypeCode.Int64 : return ToDecimal((Int64) p); + case TypeCode.Byte : return ToDecimal((Byte) p); + case TypeCode.UInt16 : return ToDecimal((UInt16) p); + case TypeCode.UInt32 : return ToDecimal((UInt32) p); + case TypeCode.Char : return ToDecimal((Char) p); + case TypeCode.UInt64 : return ToDecimal((UInt64) p); + case TypeCode.Single : return ToDecimal((Single) p); + case TypeCode.Double : return ToDecimal((Double) p); + case TypeCode.String : return ToDecimal((String) p); + case TypeCode.Boolean : return ToDecimal((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToDecimal((Boolean?) p); + if (p is Byte?) return ToDecimal((Byte?) p); + if (p is Char?) return ToDecimal((Char?) p); + if (p is Decimal?) return ToDecimal((Decimal?) p); + if (p is Double?) return ToDecimal((Double?) p); + if (p is Int16?) return ToDecimal((Int16?) p); + if (p is Int32?) return ToDecimal((Int32?) p); + if (p is Int64?) return ToDecimal((Int64?) p); + if (p is SByte?) return ToDecimal((SByte?) p); + if (p is Single?) return ToDecimal((Single?) p); + if (p is UInt16?) return ToDecimal((UInt16?) p); + if (p is UInt32?) return ToDecimal((UInt32?) p); + if (p is UInt64?) return ToDecimal((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToDecimal((Binary) p); + if (p is Byte[]) return ToDecimal((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToDecimal((SqlBoolean)p); + if (p is SqlByte) return ToDecimal((SqlByte) p); + if (p is SqlDecimal) return ToDecimal((SqlDecimal)p); + if (p is SqlDouble) return ToDecimal((SqlDouble) p); + if (p is SqlInt16) return ToDecimal((SqlInt16) p); + if (p is SqlInt32) return ToDecimal((SqlInt32) p); + if (p is SqlInt64) return ToDecimal((SqlInt64) p); + if (p is SqlMoney) return ToDecimal((SqlMoney) p); + if (p is SqlSingle) return ToDecimal((SqlSingle) p); + if (p is SqlString) return ToDecimal((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToDecimal(null); + + throw CreateInvalidCastException(p.GetType(), typeof(Decimal)); + } + + #endregion + + #region Double + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Double value. + public static Double ToDouble(Boolean p) { return p ? (Double)1 : (Double)0; } + /// Converts the value from Byte to an equivalent Double value. + public static Double ToDouble(Byte p) { return p; } + /// Converts the value from Char to an equivalent Double value. + public static Double ToDouble(Char p) { return p; } + /// Converts the value from DateTime to an equivalent Double value. + public static Double ToDouble(DateTime p) { return (p - DateTime.MinValue).TotalDays; } + /// Converts the value from DateTimeOffset to an equivalent Double value. + public static Double ToDouble(DateTimeOffset p) { return (p - DateTimeOffset.MinValue).TotalDays; } + /// Converts the value from Decimal to an equivalent Double value. + public static Double ToDouble(Decimal p) { return checked((Double)p); } + /// Converts the value from Int16 to an equivalent Double value. + public static Double ToDouble(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent Double value. + public static Double ToDouble(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent Double value. + public static Double ToDouble(Int64 p) { return p; } + /// Converts the value from SByte to an equivalent Double value. + [CLSCompliant(false)] + public static Double ToDouble(SByte p) { return p; } + /// Converts the value from Single to an equivalent Double value. + public static Double ToDouble(Single p) { return p; } + /// Converts the value from String to an equivalent Double value. + public static Double ToDouble(String p) { return p == null? Configuration.NullableValues.Double : Double.Parse(p); } + /// Converts the value from TimeSpan to an equivalent Double value. + public static Double ToDouble(TimeSpan p) { return p.TotalDays; } + /// Converts the value from UInt16 to an equivalent Double value. + [CLSCompliant(false)] + public static Double ToDouble(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent Double value. + [CLSCompliant(false)] + public static Double ToDouble(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent Double value. + [CLSCompliant(false)] + public static Double ToDouble(UInt64 p) { return p; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Double value. + public static Double ToDouble(Boolean? p) { return p.HasValue && p.Value ? (Double)1: (Double)0; } + /// Converts the value from Byte? to an equivalent Double value. + public static Double ToDouble(Byte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Double; } + /// Converts the value from Char? to an equivalent Double value. + public static Double ToDouble(Char? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Double; } + /// Converts the value from DateTime? to an equivalent Double value. + public static Double ToDouble(DateTime? p) { return p.HasValue ? (p.Value - DateTime.MinValue).TotalDays : Configuration.NullableValues.Double; } + /// Converts the value from DateTimeOffset? to an equivalent Double value. + public static Double ToDouble(DateTimeOffset? p) { return p.HasValue ? (p.Value - DateTimeOffset.MinValue).TotalDays : Configuration.NullableValues.Double; } + /// Converts the value from Decimal? to an equivalent Double value. + public static Double ToDouble(Decimal? p) { return p.HasValue ? checked((Double)p.Value) : Configuration.NullableValues.Double; } + /// Converts the value from Double? to an equivalent Double value. + public static Double ToDouble(Double? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Double; } + /// Converts the value from Int16? to an equivalent Double value. + public static Double ToDouble(Int16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Double; } + /// Converts the value from Int32? to an equivalent Double value. + public static Double ToDouble(Int32? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Double; } + /// Converts the value from Int64? to an equivalent Double value. + public static Double ToDouble(Int64? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Double; } + /// Converts the value from SByte? to an equivalent Double value. + [CLSCompliant(false)] + public static Double ToDouble(SByte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Double; } + /// Converts the value from Single? to an equivalent Double value. + public static Double ToDouble(Single? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Double; } + /// Converts the value from TimeSpan? to an equivalent Double value. + public static Double ToDouble(TimeSpan? p) { return p.HasValue ? p.Value.TotalDays : Configuration.NullableValues.Double; } + /// Converts the value from UInt16? to an equivalent Double value. + [CLSCompliant(false)] + public static Double ToDouble(UInt16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Double; } + /// Converts the value from UInt32? to an equivalent Double value. + [CLSCompliant(false)] + public static Double ToDouble(UInt32? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Double; } + /// Converts the value from UInt64? to an equivalent Double value. + [CLSCompliant(false)] + public static Double ToDouble(UInt64? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Double; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Double value. + public static Double ToDouble(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Double : BitConverter.ToDouble(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Double value. + public static Double ToDouble(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Double : BitConverter.ToDouble(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Double value. + public static Double ToDouble(SqlBoolean p) { return p.IsNull ? Configuration.NullableValues.Double : ToDouble(p.Value); } + /// Converts the value from SqlByte to an equivalent Double value. + public static Double ToDouble(SqlByte p) { return p.IsNull ? Configuration.NullableValues.Double : p.Value; } + /// Converts the value from SqlDateTime to an equivalent Double value. + public static Double ToDouble(SqlDateTime p) { return p.IsNull ? Configuration.NullableValues.Double : ToDouble(p.Value); } + /// Converts the value from SqlDecimal to an equivalent Double value. + public static Double ToDouble(SqlDecimal p) { return p.IsNull ? Configuration.NullableValues.Double : ToDouble(p.Value); } + /// Converts the value from SqlDouble to an equivalent Double value. + public static Double ToDouble(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.Double : p.Value; } + /// Converts the value from SqlInt16 to an equivalent Double value. + public static Double ToDouble(SqlInt16 p) { return p.IsNull ? Configuration.NullableValues.Double : p.Value; } + /// Converts the value from SqlInt32 to an equivalent Double value. + public static Double ToDouble(SqlInt32 p) { return p.IsNull ? Configuration.NullableValues.Double : p.Value; } + /// Converts the value from SqlInt64 to an equivalent Double value. + public static Double ToDouble(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.Double : p.Value; } + /// Converts the value from SqlMoney to an equivalent Double value. + public static Double ToDouble(SqlMoney p) { return p.IsNull ? Configuration.NullableValues.Double : ToDouble(p.Value); } + /// Converts the value from SqlSingle to an equivalent Double value. + public static Double ToDouble(SqlSingle p) { return p.IsNull ? Configuration.NullableValues.Double : p.Value; } + /// Converts the value from SqlString to an equivalent Double value. + public static Double ToDouble(SqlString p) { return p.IsNull ? Configuration.NullableValues.Double : ToDouble(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Double value. + public static Double ToDouble(object p) + { + if (p == null) return Configuration.NullableValues.Double; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.Double; + case TypeCode.Double : return (Double)p; + case TypeCode.DateTime : return ToDouble((DateTime)p); + case TypeCode.SByte : return ToDouble((SByte) p); + case TypeCode.Int16 : return ToDouble((Int16) p); + case TypeCode.Int32 : return ToDouble((Int32) p); + case TypeCode.Int64 : return ToDouble((Int64) p); + case TypeCode.Byte : return ToDouble((Byte) p); + case TypeCode.UInt16 : return ToDouble((UInt16) p); + case TypeCode.UInt32 : return ToDouble((UInt32) p); + case TypeCode.Char : return ToDouble((Char) p); + case TypeCode.UInt64 : return ToDouble((UInt64) p); + case TypeCode.Single : return ToDouble((Single) p); + case TypeCode.Decimal : return ToDouble((Decimal) p); + case TypeCode.String : return ToDouble((String) p); + case TypeCode.Boolean : return ToDouble((Boolean) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToDouble((DateTimeOffset) p); + if (p is TimeSpan) return ToDouble((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToDouble((Boolean?) p); + if (p is Byte?) return ToDouble((Byte?) p); + if (p is Char?) return ToDouble((Char?) p); + if (p is DateTime?) return ToDouble((DateTime?) p); + if (p is DateTimeOffset?) return ToDouble((DateTimeOffset?)p); + if (p is Decimal?) return ToDouble((Decimal?) p); + if (p is Double?) return ToDouble((Double?) p); + if (p is Int16?) return ToDouble((Int16?) p); + if (p is Int32?) return ToDouble((Int32?) p); + if (p is Int64?) return ToDouble((Int64?) p); + if (p is SByte?) return ToDouble((SByte?) p); + if (p is Single?) return ToDouble((Single?) p); + if (p is TimeSpan?) return ToDouble((TimeSpan?) p); + if (p is UInt16?) return ToDouble((UInt16?) p); + if (p is UInt32?) return ToDouble((UInt32?) p); + if (p is UInt64?) return ToDouble((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToDouble((Binary) p); + if (p is Byte[]) return ToDouble((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToDouble((SqlBoolean) p); + if (p is SqlByte) return ToDouble((SqlByte) p); + if (p is SqlDateTime) return ToDouble((SqlDateTime) p); + if (p is SqlDecimal) return ToDouble((SqlDecimal) p); + if (p is SqlDouble) return ToDouble((SqlDouble) p); + if (p is SqlInt16) return ToDouble((SqlInt16) p); + if (p is SqlInt32) return ToDouble((SqlInt32) p); + if (p is SqlInt64) return ToDouble((SqlInt64) p); + if (p is SqlMoney) return ToDouble((SqlMoney) p); + if (p is SqlSingle) return ToDouble((SqlSingle) p); + if (p is SqlString) return ToDouble((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToDouble(null); + + throw CreateInvalidCastException(p.GetType(), typeof(Double)); + } + + #endregion + + #region Guid + + // Simple Types + // + /// Converts the value from String to an equivalent Guid value. + public static Guid ToGuid(String p) { return p == null ? Configuration.NullableValues.Guid : new Guid(p); } + + // Nullable Types + // + /// Converts the value from Guid? to an equivalent Guid value. + public static Guid ToGuid(Guid? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Guid; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Guid value. + public static Guid ToGuid(Binary p) { return p == null ? Configuration.NullableValues.Guid : new Guid(p.ToArray()); } + /// Converts the value from Byte[] to an equivalent Guid value. + public static Guid ToGuid(Byte[] p) { return p == null ? Configuration.NullableValues.Guid : new Guid(p); } + /// Converts the value from Type to an equivalent Guid value. + public static Guid ToGuid(Type p) { return p == null ? Configuration.NullableValues.Guid : p.GUID; } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBinary to an equivalent Guid value. + public static Guid ToGuid(SqlBinary p) { return p.IsNull ? Configuration.NullableValues.Guid : p.ToSqlGuid().Value; } + /// Converts the value from SqlGuid to an equivalent Guid value. + public static Guid ToGuid(SqlGuid p) { return p.IsNull ? Configuration.NullableValues.Guid : p.Value; } + /// Converts the value from SqlString to an equivalent Guid value. + public static Guid ToGuid(SqlString p) { return p.IsNull ? Configuration.NullableValues.Guid : new Guid(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Guid value. + public static Guid ToGuid(object p) + { + if (p == null) return Configuration.NullableValues.Guid; + + if (p is Guid) return (Guid)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.Guid; + case TypeCode.String : return ToGuid((String)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Guid?) return ToGuid((Guid?) p); + } + + // Other Types + // + if (p is Binary) return ToGuid((Binary) p); + if (p is Byte[]) return ToGuid((Byte[]) p); + if (p is Type) return ToGuid((Type) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBinary) return ToGuid((SqlBinary)p); + if (p is SqlGuid) return ToGuid((SqlGuid) p); + if (p is SqlString) return ToGuid((SqlString)p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Guid)); + } + + #endregion + + #region Int16 + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Int16 value. + public static Int16 ToInt16(Boolean p) { return p ? (Int16)1 : (Int16)0; } + /// Converts the value from Byte to an equivalent Int16 value. + public static Int16 ToInt16(Byte p) { return p; } + /// Converts the value from Char to an equivalent Int16 value. + public static Int16 ToInt16(Char p) { return checked((Int16)p); } + /// Converts the value from Decimal to an equivalent Int16 value. + public static Int16 ToInt16(Decimal p) { return checked((Int16)p); } + /// Converts the value from Double to an equivalent Int16 value. + public static Int16 ToInt16(Double p) { return checked((Int16)p); } + /// Converts the value from Int32 to an equivalent Int16 value. + public static Int16 ToInt16(Int32 p) { return checked((Int16)p); } + /// Converts the value from Int64 to an equivalent Int16 value. + public static Int16 ToInt16(Int64 p) { return checked((Int16)p); } + /// Converts the value from SByte to an equivalent Int16 value. + [CLSCompliant(false)] + public static Int16 ToInt16(SByte p) { return p; } + /// Converts the value from Single to an equivalent Int16 value. + public static Int16 ToInt16(Single p) { return checked((Int16)p); } + /// Converts the value from String to an equivalent Int16 value. + public static Int16 ToInt16(String p) { return p == null? Configuration.NullableValues.Int16 : Int16.Parse(p); } + /// Converts the value from UInt16 to an equivalent Int16 value. + [CLSCompliant(false)] + public static Int16 ToInt16(UInt16 p) { return checked((Int16)p); } + /// Converts the value from UInt32 to an equivalent Int16 value. + [CLSCompliant(false)] + public static Int16 ToInt16(UInt32 p) { return checked((Int16)p); } + /// Converts the value from UInt64 to an equivalent Int16 value. + [CLSCompliant(false)] + public static Int16 ToInt16(UInt64 p) { return checked((Int16)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Int16 value. + public static Int16 ToInt16(Boolean? p) { return p.HasValue && p.Value ? (Int16)1: (Int16)0; } + /// Converts the value from Byte? to an equivalent Int16 value. + public static Int16 ToInt16(Byte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int16; } + /// Converts the value from Char? to an equivalent Int16 value. + public static Int16 ToInt16(Char? p) { return p.HasValue ? checked((Int16)p.Value) : Configuration.NullableValues.Int16; } + /// Converts the value from Decimal? to an equivalent Int16 value. + public static Int16 ToInt16(Decimal? p) { return p.HasValue ? checked((Int16)p.Value) : Configuration.NullableValues.Int16; } + /// Converts the value from Double? to an equivalent Int16 value. + public static Int16 ToInt16(Double? p) { return p.HasValue ? checked((Int16)p.Value) : Configuration.NullableValues.Int16; } + /// Converts the value from Int16? to an equivalent Int16 value. + public static Int16 ToInt16(Int16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int16; } + /// Converts the value from Int32? to an equivalent Int16 value. + public static Int16 ToInt16(Int32? p) { return p.HasValue ? checked((Int16)p.Value) : Configuration.NullableValues.Int16; } + /// Converts the value from Int64? to an equivalent Int16 value. + public static Int16 ToInt16(Int64? p) { return p.HasValue ? checked((Int16)p.Value) : Configuration.NullableValues.Int16; } + /// Converts the value from SByte? to an equivalent Int16 value. + [CLSCompliant(false)] + public static Int16 ToInt16(SByte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int16; } + /// Converts the value from Single? to an equivalent Int16 value. + public static Int16 ToInt16(Single? p) { return p.HasValue ? checked((Int16)p.Value) : Configuration.NullableValues.Int16; } + /// Converts the value from UInt16? to an equivalent Int16 value. + [CLSCompliant(false)] + public static Int16 ToInt16(UInt16? p) { return p.HasValue ? checked((Int16)p.Value) : Configuration.NullableValues.Int16; } + /// Converts the value from UInt32? to an equivalent Int16 value. + [CLSCompliant(false)] + public static Int16 ToInt16(UInt32? p) { return p.HasValue ? checked((Int16)p.Value) : Configuration.NullableValues.Int16; } + /// Converts the value from UInt64? to an equivalent Int16 value. + [CLSCompliant(false)] + public static Int16 ToInt16(UInt64? p) { return p.HasValue ? checked((Int16)p.Value) : Configuration.NullableValues.Int16; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Int16 value. + public static Int16 ToInt16(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Int16 : BitConverter.ToInt16(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Int16 value. + public static Int16 ToInt16(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Int16 : BitConverter.ToInt16(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Int16 value. + public static Int16 ToInt16(SqlBoolean p) { return p.IsNull ? Configuration.NullableValues.Int16 : ToInt16(p.Value); } + /// Converts the value from SqlByte to an equivalent Int16 value. + public static Int16 ToInt16(SqlByte p) { return p.IsNull ? Configuration.NullableValues.Int16 : p.Value; } + /// Converts the value from SqlDecimal to an equivalent Int16 value. + public static Int16 ToInt16(SqlDecimal p) { return p.IsNull ? Configuration.NullableValues.Int16 : ToInt16(p.Value); } + /// Converts the value from SqlDouble to an equivalent Int16 value. + public static Int16 ToInt16(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.Int16 : ToInt16(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Int16 value. + public static Int16 ToInt16(SqlInt16 p) { return p.IsNull ? Configuration.NullableValues.Int16 : p.Value; } + /// Converts the value from SqlInt32 to an equivalent Int16 value. + public static Int16 ToInt16(SqlInt32 p) { return p.IsNull ? Configuration.NullableValues.Int16 : ToInt16(p.Value); } + /// Converts the value from SqlInt64 to an equivalent Int16 value. + public static Int16 ToInt16(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.Int16 : ToInt16(p.Value); } + /// Converts the value from SqlMoney to an equivalent Int16 value. + public static Int16 ToInt16(SqlMoney p) { return p.IsNull ? Configuration.NullableValues.Int16 : ToInt16(p.Value); } + /// Converts the value from SqlSingle to an equivalent Int16 value. + public static Int16 ToInt16(SqlSingle p) { return p.IsNull ? Configuration.NullableValues.Int16 : ToInt16(p.Value); } + /// Converts the value from SqlString to an equivalent Int16 value. + public static Int16 ToInt16(SqlString p) { return p.IsNull ? Configuration.NullableValues.Int16 : ToInt16(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Int16 value. + public static Int16 ToInt16(object p) + { + if (p == null) return Configuration.NullableValues.Int16; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.Int16; + case TypeCode.Int16 : return (Int16)p; + case TypeCode.SByte : return ToInt16((SByte) p); + case TypeCode.Byte : return ToInt16((Byte) p); + case TypeCode.Int32 : return ToInt16((Int32) p); + case TypeCode.Int64 : return ToInt16((Int64) p); + case TypeCode.UInt16 : return ToInt16((UInt16) p); + case TypeCode.UInt32 : return ToInt16((UInt32) p); + case TypeCode.UInt64 : return ToInt16((UInt64) p); + case TypeCode.Single : return ToInt16((Single) p); + case TypeCode.Double : return ToInt16((Double) p); + case TypeCode.Decimal : return ToInt16((Decimal)p); + case TypeCode.Char : return ToInt16((Char) p); + case TypeCode.String : return ToInt16((String) p); + case TypeCode.Boolean : return ToInt16((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToInt16((Boolean?) p); + if (p is Byte?) return ToInt16((Byte?) p); + if (p is Char?) return ToInt16((Char?) p); + if (p is Decimal?) return ToInt16((Decimal?) p); + if (p is Double?) return ToInt16((Double?) p); + if (p is Int16?) return ToInt16((Int16?) p); + if (p is Int32?) return ToInt16((Int32?) p); + if (p is Int64?) return ToInt16((Int64?) p); + if (p is SByte?) return ToInt16((SByte?) p); + if (p is Single?) return ToInt16((Single?) p); + if (p is UInt16?) return ToInt16((UInt16?) p); + if (p is UInt32?) return ToInt16((UInt32?) p); + if (p is UInt64?) return ToInt16((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToInt16((Binary) p); + if (p is Byte[]) return ToInt16((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToInt16((SqlBoolean)p); + if (p is SqlByte) return ToInt16((SqlByte) p); + if (p is SqlDecimal) return ToInt16((SqlDecimal)p); + if (p is SqlDouble) return ToInt16((SqlDouble) p); + if (p is SqlInt16) return ToInt16((SqlInt16) p); + if (p is SqlInt32) return ToInt16((SqlInt32) p); + if (p is SqlInt64) return ToInt16((SqlInt64) p); + if (p is SqlMoney) return ToInt16((SqlMoney) p); + if (p is SqlSingle) return ToInt16((SqlSingle) p); + if (p is SqlString) return ToInt16((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToInt16(null); + + throw CreateInvalidCastException(p.GetType(), typeof(Int16)); + } + + #endregion + + #region Int32 + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Int32 value. + public static Int32 ToInt32(Boolean p) { return p ? (Int32)1 : (Int32)0; } + /// Converts the value from Byte to an equivalent Int32 value. + public static Int32 ToInt32(Byte p) { return p; } + /// Converts the value from Char to an equivalent Int32 value. + public static Int32 ToInt32(Char p) { return p; } + /// Converts the value from Decimal to an equivalent Int32 value. + public static Int32 ToInt32(Decimal p) { return checked((Int32)p); } + /// Converts the value from Double to an equivalent Int32 value. + public static Int32 ToInt32(Double p) { return checked((Int32)p); } + /// Converts the value from Int16 to an equivalent Int32 value. + public static Int32 ToInt32(Int16 p) { return p; } + /// Converts the value from Int64 to an equivalent Int32 value. + public static Int32 ToInt32(Int64 p) { return checked((Int32)p); } + /// Converts the value from SByte to an equivalent Int32 value. + [CLSCompliant(false)] + public static Int32 ToInt32(SByte p) { return p; } + /// Converts the value from Single to an equivalent Int32 value. + public static Int32 ToInt32(Single p) { return checked((Int32)p); } + /// Converts the value from String to an equivalent Int32 value. + public static Int32 ToInt32(String p) { return p == null? Configuration.NullableValues.Int32 : Int32.Parse(p); } + /// Converts the value from UInt16 to an equivalent Int32 value. + [CLSCompliant(false)] + public static Int32 ToInt32(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent Int32 value. + [CLSCompliant(false)] + public static Int32 ToInt32(UInt32 p) { return checked((Int32)p); } + /// Converts the value from UInt64 to an equivalent Int32 value. + [CLSCompliant(false)] + public static Int32 ToInt32(UInt64 p) { return checked((Int32)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Int32 value. + public static Int32 ToInt32(Boolean? p) { return p.HasValue && p.Value ? (Int32)1: (Int32)0; } + /// Converts the value from Byte? to an equivalent Int32 value. + public static Int32 ToInt32(Byte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int32; } + /// Converts the value from Char? to an equivalent Int32 value. + public static Int32 ToInt32(Char? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int32; } + /// Converts the value from Decimal? to an equivalent Int32 value. + public static Int32 ToInt32(Decimal? p) { return p.HasValue ? checked((Int32)p.Value) : Configuration.NullableValues.Int32; } + /// Converts the value from Double? to an equivalent Int32 value. + public static Int32 ToInt32(Double? p) { return p.HasValue ? checked((Int32)p.Value) : Configuration.NullableValues.Int32; } + /// Converts the value from Int16? to an equivalent Int32 value. + public static Int32 ToInt32(Int16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int32; } + /// Converts the value from Int32? to an equivalent Int32 value. + public static Int32 ToInt32(Int32? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int32; } + /// Converts the value from Int64? to an equivalent Int32 value. + public static Int32 ToInt32(Int64? p) { return p.HasValue ? checked((Int32)p.Value) : Configuration.NullableValues.Int32; } + /// Converts the value from SByte? to an equivalent Int32 value. + [CLSCompliant(false)] + public static Int32 ToInt32(SByte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int32; } + /// Converts the value from Single? to an equivalent Int32 value. + public static Int32 ToInt32(Single? p) { return p.HasValue ? checked((Int32)p.Value) : Configuration.NullableValues.Int32; } + /// Converts the value from UInt16? to an equivalent Int32 value. + [CLSCompliant(false)] + public static Int32 ToInt32(UInt16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int32; } + /// Converts the value from UInt32? to an equivalent Int32 value. + [CLSCompliant(false)] + public static Int32 ToInt32(UInt32? p) { return p.HasValue ? checked((Int32)p.Value) : Configuration.NullableValues.Int32; } + /// Converts the value from UInt64? to an equivalent Int32 value. + [CLSCompliant(false)] + public static Int32 ToInt32(UInt64? p) { return p.HasValue ? checked((Int32)p.Value) : Configuration.NullableValues.Int32; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Int32 value. + public static Int32 ToInt32(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Int32 : BitConverter.ToInt32(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Int32 value. + public static Int32 ToInt32(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Int32 : BitConverter.ToInt32(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Int32 value. + public static Int32 ToInt32(SqlBoolean p) { return p.IsNull ? Configuration.NullableValues.Int32 : ToInt32(p.Value); } + /// Converts the value from SqlByte to an equivalent Int32 value. + public static Int32 ToInt32(SqlByte p) { return p.IsNull ? Configuration.NullableValues.Int32 : p.Value; } + /// Converts the value from SqlDecimal to an equivalent Int32 value. + public static Int32 ToInt32(SqlDecimal p) { return p.IsNull ? Configuration.NullableValues.Int32 : ToInt32(p.Value); } + /// Converts the value from SqlDouble to an equivalent Int32 value. + public static Int32 ToInt32(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.Int32 : ToInt32(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Int32 value. + public static Int32 ToInt32(SqlInt16 p) { return p.IsNull ? Configuration.NullableValues.Int32 : p.Value; } + /// Converts the value from SqlInt32 to an equivalent Int32 value. + public static Int32 ToInt32(SqlInt32 p) { return p.IsNull ? Configuration.NullableValues.Int32 : p.Value; } + /// Converts the value from SqlInt64 to an equivalent Int32 value. + public static Int32 ToInt32(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.Int32 : ToInt32(p.Value); } + /// Converts the value from SqlMoney to an equivalent Int32 value. + public static Int32 ToInt32(SqlMoney p) { return p.IsNull ? Configuration.NullableValues.Int32 : ToInt32(p.Value); } + /// Converts the value from SqlSingle to an equivalent Int32 value. + public static Int32 ToInt32(SqlSingle p) { return p.IsNull ? Configuration.NullableValues.Int32 : ToInt32(p.Value); } + /// Converts the value from SqlString to an equivalent Int32 value. + public static Int32 ToInt32(SqlString p) { return p.IsNull ? Configuration.NullableValues.Int32 : ToInt32(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Int32 value. + public static Int32 ToInt32(object p) + { + if (p == null) return Configuration.NullableValues.Int32; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.Int32; + case TypeCode.Int32 : return (Int32)p; + case TypeCode.SByte : return ToInt32((SByte) p); + case TypeCode.Int16 : return ToInt32((Int16) p); + case TypeCode.Byte : return ToInt32((Byte) p); + case TypeCode.UInt16 : return ToInt32((UInt16) p); + case TypeCode.Char : return ToInt32((Char) p); + case TypeCode.Int64 : return ToInt32((Int64) p); + case TypeCode.UInt32 : return ToInt32((UInt32) p); + case TypeCode.UInt64 : return ToInt32((UInt64) p); + case TypeCode.Single : return ToInt32((Single) p); + case TypeCode.Double : return ToInt32((Double) p); + case TypeCode.Decimal : return ToInt32((Decimal)p); + case TypeCode.String : return ToInt32((String) p); + case TypeCode.Boolean : return ToInt32((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToInt32((Boolean?) p); + if (p is Byte?) return ToInt32((Byte?) p); + if (p is Char?) return ToInt32((Char?) p); + if (p is Decimal?) return ToInt32((Decimal?) p); + if (p is Double?) return ToInt32((Double?) p); + if (p is Int16?) return ToInt32((Int16?) p); + if (p is Int32?) return ToInt32((Int32?) p); + if (p is Int64?) return ToInt32((Int64?) p); + if (p is SByte?) return ToInt32((SByte?) p); + if (p is Single?) return ToInt32((Single?) p); + if (p is UInt16?) return ToInt32((UInt16?) p); + if (p is UInt32?) return ToInt32((UInt32?) p); + if (p is UInt64?) return ToInt32((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToInt32((Binary) p); + if (p is Byte[]) return ToInt32((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToInt32((SqlBoolean)p); + if (p is SqlByte) return ToInt32((SqlByte) p); + if (p is SqlDecimal) return ToInt32((SqlDecimal)p); + if (p is SqlDouble) return ToInt32((SqlDouble) p); + if (p is SqlInt16) return ToInt32((SqlInt16) p); + if (p is SqlInt32) return ToInt32((SqlInt32) p); + if (p is SqlInt64) return ToInt32((SqlInt64) p); + if (p is SqlMoney) return ToInt32((SqlMoney) p); + if (p is SqlSingle) return ToInt32((SqlSingle) p); + if (p is SqlString) return ToInt32((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToInt32(null); + + throw CreateInvalidCastException(p.GetType(), typeof(Int32)); + } + + #endregion + + #region Int64 + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Int64 value. + public static Int64 ToInt64(Boolean p) { return p ? (Int64)1 : (Int64)0; } + /// Converts the value from Byte to an equivalent Int64 value. + public static Int64 ToInt64(Byte p) { return p; } + /// Converts the value from Char to an equivalent Int64 value. + public static Int64 ToInt64(Char p) { return p; } + /// Converts the value from DateTime to an equivalent Int64 value. + public static Int64 ToInt64(DateTime p) { return (p - DateTime.MinValue).Ticks; } + /// Converts the value from DateTimeOffset to an equivalent Int64 value. + public static Int64 ToInt64(DateTimeOffset p) { return (p - DateTime.MinValue).Ticks; } + /// Converts the value from Decimal to an equivalent Int64 value. + public static Int64 ToInt64(Decimal p) { return checked((Int64)p); } + /// Converts the value from Double to an equivalent Int64 value. + public static Int64 ToInt64(Double p) { return checked((Int64)p); } + /// Converts the value from Int16 to an equivalent Int64 value. + public static Int64 ToInt64(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent Int64 value. + public static Int64 ToInt64(Int32 p) { return p; } + /// Converts the value from SByte to an equivalent Int64 value. + [CLSCompliant(false)] + public static Int64 ToInt64(SByte p) { return p; } + /// Converts the value from Single to an equivalent Int64 value. + public static Int64 ToInt64(Single p) { return checked((Int64)p); } + /// Converts the value from String to an equivalent Int64 value. + public static Int64 ToInt64(String p) { return p == null? Configuration.NullableValues.Int64 : Int64.Parse(p); } + /// Converts the value from TimeSpan to an equivalent Int64 value. + public static Int64 ToInt64(TimeSpan p) { return p.Ticks; } + /// Converts the value from UInt16 to an equivalent Int64 value. + [CLSCompliant(false)] + public static Int64 ToInt64(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent Int64 value. + [CLSCompliant(false)] + public static Int64 ToInt64(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent Int64 value. + [CLSCompliant(false)] + public static Int64 ToInt64(UInt64 p) { return checked((Int64)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Int64 value. + public static Int64 ToInt64(Boolean? p) { return p.HasValue && p.Value ? (Int64)1: (Int64)0; } + /// Converts the value from Byte? to an equivalent Int64 value. + public static Int64 ToInt64(Byte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int64; } + /// Converts the value from Char? to an equivalent Int64 value. + public static Int64 ToInt64(Char? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int64; } + /// Converts the value from DateTime? to an equivalent Int64 value. + public static Int64 ToInt64(DateTime? p) { return p.HasValue ? (p.Value - DateTime.MinValue).Ticks : 0; } + /// Converts the value from DateTimeOffset? to an equivalent Int64 value. + public static Int64 ToInt64(DateTimeOffset? p) { return p.HasValue ? (p.Value - DateTime.MinValue).Ticks : 0; } + /// Converts the value from Decimal? to an equivalent Int64 value. + public static Int64 ToInt64(Decimal? p) { return p.HasValue ? checked((Int64)p.Value) : Configuration.NullableValues.Int64; } + /// Converts the value from Double? to an equivalent Int64 value. + public static Int64 ToInt64(Double? p) { return p.HasValue ? checked((Int64)p.Value) : Configuration.NullableValues.Int64; } + /// Converts the value from Int16? to an equivalent Int64 value. + public static Int64 ToInt64(Int16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int64; } + /// Converts the value from Int32? to an equivalent Int64 value. + public static Int64 ToInt64(Int32? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int64; } + /// Converts the value from Int64? to an equivalent Int64 value. + public static Int64 ToInt64(Int64? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int64; } + /// Converts the value from SByte? to an equivalent Int64 value. + [CLSCompliant(false)] + public static Int64 ToInt64(SByte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int64; } + /// Converts the value from Single? to an equivalent Int64 value. + public static Int64 ToInt64(Single? p) { return p.HasValue ? checked((Int64)p.Value) : Configuration.NullableValues.Int64; } + /// Converts the value from TimeSpan? to an equivalent Int64 value. + public static Int64 ToInt64(TimeSpan? p) { return p.HasValue ? p.Value.Ticks : 0; } + /// Converts the value from UInt16? to an equivalent Int64 value. + [CLSCompliant(false)] + public static Int64 ToInt64(UInt16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int64; } + /// Converts the value from UInt32? to an equivalent Int64 value. + [CLSCompliant(false)] + public static Int64 ToInt64(UInt32? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Int64; } + /// Converts the value from UInt64? to an equivalent Int64 value. + [CLSCompliant(false)] + public static Int64 ToInt64(UInt64? p) { return p.HasValue ? checked((Int64)p.Value) : Configuration.NullableValues.Int64; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Int64 value. + public static Int64 ToInt64(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Int64 : BitConverter.ToInt64(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Int64 value. + public static Int64 ToInt64(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Int64 : BitConverter.ToInt64(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Int64 value. + public static Int64 ToInt64(SqlBoolean p) { return p.IsNull ? Configuration.NullableValues.Int64 : ToInt64(p.Value); } + /// Converts the value from SqlByte to an equivalent Int64 value. + public static Int64 ToInt64(SqlByte p) { return p.IsNull ? Configuration.NullableValues.Int64 : p.Value; } + /// Converts the value from SqlDateTime to an equivalent Int64 value. + public static Int64 ToInt64(SqlDateTime p) { return p.IsNull ? Configuration.NullableValues.Int64 : ToInt64(p.Value); } + /// Converts the value from SqlDecimal to an equivalent Int64 value. + public static Int64 ToInt64(SqlDecimal p) { return p.IsNull ? Configuration.NullableValues.Int64 : ToInt64(p.Value); } + /// Converts the value from SqlDouble to an equivalent Int64 value. + public static Int64 ToInt64(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.Int64 : ToInt64(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Int64 value. + public static Int64 ToInt64(SqlInt16 p) { return p.IsNull ? Configuration.NullableValues.Int64 : p.Value; } + /// Converts the value from SqlInt32 to an equivalent Int64 value. + public static Int64 ToInt64(SqlInt32 p) { return p.IsNull ? Configuration.NullableValues.Int64 : p.Value; } + /// Converts the value from SqlInt64 to an equivalent Int64 value. + public static Int64 ToInt64(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.Int64 : p.Value; } + /// Converts the value from SqlMoney to an equivalent Int64 value. + public static Int64 ToInt64(SqlMoney p) { return p.IsNull ? Configuration.NullableValues.Int64 : ToInt64(p.Value); } + /// Converts the value from SqlSingle to an equivalent Int64 value. + public static Int64 ToInt64(SqlSingle p) { return p.IsNull ? Configuration.NullableValues.Int64 : ToInt64(p.Value); } + /// Converts the value from SqlString to an equivalent Int64 value. + public static Int64 ToInt64(SqlString p) { return p.IsNull ? Configuration.NullableValues.Int64 : ToInt64(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Int64 value. + public static Int64 ToInt64(object p) + { + if (p == null) return Configuration.NullableValues.Int64; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.Int64; + case TypeCode.Int64 : return (Int64)p; + case TypeCode.DateTime : return ToInt64((DateTime)p); + case TypeCode.SByte : return ToInt64((SByte) p); + case TypeCode.Int16 : return ToInt64((Int16) p); + case TypeCode.Int32 : return ToInt64((Int32) p); + case TypeCode.Byte : return ToInt64((Byte) p); + case TypeCode.UInt16 : return ToInt64((UInt16) p); + case TypeCode.UInt32 : return ToInt64((UInt32) p); + case TypeCode.Char : return ToInt64((Char) p); + case TypeCode.UInt64 : return ToInt64((UInt64) p); + case TypeCode.Single : return ToInt64((Single) p); + case TypeCode.Double : return ToInt64((Double) p); + case TypeCode.Decimal : return ToInt64((Decimal) p); + case TypeCode.String : return ToInt64((String) p); + case TypeCode.Boolean : return ToInt64((Boolean) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToInt64((DateTimeOffset) p); + if (p is TimeSpan) return ToInt64((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToInt64((Boolean?) p); + if (p is Byte?) return ToInt64((Byte?) p); + if (p is Char?) return ToInt64((Char?) p); + if (p is DateTime?) return ToInt64((DateTime?) p); + if (p is DateTimeOffset?) return ToInt64((DateTimeOffset?)p); + if (p is Decimal?) return ToInt64((Decimal?) p); + if (p is Double?) return ToInt64((Double?) p); + if (p is Int16?) return ToInt64((Int16?) p); + if (p is Int32?) return ToInt64((Int32?) p); + if (p is Int64?) return ToInt64((Int64?) p); + if (p is SByte?) return ToInt64((SByte?) p); + if (p is Single?) return ToInt64((Single?) p); + if (p is TimeSpan?) return ToInt64((TimeSpan?) p); + if (p is UInt16?) return ToInt64((UInt16?) p); + if (p is UInt32?) return ToInt64((UInt32?) p); + if (p is UInt64?) return ToInt64((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToInt64((Binary) p); + if (p is Byte[]) return ToInt64((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToInt64((SqlBoolean) p); + if (p is SqlByte) return ToInt64((SqlByte) p); + if (p is SqlDateTime) return ToInt64((SqlDateTime) p); + if (p is SqlDecimal) return ToInt64((SqlDecimal) p); + if (p is SqlDouble) return ToInt64((SqlDouble) p); + if (p is SqlInt16) return ToInt64((SqlInt16) p); + if (p is SqlInt32) return ToInt64((SqlInt32) p); + if (p is SqlInt64) return ToInt64((SqlInt64) p); + if (p is SqlMoney) return ToInt64((SqlMoney) p); + if (p is SqlSingle) return ToInt64((SqlSingle) p); + if (p is SqlString) return ToInt64((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToInt64(null); + + throw CreateInvalidCastException(p.GetType(), typeof(Int64)); + } + + #endregion + + #region SByte + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Boolean p) { return p ? (SByte)1 : (SByte)0; } + /// Converts the value from Byte to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Byte p) { return checked((SByte)p); } + /// Converts the value from Char to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Char p) { return checked((SByte)p); } + /// Converts the value from Decimal to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Decimal p) { return checked((SByte)p); } + /// Converts the value from Double to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Double p) { return checked((SByte)p); } + /// Converts the value from Int16 to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Int16 p) { return checked((SByte)p); } + /// Converts the value from Int32 to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Int32 p) { return checked((SByte)p); } + /// Converts the value from Int64 to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Int64 p) { return checked((SByte)p); } + /// Converts the value from Single to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Single p) { return checked((SByte)p); } + /// Converts the value from String to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(String p) { return p == null? Configuration.NullableValues.SByte : SByte.Parse(p); } + /// Converts the value from UInt16 to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(UInt16 p) { return checked((SByte)p); } + /// Converts the value from UInt32 to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(UInt32 p) { return checked((SByte)p); } + /// Converts the value from UInt64 to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(UInt64 p) { return checked((SByte)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Boolean? p) { return p.HasValue && p.Value ? (SByte)1: (SByte)0; } + /// Converts the value from Byte? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Byte? p) { return p.HasValue ? checked((SByte)p.Value) : Configuration.NullableValues.SByte; } + /// Converts the value from Char? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Char? p) { return p.HasValue ? checked((SByte)p.Value) : Configuration.NullableValues.SByte; } + /// Converts the value from Decimal? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Decimal? p) { return p.HasValue ? checked((SByte)p.Value) : Configuration.NullableValues.SByte; } + /// Converts the value from Double? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Double? p) { return p.HasValue ? checked((SByte)p.Value) : Configuration.NullableValues.SByte; } + /// Converts the value from Int16? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Int16? p) { return p.HasValue ? checked((SByte)p.Value) : Configuration.NullableValues.SByte; } + /// Converts the value from Int32? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Int32? p) { return p.HasValue ? checked((SByte)p.Value) : Configuration.NullableValues.SByte; } + /// Converts the value from Int64? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Int64? p) { return p.HasValue ? checked((SByte)p.Value) : Configuration.NullableValues.SByte; } + /// Converts the value from SByte? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(SByte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.SByte; } + /// Converts the value from Single? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Single? p) { return p.HasValue ? checked((SByte)p.Value) : Configuration.NullableValues.SByte; } + /// Converts the value from UInt16? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(UInt16? p) { return p.HasValue ? checked((SByte)p.Value) : Configuration.NullableValues.SByte; } + /// Converts the value from UInt32? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(UInt32? p) { return p.HasValue ? checked((SByte)p.Value) : Configuration.NullableValues.SByte; } + /// Converts the value from UInt64? to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(UInt64? p) { return p.HasValue ? checked((SByte)p.Value) : Configuration.NullableValues.SByte; } + + // Other Types + // + /// Converts the value from Binary to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.SByte : checked((SByte)p.ToArray()[0]); } + /// Converts the value from Byte[] to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.SByte : checked((SByte)p[0]); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(SqlBoolean p) { return p.IsNull ? Configuration.NullableValues.SByte : ToSByte(p.Value); } + /// Converts the value from SqlByte to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(SqlByte p) { return p.IsNull ? Configuration.NullableValues.SByte : ToSByte(p.Value); } + /// Converts the value from SqlDecimal to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(SqlDecimal p) { return p.IsNull ? Configuration.NullableValues.SByte : ToSByte(p.Value); } + /// Converts the value from SqlDouble to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.SByte : ToSByte(p.Value); } + /// Converts the value from SqlInt16 to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(SqlInt16 p) { return p.IsNull ? Configuration.NullableValues.SByte : ToSByte(p.Value); } + /// Converts the value from SqlInt32 to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(SqlInt32 p) { return p.IsNull ? Configuration.NullableValues.SByte : ToSByte(p.Value); } + /// Converts the value from SqlInt64 to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.SByte : ToSByte(p.Value); } + /// Converts the value from SqlMoney to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(SqlMoney p) { return p.IsNull ? Configuration.NullableValues.SByte : ToSByte(p.Value); } + /// Converts the value from SqlSingle to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(SqlSingle p) { return p.IsNull ? Configuration.NullableValues.SByte : ToSByte(p.Value); } + /// Converts the value from SqlString to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(SqlString p) { return p.IsNull ? Configuration.NullableValues.SByte : ToSByte(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent SByte value. + [CLSCompliant(false)] + public static SByte ToSByte(object p) + { + if (p == null) return Configuration.NullableValues.SByte; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.SByte; + case TypeCode.SByte : return (SByte)p; + case TypeCode.Int16 : return ToSByte((Int16) p); + case TypeCode.Int32 : return ToSByte((Int32) p); + case TypeCode.Int64 : return ToSByte((Int64) p); + case TypeCode.Byte : return ToSByte((Byte) p); + case TypeCode.UInt16 : return ToSByte((UInt16) p); + case TypeCode.UInt32 : return ToSByte((UInt32) p); + case TypeCode.UInt64 : return ToSByte((UInt64) p); + case TypeCode.Single : return ToSByte((Single) p); + case TypeCode.Double : return ToSByte((Double) p); + case TypeCode.Decimal : return ToSByte((Decimal)p); + case TypeCode.Char : return ToSByte((Char) p); + case TypeCode.String : return ToSByte((String) p); + case TypeCode.Boolean : return ToSByte((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSByte((Boolean?) p); + if (p is Byte?) return ToSByte((Byte?) p); + if (p is Char?) return ToSByte((Char?) p); + if (p is Decimal?) return ToSByte((Decimal?) p); + if (p is Double?) return ToSByte((Double?) p); + if (p is Int16?) return ToSByte((Int16?) p); + if (p is Int32?) return ToSByte((Int32?) p); + if (p is Int64?) return ToSByte((Int64?) p); + if (p is SByte?) return ToSByte((SByte?) p); + if (p is Single?) return ToSByte((Single?) p); + if (p is UInt16?) return ToSByte((UInt16?) p); + if (p is UInt32?) return ToSByte((UInt32?) p); + if (p is UInt64?) return ToSByte((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToSByte((Binary) p); + if (p is Byte[]) return ToSByte((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToSByte((SqlBoolean)p); + if (p is SqlByte) return ToSByte((SqlByte) p); + if (p is SqlDecimal) return ToSByte((SqlDecimal)p); + if (p is SqlDouble) return ToSByte((SqlDouble) p); + if (p is SqlInt16) return ToSByte((SqlInt16) p); + if (p is SqlInt32) return ToSByte((SqlInt32) p); + if (p is SqlInt64) return ToSByte((SqlInt64) p); + if (p is SqlMoney) return ToSByte((SqlMoney) p); + if (p is SqlSingle) return ToSByte((SqlSingle) p); + if (p is SqlString) return ToSByte((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToSByte(null); + + throw CreateInvalidCastException(p.GetType(), typeof(SByte)); + } + + #endregion + + #region Single + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Single value. + public static Single ToSingle(Boolean p) { return p ? (Single)1 : (Single)0; } + /// Converts the value from Byte to an equivalent Single value. + public static Single ToSingle(Byte p) { return p; } + /// Converts the value from Char to an equivalent Single value. + public static Single ToSingle(Char p) { return p; } + /// Converts the value from Decimal to an equivalent Single value. + public static Single ToSingle(Decimal p) { return checked((Single)p); } + /// Converts the value from Double to an equivalent Single value. + public static Single ToSingle(Double p) { return checked((Single)p); } + /// Converts the value from Int16 to an equivalent Single value. + public static Single ToSingle(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent Single value. + public static Single ToSingle(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent Single value. + public static Single ToSingle(Int64 p) { return p; } + /// Converts the value from SByte to an equivalent Single value. + [CLSCompliant(false)] + public static Single ToSingle(SByte p) { return p; } + /// Converts the value from String to an equivalent Single value. + public static Single ToSingle(String p) { return p == null? Configuration.NullableValues.Single : Single.Parse(p); } + /// Converts the value from UInt16 to an equivalent Single value. + [CLSCompliant(false)] + public static Single ToSingle(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent Single value. + [CLSCompliant(false)] + public static Single ToSingle(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent Single value. + [CLSCompliant(false)] + public static Single ToSingle(UInt64 p) { return p; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Single value. + public static Single ToSingle(Boolean? p) { return p.HasValue && p.Value ? (Single)1: (Single)0; } + /// Converts the value from Byte? to an equivalent Single value. + public static Single ToSingle(Byte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Single; } + /// Converts the value from Char? to an equivalent Single value. + public static Single ToSingle(Char? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Single; } + /// Converts the value from Decimal? to an equivalent Single value. + public static Single ToSingle(Decimal? p) { return p.HasValue ? checked((Single)p.Value) : Configuration.NullableValues.Single; } + /// Converts the value from Double? to an equivalent Single value. + public static Single ToSingle(Double? p) { return p.HasValue ? checked((Single)p.Value) : Configuration.NullableValues.Single; } + /// Converts the value from Int16? to an equivalent Single value. + public static Single ToSingle(Int16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Single; } + /// Converts the value from Int32? to an equivalent Single value. + public static Single ToSingle(Int32? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Single; } + /// Converts the value from Int64? to an equivalent Single value. + public static Single ToSingle(Int64? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Single; } + /// Converts the value from SByte? to an equivalent Single value. + [CLSCompliant(false)] + public static Single ToSingle(SByte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Single; } + /// Converts the value from Single? to an equivalent Single value. + public static Single ToSingle(Single? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Single; } + /// Converts the value from UInt16? to an equivalent Single value. + [CLSCompliant(false)] + public static Single ToSingle(UInt16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Single; } + /// Converts the value from UInt32? to an equivalent Single value. + [CLSCompliant(false)] + public static Single ToSingle(UInt32? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Single; } + /// Converts the value from UInt64? to an equivalent Single value. + [CLSCompliant(false)] + public static Single ToSingle(UInt64? p) { return p.HasValue ? p.Value : Configuration.NullableValues.Single; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Single value. + public static Single ToSingle(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Single : BitConverter.ToSingle(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Single value. + public static Single ToSingle(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.Single : BitConverter.ToSingle(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Single value. + public static Single ToSingle(SqlBoolean p) { return p.IsNull ? Configuration.NullableValues.Single : ToSingle(p.Value); } + /// Converts the value from SqlByte to an equivalent Single value. + public static Single ToSingle(SqlByte p) { return p.IsNull ? Configuration.NullableValues.Single : p.Value; } + /// Converts the value from SqlDecimal to an equivalent Single value. + public static Single ToSingle(SqlDecimal p) { return p.IsNull ? Configuration.NullableValues.Single : ToSingle(p.Value); } + /// Converts the value from SqlDouble to an equivalent Single value. + public static Single ToSingle(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.Single : ToSingle(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Single value. + public static Single ToSingle(SqlInt16 p) { return p.IsNull ? Configuration.NullableValues.Single : p.Value; } + /// Converts the value from SqlInt32 to an equivalent Single value. + public static Single ToSingle(SqlInt32 p) { return p.IsNull ? Configuration.NullableValues.Single : p.Value; } + /// Converts the value from SqlInt64 to an equivalent Single value. + public static Single ToSingle(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.Single : p.Value; } + /// Converts the value from SqlMoney to an equivalent Single value. + public static Single ToSingle(SqlMoney p) { return p.IsNull ? Configuration.NullableValues.Single : ToSingle(p.Value); } + /// Converts the value from SqlSingle to an equivalent Single value. + public static Single ToSingle(SqlSingle p) { return p.IsNull ? Configuration.NullableValues.Single : p.Value; } + /// Converts the value from SqlString to an equivalent Single value. + public static Single ToSingle(SqlString p) { return p.IsNull ? Configuration.NullableValues.Single : ToSingle(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Single value. + public static Single ToSingle(object p) + { + if (p == null) return Configuration.NullableValues.Single; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.Single; + case TypeCode.Single : return (Single)p; + case TypeCode.SByte : return ToSingle((SByte) p); + case TypeCode.Int16 : return ToSingle((Int16) p); + case TypeCode.Int32 : return ToSingle((Int32) p); + case TypeCode.Int64 : return ToSingle((Int64) p); + case TypeCode.Byte : return ToSingle((Byte) p); + case TypeCode.UInt16 : return ToSingle((UInt16) p); + case TypeCode.UInt32 : return ToSingle((UInt32) p); + case TypeCode.Char : return ToSingle((Char) p); + case TypeCode.UInt64 : return ToSingle((UInt64) p); + case TypeCode.Double : return ToSingle((Double) p); + case TypeCode.Decimal : return ToSingle((Decimal)p); + case TypeCode.String : return ToSingle((String) p); + case TypeCode.Boolean : return ToSingle((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSingle((Boolean?) p); + if (p is Byte?) return ToSingle((Byte?) p); + if (p is Char?) return ToSingle((Char?) p); + if (p is Decimal?) return ToSingle((Decimal?) p); + if (p is Double?) return ToSingle((Double?) p); + if (p is Int16?) return ToSingle((Int16?) p); + if (p is Int32?) return ToSingle((Int32?) p); + if (p is Int64?) return ToSingle((Int64?) p); + if (p is SByte?) return ToSingle((SByte?) p); + if (p is Single?) return ToSingle((Single?) p); + if (p is UInt16?) return ToSingle((UInt16?) p); + if (p is UInt32?) return ToSingle((UInt32?) p); + if (p is UInt64?) return ToSingle((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToSingle((Binary) p); + if (p is Byte[]) return ToSingle((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToSingle((SqlBoolean)p); + if (p is SqlByte) return ToSingle((SqlByte) p); + if (p is SqlDecimal) return ToSingle((SqlDecimal)p); + if (p is SqlDouble) return ToSingle((SqlDouble) p); + if (p is SqlInt16) return ToSingle((SqlInt16) p); + if (p is SqlInt32) return ToSingle((SqlInt32) p); + if (p is SqlInt64) return ToSingle((SqlInt64) p); + if (p is SqlMoney) return ToSingle((SqlMoney) p); + if (p is SqlSingle) return ToSingle((SqlSingle) p); + if (p is SqlString) return ToSingle((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToSingle(null); + + throw CreateInvalidCastException(p.GetType(), typeof(Single)); + } + + #endregion + + #region String + + // Simple Types + // + /// Converts the value from Boolean to an equivalent String value. + public static String ToString(Boolean p) { return p.ToString(); } + /// Converts the value from Byte to an equivalent String value. + public static String ToString(Byte p) { return p.ToString(); } + /// Converts the value from Char to an equivalent String value. + public static String ToString(Char p) { return p.ToString(); } + /// Converts the value from DateTime to an equivalent String value. + public static String ToString(DateTime p) { return p.ToString(); } + /// Converts the value from DateTimeOffset to an equivalent String value. + public static String ToString(DateTimeOffset p) { return p.ToString(); } + /// Converts the value from Decimal to an equivalent String value. + public static String ToString(Decimal p) { return p.ToString(); } + /// Converts the value from Double to an equivalent String value. + public static String ToString(Double p) { return p.ToString(); } + /// Converts the value from Guid to an equivalent String value. + public static String ToString(Guid p) { return p.ToString(); } + /// Converts the value from Int16 to an equivalent String value. + public static String ToString(Int16 p) { return p.ToString(); } + /// Converts the value from Int32 to an equivalent String value. + public static String ToString(Int32 p) { return p.ToString(); } + /// Converts the value from Int64 to an equivalent String value. + public static String ToString(Int64 p) { return p.ToString(); } + /// Converts the value from SByte to an equivalent String value. + [CLSCompliant(false)] + public static String ToString(SByte p) { return p.ToString(); } + /// Converts the value from Single to an equivalent String value. + public static String ToString(Single p) { return p.ToString(); } + /// Converts the value from TimeSpan to an equivalent String value. + public static String ToString(TimeSpan p) { return p.ToString(); } + /// Converts the value from UInt16 to an equivalent String value. + [CLSCompliant(false)] + public static String ToString(UInt16 p) { return p.ToString(); } + /// Converts the value from UInt32 to an equivalent String value. + [CLSCompliant(false)] + public static String ToString(UInt32 p) { return p.ToString(); } + /// Converts the value from UInt64 to an equivalent String value. + [CLSCompliant(false)] + public static String ToString(UInt64 p) { return p.ToString(); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent String value. + public static String ToString(Boolean? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from Byte? to an equivalent String value. + public static String ToString(Byte? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from Char? to an equivalent String value. + public static String ToString(Char? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from DateTime? to an equivalent String value. + public static String ToString(DateTime? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from DateTimeOffset? to an equivalent String value. + public static String ToString(DateTimeOffset? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from Decimal? to an equivalent String value. + public static String ToString(Decimal? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from Double? to an equivalent String value. + public static String ToString(Double? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from Guid? to an equivalent String value. + public static String ToString(Guid? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from Int16? to an equivalent String value. + public static String ToString(Int16? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from Int32? to an equivalent String value. + public static String ToString(Int32? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from Int64? to an equivalent String value. + public static String ToString(Int64? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from SByte? to an equivalent String value. + [CLSCompliant(false)] + public static String ToString(SByte? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from Single? to an equivalent String value. + public static String ToString(Single? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from TimeSpan? to an equivalent String value. + public static String ToString(TimeSpan? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from UInt16? to an equivalent String value. + [CLSCompliant(false)] + public static String ToString(UInt16? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from UInt32? to an equivalent String value. + [CLSCompliant(false)] + public static String ToString(UInt32? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + /// Converts the value from UInt64? to an equivalent String value. + [CLSCompliant(false)] + public static String ToString(UInt64? p) { return p.HasValue ? p.Value.ToString() : Configuration.NullableValues.String; } + + // Other Types + // + /// Converts the value from Binary to an equivalent String value. + public static String ToString(Binary p) { return ToString(p.ToArray()); } + /// Converts the value from Byte[] to an equivalent String value. + public static String ToString(Byte[] p) { return p == null ? Configuration.NullableValues.String : System.Text.Encoding.UTF8.GetString(p, 0, p.Length); } + /// Converts the value from Type to an equivalent String value. + public static String ToString(Type p) { return p == null ? Configuration.NullableValues.String : p.FullName; } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent String value. + public static String ToString(SqlBoolean p) { return p.ToString(); } + /// Converts the value from SqlByte to an equivalent String value. + public static String ToString(SqlByte p) { return p.ToString(); } + /// Converts the value from SqlChars to an equivalent String value. + public static String ToString(SqlChars p) { return p.IsNull ? Configuration.NullableValues.String : p.ToSqlString().Value; } + /// Converts the value from SqlDecimal to an equivalent String value. + public static String ToString(SqlDecimal p) { return p.ToString(); } + /// Converts the value from SqlDouble to an equivalent String value. + public static String ToString(SqlDouble p) { return p.ToString(); } + /// Converts the value from SqlGuid to an equivalent String value. + public static String ToString(SqlGuid p) { return p.ToString(); } + /// Converts the value from SqlInt16 to an equivalent String value. + public static String ToString(SqlInt16 p) { return p.ToString(); } + /// Converts the value from SqlInt32 to an equivalent String value. + public static String ToString(SqlInt32 p) { return p.ToString(); } + /// Converts the value from SqlInt64 to an equivalent String value. + public static String ToString(SqlInt64 p) { return p.ToString(); } + /// Converts the value from SqlMoney to an equivalent String value. + public static String ToString(SqlMoney p) { return p.ToString(); } + /// Converts the value from SqlSingle to an equivalent String value. + public static String ToString(SqlSingle p) { return p.ToString(); } + /// Converts the value from SqlString to an equivalent String value. + public static String ToString(SqlString p) { return p.ToString(); } + /// Converts the value from SqlXml to an equivalent String value. + public static String ToString(SqlXml p) { return p.IsNull ? Configuration.NullableValues.String : p.Value; } + + // Other Types + // + /// Converts the value from XElement to an equivalent String value. + public static String ToString(XElement p) { return p == null ? Configuration.NullableValues.String : p.ToString(); } + /// Converts the value from XmlDocument to an equivalent String value. + public static String ToString(XmlDocument p) { return p == null ? Configuration.NullableValues.String : p.InnerXml; } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent String value. + public static String ToString(object p) + { + if (p == null) return Configuration.NullableValues.String; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.String; + case TypeCode.String : return (String)p; + case TypeCode.SByte : return ToString((SByte) p); + case TypeCode.Int16 : return ToString((Int16) p); + case TypeCode.Int32 : return ToString((Int32) p); + case TypeCode.Int64 : return ToString((Int64) p); + case TypeCode.Byte : return ToString((Byte) p); + case TypeCode.UInt16 : return ToString((UInt16) p); + case TypeCode.UInt32 : return ToString((UInt32) p); + case TypeCode.UInt64 : return ToString((UInt64) p); + case TypeCode.Single : return ToString((Single) p); + case TypeCode.Double : return ToString((Double) p); + case TypeCode.Boolean : return ToString((Boolean) p); + case TypeCode.Decimal : return ToString((Decimal) p); + case TypeCode.Char : return ToString((Char) p); + case TypeCode.DateTime : return ToString((DateTime)p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToString((DateTimeOffset) p); + if (p is Guid) return ToString((Guid) p); + if (p is TimeSpan) return ToString((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToString((Boolean?) p); + if (p is Byte?) return ToString((Byte?) p); + if (p is Char?) return ToString((Char?) p); + if (p is DateTime?) return ToString((DateTime?) p); + if (p is DateTimeOffset?) return ToString((DateTimeOffset?)p); + if (p is Decimal?) return ToString((Decimal?) p); + if (p is Double?) return ToString((Double?) p); + if (p is Guid?) return ToString((Guid?) p); + if (p is Int16?) return ToString((Int16?) p); + if (p is Int32?) return ToString((Int32?) p); + if (p is Int64?) return ToString((Int64?) p); + if (p is SByte?) return ToString((SByte?) p); + if (p is Single?) return ToString((Single?) p); + if (p is TimeSpan?) return ToString((TimeSpan?) p); + if (p is UInt16?) return ToString((UInt16?) p); + if (p is UInt32?) return ToString((UInt32?) p); + if (p is UInt64?) return ToString((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToString((Binary) p); + if (p is Byte[]) return ToString((Byte[]) p); + if (p is Type) return ToString((Type) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToString((SqlBoolean) p); + if (p is SqlByte) return ToString((SqlByte) p); + if (p is SqlChars) return ToString((SqlChars) p); + if (p is SqlDecimal) return ToString((SqlDecimal) p); + if (p is SqlDouble) return ToString((SqlDouble) p); + if (p is SqlGuid) return ToString((SqlGuid) p); + if (p is SqlInt16) return ToString((SqlInt16) p); + if (p is SqlInt32) return ToString((SqlInt32) p); + if (p is SqlInt64) return ToString((SqlInt64) p); + if (p is SqlMoney) return ToString((SqlMoney) p); + if (p is SqlSingle) return ToString((SqlSingle) p); + if (p is SqlString) return ToString((SqlString) p); + if (p is SqlXml) return ToString((SqlXml) p); + } + + // Other Types + // + if (p is XElement) return ToString((XElement) p); + if (p is XmlDocument) return ToString((XmlDocument) p); + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToString(null); + + return p.ToString(); + } + + #endregion + + #region TimeSpan + + // Simple Types + // + /// Converts the value from DateTime to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(DateTime p) { return p - DateTime.MinValue; } + /// Converts the value from DateTimeOffset to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(DateTimeOffset p) { return p - DateTimeOffset.MinValue; } + /// Converts the value from Double to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(Double p) { return TimeSpan.FromDays (p); } + /// Converts the value from Int64 to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(Int64 p) { return TimeSpan.FromTicks(p); } + /// Converts the value from String to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(String p) { return p == null? Configuration.NullableValues.TimeSpan : TimeSpan.Parse(p); } + + // Nullable Types + // + /// Converts the value from DateTime? to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(DateTime? p) { return p.HasValue ? p.Value - DateTime.MinValue : Configuration.NullableValues.TimeSpan; } + /// Converts the value from DateTimeOffset? to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(DateTimeOffset? p) { return p.HasValue ? p.Value - DateTimeOffset.MinValue : Configuration.NullableValues.TimeSpan; } + /// Converts the value from Double? to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(Double? p) { return p.HasValue ? TimeSpan.FromDays (p.Value) : Configuration.NullableValues.TimeSpan; } + /// Converts the value from Int64? to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(Int64? p) { return p.HasValue ? TimeSpan.FromTicks(p.Value) : Configuration.NullableValues.TimeSpan; } + /// Converts the value from TimeSpan? to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(TimeSpan? p) { return p.HasValue ? p.Value : Configuration.NullableValues.TimeSpan; } + + // Other Types + // + /// Converts the value from Binary to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(Binary p) { return p == null || p.Length == 0? Configuration.NullableValues.TimeSpan : TimeSpan.FromTicks(ToInt64(p.ToArray())); } + /// Converts the value from Byte[] to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(Byte[] p) { return p == null || p.Length == 0? Configuration.NullableValues.TimeSpan : TimeSpan.FromTicks(ToInt64(p)); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlDateTime to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(SqlDateTime p) { return p.IsNull ? Configuration.NullableValues.TimeSpan : p.Value - DateTime.MinValue; } + /// Converts the value from SqlDouble to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.TimeSpan : TimeSpan.FromDays(p.Value); } + /// Converts the value from SqlInt64 to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.TimeSpan : TimeSpan.FromTicks(p.Value); } + /// Converts the value from SqlString to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(SqlString p) { return p.IsNull ? Configuration.NullableValues.TimeSpan : TimeSpan.Parse(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent TimeSpan value. + public static TimeSpan ToTimeSpan(object p) + { + if (p == null) return Configuration.NullableValues.TimeSpan; + + if (p is TimeSpan) return (TimeSpan)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.TimeSpan; + case TypeCode.DateTime : return ToTimeSpan((DateTime)p); + case TypeCode.Int64 : return ToTimeSpan((Int64) p); + case TypeCode.Double : return ToTimeSpan((Double) p); + case TypeCode.String : return ToTimeSpan((String) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToTimeSpan((DateTimeOffset) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is DateTime?) return ToTimeSpan((DateTime?) p); + if (p is DateTimeOffset?) return ToTimeSpan((DateTimeOffset?)p); + if (p is Double?) return ToTimeSpan((Double?) p); + if (p is Int64?) return ToTimeSpan((Int64?) p); + if (p is TimeSpan?) return ToTimeSpan((TimeSpan?) p); + } + + // Other Types + // + if (p is Binary) return ToTimeSpan((Binary) p); + if (p is Byte[]) return ToTimeSpan((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlDateTime) return ToTimeSpan((SqlDateTime) p); + if (p is SqlDouble) return ToTimeSpan((SqlDouble) p); + if (p is SqlInt64) return ToTimeSpan((SqlInt64) p); + if (p is SqlString) return ToTimeSpan((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(TimeSpan)); + } + + #endregion + + #region UInt16 + + // Simple Types + // + /// Converts the value from Boolean to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Boolean p) { return p ? (UInt16)1 : (UInt16)0; } + /// Converts the value from Byte to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Byte p) { return p; } + /// Converts the value from Char to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Char p) { return checked((UInt16)p); } + /// Converts the value from Decimal to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Decimal p) { return checked((UInt16)p); } + /// Converts the value from Double to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Double p) { return checked((UInt16)p); } + /// Converts the value from Int16 to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Int16 p) { return checked((UInt16)p); } + /// Converts the value from Int32 to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Int32 p) { return checked((UInt16)p); } + /// Converts the value from Int64 to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Int64 p) { return checked((UInt16)p); } + /// Converts the value from SByte to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(SByte p) { return checked((UInt16)p); } + /// Converts the value from Single to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Single p) { return checked((UInt16)p); } + /// Converts the value from String to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(String p) { return p == null? Configuration.NullableValues.UInt16 : UInt16.Parse(p); } + /// Converts the value from UInt32 to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(UInt32 p) { return checked((UInt16)p); } + /// Converts the value from UInt64 to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(UInt64 p) { return checked((UInt16)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Boolean? p) { return p.HasValue && p.Value ? (UInt16)1: (UInt16)0; } + /// Converts the value from Byte? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Byte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.UInt16; } + /// Converts the value from Char? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Char? p) { return p.HasValue ? checked((UInt16)p.Value) : Configuration.NullableValues.UInt16; } + /// Converts the value from Decimal? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Decimal? p) { return p.HasValue ? checked((UInt16)p.Value) : Configuration.NullableValues.UInt16; } + /// Converts the value from Double? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Double? p) { return p.HasValue ? checked((UInt16)p.Value) : Configuration.NullableValues.UInt16; } + /// Converts the value from Int16? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Int16? p) { return p.HasValue ? checked((UInt16)p.Value) : Configuration.NullableValues.UInt16; } + /// Converts the value from Int32? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Int32? p) { return p.HasValue ? checked((UInt16)p.Value) : Configuration.NullableValues.UInt16; } + /// Converts the value from Int64? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Int64? p) { return p.HasValue ? checked((UInt16)p.Value) : Configuration.NullableValues.UInt16; } + /// Converts the value from SByte? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(SByte? p) { return p.HasValue ? checked((UInt16)p.Value) : Configuration.NullableValues.UInt16; } + /// Converts the value from Single? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Single? p) { return p.HasValue ? checked((UInt16)p.Value) : Configuration.NullableValues.UInt16; } + /// Converts the value from UInt16? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(UInt16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.UInt16; } + /// Converts the value from UInt32? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(UInt32? p) { return p.HasValue ? checked((UInt16)p.Value) : Configuration.NullableValues.UInt16; } + /// Converts the value from UInt64? to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(UInt64? p) { return p.HasValue ? checked((UInt16)p.Value) : Configuration.NullableValues.UInt16; } + + // Other Types + // + /// Converts the value from Binary to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.UInt16 : BitConverter.ToUInt16(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.UInt16 : BitConverter.ToUInt16(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(SqlBoolean p) { return p.IsNull ? Configuration.NullableValues.UInt16 : ToUInt16(p.Value); } + /// Converts the value from SqlByte to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(SqlByte p) { return p.IsNull ? Configuration.NullableValues.UInt16 : p.Value; } + /// Converts the value from SqlDecimal to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(SqlDecimal p) { return p.IsNull ? Configuration.NullableValues.UInt16 : ToUInt16(p.Value); } + /// Converts the value from SqlDouble to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.UInt16 : ToUInt16(p.Value); } + /// Converts the value from SqlInt16 to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(SqlInt16 p) { return p.IsNull ? Configuration.NullableValues.UInt16 : ToUInt16(p.Value); } + /// Converts the value from SqlInt32 to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(SqlInt32 p) { return p.IsNull ? Configuration.NullableValues.UInt16 : ToUInt16(p.Value); } + /// Converts the value from SqlInt64 to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.UInt16 : ToUInt16(p.Value); } + /// Converts the value from SqlMoney to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(SqlMoney p) { return p.IsNull ? Configuration.NullableValues.UInt16 : ToUInt16(p.Value); } + /// Converts the value from SqlSingle to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(SqlSingle p) { return p.IsNull ? Configuration.NullableValues.UInt16 : ToUInt16(p.Value); } + /// Converts the value from SqlString to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(SqlString p) { return p.IsNull ? Configuration.NullableValues.UInt16 : ToUInt16(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent UInt16 value. + [CLSCompliant(false)] + public static UInt16 ToUInt16(object p) + { + if (p == null) return Configuration.NullableValues.UInt16; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.UInt16; + case TypeCode.UInt16 : return (UInt16)p; + case TypeCode.Byte : return ToUInt16((Byte) p); + case TypeCode.SByte : return ToUInt16((SByte) p); + case TypeCode.Int16 : return ToUInt16((Int16) p); + case TypeCode.Int32 : return ToUInt16((Int32) p); + case TypeCode.Int64 : return ToUInt16((Int64) p); + case TypeCode.UInt32 : return ToUInt16((UInt32) p); + case TypeCode.UInt64 : return ToUInt16((UInt64) p); + case TypeCode.Single : return ToUInt16((Single) p); + case TypeCode.Double : return ToUInt16((Double) p); + case TypeCode.Decimal : return ToUInt16((Decimal)p); + case TypeCode.Char : return ToUInt16((Char) p); + case TypeCode.String : return ToUInt16((String) p); + case TypeCode.Boolean : return ToUInt16((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToUInt16((Boolean?) p); + if (p is Byte?) return ToUInt16((Byte?) p); + if (p is Char?) return ToUInt16((Char?) p); + if (p is Decimal?) return ToUInt16((Decimal?) p); + if (p is Double?) return ToUInt16((Double?) p); + if (p is Int16?) return ToUInt16((Int16?) p); + if (p is Int32?) return ToUInt16((Int32?) p); + if (p is Int64?) return ToUInt16((Int64?) p); + if (p is SByte?) return ToUInt16((SByte?) p); + if (p is Single?) return ToUInt16((Single?) p); + if (p is UInt16?) return ToUInt16((UInt16?) p); + if (p is UInt32?) return ToUInt16((UInt32?) p); + if (p is UInt64?) return ToUInt16((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToUInt16((Binary) p); + if (p is Byte[]) return ToUInt16((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToUInt16((SqlBoolean)p); + if (p is SqlByte) return ToUInt16((SqlByte) p); + if (p is SqlDecimal) return ToUInt16((SqlDecimal)p); + if (p is SqlDouble) return ToUInt16((SqlDouble) p); + if (p is SqlInt16) return ToUInt16((SqlInt16) p); + if (p is SqlInt32) return ToUInt16((SqlInt32) p); + if (p is SqlInt64) return ToUInt16((SqlInt64) p); + if (p is SqlMoney) return ToUInt16((SqlMoney) p); + if (p is SqlSingle) return ToUInt16((SqlSingle) p); + if (p is SqlString) return ToUInt16((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToUInt16(null); + + throw CreateInvalidCastException(p.GetType(), typeof(UInt16)); + } + + #endregion + + #region UInt32 + + // Simple Types + // + /// Converts the value from Boolean to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Boolean p) { return p ? (UInt32)1 : (UInt32)0; } + /// Converts the value from Byte to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Byte p) { return p; } + /// Converts the value from Char to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Char p) { return checked((UInt32)p); } + /// Converts the value from Decimal to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Decimal p) { return checked((UInt32)p); } + /// Converts the value from Double to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Double p) { return checked((UInt32)p); } + /// Converts the value from Int16 to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Int16 p) { return checked((UInt32)p); } + /// Converts the value from Int32 to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Int32 p) { return checked((UInt32)p); } + /// Converts the value from Int64 to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Int64 p) { return checked((UInt32)p); } + /// Converts the value from SByte to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(SByte p) { return checked((UInt32)p); } + /// Converts the value from Single to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Single p) { return checked((UInt32)p); } + /// Converts the value from String to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(String p) { return p == null? Configuration.NullableValues.UInt32 : UInt32.Parse(p); } + /// Converts the value from UInt16 to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(UInt16 p) { return p; } + /// Converts the value from UInt64 to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(UInt64 p) { return checked((UInt32)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Boolean? p) { return p.HasValue && p.Value ? (UInt32)1: (UInt32)0; } + /// Converts the value from Byte? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Byte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.UInt32; } + /// Converts the value from Char? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Char? p) { return p.HasValue ? checked((UInt32)p.Value) : Configuration.NullableValues.UInt32; } + /// Converts the value from Decimal? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Decimal? p) { return p.HasValue ? checked((UInt32)p.Value) : Configuration.NullableValues.UInt32; } + /// Converts the value from Double? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Double? p) { return p.HasValue ? checked((UInt32)p.Value) : Configuration.NullableValues.UInt32; } + /// Converts the value from Int16? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Int16? p) { return p.HasValue ? checked((UInt32)p.Value) : Configuration.NullableValues.UInt32; } + /// Converts the value from Int32? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Int32? p) { return p.HasValue ? checked((UInt32)p.Value) : Configuration.NullableValues.UInt32; } + /// Converts the value from Int64? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Int64? p) { return p.HasValue ? checked((UInt32)p.Value) : Configuration.NullableValues.UInt32; } + /// Converts the value from SByte? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(SByte? p) { return p.HasValue ? checked((UInt32)p.Value) : Configuration.NullableValues.UInt32; } + /// Converts the value from Single? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Single? p) { return p.HasValue ? checked((UInt32)p.Value) : Configuration.NullableValues.UInt32; } + /// Converts the value from UInt16? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(UInt16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.UInt32; } + /// Converts the value from UInt32? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(UInt32? p) { return p.HasValue ? p.Value : Configuration.NullableValues.UInt32; } + /// Converts the value from UInt64? to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(UInt64? p) { return p.HasValue ? checked((UInt32)p.Value) : Configuration.NullableValues.UInt32; } + + // Other Types + // + /// Converts the value from Binary to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.UInt32 : BitConverter.ToUInt32(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.UInt32 : BitConverter.ToUInt32(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(SqlBoolean p) { return p.IsNull ? Configuration.NullableValues.UInt32 : ToUInt32(p.Value); } + /// Converts the value from SqlByte to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(SqlByte p) { return p.IsNull ? Configuration.NullableValues.UInt32 : p.Value; } + /// Converts the value from SqlDecimal to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(SqlDecimal p) { return p.IsNull ? Configuration.NullableValues.UInt32 : ToUInt32(p.Value); } + /// Converts the value from SqlDouble to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.UInt32 : ToUInt32(p.Value); } + /// Converts the value from SqlInt16 to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(SqlInt16 p) { return p.IsNull ? Configuration.NullableValues.UInt32 : ToUInt32(p.Value); } + /// Converts the value from SqlInt32 to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(SqlInt32 p) { return p.IsNull ? Configuration.NullableValues.UInt32 : ToUInt32(p.Value); } + /// Converts the value from SqlInt64 to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.UInt32 : ToUInt32(p.Value); } + /// Converts the value from SqlMoney to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(SqlMoney p) { return p.IsNull ? Configuration.NullableValues.UInt32 : ToUInt32(p.Value); } + /// Converts the value from SqlSingle to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(SqlSingle p) { return p.IsNull ? Configuration.NullableValues.UInt32 : ToUInt32(p.Value); } + /// Converts the value from SqlString to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(SqlString p) { return p.IsNull ? Configuration.NullableValues.UInt32 : ToUInt32(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent UInt32 value. + [CLSCompliant(false)] + public static UInt32 ToUInt32(object p) + { + if (p == null) return Configuration.NullableValues.UInt32; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.UInt32; + case TypeCode.UInt32 : return (UInt32)p; + case TypeCode.Byte : return ToUInt32((Byte) p); + case TypeCode.UInt16 : return ToUInt32((UInt16) p); + case TypeCode.SByte : return ToUInt32((SByte) p); + case TypeCode.Int16 : return ToUInt32((Int16) p); + case TypeCode.Int32 : return ToUInt32((Int32) p); + case TypeCode.Int64 : return ToUInt32((Int64) p); + case TypeCode.UInt64 : return ToUInt32((UInt64) p); + case TypeCode.Single : return ToUInt32((Single) p); + case TypeCode.Double : return ToUInt32((Double) p); + case TypeCode.Decimal : return ToUInt32((Decimal)p); + case TypeCode.Char : return ToUInt32((Char) p); + case TypeCode.String : return ToUInt32((String) p); + case TypeCode.Boolean : return ToUInt32((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToUInt32((Boolean?) p); + if (p is Byte?) return ToUInt32((Byte?) p); + if (p is Char?) return ToUInt32((Char?) p); + if (p is Decimal?) return ToUInt32((Decimal?) p); + if (p is Double?) return ToUInt32((Double?) p); + if (p is Int16?) return ToUInt32((Int16?) p); + if (p is Int32?) return ToUInt32((Int32?) p); + if (p is Int64?) return ToUInt32((Int64?) p); + if (p is SByte?) return ToUInt32((SByte?) p); + if (p is Single?) return ToUInt32((Single?) p); + if (p is UInt16?) return ToUInt32((UInt16?) p); + if (p is UInt32?) return ToUInt32((UInt32?) p); + if (p is UInt64?) return ToUInt32((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToUInt32((Binary) p); + if (p is Byte[]) return ToUInt32((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToUInt32((SqlBoolean)p); + if (p is SqlByte) return ToUInt32((SqlByte) p); + if (p is SqlDecimal) return ToUInt32((SqlDecimal)p); + if (p is SqlDouble) return ToUInt32((SqlDouble) p); + if (p is SqlInt16) return ToUInt32((SqlInt16) p); + if (p is SqlInt32) return ToUInt32((SqlInt32) p); + if (p is SqlInt64) return ToUInt32((SqlInt64) p); + if (p is SqlMoney) return ToUInt32((SqlMoney) p); + if (p is SqlSingle) return ToUInt32((SqlSingle) p); + if (p is SqlString) return ToUInt32((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToUInt32(null); + + throw CreateInvalidCastException(p.GetType(), typeof(UInt32)); + } + + #endregion + + #region UInt64 + + // Simple Types + // + /// Converts the value from Boolean to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Boolean p) { return p ? (UInt64)1 : (UInt64)0; } + /// Converts the value from Byte to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Byte p) { return p; } + /// Converts the value from Char to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Char p) { return checked((UInt64)p); } + /// Converts the value from Decimal to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Decimal p) { return checked((UInt64)p); } + /// Converts the value from Double to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Double p) { return checked((UInt64)p); } + /// Converts the value from Int16 to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Int16 p) { return checked((UInt64)p); } + /// Converts the value from Int32 to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Int32 p) { return checked((UInt64)p); } + /// Converts the value from Int64 to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Int64 p) { return checked((UInt64)p); } + /// Converts the value from SByte to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(SByte p) { return checked((UInt64)p); } + /// Converts the value from Single to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Single p) { return checked((UInt64)p); } + /// Converts the value from String to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(String p) { return p == null? Configuration.NullableValues.UInt64 : UInt64.Parse(p); } + /// Converts the value from UInt16 to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(UInt32 p) { return p; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Boolean? p) { return p.HasValue && p.Value ? (UInt64)1: (UInt64)0; } + /// Converts the value from Byte? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Byte? p) { return p.HasValue ? p.Value : Configuration.NullableValues.UInt64; } + /// Converts the value from Char? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Char? p) { return p.HasValue ? checked((UInt64)p.Value) : Configuration.NullableValues.UInt64; } + /// Converts the value from Decimal? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Decimal? p) { return p.HasValue ? checked((UInt64)p.Value) : Configuration.NullableValues.UInt64; } + /// Converts the value from Double? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Double? p) { return p.HasValue ? checked((UInt64)p.Value) : Configuration.NullableValues.UInt64; } + /// Converts the value from Int16? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Int16? p) { return p.HasValue ? checked((UInt64)p.Value) : Configuration.NullableValues.UInt64; } + /// Converts the value from Int32? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Int32? p) { return p.HasValue ? checked((UInt64)p.Value) : Configuration.NullableValues.UInt64; } + /// Converts the value from Int64? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Int64? p) { return p.HasValue ? checked((UInt64)p.Value) : Configuration.NullableValues.UInt64; } + /// Converts the value from SByte? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(SByte? p) { return p.HasValue ? checked((UInt64)p.Value) : Configuration.NullableValues.UInt64; } + /// Converts the value from Single? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Single? p) { return p.HasValue ? checked((UInt64)p.Value) : Configuration.NullableValues.UInt64; } + /// Converts the value from UInt16? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(UInt16? p) { return p.HasValue ? p.Value : Configuration.NullableValues.UInt64; } + /// Converts the value from UInt32? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(UInt32? p) { return p.HasValue ? p.Value : Configuration.NullableValues.UInt64; } + /// Converts the value from UInt64? to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(UInt64? p) { return p.HasValue ? p.Value : Configuration.NullableValues.UInt64; } + + // Other Types + // + /// Converts the value from Binary to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Binary p) { return p == null || p.Length == 0 ? Configuration.NullableValues.UInt64 : BitConverter.ToUInt64(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(Byte[] p) { return p == null || p.Length == 0 ? Configuration.NullableValues.UInt64 : BitConverter.ToUInt64(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(SqlBoolean p) { return p.IsNull ? Configuration.NullableValues.UInt64 : ToUInt64(p.Value); } + /// Converts the value from SqlByte to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(SqlByte p) { return p.IsNull ? Configuration.NullableValues.UInt64 : p.Value; } + /// Converts the value from SqlDecimal to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(SqlDecimal p) { return p.IsNull ? Configuration.NullableValues.UInt64 : ToUInt64(p.Value); } + /// Converts the value from SqlDouble to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(SqlDouble p) { return p.IsNull ? Configuration.NullableValues.UInt64 : ToUInt64(p.Value); } + /// Converts the value from SqlInt16 to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(SqlInt16 p) { return p.IsNull ? Configuration.NullableValues.UInt64 : ToUInt64(p.Value); } + /// Converts the value from SqlInt32 to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(SqlInt32 p) { return p.IsNull ? Configuration.NullableValues.UInt64 : ToUInt64(p.Value); } + /// Converts the value from SqlInt64 to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(SqlInt64 p) { return p.IsNull ? Configuration.NullableValues.UInt64 : ToUInt64(p.Value); } + /// Converts the value from SqlMoney to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(SqlMoney p) { return p.IsNull ? Configuration.NullableValues.UInt64 : ToUInt64(p.Value); } + /// Converts the value from SqlSingle to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(SqlSingle p) { return p.IsNull ? Configuration.NullableValues.UInt64 : ToUInt64(p.Value); } + /// Converts the value from SqlString to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(SqlString p) { return p.IsNull ? Configuration.NullableValues.UInt64 : ToUInt64(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent UInt64 value. + [CLSCompliant(false)] + public static UInt64 ToUInt64(object p) + { + if (p == null) return Configuration.NullableValues.UInt64; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return Configuration.NullableValues.UInt64; + case TypeCode.UInt64 : return (UInt64)p; + case TypeCode.Byte : return ToUInt64((Byte) p); + case TypeCode.UInt16 : return ToUInt64((UInt16) p); + case TypeCode.UInt32 : return ToUInt64((UInt32) p); + case TypeCode.SByte : return ToUInt64((SByte) p); + case TypeCode.Int16 : return ToUInt64((Int16) p); + case TypeCode.Int32 : return ToUInt64((Int32) p); + case TypeCode.Int64 : return ToUInt64((Int64) p); + case TypeCode.Single : return ToUInt64((Single) p); + case TypeCode.Double : return ToUInt64((Double) p); + case TypeCode.Decimal : return ToUInt64((Decimal)p); + case TypeCode.Char : return ToUInt64((Char) p); + case TypeCode.String : return ToUInt64((String) p); + case TypeCode.Boolean : return ToUInt64((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToUInt64((Boolean?) p); + if (p is Byte?) return ToUInt64((Byte?) p); + if (p is Char?) return ToUInt64((Char?) p); + if (p is Decimal?) return ToUInt64((Decimal?) p); + if (p is Double?) return ToUInt64((Double?) p); + if (p is Int16?) return ToUInt64((Int16?) p); + if (p is Int32?) return ToUInt64((Int32?) p); + if (p is Int64?) return ToUInt64((Int64?) p); + if (p is SByte?) return ToUInt64((SByte?) p); + if (p is Single?) return ToUInt64((Single?) p); + if (p is UInt16?) return ToUInt64((UInt16?) p); + if (p is UInt32?) return ToUInt64((UInt32?) p); + if (p is UInt64?) return ToUInt64((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToUInt64((Binary) p); + if (p is Byte[]) return ToUInt64((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToUInt64((SqlBoolean)p); + if (p is SqlByte) return ToUInt64((SqlByte) p); + if (p is SqlDecimal) return ToUInt64((SqlDecimal)p); + if (p is SqlDouble) return ToUInt64((SqlDouble) p); + if (p is SqlInt16) return ToUInt64((SqlInt16) p); + if (p is SqlInt32) return ToUInt64((SqlInt32) p); + if (p is SqlInt64) return ToUInt64((SqlInt64) p); + if (p is SqlMoney) return ToUInt64((SqlMoney) p); + if (p is SqlSingle) return ToUInt64((SqlSingle) p); + if (p is SqlString) return ToUInt64((SqlString) p); + } + +#endif + + if (p is IConvertible) return ((IConvertible)p).ToUInt64(null); + + throw CreateInvalidCastException(p.GetType(), typeof(UInt64)); + } + + #endregion + + #endregion + + #region Nullable Types + + #region Boolean? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Boolean p) { return p; } + /// Converts the value from Byte to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Byte p) { return p != 0; } + /// Converts the value from Char to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Char p) { return ToBoolean(p); } + /// Converts the value from Decimal to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Decimal p) { return p != 0; } + /// Converts the value from Double to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Double p) { return p != 0; } + /// Converts the value from Int16 to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Int16 p) { return p != 0; } + /// Converts the value from Int32 to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Int32 p) { return p != 0; } + /// Converts the value from Int64 to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Int64 p) { return p != 0; } + /// Converts the value from SByte to an equivalent Boolean? value. + [CLSCompliant(false)] + public static Boolean? ToNullableBoolean(SByte p) { return p != 0; } + /// Converts the value from Single to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Single p) { return p != 0; } + /// Converts the value from String to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(String p) { return p == null? (Boolean?)null : p.Length == 1 ? ToBoolean(p[0]) : Boolean.Parse(p); } + /// Converts the value from UInt16 to an equivalent Boolean? value. + [CLSCompliant(false)] + public static Boolean? ToNullableBoolean(UInt16 p) { return p != 0; } + /// Converts the value from UInt32 to an equivalent Boolean? value. + [CLSCompliant(false)] + public static Boolean? ToNullableBoolean(UInt32 p) { return p != 0; } + /// Converts the value from UInt64 to an equivalent Boolean? value. + [CLSCompliant(false)] + public static Boolean? ToNullableBoolean(UInt64 p) { return p != 0; } + + // Nullable Types + // + /// Converts the value from Byte? to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Byte? p) { return p.HasValue ? p.Value != 0 : (Boolean?)null; } + /// Converts the value from Char? to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Char? p) { return p.HasValue && ToBoolean(p.Value); } + /// Converts the value from Decimal? to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Decimal? p) { return p.HasValue ? p.Value != 0 : (Boolean?)null; } + /// Converts the value from Double? to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Double? p) { return p.HasValue ? p.Value != 0 : (Boolean?)null; } + /// Converts the value from Int16? to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Int16? p) { return p.HasValue ? p.Value != 0 : (Boolean?)null; } + /// Converts the value from Int32? to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Int32? p) { return p.HasValue ? p.Value != 0 : (Boolean?)null; } + /// Converts the value from Int64? to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Int64? p) { return p.HasValue ? p.Value != 0 : (Boolean?)null; } + /// Converts the value from SByte? to an equivalent Boolean? value. + [CLSCompliant(false)] + public static Boolean? ToNullableBoolean(SByte? p) { return p.HasValue ? p.Value != 0 : (Boolean?)null; } + /// Converts the value from Single? to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Single? p) { return p.HasValue ? p.Value != 0 : (Boolean?)null; } + /// Converts the value from UInt16? to an equivalent Boolean? value. + [CLSCompliant(false)] + public static Boolean? ToNullableBoolean(UInt16? p) { return p.HasValue ? p.Value != 0 : (Boolean?)null; } + /// Converts the value from UInt32? to an equivalent Boolean? value. + [CLSCompliant(false)] + public static Boolean? ToNullableBoolean(UInt32? p) { return p.HasValue ? p.Value != 0 : (Boolean?)null; } + /// Converts the value from UInt64? to an equivalent Boolean? value. + [CLSCompliant(false)] + public static Boolean? ToNullableBoolean(UInt64? p) { return p.HasValue ? p.Value != 0 : (Boolean?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Binary p) { return p == null || p.Length == 0 ? (Boolean?)null : BitConverter.ToBoolean(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(Byte[] p) { return p == null || p.Length == 0 ? (Boolean?)null : BitConverter.ToBoolean(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(SqlBoolean p) { return p.IsNull ? (Boolean?)null : p.Value; } + /// Converts the value from SqlByte to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(SqlByte p) { return p.IsNull ? (Boolean?)null : ToBoolean(p.Value); } + /// Converts the value from SqlDecimal to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(SqlDecimal p) { return p.IsNull ? (Boolean?)null : ToBoolean(p.Value); } + /// Converts the value from SqlDouble to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(SqlDouble p) { return p.IsNull ? (Boolean?)null : ToBoolean(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(SqlInt16 p) { return p.IsNull ? (Boolean?)null : ToBoolean(p.Value); } + /// Converts the value from SqlInt32 to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(SqlInt32 p) { return p.IsNull ? (Boolean?)null : ToBoolean(p.Value); } + /// Converts the value from SqlInt64 to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(SqlInt64 p) { return p.IsNull ? (Boolean?)null : ToBoolean(p.Value); } + /// Converts the value from SqlMoney to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(SqlMoney p) { return p.IsNull ? (Boolean?)null : ToBoolean(p.Value); } + /// Converts the value from SqlSingle to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(SqlSingle p) { return p.IsNull ? (Boolean?)null : ToBoolean(p.Value); } + /// Converts the value from SqlString to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(SqlString p) { return p.IsNull ? (Boolean?)null : ToBoolean(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Boolean? value. + public static Boolean? ToNullableBoolean(object p) + { + if (p == null) return null; + + if (p is Boolean?) return (Boolean?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.String : return ToNullableBoolean((String) p); + case TypeCode.Boolean : return ToNullableBoolean((Boolean) p); + case TypeCode.Char : return ToNullableBoolean((Char) p); + case TypeCode.SByte : return ToNullableBoolean((SByte) p); + case TypeCode.Int16 : return ToNullableBoolean((Int16) p); + case TypeCode.Int32 : return ToNullableBoolean((Int32) p); + case TypeCode.Int64 : return ToNullableBoolean((Int64) p); + case TypeCode.Byte : return ToNullableBoolean((Byte) p); + case TypeCode.UInt16 : return ToNullableBoolean((UInt16) p); + case TypeCode.UInt32 : return ToNullableBoolean((UInt32) p); + case TypeCode.UInt64 : return ToNullableBoolean((UInt64) p); + case TypeCode.Single : return ToNullableBoolean((Single) p); + case TypeCode.Double : return ToNullableBoolean((Double) p); + case TypeCode.Decimal : return ToNullableBoolean((Decimal) p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Byte?) return ToNullableBoolean((Byte?) p); + if (p is Char?) return ToNullableBoolean((Char?) p); + if (p is Decimal?) return ToNullableBoolean((Decimal?) p); + if (p is Double?) return ToNullableBoolean((Double?) p); + if (p is Int16?) return ToNullableBoolean((Int16?) p); + if (p is Int32?) return ToNullableBoolean((Int32?) p); + if (p is Int64?) return ToNullableBoolean((Int64?) p); + if (p is SByte?) return ToNullableBoolean((SByte?) p); + if (p is Single?) return ToNullableBoolean((Single?) p); + if (p is UInt16?) return ToNullableBoolean((UInt16?) p); + if (p is UInt32?) return ToNullableBoolean((UInt32?) p); + if (p is UInt64?) return ToNullableBoolean((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableBoolean((Binary) p); + if (p is Byte[]) return ToNullableBoolean((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableBoolean((SqlBoolean)p); + if (p is SqlByte) return ToNullableBoolean((SqlByte) p); + if (p is SqlDecimal) return ToNullableBoolean((SqlDecimal)p); + if (p is SqlDouble) return ToNullableBoolean((SqlDouble) p); + if (p is SqlInt16) return ToNullableBoolean((SqlInt16) p); + if (p is SqlInt32) return ToNullableBoolean((SqlInt32) p); + if (p is SqlInt64) return ToNullableBoolean((SqlInt64) p); + if (p is SqlMoney) return ToNullableBoolean((SqlMoney) p); + if (p is SqlSingle) return ToNullableBoolean((SqlSingle) p); + if (p is SqlString) return ToNullableBoolean((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Boolean?)); + } + + #endregion + + #region Byte? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Byte? value. + public static Byte? ToNullableByte(Boolean p) { return p ? (Byte?)1 : (Byte?)0; } + /// Converts the value from Byte to an equivalent Byte? value. + public static Byte? ToNullableByte(Byte p) { return p; } + /// Converts the value from Char to an equivalent Byte? value. + public static Byte? ToNullableByte(Char p) { return checked((Byte?)p); } + /// Converts the value from Decimal to an equivalent Byte? value. + public static Byte? ToNullableByte(Decimal p) { return checked((Byte?)p); } + /// Converts the value from Double to an equivalent Byte? value. + public static Byte? ToNullableByte(Double p) { return checked((Byte?)p); } + /// Converts the value from Int16 to an equivalent Byte? value. + public static Byte? ToNullableByte(Int16 p) { return checked((Byte?)p); } + /// Converts the value from Int32 to an equivalent Byte? value. + public static Byte? ToNullableByte(Int32 p) { return checked((Byte?)p); } + /// Converts the value from Int64 to an equivalent Byte? value. + public static Byte? ToNullableByte(Int64 p) { return checked((Byte?)p); } + /// Converts the value from SByte to an equivalent Byte? value. + [CLSCompliant(false)] + public static Byte? ToNullableByte(SByte p) { return checked((Byte?)p); } + /// Converts the value from Single to an equivalent Byte? value. + public static Byte? ToNullableByte(Single p) { return checked((Byte?)p); } + /// Converts the value from String to an equivalent Byte? value. + public static Byte? ToNullableByte(String p) { return p == null? (Byte?)null : Byte.Parse(p); } + /// Converts the value from UInt16 to an equivalent Byte? value. + [CLSCompliant(false)] + public static Byte? ToNullableByte(UInt16 p) { return checked((Byte?)p); } + /// Converts the value from UInt32 to an equivalent Byte? value. + [CLSCompliant(false)] + public static Byte? ToNullableByte(UInt32 p) { return checked((Byte?)p); } + /// Converts the value from UInt64 to an equivalent Byte? value. + [CLSCompliant(false)] + public static Byte? ToNullableByte(UInt64 p) { return checked((Byte?)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Byte? value. + public static Byte? ToNullableByte(Boolean? p) { return p.HasValue && p.Value ? (Byte?)1: (Byte?)0; } + /// Converts the value from Char? to an equivalent Byte? value. + public static Byte? ToNullableByte(Char? p) { return p.HasValue ? checked((Byte?)p.Value) : (Byte?)null; } + /// Converts the value from Decimal? to an equivalent Byte? value. + public static Byte? ToNullableByte(Decimal? p) { return p.HasValue ? checked((Byte?)p.Value) : (Byte?)null; } + /// Converts the value from Double? to an equivalent Byte? value. + public static Byte? ToNullableByte(Double? p) { return p.HasValue ? checked((Byte?)p.Value) : (Byte?)null; } + /// Converts the value from Int16? to an equivalent Byte? value. + public static Byte? ToNullableByte(Int16? p) { return p.HasValue ? checked((Byte?)p.Value) : (Byte?)null; } + /// Converts the value from Int32? to an equivalent Byte? value. + public static Byte? ToNullableByte(Int32? p) { return p.HasValue ? checked((Byte?)p.Value) : (Byte?)null; } + /// Converts the value from Int64? to an equivalent Byte? value. + public static Byte? ToNullableByte(Int64? p) { return p.HasValue ? checked((Byte?)p.Value) : (Byte?)null; } + /// Converts the value from SByte? to an equivalent Byte? value. + [CLSCompliant(false)] + public static Byte? ToNullableByte(SByte? p) { return p.HasValue ? checked((Byte?)p.Value) : (Byte?)null; } + /// Converts the value from Single? to an equivalent Byte? value. + public static Byte? ToNullableByte(Single? p) { return p.HasValue ? checked((Byte?)p.Value) : (Byte?)null; } + /// Converts the value from UInt16? to an equivalent Byte? value. + [CLSCompliant(false)] + public static Byte? ToNullableByte(UInt16? p) { return p.HasValue ? checked((Byte?)p.Value) : (Byte?)null; } + /// Converts the value from UInt32? to an equivalent Byte? value. + [CLSCompliant(false)] + public static Byte? ToNullableByte(UInt32? p) { return p.HasValue ? checked((Byte?)p.Value) : (Byte?)null; } + /// Converts the value from UInt64? to an equivalent Byte? value. + [CLSCompliant(false)] + public static Byte? ToNullableByte(UInt64? p) { return p.HasValue ? checked((Byte?)p.Value) : (Byte?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Byte? value. + public static Byte? ToNullableByte(Binary p) { return p == null || p.Length == 0 ? (Byte?)null : p.ToArray()[0]; } + /// Converts the value from Byte[] to an equivalent Byte? value. + public static Byte? ToNullableByte(Byte[] p) { return p == null || p.Length == 0 ? (Byte?)null : p[0]; } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Byte? value. + public static Byte? ToNullableByte(SqlBoolean p) { return p.IsNull ? (Byte?)null : ToByte(p.Value); } + /// Converts the value from SqlByte to an equivalent Byte? value. + public static Byte? ToNullableByte(SqlByte p) { return p.IsNull ? (Byte?)null : p.Value; } + /// Converts the value from SqlDecimal to an equivalent Byte? value. + public static Byte? ToNullableByte(SqlDecimal p) { return p.IsNull ? (Byte?)null : ToByte(p.Value); } + /// Converts the value from SqlDouble to an equivalent Byte? value. + public static Byte? ToNullableByte(SqlDouble p) { return p.IsNull ? (Byte?)null : ToByte(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Byte? value. + public static Byte? ToNullableByte(SqlInt16 p) { return p.IsNull ? (Byte?)null : ToByte(p.Value); } + /// Converts the value from SqlInt32 to an equivalent Byte? value. + public static Byte? ToNullableByte(SqlInt32 p) { return p.IsNull ? (Byte?)null : ToByte(p.Value); } + /// Converts the value from SqlInt64 to an equivalent Byte? value. + public static Byte? ToNullableByte(SqlInt64 p) { return p.IsNull ? (Byte?)null : ToByte(p.Value); } + /// Converts the value from SqlMoney to an equivalent Byte? value. + public static Byte? ToNullableByte(SqlMoney p) { return p.IsNull ? (Byte?)null : ToByte(p.Value); } + /// Converts the value from SqlSingle to an equivalent Byte? value. + public static Byte? ToNullableByte(SqlSingle p) { return p.IsNull ? (Byte?)null : ToByte(p.Value); } + /// Converts the value from SqlString to an equivalent Byte? value. + public static Byte? ToNullableByte(SqlString p) { return p.IsNull ? (Byte?)null : ToByte(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Byte? value. + public static Byte? ToNullableByte(object p) + { + if (p == null) return null; + + if (p is Byte?) return (Byte?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.Byte : return ToNullableByte((Byte) p); + case TypeCode.SByte : return ToNullableByte((SByte) p); + case TypeCode.Int16 : return ToNullableByte((Int16) p); + case TypeCode.Int32 : return ToNullableByte((Int32) p); + case TypeCode.Int64 : return ToNullableByte((Int64) p); + case TypeCode.UInt16 : return ToNullableByte((UInt16) p); + case TypeCode.UInt32 : return ToNullableByte((UInt32) p); + case TypeCode.UInt64 : return ToNullableByte((UInt64) p); + case TypeCode.Single : return ToNullableByte((Single) p); + case TypeCode.Double : return ToNullableByte((Double) p); + case TypeCode.Decimal : return ToNullableByte((Decimal)p); + case TypeCode.Char : return ToNullableByte((Char) p); + case TypeCode.String : return ToNullableByte((String) p); + case TypeCode.Boolean : return ToNullableByte((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToNullableByte((Boolean?) p); + if (p is Char?) return ToNullableByte((Char?) p); + if (p is Decimal?) return ToNullableByte((Decimal?) p); + if (p is Double?) return ToNullableByte((Double?) p); + if (p is Int16?) return ToNullableByte((Int16?) p); + if (p is Int32?) return ToNullableByte((Int32?) p); + if (p is Int64?) return ToNullableByte((Int64?) p); + if (p is SByte?) return ToNullableByte((SByte?) p); + if (p is Single?) return ToNullableByte((Single?) p); + if (p is UInt16?) return ToNullableByte((UInt16?) p); + if (p is UInt32?) return ToNullableByte((UInt32?) p); + if (p is UInt64?) return ToNullableByte((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableByte((Binary) p); + if (p is Byte[]) return ToNullableByte((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableByte((SqlBoolean)p); + if (p is SqlByte) return ToNullableByte((SqlByte) p); + if (p is SqlDecimal) return ToNullableByte((SqlDecimal)p); + if (p is SqlDouble) return ToNullableByte((SqlDouble) p); + if (p is SqlInt16) return ToNullableByte((SqlInt16) p); + if (p is SqlInt32) return ToNullableByte((SqlInt32) p); + if (p is SqlInt64) return ToNullableByte((SqlInt64) p); + if (p is SqlMoney) return ToNullableByte((SqlMoney) p); + if (p is SqlSingle) return ToNullableByte((SqlSingle) p); + if (p is SqlString) return ToNullableByte((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Byte?)); + } + + #endregion + + #region Char? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Char? value. + public static Char? ToNullableChar(Boolean p) { return p ? (Char?)1 : (Char?)0; } + /// Converts the value from Byte to an equivalent Char? value. + public static Char? ToNullableChar(Byte p) { return checked((Char?)p); } + /// Converts the value from Char to an equivalent Char? value. + public static Char? ToNullableChar(Char p) { return p; } + /// Converts the value from Decimal to an equivalent Char? value. + public static Char? ToNullableChar(Decimal p) { return checked((Char?)p); } + /// Converts the value from Double to an equivalent Char? value. + public static Char? ToNullableChar(Double p) { return checked((Char?)p); } + /// Converts the value from Int16 to an equivalent Char? value. + public static Char? ToNullableChar(Int16 p) { return checked((Char?)p); } + /// Converts the value from Int32 to an equivalent Char? value. + public static Char? ToNullableChar(Int32 p) { return checked((Char?)p); } + /// Converts the value from Int64 to an equivalent Char? value. + public static Char? ToNullableChar(Int64 p) { return checked((Char?)p); } + /// Converts the value from SByte to an equivalent Char? value. + [CLSCompliant(false)] + public static Char? ToNullableChar(SByte p) { return checked((Char?)p); } + /// Converts the value from Single to an equivalent Char? value. + public static Char? ToNullableChar(Single p) { return checked((Char?)p); } + /// Converts the value from String to an equivalent Char? value. + public static Char? ToNullableChar(String p) { return string.IsNullOrEmpty(p)? (Char?)0 : p[0]; } + /// Converts the value from UInt16 to an equivalent Char? value. + [CLSCompliant(false)] + public static Char? ToNullableChar(UInt16 p) { return checked((Char?)p); } + /// Converts the value from UInt32 to an equivalent Char? value. + [CLSCompliant(false)] + public static Char? ToNullableChar(UInt32 p) { return checked((Char?)p); } + /// Converts the value from UInt64 to an equivalent Char? value. + [CLSCompliant(false)] + public static Char? ToNullableChar(UInt64 p) { return checked((Char?)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Char? value. + public static Char? ToNullableChar(Boolean? p) { return p.HasValue && p.Value ? (Char?)1: (Char?)0; } + /// Converts the value from Byte? to an equivalent Char? value. + public static Char? ToNullableChar(Byte? p) { return p.HasValue ? checked((Char?)p.Value) : (Char?)null; } + /// Converts the value from Decimal? to an equivalent Char? value. + public static Char? ToNullableChar(Decimal? p) { return p.HasValue ? checked((Char?)p.Value) : (Char?)null; } + /// Converts the value from Double? to an equivalent Char? value. + public static Char? ToNullableChar(Double? p) { return p.HasValue ? checked((Char?)p.Value) : (Char?)null; } + /// Converts the value from Int16? to an equivalent Char? value. + public static Char? ToNullableChar(Int16? p) { return p.HasValue ? checked((Char?)p.Value) : (Char?)null; } + /// Converts the value from Int32? to an equivalent Char? value. + public static Char? ToNullableChar(Int32? p) { return p.HasValue ? checked((Char?)p.Value) : (Char?)null; } + /// Converts the value from Int64? to an equivalent Char? value. + public static Char? ToNullableChar(Int64? p) { return p.HasValue ? checked((Char?)p.Value) : (Char?)null; } + /// Converts the value from SByte? to an equivalent Char? value. + [CLSCompliant(false)] + public static Char? ToNullableChar(SByte? p) { return p.HasValue ? checked((Char?)p.Value) : (Char?)null; } + /// Converts the value from Single? to an equivalent Char? value. + public static Char? ToNullableChar(Single? p) { return p.HasValue ? checked((Char?)p.Value) : (Char?)null; } + /// Converts the value from UInt16? to an equivalent Char? value. + [CLSCompliant(false)] + public static Char? ToNullableChar(UInt16? p) { return p.HasValue ? checked((Char?)p.Value) : (Char?)null; } + /// Converts the value from UInt32? to an equivalent Char? value. + [CLSCompliant(false)] + public static Char? ToNullableChar(UInt32? p) { return p.HasValue ? checked((Char?)p.Value) : (Char?)null; } + /// Converts the value from UInt64? to an equivalent Char? value. + [CLSCompliant(false)] + public static Char? ToNullableChar(UInt64? p) { return p.HasValue ? checked((Char?)p.Value) : (Char?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Char? value. + public static Char? ToNullableChar(Binary p) { return p == null || p.Length == 0 ? (Char?)null : BitConverter.ToChar(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Char? value. + public static Char? ToNullableChar(Byte[] p) { return p == null || p.Length == 0 ? (Char?)null : BitConverter.ToChar(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Char? value. + public static Char? ToNullableChar(SqlBoolean p) { return p.IsNull ? (Char?)null : ToChar(p.Value); } + /// Converts the value from SqlByte to an equivalent Char? value. + public static Char? ToNullableChar(SqlByte p) { return p.IsNull ? (Char?)null : ToChar(p.Value); } + /// Converts the value from SqlDecimal to an equivalent Char? value. + public static Char? ToNullableChar(SqlDecimal p) { return p.IsNull ? (Char?)null : ToChar(p.Value); } + /// Converts the value from SqlDouble to an equivalent Char? value. + public static Char? ToNullableChar(SqlDouble p) { return p.IsNull ? (Char?)null : ToChar(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Char? value. + public static Char? ToNullableChar(SqlInt16 p) { return p.IsNull ? (Char?)null : ToChar(p.Value); } + /// Converts the value from SqlInt32 to an equivalent Char? value. + public static Char? ToNullableChar(SqlInt32 p) { return p.IsNull ? (Char?)null : ToChar(p.Value); } + /// Converts the value from SqlInt64 to an equivalent Char? value. + public static Char? ToNullableChar(SqlInt64 p) { return p.IsNull ? (Char?)null : ToChar(p.Value); } + /// Converts the value from SqlMoney to an equivalent Char? value. + public static Char? ToNullableChar(SqlMoney p) { return p.IsNull ? (Char?)null : ToChar(p.Value); } + /// Converts the value from SqlSingle to an equivalent Char? value. + public static Char? ToNullableChar(SqlSingle p) { return p.IsNull ? (Char?)null : ToChar(p.Value); } + /// Converts the value from SqlString to an equivalent Char? value. + public static Char? ToNullableChar(SqlString p) { return p.IsNull ? (Char?)null : ToChar(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Char? value. + public static Char? ToNullableChar(object p) + { + if (p == null) return null; + + if (p is Char?) return (Char?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.Char : return ToNullableChar((Char) p); + case TypeCode.SByte : return ToNullableChar((SByte) p); + case TypeCode.Int16 : return ToNullableChar((Int16) p); + case TypeCode.Int32 : return ToNullableChar((Int32) p); + case TypeCode.Int64 : return ToNullableChar((Int64) p); + case TypeCode.Byte : return ToNullableChar((Byte) p); + case TypeCode.UInt16 : return ToNullableChar((UInt16) p); + case TypeCode.UInt32 : return ToNullableChar((UInt32) p); + case TypeCode.UInt64 : return ToNullableChar((UInt64) p); + case TypeCode.Single : return ToNullableChar((Single) p); + case TypeCode.Double : return ToNullableChar((Double) p); + case TypeCode.Decimal : return ToNullableChar((Decimal)p); + case TypeCode.String : return ToNullableChar((String) p); + case TypeCode.Boolean : return ToNullableChar((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToNullableChar((Boolean?) p); + if (p is Byte?) return ToNullableChar((Byte?) p); + if (p is Decimal?) return ToNullableChar((Decimal?) p); + if (p is Double?) return ToNullableChar((Double?) p); + if (p is Int16?) return ToNullableChar((Int16?) p); + if (p is Int32?) return ToNullableChar((Int32?) p); + if (p is Int64?) return ToNullableChar((Int64?) p); + if (p is SByte?) return ToNullableChar((SByte?) p); + if (p is Single?) return ToNullableChar((Single?) p); + if (p is UInt16?) return ToNullableChar((UInt16?) p); + if (p is UInt32?) return ToNullableChar((UInt32?) p); + if (p is UInt64?) return ToNullableChar((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableChar((Binary) p); + if (p is Byte[]) return ToNullableChar((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableChar((SqlBoolean)p); + if (p is SqlByte) return ToNullableChar((SqlByte) p); + if (p is SqlDecimal) return ToNullableChar((SqlDecimal)p); + if (p is SqlDouble) return ToNullableChar((SqlDouble) p); + if (p is SqlInt16) return ToNullableChar((SqlInt16) p); + if (p is SqlInt32) return ToNullableChar((SqlInt32) p); + if (p is SqlInt64) return ToNullableChar((SqlInt64) p); + if (p is SqlMoney) return ToNullableChar((SqlMoney) p); + if (p is SqlSingle) return ToNullableChar((SqlSingle) p); + if (p is SqlString) return ToNullableChar((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Char?)); + } + + #endregion + + #region DateTime? + + // Simple Types + // + /// Converts the value from DateTime to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(DateTime p) { return p; } + /// Converts the value from DateTimeOffset to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(DateTimeOffset p) { return p.LocalDateTime; } + /// Converts the value from Double to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(Double p) { return DateTime.MinValue + TimeSpan.FromDays (p); } + /// Converts the value from Int64 to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(Int64 p) { return DateTime.MinValue + TimeSpan.FromTicks(p); } + /// Converts the value from String to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(String p) { return p == null ? (DateTime?)null : DateTime.Parse(p, null, DateTimeStyles.NoCurrentDateDefault); } + /// Converts the value from TimeSpan to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(TimeSpan p) { return DateTime.MinValue + p; } + + // Nullable Types + // + /// Converts the value from DateTimeOffset? to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(DateTimeOffset? p) { return p.HasValue ? p.Value.LocalDateTime : (DateTime?)null; } + /// Converts the value from Double? to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(Double? p) { return p.HasValue ? DateTime.MinValue + TimeSpan.FromDays (p.Value): (DateTime?)null; } + /// Converts the value from Int64? to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(Int64? p) { return p.HasValue ? DateTime.MinValue + TimeSpan.FromTicks(p.Value): (DateTime?)null; } + /// Converts the value from TimeSpan? to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(TimeSpan? p) { return p.HasValue ? DateTime.MinValue + p.Value : (DateTime?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(Binary p) { return p == null || p.Length == 0 ? (DateTime?)null : DateTime.FromBinary(ToInt64(p.ToArray())); } + /// Converts the value from Byte[] to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(Byte[] p) { return p == null || p.Length == 0 ? (DateTime?)null : DateTime.FromBinary(ToInt64(p)); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlDateTime to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(SqlDateTime p) { return p.IsNull ? (DateTime?)null : p.Value; } + /// Converts the value from SqlDouble to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(SqlDouble p) { return p.IsNull ? (DateTime?)null : DateTime.MinValue + TimeSpan.FromDays (p.Value); } + /// Converts the value from SqlInt64 to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(SqlInt64 p) { return p.IsNull ? (DateTime?)null : DateTime.MinValue + TimeSpan.FromTicks(p.Value); } + /// Converts the value from SqlString to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(SqlString p) { return p.IsNull ? (DateTime?)null : ToDateTime(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent DateTime? value. + public static DateTime? ToNullableDateTime(object p) + { + if (p == null) return null; + + if (p is DateTime?) return (DateTime?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.DateTime : return ToNullableDateTime((DateTime) p); + case TypeCode.String : return ToNullableDateTime((String) p); + case TypeCode.Int64 : return ToNullableDateTime((Int64) p); + case TypeCode.Double : return ToNullableDateTime((Double) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToNullableDateTime((DateTimeOffset) p); + if (p is TimeSpan) return ToNullableDateTime((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is DateTimeOffset?) return ToNullableDateTime((DateTimeOffset?)p); + if (p is Double?) return ToNullableDateTime((Double?) p); + if (p is Int64?) return ToNullableDateTime((Int64?) p); + if (p is TimeSpan?) return ToNullableDateTime((TimeSpan?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableDateTime((Binary) p); + if (p is Byte[]) return ToNullableDateTime((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlDateTime) return ToNullableDateTime((SqlDateTime) p); + if (p is SqlDouble) return ToNullableDateTime((SqlDouble) p); + if (p is SqlInt64) return ToNullableDateTime((SqlInt64) p); + if (p is SqlString) return ToNullableDateTime((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(DateTime?)); + } + + #endregion + + #region DateTimeOffset? + + // Simple Types + // + /// Converts the value from DateTime to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(DateTime p) { return p; } + /// Converts the value from DateTimeOffset to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(DateTimeOffset p) { return p; } + /// Converts the value from Double to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(Double p) { return DateTimeOffset.MinValue + TimeSpan.FromDays (p); } + /// Converts the value from Int64 to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(Int64 p) { return DateTimeOffset.MinValue + TimeSpan.FromTicks(p); } + /// Converts the value from String to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(String p) { return p == null? (DateTimeOffset?)null : DateTimeOffset.Parse(p); } + /// Converts the value from TimeSpan to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(TimeSpan p) { return DateTimeOffset.MinValue + p; } + + // Nullable Types + // + /// Converts the value from DateTime? to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(DateTime? p) { return p.HasValue ? p.Value : (DateTimeOffset?)null; } + /// Converts the value from Double? to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(Double? p) { return p.HasValue ? DateTimeOffset.MinValue + TimeSpan.FromDays (p.Value): (DateTimeOffset?)null; } + /// Converts the value from Int64? to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(Int64? p) { return p.HasValue ? DateTimeOffset.MinValue + TimeSpan.FromTicks(p.Value): (DateTimeOffset?)null; } + /// Converts the value from TimeSpan? to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(TimeSpan? p) { return p.HasValue ? DateTimeOffset.MinValue + p.Value : (DateTimeOffset?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(Binary p) { return p == null || p.Length == 0 ? (DateTimeOffset?)null : new DateTimeOffset?(ToDateTime(p.ToArray())); } + /// Converts the value from Byte[] to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(Byte[] p) { return p == null || p.Length == 0 ? (DateTimeOffset?)null : new DateTimeOffset?(ToDateTime(p)); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlDateTime to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(SqlDateTime p) { return p.IsNull ? (DateTimeOffset?)null : p.Value; } + /// Converts the value from SqlDouble to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(SqlDouble p) { return p.IsNull ? (DateTimeOffset?)null : DateTimeOffset.MinValue + TimeSpan.FromDays (p.Value); } + /// Converts the value from SqlInt64 to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(SqlInt64 p) { return p.IsNull ? (DateTimeOffset?)null : DateTimeOffset.MinValue + TimeSpan.FromTicks(p.Value); } + /// Converts the value from SqlString to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(SqlString p) { return p.IsNull ? (DateTimeOffset?)null : ToDateTimeOffset(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent DateTimeOffset? value. + public static DateTimeOffset? ToNullableDateTimeOffset(object p) + { + if (p == null) return null; + + if (p is DateTimeOffset?) return (DateTimeOffset?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.Int64 : return ToNullableDateTimeOffset((Int64) p); + case TypeCode.Double : return ToNullableDateTimeOffset((Double) p); + case TypeCode.DateTime : return ToNullableDateTimeOffset((DateTime) p); + case TypeCode.String : return ToNullableDateTimeOffset((String) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToNullableDateTimeOffset((DateTimeOffset)p); + if (p is TimeSpan) return ToNullableDateTimeOffset((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is DateTime?) return ToNullableDateTimeOffset((DateTime?) p); + if (p is Double?) return ToNullableDateTimeOffset((Double?) p); + if (p is Int64?) return ToNullableDateTimeOffset((Int64?) p); + if (p is TimeSpan?) return ToNullableDateTimeOffset((TimeSpan?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableDateTimeOffset((Binary) p); + if (p is Byte[]) return ToNullableDateTimeOffset((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlDateTime) return ToNullableDateTimeOffset((SqlDateTime) p); + if (p is SqlDouble) return ToNullableDateTimeOffset((SqlDouble) p); + if (p is SqlInt64) return ToNullableDateTimeOffset((SqlInt64) p); + if (p is SqlString) return ToNullableDateTimeOffset((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(DateTimeOffset?)); + } + + #endregion + + #region Decimal? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Boolean p) { return p ? (Decimal?)1 : (Decimal?)0; } + /// Converts the value from Byte to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Byte p) { return p; } + /// Converts the value from Char to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Char p) { return p; } + /// Converts the value from Decimal to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Decimal p) { return p; } + /// Converts the value from Double to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Double p) { return checked((Decimal?)p); } + /// Converts the value from Int16 to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Int64 p) { return p; } + /// Converts the value from SByte to an equivalent Decimal? value. + [CLSCompliant(false)] + public static Decimal? ToNullableDecimal(SByte p) { return p; } + /// Converts the value from Single to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Single p) { return checked((Decimal?)p); } + /// Converts the value from String to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(String p) { return p == null? (Decimal?)null : Decimal.Parse(p); } + /// Converts the value from UInt16 to an equivalent Decimal? value. + [CLSCompliant(false)] + public static Decimal? ToNullableDecimal(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent Decimal? value. + [CLSCompliant(false)] + public static Decimal? ToNullableDecimal(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent Decimal? value. + [CLSCompliant(false)] + public static Decimal? ToNullableDecimal(UInt64 p) { return p; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Boolean? p) { return p.HasValue && p.Value ? (Decimal?)1: (Decimal?)0; } + /// Converts the value from Byte? to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Byte? p) { return p.HasValue ? p.Value : (Decimal?)null; } + /// Converts the value from Char? to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Char? p) { return p.HasValue ? p.Value : (Decimal?)null; } + /// Converts the value from Double? to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Double? p) { return p.HasValue ? checked((Decimal?)p.Value) : (Decimal?)null; } + /// Converts the value from Int16? to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Int16? p) { return p.HasValue ? p.Value : (Decimal?)null; } + /// Converts the value from Int32? to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Int32? p) { return p.HasValue ? p.Value : (Decimal?)null; } + /// Converts the value from Int64? to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Int64? p) { return p.HasValue ? p.Value : (Decimal?)null; } + /// Converts the value from SByte? to an equivalent Decimal? value. + [CLSCompliant(false)] + public static Decimal? ToNullableDecimal(SByte? p) { return p.HasValue ? p.Value : (Decimal?)null; } + /// Converts the value from Single? to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Single? p) { return p.HasValue ? checked((Decimal?)p.Value) : (Decimal?)null; } + /// Converts the value from UInt16? to an equivalent Decimal? value. + [CLSCompliant(false)] + public static Decimal? ToNullableDecimal(UInt16? p) { return p.HasValue ? p.Value : (Decimal?)null; } + /// Converts the value from UInt32? to an equivalent Decimal? value. + [CLSCompliant(false)] + public static Decimal? ToNullableDecimal(UInt32? p) { return p.HasValue ? p.Value : (Decimal?)null; } + /// Converts the value from UInt64? to an equivalent Decimal? value. + [CLSCompliant(false)] + public static Decimal? ToNullableDecimal(UInt64? p) { return p.HasValue ? p.Value : (Decimal?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Binary p) { return p == null || p.Length == 0 ? (Decimal?)null : ToDecimal(p); } + /// Converts the value from Byte[] to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(Byte[] p) { return p == null || p.Length == 0 ? (Decimal?)null : ToDecimal(p); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(SqlBoolean p) { return p.IsNull ? (Decimal?)null : ToDecimal(p.Value); } + /// Converts the value from SqlByte to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(SqlByte p) { return p.IsNull ? (Decimal?)null : p.Value; } + /// Converts the value from SqlDecimal to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(SqlDecimal p) { return p.IsNull ? (Decimal?)null : p.Value; } + /// Converts the value from SqlDouble to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(SqlDouble p) { return p.IsNull ? (Decimal?)null : ToDecimal(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(SqlInt16 p) { return p.IsNull ? (Decimal?)null : p.Value; } + /// Converts the value from SqlInt32 to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(SqlInt32 p) { return p.IsNull ? (Decimal?)null : p.Value; } + /// Converts the value from SqlInt64 to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(SqlInt64 p) { return p.IsNull ? (Decimal?)null : p.Value; } + /// Converts the value from SqlMoney to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(SqlMoney p) { return p.IsNull ? (Decimal?)null : p.Value; } + /// Converts the value from SqlSingle to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(SqlSingle p) { return p.IsNull ? (Decimal?)null : ToDecimal(p.Value); } + /// Converts the value from SqlString to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(SqlString p) { return p.IsNull ? (Decimal?)null : ToDecimal(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Decimal? value. + public static Decimal? ToNullableDecimal(object p) + { + if (p == null) return null; + + if (p is Decimal?) return (Decimal?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.SByte : return ToNullableDecimal((SByte) p); + case TypeCode.Int16 : return ToNullableDecimal((Int16) p); + case TypeCode.Int32 : return ToNullableDecimal((Int32) p); + case TypeCode.Int64 : return ToNullableDecimal((Int64) p); + case TypeCode.Byte : return ToNullableDecimal((Byte) p); + case TypeCode.UInt16 : return ToNullableDecimal((UInt16) p); + case TypeCode.UInt32 : return ToNullableDecimal((UInt32) p); + case TypeCode.Char : return ToNullableDecimal((Char) p); + case TypeCode.UInt64 : return ToNullableDecimal((UInt64) p); + case TypeCode.Decimal : return ToNullableDecimal((Decimal) p); + case TypeCode.Single : return ToNullableDecimal((Single) p); + case TypeCode.Double : return ToNullableDecimal((Double) p); + case TypeCode.String : return ToNullableDecimal((String) p); + case TypeCode.Boolean : return ToNullableDecimal((Boolean) p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToNullableDecimal((Boolean?) p); + if (p is Byte?) return ToNullableDecimal((Byte?) p); + if (p is Char?) return ToNullableDecimal((Char?) p); + if (p is Double?) return ToNullableDecimal((Double?) p); + if (p is Int16?) return ToNullableDecimal((Int16?) p); + if (p is Int32?) return ToNullableDecimal((Int32?) p); + if (p is Int64?) return ToNullableDecimal((Int64?) p); + if (p is SByte?) return ToNullableDecimal((SByte?) p); + if (p is Single?) return ToNullableDecimal((Single?) p); + if (p is UInt16?) return ToNullableDecimal((UInt16?) p); + if (p is UInt32?) return ToNullableDecimal((UInt32?) p); + if (p is UInt64?) return ToNullableDecimal((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableDecimal((Binary) p); + if (p is Byte[]) return ToNullableDecimal((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableDecimal((SqlBoolean)p); + if (p is SqlByte) return ToNullableDecimal((SqlByte) p); + if (p is SqlDecimal) return ToNullableDecimal((SqlDecimal)p); + if (p is SqlDouble) return ToNullableDecimal((SqlDouble) p); + if (p is SqlInt16) return ToNullableDecimal((SqlInt16) p); + if (p is SqlInt32) return ToNullableDecimal((SqlInt32) p); + if (p is SqlInt64) return ToNullableDecimal((SqlInt64) p); + if (p is SqlMoney) return ToNullableDecimal((SqlMoney) p); + if (p is SqlSingle) return ToNullableDecimal((SqlSingle) p); + if (p is SqlString) return ToNullableDecimal((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Decimal?)); + } + + #endregion + + #region Double? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Double? value. + public static Double? ToNullableDouble(Boolean p) { return p ? (Double?)1 : (Double?)0; } + /// Converts the value from Byte to an equivalent Double? value. + public static Double? ToNullableDouble(Byte p) { return p; } + /// Converts the value from Char to an equivalent Double? value. + public static Double? ToNullableDouble(Char p) { return p; } + /// Converts the value from DateTime to an equivalent Double? value. + public static Double? ToNullableDouble(DateTime p) { return (p - DateTime.MinValue).TotalDays; } + /// Converts the value from DateTimeOffset to an equivalent Double? value. + public static Double? ToNullableDouble(DateTimeOffset p) { return (p - DateTimeOffset.MinValue).TotalDays; } + /// Converts the value from Decimal to an equivalent Double? value. + public static Double? ToNullableDouble(Decimal p) { return checked((Double?)p); } + /// Converts the value from Double to an equivalent Double? value. + public static Double? ToNullableDouble(Double p) { return p; } + /// Converts the value from Int16 to an equivalent Double? value. + public static Double? ToNullableDouble(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent Double? value. + public static Double? ToNullableDouble(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent Double? value. + public static Double? ToNullableDouble(Int64 p) { return p; } + /// Converts the value from SByte to an equivalent Double? value. + [CLSCompliant(false)] + public static Double? ToNullableDouble(SByte p) { return p; } + /// Converts the value from Single to an equivalent Double? value. + public static Double? ToNullableDouble(Single p) { return p; } + /// Converts the value from String to an equivalent Double? value. + public static Double? ToNullableDouble(String p) { return p == null? (Double?)null : Double.Parse(p); } + /// Converts the value from TimeSpan to an equivalent Double? value. + public static Double? ToNullableDouble(TimeSpan p) { return p.TotalDays; } + /// Converts the value from UInt16 to an equivalent Double? value. + [CLSCompliant(false)] + public static Double? ToNullableDouble(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent Double? value. + [CLSCompliant(false)] + public static Double? ToNullableDouble(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent Double? value. + [CLSCompliant(false)] + public static Double? ToNullableDouble(UInt64 p) { return p; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Double? value. + public static Double? ToNullableDouble(Boolean? p) { return p.HasValue && p.Value ? (Double?)1: (Double?)0; } + /// Converts the value from Byte? to an equivalent Double? value. + public static Double? ToNullableDouble(Byte? p) { return p.HasValue ? p.Value : (Double?)null; } + /// Converts the value from Char? to an equivalent Double? value. + public static Double? ToNullableDouble(Char? p) { return p.HasValue ? p.Value : (Double?)null; } + /// Converts the value from DateTime? to an equivalent Double? value. + public static Double? ToNullableDouble(DateTime? p) { return p.HasValue ? (p.Value - DateTime.MinValue).TotalDays : (Double?)null; } + /// Converts the value from DateTimeOffset? to an equivalent Double? value. + public static Double? ToNullableDouble(DateTimeOffset? p) { return p.HasValue ? (p.Value - DateTimeOffset.MinValue).TotalDays : (Double?)null; } + /// Converts the value from Decimal? to an equivalent Double? value. + public static Double? ToNullableDouble(Decimal? p) { return p.HasValue ? checked((Double?)p.Value) : (Double?)null; } + /// Converts the value from Int16? to an equivalent Double? value. + public static Double? ToNullableDouble(Int16? p) { return p.HasValue ? p.Value : (Double?)null; } + /// Converts the value from Int32? to an equivalent Double? value. + public static Double? ToNullableDouble(Int32? p) { return p.HasValue ? p.Value : (Double?)null; } + /// Converts the value from Int64? to an equivalent Double? value. + public static Double? ToNullableDouble(Int64? p) { return p.HasValue ? p.Value : (Double?)null; } + /// Converts the value from SByte? to an equivalent Double? value. + [CLSCompliant(false)] + public static Double? ToNullableDouble(SByte? p) { return p.HasValue ? p.Value : (Double?)null; } + /// Converts the value from Single? to an equivalent Double? value. + public static Double? ToNullableDouble(Single? p) { return p.HasValue ? p.Value : (Double?)null; } + /// Converts the value from TimeSpan? to an equivalent Double? value. + public static Double? ToNullableDouble(TimeSpan? p) { return p.HasValue ? p.Value.TotalDays : (Double?)null; } + /// Converts the value from UInt16? to an equivalent Double? value. + [CLSCompliant(false)] + public static Double? ToNullableDouble(UInt16? p) { return p.HasValue ? p.Value : (Double?)null; } + /// Converts the value from UInt32? to an equivalent Double? value. + [CLSCompliant(false)] + public static Double? ToNullableDouble(UInt32? p) { return p.HasValue ? p.Value : (Double?)null; } + /// Converts the value from UInt64? to an equivalent Double? value. + [CLSCompliant(false)] + public static Double? ToNullableDouble(UInt64? p) { return p.HasValue ? p.Value : (Double?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Double? value. + public static Double? ToNullableDouble(Binary p) { return p == null || p.Length == 0 ? (Double?)null : BitConverter.ToDouble(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Double? value. + public static Double? ToNullableDouble(Byte[] p) { return p == null || p.Length == 0 ? (Double?)null : BitConverter.ToDouble(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Double? value. + public static Double? ToNullableDouble(SqlBoolean p) { return p.IsNull ? (Double?)null : ToDouble(p.Value); } + /// Converts the value from SqlByte to an equivalent Double? value. + public static Double? ToNullableDouble(SqlByte p) { return p.IsNull ? (Double?)null : p.Value; } + /// Converts the value from SqlDateTime to an equivalent Double? value. + public static Double? ToNullableDouble(SqlDateTime p) { return p.IsNull ? (Double?)null : ToDouble(p.Value); } + /// Converts the value from SqlDecimal to an equivalent Double? value. + public static Double? ToNullableDouble(SqlDecimal p) { return p.IsNull ? (Double?)null : ToDouble(p.Value); } + /// Converts the value from SqlDouble to an equivalent Double? value. + public static Double? ToNullableDouble(SqlDouble p) { return p.IsNull ? (Double?)null : p.Value; } + /// Converts the value from SqlInt16 to an equivalent Double? value. + public static Double? ToNullableDouble(SqlInt16 p) { return p.IsNull ? (Double?)null : p.Value; } + /// Converts the value from SqlInt32 to an equivalent Double? value. + public static Double? ToNullableDouble(SqlInt32 p) { return p.IsNull ? (Double?)null : p.Value; } + /// Converts the value from SqlInt64 to an equivalent Double? value. + public static Double? ToNullableDouble(SqlInt64 p) { return p.IsNull ? (Double?)null : p.Value; } + /// Converts the value from SqlMoney to an equivalent Double? value. + public static Double? ToNullableDouble(SqlMoney p) { return p.IsNull ? (Double?)null : ToDouble(p.Value); } + /// Converts the value from SqlSingle to an equivalent Double? value. + public static Double? ToNullableDouble(SqlSingle p) { return p.IsNull ? (Double?)null : p.Value; } + /// Converts the value from SqlString to an equivalent Double? value. + public static Double? ToNullableDouble(SqlString p) { return p.IsNull ? (Double?)null : ToDouble(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Double? value. + public static Double? ToNullableDouble(object p) + { + if (p == null) return null; + + if (p is Double?) return (Double?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.DateTime : return ToNullableDouble((DateTime)p); + case TypeCode.SByte : return ToNullableDouble((SByte) p); + case TypeCode.Int16 : return ToNullableDouble((Int16) p); + case TypeCode.Int32 : return ToNullableDouble((Int32) p); + case TypeCode.Int64 : return ToNullableDouble((Int64) p); + case TypeCode.Byte : return ToNullableDouble((Byte) p); + case TypeCode.UInt16 : return ToNullableDouble((UInt16) p); + case TypeCode.UInt32 : return ToNullableDouble((UInt32) p); + case TypeCode.Char : return ToNullableDouble((Char) p); + case TypeCode.UInt64 : return ToNullableDouble((UInt64) p); + case TypeCode.Single : return ToNullableDouble((Single) p); + case TypeCode.Double : return ToNullableDouble((Double) p); + case TypeCode.Decimal : return ToNullableDouble((Decimal) p); + case TypeCode.String : return ToNullableDouble((String) p); + case TypeCode.Boolean : return ToNullableDouble((Boolean) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToNullableDouble((DateTimeOffset) p); + if (p is TimeSpan) return ToNullableDouble((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToNullableDouble((Boolean?) p); + if (p is Byte?) return ToNullableDouble((Byte?) p); + if (p is Char?) return ToNullableDouble((Char?) p); + if (p is DateTime?) return ToNullableDouble((DateTime?) p); + if (p is DateTimeOffset?) return ToNullableDouble((DateTimeOffset?)p); + if (p is Decimal?) return ToNullableDouble((Decimal?) p); + if (p is Int16?) return ToNullableDouble((Int16?) p); + if (p is Int32?) return ToNullableDouble((Int32?) p); + if (p is Int64?) return ToNullableDouble((Int64?) p); + if (p is SByte?) return ToNullableDouble((SByte?) p); + if (p is Single?) return ToNullableDouble((Single?) p); + if (p is TimeSpan?) return ToNullableDouble((TimeSpan?) p); + if (p is UInt16?) return ToNullableDouble((UInt16?) p); + if (p is UInt32?) return ToNullableDouble((UInt32?) p); + if (p is UInt64?) return ToNullableDouble((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableDouble((Binary) p); + if (p is Byte[]) return ToNullableDouble((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableDouble((SqlBoolean) p); + if (p is SqlByte) return ToNullableDouble((SqlByte) p); + if (p is SqlDateTime) return ToNullableDouble((SqlDateTime) p); + if (p is SqlDecimal) return ToNullableDouble((SqlDecimal) p); + if (p is SqlDouble) return ToNullableDouble((SqlDouble) p); + if (p is SqlInt16) return ToNullableDouble((SqlInt16) p); + if (p is SqlInt32) return ToNullableDouble((SqlInt32) p); + if (p is SqlInt64) return ToNullableDouble((SqlInt64) p); + if (p is SqlMoney) return ToNullableDouble((SqlMoney) p); + if (p is SqlSingle) return ToNullableDouble((SqlSingle) p); + if (p is SqlString) return ToNullableDouble((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Double?)); + } + + #endregion + + #region Guid? + + // Simple Types + // + /// Converts the value from Guid to an equivalent Guid? value. + public static Guid? ToNullableGuid(Guid p) { return p; } + /// Converts the value from String to an equivalent Guid? value. + public static Guid? ToNullableGuid(String p) { return p == null ? (Guid?)null : new Guid(p); } + + // Other Types + // + /// Converts the value from Binary to an equivalent Guid? value. + public static Guid? ToNullableGuid(Binary p) { return p == null ? (Guid?)null : new Guid(p.ToArray()); } + /// Converts the value from Byte[] to an equivalent Guid? value. + public static Guid? ToNullableGuid(Byte[] p) { return p == null ? (Guid?)null : new Guid(p); } + /// Converts the value from Type to an equivalent Guid? value. + public static Guid? ToNullableGuid(Type p) { return p == null ? (Guid?)null : p.GUID; } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBinary to an equivalent Guid? value. + public static Guid? ToNullableGuid(SqlBinary p) { return p.IsNull ? (Guid?)null : p.ToSqlGuid().Value; } + /// Converts the value from SqlGuid to an equivalent Guid? value. + public static Guid? ToNullableGuid(SqlGuid p) { return p.IsNull ? (Guid?)null : p.Value; } + /// Converts the value from SqlString to an equivalent Guid? value. + public static Guid? ToNullableGuid(SqlString p) { return p.IsNull ? (Guid?)null : new Guid(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Guid? value. + public static Guid? ToNullableGuid(object p) + { + if (p == null) return null; + + if (p is Guid?) return (Guid?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.String : return ToNullableGuid((String)p); + } + + // Simple Types + // + if (p is Guid) return ToNullableGuid((Guid) p); + + // Other Types + // + if (p is Binary) return ToNullableGuid((Binary) p); + if (p is Byte[]) return ToNullableGuid((Byte[]) p); + if (p is Type) return ToNullableGuid((Type) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBinary) return ToNullableGuid((SqlBinary)p); + if (p is SqlGuid) return ToNullableGuid((SqlGuid) p); + if (p is SqlString) return ToNullableGuid((SqlString)p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Guid?)); + } + + #endregion + + #region Int16? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Int16? value. + public static Int16? ToNullableInt16(Boolean p) { return p ? (Int16?)1 : (Int16?)0; } + /// Converts the value from Byte to an equivalent Int16? value. + public static Int16? ToNullableInt16(Byte p) { return p; } + /// Converts the value from Char to an equivalent Int16? value. + public static Int16? ToNullableInt16(Char p) { return checked((Int16?)p); } + /// Converts the value from Decimal to an equivalent Int16? value. + public static Int16? ToNullableInt16(Decimal p) { return checked((Int16?)p); } + /// Converts the value from Double to an equivalent Int16? value. + public static Int16? ToNullableInt16(Double p) { return checked((Int16?)p); } + /// Converts the value from Int16 to an equivalent Int16? value. + public static Int16? ToNullableInt16(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent Int16? value. + public static Int16? ToNullableInt16(Int32 p) { return checked((Int16?)p); } + /// Converts the value from Int64 to an equivalent Int16? value. + public static Int16? ToNullableInt16(Int64 p) { return checked((Int16?)p); } + /// Converts the value from SByte to an equivalent Int16? value. + [CLSCompliant(false)] + public static Int16? ToNullableInt16(SByte p) { return p; } + /// Converts the value from Single to an equivalent Int16? value. + public static Int16? ToNullableInt16(Single p) { return checked((Int16?)p); } + /// Converts the value from String to an equivalent Int16? value. + public static Int16? ToNullableInt16(String p) { return p == null? (Int16?)null : Int16.Parse(p); } + /// Converts the value from UInt16 to an equivalent Int16? value. + [CLSCompliant(false)] + public static Int16? ToNullableInt16(UInt16 p) { return checked((Int16?)p); } + /// Converts the value from UInt32 to an equivalent Int16? value. + [CLSCompliant(false)] + public static Int16? ToNullableInt16(UInt32 p) { return checked((Int16?)p); } + /// Converts the value from UInt64 to an equivalent Int16? value. + [CLSCompliant(false)] + public static Int16? ToNullableInt16(UInt64 p) { return checked((Int16?)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Int16? value. + public static Int16? ToNullableInt16(Boolean? p) { return p.HasValue && p.Value ? (Int16?)1: (Int16?)0; } + /// Converts the value from Byte? to an equivalent Int16? value. + public static Int16? ToNullableInt16(Byte? p) { return p.HasValue ? p.Value : (Int16?)null; } + /// Converts the value from Char? to an equivalent Int16? value. + public static Int16? ToNullableInt16(Char? p) { return p.HasValue ? checked((Int16?)p.Value) : (Int16?)null; } + /// Converts the value from Decimal? to an equivalent Int16? value. + public static Int16? ToNullableInt16(Decimal? p) { return p.HasValue ? checked((Int16?)p.Value) : (Int16?)null; } + /// Converts the value from Double? to an equivalent Int16? value. + public static Int16? ToNullableInt16(Double? p) { return p.HasValue ? checked((Int16?)p.Value) : (Int16?)null; } + /// Converts the value from Int32? to an equivalent Int16? value. + public static Int16? ToNullableInt16(Int32? p) { return p.HasValue ? checked((Int16?)p.Value) : (Int16?)null; } + /// Converts the value from Int64? to an equivalent Int16? value. + public static Int16? ToNullableInt16(Int64? p) { return p.HasValue ? checked((Int16?)p.Value) : (Int16?)null; } + /// Converts the value from SByte? to an equivalent Int16? value. + [CLSCompliant(false)] + public static Int16? ToNullableInt16(SByte? p) { return p.HasValue ? p.Value : (Int16?)null; } + /// Converts the value from Single? to an equivalent Int16? value. + public static Int16? ToNullableInt16(Single? p) { return p.HasValue ? checked((Int16?)p.Value) : (Int16?)null; } + /// Converts the value from UInt16? to an equivalent Int16? value. + [CLSCompliant(false)] + public static Int16? ToNullableInt16(UInt16? p) { return p.HasValue ? checked((Int16?)p.Value) : (Int16?)null; } + /// Converts the value from UInt32? to an equivalent Int16? value. + [CLSCompliant(false)] + public static Int16? ToNullableInt16(UInt32? p) { return p.HasValue ? checked((Int16?)p.Value) : (Int16?)null; } + /// Converts the value from UInt64? to an equivalent Int16? value. + [CLSCompliant(false)] + public static Int16? ToNullableInt16(UInt64? p) { return p.HasValue ? checked((Int16?)p.Value) : (Int16?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Int16? value. + public static Int16? ToNullableInt16(Binary p) { return p == null || p.Length == 0 ? (Int16?)null : BitConverter.ToInt16(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Int16? value. + public static Int16? ToNullableInt16(Byte[] p) { return p == null || p.Length == 0 ? (Int16?)null : BitConverter.ToInt16(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Int16? value. + public static Int16? ToNullableInt16(SqlBoolean p) { return p.IsNull ? (Int16?)null : ToInt16(p.Value); } + /// Converts the value from SqlByte to an equivalent Int16? value. + public static Int16? ToNullableInt16(SqlByte p) { return p.IsNull ? (Int16?)null : p.Value; } + /// Converts the value from SqlDecimal to an equivalent Int16? value. + public static Int16? ToNullableInt16(SqlDecimal p) { return p.IsNull ? (Int16?)null : ToInt16(p.Value); } + /// Converts the value from SqlDouble to an equivalent Int16? value. + public static Int16? ToNullableInt16(SqlDouble p) { return p.IsNull ? (Int16?)null : ToInt16(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Int16? value. + public static Int16? ToNullableInt16(SqlInt16 p) { return p.IsNull ? (Int16?)null : p.Value; } + /// Converts the value from SqlInt32 to an equivalent Int16? value. + public static Int16? ToNullableInt16(SqlInt32 p) { return p.IsNull ? (Int16?)null : ToInt16(p.Value); } + /// Converts the value from SqlInt64 to an equivalent Int16? value. + public static Int16? ToNullableInt16(SqlInt64 p) { return p.IsNull ? (Int16?)null : ToInt16(p.Value); } + /// Converts the value from SqlMoney to an equivalent Int16? value. + public static Int16? ToNullableInt16(SqlMoney p) { return p.IsNull ? (Int16?)null : ToInt16(p.Value); } + /// Converts the value from SqlSingle to an equivalent Int16? value. + public static Int16? ToNullableInt16(SqlSingle p) { return p.IsNull ? (Int16?)null : ToInt16(p.Value); } + /// Converts the value from SqlString to an equivalent Int16? value. + public static Int16? ToNullableInt16(SqlString p) { return p.IsNull ? (Int16?)null : ToInt16(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Int16? value. + public static Int16? ToNullableInt16(object p) + { + if (p == null) return null; + + if (p is Int16?) return (Int16?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.SByte : return ToNullableInt16((SByte) p); + case TypeCode.Int16 : return ToNullableInt16((Int16) p); + case TypeCode.Byte : return ToNullableInt16((Byte) p); + case TypeCode.Int32 : return ToNullableInt16((Int32) p); + case TypeCode.Int64 : return ToNullableInt16((Int64) p); + case TypeCode.UInt16 : return ToNullableInt16((UInt16) p); + case TypeCode.UInt32 : return ToNullableInt16((UInt32) p); + case TypeCode.UInt64 : return ToNullableInt16((UInt64) p); + case TypeCode.Single : return ToNullableInt16((Single) p); + case TypeCode.Double : return ToNullableInt16((Double) p); + case TypeCode.Decimal : return ToNullableInt16((Decimal)p); + case TypeCode.Char : return ToNullableInt16((Char) p); + case TypeCode.String : return ToNullableInt16((String) p); + case TypeCode.Boolean : return ToNullableInt16((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToNullableInt16((Boolean?) p); + if (p is Byte?) return ToNullableInt16((Byte?) p); + if (p is Char?) return ToNullableInt16((Char?) p); + if (p is Decimal?) return ToNullableInt16((Decimal?) p); + if (p is Double?) return ToNullableInt16((Double?) p); + if (p is Int32?) return ToNullableInt16((Int32?) p); + if (p is Int64?) return ToNullableInt16((Int64?) p); + if (p is SByte?) return ToNullableInt16((SByte?) p); + if (p is Single?) return ToNullableInt16((Single?) p); + if (p is UInt16?) return ToNullableInt16((UInt16?) p); + if (p is UInt32?) return ToNullableInt16((UInt32?) p); + if (p is UInt64?) return ToNullableInt16((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableInt16((Binary) p); + if (p is Byte[]) return ToNullableInt16((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableInt16((SqlBoolean)p); + if (p is SqlByte) return ToNullableInt16((SqlByte) p); + if (p is SqlDecimal) return ToNullableInt16((SqlDecimal)p); + if (p is SqlDouble) return ToNullableInt16((SqlDouble) p); + if (p is SqlInt16) return ToNullableInt16((SqlInt16) p); + if (p is SqlInt32) return ToNullableInt16((SqlInt32) p); + if (p is SqlInt64) return ToNullableInt16((SqlInt64) p); + if (p is SqlMoney) return ToNullableInt16((SqlMoney) p); + if (p is SqlSingle) return ToNullableInt16((SqlSingle) p); + if (p is SqlString) return ToNullableInt16((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Int16?)); + } + + #endregion + + #region Int32? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Int32? value. + public static Int32? ToNullableInt32(Boolean p) { return p ? (Int32?)1 : (Int32?)0; } + /// Converts the value from Byte to an equivalent Int32? value. + public static Int32? ToNullableInt32(Byte p) { return p; } + /// Converts the value from Char to an equivalent Int32? value. + public static Int32? ToNullableInt32(Char p) { return p; } + /// Converts the value from Decimal to an equivalent Int32? value. + public static Int32? ToNullableInt32(Decimal p) { return checked((Int32?)p); } + /// Converts the value from Double to an equivalent Int32? value. + public static Int32? ToNullableInt32(Double p) { return checked((Int32?)p); } + /// Converts the value from Int16 to an equivalent Int32? value. + public static Int32? ToNullableInt32(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent Int32? value. + public static Int32? ToNullableInt32(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent Int32? value. + public static Int32? ToNullableInt32(Int64 p) { return checked((Int32?)p); } + /// Converts the value from SByte to an equivalent Int32? value. + [CLSCompliant(false)] + public static Int32? ToNullableInt32(SByte p) { return p; } + /// Converts the value from Single to an equivalent Int32? value. + public static Int32? ToNullableInt32(Single p) { return checked((Int32?)p); } + /// Converts the value from String to an equivalent Int32? value. + public static Int32? ToNullableInt32(String p) { return p == null? (Int32?)null : Int32.Parse(p); } + /// Converts the value from UInt16 to an equivalent Int32? value. + [CLSCompliant(false)] + public static Int32? ToNullableInt32(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent Int32? value. + [CLSCompliant(false)] + public static Int32? ToNullableInt32(UInt32 p) { return checked((Int32?)p); } + /// Converts the value from UInt64 to an equivalent Int32? value. + [CLSCompliant(false)] + public static Int32? ToNullableInt32(UInt64 p) { return checked((Int32?)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Int32? value. + public static Int32? ToNullableInt32(Boolean? p) { return p.HasValue && p.Value ? (Int32?)1: (Int32?)0; } + /// Converts the value from Byte? to an equivalent Int32? value. + public static Int32? ToNullableInt32(Byte? p) { return p.HasValue ? p.Value : (Int32?)null; } + /// Converts the value from Char? to an equivalent Int32? value. + public static Int32? ToNullableInt32(Char? p) { return p.HasValue ? p.Value : (Int32?)null; } + /// Converts the value from Decimal? to an equivalent Int32? value. + public static Int32? ToNullableInt32(Decimal? p) { return p.HasValue ? checked((Int32?)p.Value) : (Int32?)null; } + /// Converts the value from Double? to an equivalent Int32? value. + public static Int32? ToNullableInt32(Double? p) { return p.HasValue ? checked((Int32?)p.Value) : (Int32?)null; } + /// Converts the value from Int16? to an equivalent Int32? value. + public static Int32? ToNullableInt32(Int16? p) { return p.HasValue ? p.Value : (Int32?)null; } + /// Converts the value from Int64? to an equivalent Int32? value. + public static Int32? ToNullableInt32(Int64? p) { return p.HasValue ? checked((Int32?)p.Value) : (Int32?)null; } + /// Converts the value from SByte? to an equivalent Int32? value. + [CLSCompliant(false)] + public static Int32? ToNullableInt32(SByte? p) { return p.HasValue ? p.Value : (Int32?)null; } + /// Converts the value from Single? to an equivalent Int32? value. + public static Int32? ToNullableInt32(Single? p) { return p.HasValue ? checked((Int32?)p.Value) : (Int32?)null; } + /// Converts the value from UInt16? to an equivalent Int32? value. + [CLSCompliant(false)] + public static Int32? ToNullableInt32(UInt16? p) { return p.HasValue ? p.Value : (Int32?)null; } + /// Converts the value from UInt32? to an equivalent Int32? value. + [CLSCompliant(false)] + public static Int32? ToNullableInt32(UInt32? p) { return p.HasValue ? checked((Int32?)p.Value) : (Int32?)null; } + /// Converts the value from UInt64? to an equivalent Int32? value. + [CLSCompliant(false)] + public static Int32? ToNullableInt32(UInt64? p) { return p.HasValue ? checked((Int32?)p.Value) : (Int32?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Int32? value. + public static Int32? ToNullableInt32(Binary p) { return p == null || p.Length == 0 ? (Int32?)null : BitConverter.ToInt32(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Int32? value. + public static Int32? ToNullableInt32(Byte[] p) { return p == null || p.Length == 0 ? (Int32?)null : BitConverter.ToInt32(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Int32? value. + public static Int32? ToNullableInt32(SqlBoolean p) { return p.IsNull ? (Int32?)null : ToInt32(p.Value); } + /// Converts the value from SqlByte to an equivalent Int32? value. + public static Int32? ToNullableInt32(SqlByte p) { return p.IsNull ? (Int32?)null : p.Value; } + /// Converts the value from SqlDecimal to an equivalent Int32? value. + public static Int32? ToNullableInt32(SqlDecimal p) { return p.IsNull ? (Int32?)null : ToInt32(p.Value); } + /// Converts the value from SqlDouble to an equivalent Int32? value. + public static Int32? ToNullableInt32(SqlDouble p) { return p.IsNull ? (Int32?)null : ToInt32(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Int32? value. + public static Int32? ToNullableInt32(SqlInt16 p) { return p.IsNull ? (Int32?)null : p.Value; } + /// Converts the value from SqlInt32 to an equivalent Int32? value. + public static Int32? ToNullableInt32(SqlInt32 p) { return p.IsNull ? (Int32?)null : p.Value; } + /// Converts the value from SqlInt64 to an equivalent Int32? value. + public static Int32? ToNullableInt32(SqlInt64 p) { return p.IsNull ? (Int32?)null : ToInt32(p.Value); } + /// Converts the value from SqlMoney to an equivalent Int32? value. + public static Int32? ToNullableInt32(SqlMoney p) { return p.IsNull ? (Int32?)null : ToInt32(p.Value); } + /// Converts the value from SqlSingle to an equivalent Int32? value. + public static Int32? ToNullableInt32(SqlSingle p) { return p.IsNull ? (Int32?)null : ToInt32(p.Value); } + /// Converts the value from SqlString to an equivalent Int32? value. + public static Int32? ToNullableInt32(SqlString p) { return p.IsNull ? (Int32?)null : ToInt32(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Int32? value. + public static Int32? ToNullableInt32(object p) + { + if (p == null) return null; + + if (p is Int32?) return (Int32?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.SByte : return ToNullableInt32((SByte) p); + case TypeCode.Int16 : return ToNullableInt32((Int16) p); + case TypeCode.Int32 : return ToNullableInt32((Int32) p); + case TypeCode.Byte : return ToNullableInt32((Byte) p); + case TypeCode.UInt16 : return ToNullableInt32((UInt16) p); + case TypeCode.Char : return ToNullableInt32((Char) p); + case TypeCode.Int64 : return ToNullableInt32((Int64) p); + case TypeCode.UInt32 : return ToNullableInt32((UInt32) p); + case TypeCode.UInt64 : return ToNullableInt32((UInt64) p); + case TypeCode.Single : return ToNullableInt32((Single) p); + case TypeCode.Double : return ToNullableInt32((Double) p); + case TypeCode.Decimal : return ToNullableInt32((Decimal)p); + case TypeCode.String : return ToNullableInt32((String) p); + case TypeCode.Boolean : return ToNullableInt32((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToNullableInt32((Boolean?) p); + if (p is Byte?) return ToNullableInt32((Byte?) p); + if (p is Char?) return ToNullableInt32((Char?) p); + if (p is Decimal?) return ToNullableInt32((Decimal?) p); + if (p is Double?) return ToNullableInt32((Double?) p); + if (p is Int16?) return ToNullableInt32((Int16?) p); + if (p is Int64?) return ToNullableInt32((Int64?) p); + if (p is SByte?) return ToNullableInt32((SByte?) p); + if (p is Single?) return ToNullableInt32((Single?) p); + if (p is UInt16?) return ToNullableInt32((UInt16?) p); + if (p is UInt32?) return ToNullableInt32((UInt32?) p); + if (p is UInt64?) return ToNullableInt32((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableInt32((Binary) p); + if (p is Byte[]) return ToNullableInt32((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableInt32((SqlBoolean)p); + if (p is SqlByte) return ToNullableInt32((SqlByte) p); + if (p is SqlDecimal) return ToNullableInt32((SqlDecimal)p); + if (p is SqlDouble) return ToNullableInt32((SqlDouble) p); + if (p is SqlInt16) return ToNullableInt32((SqlInt16) p); + if (p is SqlInt32) return ToNullableInt32((SqlInt32) p); + if (p is SqlInt64) return ToNullableInt32((SqlInt64) p); + if (p is SqlMoney) return ToNullableInt32((SqlMoney) p); + if (p is SqlSingle) return ToNullableInt32((SqlSingle) p); + if (p is SqlString) return ToNullableInt32((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Int32?)); + } + + #endregion + + #region Int64? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Int64? value. + public static Int64? ToNullableInt64(Boolean p) { return p ? (Int64?)1 : (Int64?)0; } + /// Converts the value from Byte to an equivalent Int64? value. + public static Int64? ToNullableInt64(Byte p) { return p; } + /// Converts the value from Char to an equivalent Int64? value. + public static Int64? ToNullableInt64(Char p) { return p; } + /// Converts the value from DateTime to an equivalent Int64? value. + public static Int64? ToNullableInt64(DateTime p) { return (p - DateTime.MinValue).Ticks; } + /// Converts the value from DateTimeOffset to an equivalent Int64? value. + public static Int64? ToNullableInt64(DateTimeOffset p) { return (p - DateTime.MinValue).Ticks; } + /// Converts the value from Decimal to an equivalent Int64? value. + public static Int64? ToNullableInt64(Decimal p) { return checked((Int64?)p); } + /// Converts the value from Double to an equivalent Int64? value. + public static Int64? ToNullableInt64(Double p) { return checked((Int64?)p); } + /// Converts the value from Int16 to an equivalent Int64? value. + public static Int64? ToNullableInt64(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent Int64? value. + public static Int64? ToNullableInt64(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent Int64? value. + public static Int64? ToNullableInt64(Int64 p) { return p; } + /// Converts the value from SByte to an equivalent Int64? value. + [CLSCompliant(false)] + public static Int64? ToNullableInt64(SByte p) { return p; } + /// Converts the value from Single to an equivalent Int64? value. + public static Int64? ToNullableInt64(Single p) { return checked((Int64?)p); } + /// Converts the value from String to an equivalent Int64? value. + public static Int64? ToNullableInt64(String p) { return p == null? (Int64?)null : Int64.Parse(p); } + /// Converts the value from TimeSpan to an equivalent Int64? value. + public static Int64? ToNullableInt64(TimeSpan p) { return p.Ticks; } + /// Converts the value from UInt16 to an equivalent Int64? value. + [CLSCompliant(false)] + public static Int64? ToNullableInt64(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent Int64? value. + [CLSCompliant(false)] + public static Int64? ToNullableInt64(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent Int64? value. + [CLSCompliant(false)] + public static Int64? ToNullableInt64(UInt64 p) { return checked((Int64?)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Int64? value. + public static Int64? ToNullableInt64(Boolean? p) { return p.HasValue && p.Value ? (Int64?)1: (Int64?)0; } + /// Converts the value from Byte? to an equivalent Int64? value. + public static Int64? ToNullableInt64(Byte? p) { return p.HasValue ? p.Value : (Int64?)null; } + /// Converts the value from Char? to an equivalent Int64? value. + public static Int64? ToNullableInt64(Char? p) { return p.HasValue ? p.Value : (Int64?)null; } + /// Converts the value from DateTime? to an equivalent Int64? value. + public static Int64? ToNullableInt64(DateTime? p) { return p.HasValue ? (p.Value - DateTime.MinValue).Ticks : 0; } + /// Converts the value from DateTimeOffset? to an equivalent Int64? value. + public static Int64? ToNullableInt64(DateTimeOffset? p) { return p.HasValue ? (p.Value - DateTime.MinValue).Ticks : 0; } + /// Converts the value from Decimal? to an equivalent Int64? value. + public static Int64? ToNullableInt64(Decimal? p) { return p.HasValue ? checked((Int64?)p.Value) : (Int64?)null; } + /// Converts the value from Double? to an equivalent Int64? value. + public static Int64? ToNullableInt64(Double? p) { return p.HasValue ? checked((Int64?)p.Value) : (Int64?)null; } + /// Converts the value from Int16? to an equivalent Int64? value. + public static Int64? ToNullableInt64(Int16? p) { return p.HasValue ? p.Value : (Int64?)null; } + /// Converts the value from Int32? to an equivalent Int64? value. + public static Int64? ToNullableInt64(Int32? p) { return p.HasValue ? p.Value : (Int64?)null; } + /// Converts the value from SByte? to an equivalent Int64? value. + [CLSCompliant(false)] + public static Int64? ToNullableInt64(SByte? p) { return p.HasValue ? p.Value : (Int64?)null; } + /// Converts the value from Single? to an equivalent Int64? value. + public static Int64? ToNullableInt64(Single? p) { return p.HasValue ? checked((Int64?)p.Value) : (Int64?)null; } + /// Converts the value from TimeSpan? to an equivalent Int64? value. + public static Int64? ToNullableInt64(TimeSpan? p) { return p.HasValue ? p.Value.Ticks : 0; } + /// Converts the value from UInt16? to an equivalent Int64? value. + [CLSCompliant(false)] + public static Int64? ToNullableInt64(UInt16? p) { return p.HasValue ? p.Value : (Int64?)null; } + /// Converts the value from UInt32? to an equivalent Int64? value. + [CLSCompliant(false)] + public static Int64? ToNullableInt64(UInt32? p) { return p.HasValue ? p.Value : (Int64?)null; } + /// Converts the value from UInt64? to an equivalent Int64? value. + [CLSCompliant(false)] + public static Int64? ToNullableInt64(UInt64? p) { return p.HasValue ? checked((Int64?)p.Value) : (Int64?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Int64? value. + public static Int64? ToNullableInt64(Binary p) { return p == null || p.Length == 0 ? (Int64?)null : BitConverter.ToInt64(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Int64? value. + public static Int64? ToNullableInt64(Byte[] p) { return p == null || p.Length == 0 ? (Int64?)null : BitConverter.ToInt64(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Int64? value. + public static Int64? ToNullableInt64(SqlBoolean p) { return p.IsNull ? (Int64?)null : ToInt64(p.Value); } + /// Converts the value from SqlByte to an equivalent Int64? value. + public static Int64? ToNullableInt64(SqlByte p) { return p.IsNull ? (Int64?)null : p.Value; } + /// Converts the value from SqlDateTime to an equivalent Int64? value. + public static Int64? ToNullableInt64(SqlDateTime p) { return p.IsNull ? (Int64?)null : ToInt64(p.Value); } + /// Converts the value from SqlDecimal to an equivalent Int64? value. + public static Int64? ToNullableInt64(SqlDecimal p) { return p.IsNull ? (Int64?)null : ToInt64(p.Value); } + /// Converts the value from SqlDouble to an equivalent Int64? value. + public static Int64? ToNullableInt64(SqlDouble p) { return p.IsNull ? (Int64?)null : ToInt64(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Int64? value. + public static Int64? ToNullableInt64(SqlInt16 p) { return p.IsNull ? (Int64?)null : p.Value; } + /// Converts the value from SqlInt32 to an equivalent Int64? value. + public static Int64? ToNullableInt64(SqlInt32 p) { return p.IsNull ? (Int64?)null : p.Value; } + /// Converts the value from SqlInt64 to an equivalent Int64? value. + public static Int64? ToNullableInt64(SqlInt64 p) { return p.IsNull ? (Int64?)null : p.Value; } + /// Converts the value from SqlMoney to an equivalent Int64? value. + public static Int64? ToNullableInt64(SqlMoney p) { return p.IsNull ? (Int64?)null : ToInt64(p.Value); } + /// Converts the value from SqlSingle to an equivalent Int64? value. + public static Int64? ToNullableInt64(SqlSingle p) { return p.IsNull ? (Int64?)null : ToInt64(p.Value); } + /// Converts the value from SqlString to an equivalent Int64? value. + public static Int64? ToNullableInt64(SqlString p) { return p.IsNull ? (Int64?)null : ToInt64(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Int64? value. + public static Int64? ToNullableInt64(object p) + { + if (p == null) return null; + + if (p is Int64?) return (Int64?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.DateTime : return ToNullableInt64((DateTime)p); + case TypeCode.SByte : return ToNullableInt64((SByte) p); + case TypeCode.Int16 : return ToNullableInt64((Int16) p); + case TypeCode.Int32 : return ToNullableInt64((Int32) p); + case TypeCode.Int64 : return ToNullableInt64((Int64) p); + case TypeCode.Byte : return ToNullableInt64((Byte) p); + case TypeCode.UInt16 : return ToNullableInt64((UInt16) p); + case TypeCode.UInt32 : return ToNullableInt64((UInt32) p); + case TypeCode.Char : return ToNullableInt64((Char) p); + case TypeCode.UInt64 : return ToNullableInt64((UInt64) p); + case TypeCode.Single : return ToNullableInt64((Single) p); + case TypeCode.Double : return ToNullableInt64((Double) p); + case TypeCode.Decimal : return ToNullableInt64((Decimal) p); + case TypeCode.String : return ToNullableInt64((String) p); + case TypeCode.Boolean : return ToNullableInt64((Boolean) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToNullableInt64((DateTimeOffset) p); + if (p is TimeSpan) return ToNullableInt64((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToNullableInt64((Boolean?) p); + if (p is Byte?) return ToNullableInt64((Byte?) p); + if (p is Char?) return ToNullableInt64((Char?) p); + if (p is DateTime?) return ToNullableInt64((DateTime?) p); + if (p is DateTimeOffset?) return ToNullableInt64((DateTimeOffset?)p); + if (p is Decimal?) return ToNullableInt64((Decimal?) p); + if (p is Double?) return ToNullableInt64((Double?) p); + if (p is Int16?) return ToNullableInt64((Int16?) p); + if (p is Int32?) return ToNullableInt64((Int32?) p); + if (p is SByte?) return ToNullableInt64((SByte?) p); + if (p is Single?) return ToNullableInt64((Single?) p); + if (p is TimeSpan?) return ToNullableInt64((TimeSpan?) p); + if (p is UInt16?) return ToNullableInt64((UInt16?) p); + if (p is UInt32?) return ToNullableInt64((UInt32?) p); + if (p is UInt64?) return ToNullableInt64((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableInt64((Binary) p); + if (p is Byte[]) return ToNullableInt64((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableInt64((SqlBoolean) p); + if (p is SqlByte) return ToNullableInt64((SqlByte) p); + if (p is SqlDateTime) return ToNullableInt64((SqlDateTime) p); + if (p is SqlDecimal) return ToNullableInt64((SqlDecimal) p); + if (p is SqlDouble) return ToNullableInt64((SqlDouble) p); + if (p is SqlInt16) return ToNullableInt64((SqlInt16) p); + if (p is SqlInt32) return ToNullableInt64((SqlInt32) p); + if (p is SqlInt64) return ToNullableInt64((SqlInt64) p); + if (p is SqlMoney) return ToNullableInt64((SqlMoney) p); + if (p is SqlSingle) return ToNullableInt64((SqlSingle) p); + if (p is SqlString) return ToNullableInt64((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Int64?)); + } + + #endregion + + #region SByte? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Boolean p) { return p ? (SByte?)1 : (SByte?)0; } + /// Converts the value from Byte to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Byte p) { return checked((SByte?)p); } + /// Converts the value from Char to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Char p) { return checked((SByte?)p); } + /// Converts the value from Decimal to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Decimal p) { return checked((SByte?)p); } + /// Converts the value from Double to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Double p) { return checked((SByte?)p); } + /// Converts the value from Int16 to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Int16 p) { return checked((SByte?)p); } + /// Converts the value from Int32 to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Int32 p) { return checked((SByte?)p); } + /// Converts the value from Int64 to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Int64 p) { return checked((SByte?)p); } + /// Converts the value from SByte to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(SByte p) { return p; } + /// Converts the value from Single to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Single p) { return checked((SByte?)p); } + /// Converts the value from String to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(String p) { return p == null? (SByte?)null : SByte.Parse(p); } + /// Converts the value from UInt16 to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(UInt16 p) { return checked((SByte?)p); } + /// Converts the value from UInt32 to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(UInt32 p) { return checked((SByte?)p); } + /// Converts the value from UInt64 to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(UInt64 p) { return checked((SByte?)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Boolean? p) { return p.HasValue && p.Value ? (SByte?)1: (SByte?)0; } + /// Converts the value from Byte? to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Byte? p) { return p.HasValue ? checked((SByte?)p.Value) : (SByte?)null; } + /// Converts the value from Char? to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Char? p) { return p.HasValue ? checked((SByte?)p.Value) : (SByte?)null; } + /// Converts the value from Decimal? to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Decimal? p) { return p.HasValue ? checked((SByte?)p.Value) : (SByte?)null; } + /// Converts the value from Double? to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Double? p) { return p.HasValue ? checked((SByte?)p.Value) : (SByte?)null; } + /// Converts the value from Int16? to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Int16? p) { return p.HasValue ? checked((SByte?)p.Value) : (SByte?)null; } + /// Converts the value from Int32? to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Int32? p) { return p.HasValue ? checked((SByte?)p.Value) : (SByte?)null; } + /// Converts the value from Int64? to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Int64? p) { return p.HasValue ? checked((SByte?)p.Value) : (SByte?)null; } + /// Converts the value from Single? to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Single? p) { return p.HasValue ? checked((SByte?)p.Value) : (SByte?)null; } + /// Converts the value from UInt16? to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(UInt16? p) { return p.HasValue ? checked((SByte?)p.Value) : (SByte?)null; } + /// Converts the value from UInt32? to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(UInt32? p) { return p.HasValue ? checked((SByte?)p.Value) : (SByte?)null; } + /// Converts the value from UInt64? to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(UInt64? p) { return p.HasValue ? checked((SByte?)p.Value) : (SByte?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Binary p) { return p == null || p.Length == 0 ? (SByte?)null : checked((SByte?)p.ToArray()[0]); } + /// Converts the value from Byte[] to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(Byte[] p) { return p == null || p.Length == 0 ? (SByte?)null : checked((SByte?)p[0]); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(SqlBoolean p) { return p.IsNull ? (SByte?)null : ToSByte(p.Value); } + /// Converts the value from SqlByte to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(SqlByte p) { return p.IsNull ? (SByte?)null : ToSByte(p.Value); } + /// Converts the value from SqlDecimal to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(SqlDecimal p) { return p.IsNull ? (SByte?)null : ToSByte(p.Value); } + /// Converts the value from SqlDouble to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(SqlDouble p) { return p.IsNull ? (SByte?)null : ToSByte(p.Value); } + /// Converts the value from SqlInt16 to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(SqlInt16 p) { return p.IsNull ? (SByte?)null : ToSByte(p.Value); } + /// Converts the value from SqlInt32 to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(SqlInt32 p) { return p.IsNull ? (SByte?)null : ToSByte(p.Value); } + /// Converts the value from SqlInt64 to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(SqlInt64 p) { return p.IsNull ? (SByte?)null : ToSByte(p.Value); } + /// Converts the value from SqlMoney to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(SqlMoney p) { return p.IsNull ? (SByte?)null : ToSByte(p.Value); } + /// Converts the value from SqlSingle to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(SqlSingle p) { return p.IsNull ? (SByte?)null : ToSByte(p.Value); } + /// Converts the value from SqlString to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(SqlString p) { return p.IsNull ? (SByte?)null : ToSByte(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent SByte? value. + [CLSCompliant(false)] + public static SByte? ToNullableSByte(object p) + { + if (p == null) return null; + + if (p is SByte?) return (SByte?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.SByte : return ToNullableSByte((SByte) p); + case TypeCode.Int16 : return ToNullableSByte((Int16) p); + case TypeCode.Int32 : return ToNullableSByte((Int32) p); + case TypeCode.Int64 : return ToNullableSByte((Int64) p); + case TypeCode.Byte : return ToNullableSByte((Byte) p); + case TypeCode.UInt16 : return ToNullableSByte((UInt16) p); + case TypeCode.UInt32 : return ToNullableSByte((UInt32) p); + case TypeCode.UInt64 : return ToNullableSByte((UInt64) p); + case TypeCode.Single : return ToNullableSByte((Single) p); + case TypeCode.Double : return ToNullableSByte((Double) p); + case TypeCode.Decimal : return ToNullableSByte((Decimal)p); + case TypeCode.Char : return ToNullableSByte((Char) p); + case TypeCode.String : return ToNullableSByte((String) p); + case TypeCode.Boolean : return ToNullableSByte((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToNullableSByte((Boolean?) p); + if (p is Byte?) return ToNullableSByte((Byte?) p); + if (p is Char?) return ToNullableSByte((Char?) p); + if (p is Decimal?) return ToNullableSByte((Decimal?) p); + if (p is Double?) return ToNullableSByte((Double?) p); + if (p is Int16?) return ToNullableSByte((Int16?) p); + if (p is Int32?) return ToNullableSByte((Int32?) p); + if (p is Int64?) return ToNullableSByte((Int64?) p); + if (p is Single?) return ToNullableSByte((Single?) p); + if (p is UInt16?) return ToNullableSByte((UInt16?) p); + if (p is UInt32?) return ToNullableSByte((UInt32?) p); + if (p is UInt64?) return ToNullableSByte((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableSByte((Binary) p); + if (p is Byte[]) return ToNullableSByte((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableSByte((SqlBoolean)p); + if (p is SqlByte) return ToNullableSByte((SqlByte) p); + if (p is SqlDecimal) return ToNullableSByte((SqlDecimal)p); + if (p is SqlDouble) return ToNullableSByte((SqlDouble) p); + if (p is SqlInt16) return ToNullableSByte((SqlInt16) p); + if (p is SqlInt32) return ToNullableSByte((SqlInt32) p); + if (p is SqlInt64) return ToNullableSByte((SqlInt64) p); + if (p is SqlMoney) return ToNullableSByte((SqlMoney) p); + if (p is SqlSingle) return ToNullableSByte((SqlSingle) p); + if (p is SqlString) return ToNullableSByte((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(SByte?)); + } + + #endregion + + #region Single? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Single? value. + public static Single? ToNullableSingle(Boolean p) { return p ? (Single?)1 : (Single?)0; } + /// Converts the value from Byte to an equivalent Single? value. + public static Single? ToNullableSingle(Byte p) { return p; } + /// Converts the value from Char to an equivalent Single? value. + public static Single? ToNullableSingle(Char p) { return p; } + /// Converts the value from Decimal to an equivalent Single? value. + public static Single? ToNullableSingle(Decimal p) { return checked((Single?)p); } + /// Converts the value from Double to an equivalent Single? value. + public static Single? ToNullableSingle(Double p) { return checked((Single?)p); } + /// Converts the value from Int16 to an equivalent Single? value. + public static Single? ToNullableSingle(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent Single? value. + public static Single? ToNullableSingle(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent Single? value. + public static Single? ToNullableSingle(Int64 p) { return p; } + /// Converts the value from SByte to an equivalent Single? value. + [CLSCompliant(false)] + public static Single? ToNullableSingle(SByte p) { return p; } + /// Converts the value from Single to an equivalent Single? value. + public static Single? ToNullableSingle(Single p) { return p; } + /// Converts the value from String to an equivalent Single? value. + public static Single? ToNullableSingle(String p) { return p == null? (Single?)null : Single.Parse(p); } + /// Converts the value from UInt16 to an equivalent Single? value. + [CLSCompliant(false)] + public static Single? ToNullableSingle(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent Single? value. + [CLSCompliant(false)] + public static Single? ToNullableSingle(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent Single? value. + [CLSCompliant(false)] + public static Single? ToNullableSingle(UInt64 p) { return p; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Single? value. + public static Single? ToNullableSingle(Boolean? p) { return p.HasValue && p.Value ? (Single?)1: (Single?)0; } + /// Converts the value from Byte? to an equivalent Single? value. + public static Single? ToNullableSingle(Byte? p) { return p.HasValue ? p.Value : (Single?)null; } + /// Converts the value from Char? to an equivalent Single? value. + public static Single? ToNullableSingle(Char? p) { return p.HasValue ? p.Value : (Single?)null; } + /// Converts the value from Decimal? to an equivalent Single? value. + public static Single? ToNullableSingle(Decimal? p) { return p.HasValue ? checked((Single?)p.Value) : (Single?)null; } + /// Converts the value from Double? to an equivalent Single? value. + public static Single? ToNullableSingle(Double? p) { return p.HasValue ? checked((Single?)p.Value) : (Single?)null; } + /// Converts the value from Int16? to an equivalent Single? value. + public static Single? ToNullableSingle(Int16? p) { return p.HasValue ? p.Value : (Single?)null; } + /// Converts the value from Int32? to an equivalent Single? value. + public static Single? ToNullableSingle(Int32? p) { return p.HasValue ? p.Value : (Single?)null; } + /// Converts the value from Int64? to an equivalent Single? value. + public static Single? ToNullableSingle(Int64? p) { return p.HasValue ? p.Value : (Single?)null; } + /// Converts the value from SByte? to an equivalent Single? value. + [CLSCompliant(false)] + public static Single? ToNullableSingle(SByte? p) { return p.HasValue ? p.Value : (Single?)null; } + /// Converts the value from UInt16? to an equivalent Single? value. + [CLSCompliant(false)] + public static Single? ToNullableSingle(UInt16? p) { return p.HasValue ? p.Value : (Single?)null; } + /// Converts the value from UInt32? to an equivalent Single? value. + [CLSCompliant(false)] + public static Single? ToNullableSingle(UInt32? p) { return p.HasValue ? p.Value : (Single?)null; } + /// Converts the value from UInt64? to an equivalent Single? value. + [CLSCompliant(false)] + public static Single? ToNullableSingle(UInt64? p) { return p.HasValue ? p.Value : (Single?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Single? value. + public static Single? ToNullableSingle(Binary p) { return p == null || p.Length == 0 ? (Single?)null : BitConverter.ToSingle(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent Single? value. + public static Single? ToNullableSingle(Byte[] p) { return p == null || p.Length == 0 ? (Single?)null : BitConverter.ToSingle(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent Single? value. + public static Single? ToNullableSingle(SqlBoolean p) { return p.IsNull ? (Single?)null : ToSingle(p.Value); } + /// Converts the value from SqlByte to an equivalent Single? value. + public static Single? ToNullableSingle(SqlByte p) { return p.IsNull ? (Single?)null : p.Value; } + /// Converts the value from SqlDecimal to an equivalent Single? value. + public static Single? ToNullableSingle(SqlDecimal p) { return p.IsNull ? (Single?)null : ToSingle(p.Value); } + /// Converts the value from SqlDouble to an equivalent Single? value. + public static Single? ToNullableSingle(SqlDouble p) { return p.IsNull ? (Single?)null : ToSingle(p.Value); } + /// Converts the value from SqlInt16 to an equivalent Single? value. + public static Single? ToNullableSingle(SqlInt16 p) { return p.IsNull ? (Single?)null : p.Value; } + /// Converts the value from SqlInt32 to an equivalent Single? value. + public static Single? ToNullableSingle(SqlInt32 p) { return p.IsNull ? (Single?)null : p.Value; } + /// Converts the value from SqlInt64 to an equivalent Single? value. + public static Single? ToNullableSingle(SqlInt64 p) { return p.IsNull ? (Single?)null : p.Value; } + /// Converts the value from SqlMoney to an equivalent Single? value. + public static Single? ToNullableSingle(SqlMoney p) { return p.IsNull ? (Single?)null : ToSingle(p.Value); } + /// Converts the value from SqlSingle to an equivalent Single? value. + public static Single? ToNullableSingle(SqlSingle p) { return p.IsNull ? (Single?)null : p.Value; } + /// Converts the value from SqlString to an equivalent Single? value. + public static Single? ToNullableSingle(SqlString p) { return p.IsNull ? (Single?)null : ToSingle(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Single? value. + public static Single? ToNullableSingle(object p) + { + if (p == null) return null; + + if (p is Single?) return (Single?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.SByte : return ToNullableSingle((SByte) p); + case TypeCode.Int16 : return ToNullableSingle((Int16) p); + case TypeCode.Int32 : return ToNullableSingle((Int32) p); + case TypeCode.Int64 : return ToNullableSingle((Int64) p); + case TypeCode.Byte : return ToNullableSingle((Byte) p); + case TypeCode.UInt16 : return ToNullableSingle((UInt16) p); + case TypeCode.UInt32 : return ToNullableSingle((UInt32) p); + case TypeCode.Char : return ToNullableSingle((Char) p); + case TypeCode.UInt64 : return ToNullableSingle((UInt64) p); + case TypeCode.Single : return ToNullableSingle((Single) p); + case TypeCode.Double : return ToNullableSingle((Double) p); + case TypeCode.Decimal : return ToNullableSingle((Decimal)p); + case TypeCode.String : return ToNullableSingle((String) p); + case TypeCode.Boolean : return ToNullableSingle((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToNullableSingle((Boolean?) p); + if (p is Byte?) return ToNullableSingle((Byte?) p); + if (p is Char?) return ToNullableSingle((Char?) p); + if (p is Decimal?) return ToNullableSingle((Decimal?) p); + if (p is Double?) return ToNullableSingle((Double?) p); + if (p is Int16?) return ToNullableSingle((Int16?) p); + if (p is Int32?) return ToNullableSingle((Int32?) p); + if (p is Int64?) return ToNullableSingle((Int64?) p); + if (p is SByte?) return ToNullableSingle((SByte?) p); + if (p is UInt16?) return ToNullableSingle((UInt16?) p); + if (p is UInt32?) return ToNullableSingle((UInt32?) p); + if (p is UInt64?) return ToNullableSingle((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableSingle((Binary) p); + if (p is Byte[]) return ToNullableSingle((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableSingle((SqlBoolean)p); + if (p is SqlByte) return ToNullableSingle((SqlByte) p); + if (p is SqlDecimal) return ToNullableSingle((SqlDecimal)p); + if (p is SqlDouble) return ToNullableSingle((SqlDouble) p); + if (p is SqlInt16) return ToNullableSingle((SqlInt16) p); + if (p is SqlInt32) return ToNullableSingle((SqlInt32) p); + if (p is SqlInt64) return ToNullableSingle((SqlInt64) p); + if (p is SqlMoney) return ToNullableSingle((SqlMoney) p); + if (p is SqlSingle) return ToNullableSingle((SqlSingle) p); + if (p is SqlString) return ToNullableSingle((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Single?)); + } + + #endregion + + #region TimeSpan? + + // Simple Types + // + /// Converts the value from DateTime to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(DateTime p) { return p - DateTime.MinValue; } + /// Converts the value from DateTimeOffset to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(DateTimeOffset p) { return p - DateTimeOffset.MinValue; } + /// Converts the value from Double to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(Double p) { return TimeSpan.FromDays (p); } + /// Converts the value from Int64 to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(Int64 p) { return TimeSpan.FromTicks(p); } + /// Converts the value from String to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(String p) { return p == null? (TimeSpan?)null : TimeSpan.Parse(p); } + /// Converts the value from TimeSpan to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(TimeSpan p) { return p; } + + // Nullable Types + // + /// Converts the value from DateTime? to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(DateTime? p) { return p.HasValue ? p.Value - DateTime.MinValue : (TimeSpan?)null; } + /// Converts the value from DateTimeOffset? to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(DateTimeOffset? p) { return p.HasValue ? p.Value - DateTimeOffset.MinValue : (TimeSpan?)null; } + /// Converts the value from Double? to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(Double? p) { return p.HasValue ? TimeSpan.FromDays (p.Value) : (TimeSpan?)null; } + /// Converts the value from Int64? to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(Int64? p) { return p.HasValue ? TimeSpan.FromTicks(p.Value) : (TimeSpan?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(Binary p) { return p == null || p.Length == 0? (TimeSpan?)null : TimeSpan.FromTicks(ToInt64(p.ToArray())); } + /// Converts the value from Byte[] to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(Byte[] p) { return p == null || p.Length == 0? (TimeSpan?)null : TimeSpan.FromTicks(ToInt64(p)); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlDateTime to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(SqlDateTime p) { return p.IsNull ? (TimeSpan?)null : p.Value - DateTime.MinValue; } + /// Converts the value from SqlDouble to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(SqlDouble p) { return p.IsNull ? (TimeSpan?)null : TimeSpan.FromDays(p.Value); } + /// Converts the value from SqlInt64 to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(SqlInt64 p) { return p.IsNull ? (TimeSpan?)null : TimeSpan.FromTicks(p.Value); } + /// Converts the value from SqlString to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(SqlString p) { return p.IsNull ? (TimeSpan?)null : TimeSpan.Parse(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent TimeSpan? value. + public static TimeSpan? ToNullableTimeSpan(object p) + { + if (p == null) return null; + + if (p is TimeSpan?) return (TimeSpan?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.DateTime : return ToNullableTimeSpan((DateTime) p); + case TypeCode.Int64 : return ToNullableTimeSpan((Int64) p); + case TypeCode.Double : return ToNullableTimeSpan((Double) p); + case TypeCode.String : return ToNullableTimeSpan((String) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToNullableTimeSpan((DateTimeOffset) p); + if (p is TimeSpan) return ToNullableTimeSpan((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is DateTime?) return ToNullableTimeSpan((DateTime?) p); + if (p is DateTimeOffset?) return ToNullableTimeSpan((DateTimeOffset?)p); + if (p is Double?) return ToNullableTimeSpan((Double?) p); + if (p is Int64?) return ToNullableTimeSpan((Int64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableTimeSpan((Binary) p); + if (p is Byte[]) return ToNullableTimeSpan((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlDateTime) return ToNullableTimeSpan((SqlDateTime) p); + if (p is SqlDouble) return ToNullableTimeSpan((SqlDouble) p); + if (p is SqlInt64) return ToNullableTimeSpan((SqlInt64) p); + if (p is SqlString) return ToNullableTimeSpan((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(TimeSpan?)); + } + + #endregion + + #region UInt16? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Boolean p) { return p ? (UInt16?)1 : (UInt16?)0; } + /// Converts the value from Byte to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Byte p) { return p; } + /// Converts the value from Char to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Char p) { return checked((UInt16?)p); } + /// Converts the value from Decimal to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Decimal p) { return checked((UInt16?)p); } + /// Converts the value from Double to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Double p) { return checked((UInt16?)p); } + /// Converts the value from Int16 to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Int16 p) { return checked((UInt16?)p); } + /// Converts the value from Int32 to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Int32 p) { return checked((UInt16?)p); } + /// Converts the value from Int64 to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Int64 p) { return checked((UInt16?)p); } + /// Converts the value from SByte to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(SByte p) { return checked((UInt16?)p); } + /// Converts the value from Single to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Single p) { return checked((UInt16?)p); } + /// Converts the value from String to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(String p) { return p == null? (UInt16?)null : UInt16.Parse(p); } + /// Converts the value from UInt16 to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(UInt32 p) { return checked((UInt16?)p); } + /// Converts the value from UInt64 to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(UInt64 p) { return checked((UInt16?)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Boolean? p) { return p.HasValue && p.Value ? (UInt16?)1: (UInt16?)0; } + /// Converts the value from Byte? to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Byte? p) { return p.HasValue ? p.Value : (UInt16?)null; } + /// Converts the value from Char? to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Char? p) { return p.HasValue ? checked((UInt16?)p.Value) : (UInt16?)null; } + /// Converts the value from Decimal? to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Decimal? p) { return p.HasValue ? checked((UInt16?)p.Value) : (UInt16?)null; } + /// Converts the value from Double? to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Double? p) { return p.HasValue ? checked((UInt16?)p.Value) : (UInt16?)null; } + /// Converts the value from Int16? to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Int16? p) { return p.HasValue ? checked((UInt16?)p.Value) : (UInt16?)null; } + /// Converts the value from Int32? to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Int32? p) { return p.HasValue ? checked((UInt16?)p.Value) : (UInt16?)null; } + /// Converts the value from Int64? to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Int64? p) { return p.HasValue ? checked((UInt16?)p.Value) : (UInt16?)null; } + /// Converts the value from SByte? to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(SByte? p) { return p.HasValue ? checked((UInt16?)p.Value) : (UInt16?)null; } + /// Converts the value from Single? to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Single? p) { return p.HasValue ? checked((UInt16?)p.Value) : (UInt16?)null; } + /// Converts the value from UInt32? to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(UInt32? p) { return p.HasValue ? checked((UInt16?)p.Value) : (UInt16?)null; } + /// Converts the value from UInt64? to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(UInt64? p) { return p.HasValue ? checked((UInt16?)p.Value) : (UInt16?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Binary p) { return p == null || p.Length == 0 ? (UInt16?)null : BitConverter.ToUInt16(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(Byte[] p) { return p == null || p.Length == 0 ? (UInt16?)null : BitConverter.ToUInt16(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(SqlBoolean p) { return p.IsNull ? (UInt16?)null : ToUInt16(p.Value); } + /// Converts the value from SqlByte to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(SqlByte p) { return p.IsNull ? (UInt16?)null : p.Value; } + /// Converts the value from SqlDecimal to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(SqlDecimal p) { return p.IsNull ? (UInt16?)null : ToUInt16(p.Value); } + /// Converts the value from SqlDouble to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(SqlDouble p) { return p.IsNull ? (UInt16?)null : ToUInt16(p.Value); } + /// Converts the value from SqlInt16 to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(SqlInt16 p) { return p.IsNull ? (UInt16?)null : ToUInt16(p.Value); } + /// Converts the value from SqlInt32 to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(SqlInt32 p) { return p.IsNull ? (UInt16?)null : ToUInt16(p.Value); } + /// Converts the value from SqlInt64 to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(SqlInt64 p) { return p.IsNull ? (UInt16?)null : ToUInt16(p.Value); } + /// Converts the value from SqlMoney to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(SqlMoney p) { return p.IsNull ? (UInt16?)null : ToUInt16(p.Value); } + /// Converts the value from SqlSingle to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(SqlSingle p) { return p.IsNull ? (UInt16?)null : ToUInt16(p.Value); } + /// Converts the value from SqlString to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(SqlString p) { return p.IsNull ? (UInt16?)null : ToUInt16(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent UInt16? value. + [CLSCompliant(false)] + public static UInt16? ToNullableUInt16(object p) + { + if (p == null) return null; + + if (p is UInt16?) return (UInt16?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.UInt16 : return ToNullableUInt16((UInt16) p); + case TypeCode.Byte : return ToNullableUInt16((Byte) p); + case TypeCode.SByte : return ToNullableUInt16((SByte) p); + case TypeCode.Int16 : return ToNullableUInt16((Int16) p); + case TypeCode.Int32 : return ToNullableUInt16((Int32) p); + case TypeCode.Int64 : return ToNullableUInt16((Int64) p); + case TypeCode.UInt32 : return ToNullableUInt16((UInt32) p); + case TypeCode.UInt64 : return ToNullableUInt16((UInt64) p); + case TypeCode.Single : return ToNullableUInt16((Single) p); + case TypeCode.Double : return ToNullableUInt16((Double) p); + case TypeCode.Decimal : return ToNullableUInt16((Decimal)p); + case TypeCode.Char : return ToNullableUInt16((Char) p); + case TypeCode.String : return ToNullableUInt16((String) p); + case TypeCode.Boolean : return ToNullableUInt16((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToNullableUInt16((Boolean?) p); + if (p is Byte?) return ToNullableUInt16((Byte?) p); + if (p is Char?) return ToNullableUInt16((Char?) p); + if (p is Decimal?) return ToNullableUInt16((Decimal?) p); + if (p is Double?) return ToNullableUInt16((Double?) p); + if (p is Int16?) return ToNullableUInt16((Int16?) p); + if (p is Int32?) return ToNullableUInt16((Int32?) p); + if (p is Int64?) return ToNullableUInt16((Int64?) p); + if (p is SByte?) return ToNullableUInt16((SByte?) p); + if (p is Single?) return ToNullableUInt16((Single?) p); + if (p is UInt32?) return ToNullableUInt16((UInt32?) p); + if (p is UInt64?) return ToNullableUInt16((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableUInt16((Binary) p); + if (p is Byte[]) return ToNullableUInt16((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableUInt16((SqlBoolean)p); + if (p is SqlByte) return ToNullableUInt16((SqlByte) p); + if (p is SqlDecimal) return ToNullableUInt16((SqlDecimal)p); + if (p is SqlDouble) return ToNullableUInt16((SqlDouble) p); + if (p is SqlInt16) return ToNullableUInt16((SqlInt16) p); + if (p is SqlInt32) return ToNullableUInt16((SqlInt32) p); + if (p is SqlInt64) return ToNullableUInt16((SqlInt64) p); + if (p is SqlMoney) return ToNullableUInt16((SqlMoney) p); + if (p is SqlSingle) return ToNullableUInt16((SqlSingle) p); + if (p is SqlString) return ToNullableUInt16((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(UInt16?)); + } + + #endregion + + #region UInt32? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Boolean p) { return p ? (UInt32?)1 : (UInt32?)0; } + /// Converts the value from Byte to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Byte p) { return p; } + /// Converts the value from Char to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Char p) { return checked((UInt32?)p); } + /// Converts the value from Decimal to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Decimal p) { return checked((UInt32?)p); } + /// Converts the value from Double to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Double p) { return checked((UInt32?)p); } + /// Converts the value from Int16 to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Int16 p) { return checked((UInt32?)p); } + /// Converts the value from Int32 to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Int32 p) { return checked((UInt32?)p); } + /// Converts the value from Int64 to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Int64 p) { return checked((UInt32?)p); } + /// Converts the value from SByte to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(SByte p) { return checked((UInt32?)p); } + /// Converts the value from Single to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Single p) { return checked((UInt32?)p); } + /// Converts the value from String to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(String p) { return p == null? (UInt32?)null : UInt32.Parse(p); } + /// Converts the value from UInt16 to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(UInt64 p) { return checked((UInt32?)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Boolean? p) { return p.HasValue && p.Value ? (UInt32?)1: (UInt32?)0; } + /// Converts the value from Byte? to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Byte? p) { return p.HasValue ? p.Value : (UInt32?)null; } + /// Converts the value from Char? to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Char? p) { return p.HasValue ? checked((UInt32?)p.Value) : (UInt32?)null; } + /// Converts the value from Decimal? to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Decimal? p) { return p.HasValue ? checked((UInt32?)p.Value) : (UInt32?)null; } + /// Converts the value from Double? to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Double? p) { return p.HasValue ? checked((UInt32?)p.Value) : (UInt32?)null; } + /// Converts the value from Int16? to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Int16? p) { return p.HasValue ? checked((UInt32?)p.Value) : (UInt32?)null; } + /// Converts the value from Int32? to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Int32? p) { return p.HasValue ? checked((UInt32?)p.Value) : (UInt32?)null; } + /// Converts the value from Int64? to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Int64? p) { return p.HasValue ? checked((UInt32?)p.Value) : (UInt32?)null; } + /// Converts the value from SByte? to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(SByte? p) { return p.HasValue ? checked((UInt32?)p.Value) : (UInt32?)null; } + /// Converts the value from Single? to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Single? p) { return p.HasValue ? checked((UInt32?)p.Value) : (UInt32?)null; } + /// Converts the value from UInt16? to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(UInt16? p) { return p.HasValue ? p.Value : (UInt32?)null; } + /// Converts the value from UInt64? to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(UInt64? p) { return p.HasValue ? checked((UInt32?)p.Value) : (UInt32?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Binary p) { return p == null || p.Length == 0 ? (UInt32?)null : BitConverter.ToUInt32(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(Byte[] p) { return p == null || p.Length == 0 ? (UInt32?)null : BitConverter.ToUInt32(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(SqlBoolean p) { return p.IsNull ? (UInt32?)null : ToUInt32(p.Value); } + /// Converts the value from SqlByte to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(SqlByte p) { return p.IsNull ? (UInt32?)null : p.Value; } + /// Converts the value from SqlDecimal to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(SqlDecimal p) { return p.IsNull ? (UInt32?)null : ToUInt32(p.Value); } + /// Converts the value from SqlDouble to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(SqlDouble p) { return p.IsNull ? (UInt32?)null : ToUInt32(p.Value); } + /// Converts the value from SqlInt16 to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(SqlInt16 p) { return p.IsNull ? (UInt32?)null : ToUInt32(p.Value); } + /// Converts the value from SqlInt32 to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(SqlInt32 p) { return p.IsNull ? (UInt32?)null : ToUInt32(p.Value); } + /// Converts the value from SqlInt64 to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(SqlInt64 p) { return p.IsNull ? (UInt32?)null : ToUInt32(p.Value); } + /// Converts the value from SqlMoney to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(SqlMoney p) { return p.IsNull ? (UInt32?)null : ToUInt32(p.Value); } + /// Converts the value from SqlSingle to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(SqlSingle p) { return p.IsNull ? (UInt32?)null : ToUInt32(p.Value); } + /// Converts the value from SqlString to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(SqlString p) { return p.IsNull ? (UInt32?)null : ToUInt32(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent UInt32? value. + [CLSCompliant(false)] + public static UInt32? ToNullableUInt32(object p) + { + if (p == null) return null; + + if (p is UInt32?) return (UInt32?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.Byte : return ToNullableUInt32((Byte) p); + case TypeCode.UInt16 : return ToNullableUInt32((UInt16) p); + case TypeCode.UInt32 : return ToNullableUInt32((UInt32) p); + case TypeCode.SByte : return ToNullableUInt32((SByte) p); + case TypeCode.Int16 : return ToNullableUInt32((Int16) p); + case TypeCode.Int32 : return ToNullableUInt32((Int32) p); + case TypeCode.Int64 : return ToNullableUInt32((Int64) p); + case TypeCode.UInt64 : return ToNullableUInt32((UInt64) p); + case TypeCode.Single : return ToNullableUInt32((Single) p); + case TypeCode.Double : return ToNullableUInt32((Double) p); + case TypeCode.Decimal : return ToNullableUInt32((Decimal)p); + case TypeCode.Char : return ToNullableUInt32((Char) p); + case TypeCode.String : return ToNullableUInt32((String) p); + case TypeCode.Boolean : return ToNullableUInt32((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToNullableUInt32((Boolean?) p); + if (p is Byte?) return ToNullableUInt32((Byte?) p); + if (p is Char?) return ToNullableUInt32((Char?) p); + if (p is Decimal?) return ToNullableUInt32((Decimal?) p); + if (p is Double?) return ToNullableUInt32((Double?) p); + if (p is Int16?) return ToNullableUInt32((Int16?) p); + if (p is Int32?) return ToNullableUInt32((Int32?) p); + if (p is Int64?) return ToNullableUInt32((Int64?) p); + if (p is SByte?) return ToNullableUInt32((SByte?) p); + if (p is Single?) return ToNullableUInt32((Single?) p); + if (p is UInt16?) return ToNullableUInt32((UInt16?) p); + if (p is UInt64?) return ToNullableUInt32((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableUInt32((Binary) p); + if (p is Byte[]) return ToNullableUInt32((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableUInt32((SqlBoolean)p); + if (p is SqlByte) return ToNullableUInt32((SqlByte) p); + if (p is SqlDecimal) return ToNullableUInt32((SqlDecimal)p); + if (p is SqlDouble) return ToNullableUInt32((SqlDouble) p); + if (p is SqlInt16) return ToNullableUInt32((SqlInt16) p); + if (p is SqlInt32) return ToNullableUInt32((SqlInt32) p); + if (p is SqlInt64) return ToNullableUInt32((SqlInt64) p); + if (p is SqlMoney) return ToNullableUInt32((SqlMoney) p); + if (p is SqlSingle) return ToNullableUInt32((SqlSingle) p); + if (p is SqlString) return ToNullableUInt32((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(UInt32?)); + } + + #endregion + + #region UInt64? + + // Simple Types + // + /// Converts the value from Boolean to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Boolean p) { return p ? (UInt64?)1 : (UInt64?)0; } + /// Converts the value from Byte to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Byte p) { return p; } + /// Converts the value from Char to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Char p) { return checked((UInt64?)p); } + /// Converts the value from Decimal to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Decimal p) { return checked((UInt64?)p); } + /// Converts the value from Double to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Double p) { return checked((UInt64?)p); } + /// Converts the value from Int16 to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Int16 p) { return checked((UInt64?)p); } + /// Converts the value from Int32 to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Int32 p) { return checked((UInt64?)p); } + /// Converts the value from Int64 to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Int64 p) { return checked((UInt64?)p); } + /// Converts the value from SByte to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(SByte p) { return checked((UInt64?)p); } + /// Converts the value from Single to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Single p) { return checked((UInt64?)p); } + /// Converts the value from String to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(String p) { return p == null? (UInt64?)null : UInt64.Parse(p); } + /// Converts the value from UInt16 to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(UInt64 p) { return p; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Boolean? p) { return p.HasValue && p.Value ? (UInt64?)1: (UInt64?)0; } + /// Converts the value from Byte? to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Byte? p) { return p.HasValue ? p.Value : (UInt64?)null; } + /// Converts the value from Char? to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Char? p) { return p.HasValue ? checked((UInt64?)p.Value) : (UInt64?)null; } + /// Converts the value from Decimal? to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Decimal? p) { return p.HasValue ? checked((UInt64?)p.Value) : (UInt64?)null; } + /// Converts the value from Double? to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Double? p) { return p.HasValue ? checked((UInt64?)p.Value) : (UInt64?)null; } + /// Converts the value from Int16? to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Int16? p) { return p.HasValue ? checked((UInt64?)p.Value) : (UInt64?)null; } + /// Converts the value from Int32? to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Int32? p) { return p.HasValue ? checked((UInt64?)p.Value) : (UInt64?)null; } + /// Converts the value from Int64? to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Int64? p) { return p.HasValue ? checked((UInt64?)p.Value) : (UInt64?)null; } + /// Converts the value from SByte? to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(SByte? p) { return p.HasValue ? checked((UInt64?)p.Value) : (UInt64?)null; } + /// Converts the value from Single? to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Single? p) { return p.HasValue ? checked((UInt64?)p.Value) : (UInt64?)null; } + /// Converts the value from UInt16? to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(UInt16? p) { return p.HasValue ? p.Value : (UInt64?)null; } + /// Converts the value from UInt32? to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(UInt32? p) { return p.HasValue ? p.Value : (UInt64?)null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Binary p) { return p == null || p.Length == 0 ? (UInt64?)null : BitConverter.ToUInt64(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(Byte[] p) { return p == null || p.Length == 0 ? (UInt64?)null : BitConverter.ToUInt64(p, 0); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(SqlBoolean p) { return p.IsNull ? (UInt64?)null : ToUInt64(p.Value); } + /// Converts the value from SqlByte to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(SqlByte p) { return p.IsNull ? (UInt64?)null : p.Value; } + /// Converts the value from SqlDecimal to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(SqlDecimal p) { return p.IsNull ? (UInt64?)null : ToUInt64(p.Value); } + /// Converts the value from SqlDouble to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(SqlDouble p) { return p.IsNull ? (UInt64?)null : ToUInt64(p.Value); } + /// Converts the value from SqlInt16 to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(SqlInt16 p) { return p.IsNull ? (UInt64?)null : ToUInt64(p.Value); } + /// Converts the value from SqlInt32 to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(SqlInt32 p) { return p.IsNull ? (UInt64?)null : ToUInt64(p.Value); } + /// Converts the value from SqlInt64 to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(SqlInt64 p) { return p.IsNull ? (UInt64?)null : ToUInt64(p.Value); } + /// Converts the value from SqlMoney to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(SqlMoney p) { return p.IsNull ? (UInt64?)null : ToUInt64(p.Value); } + /// Converts the value from SqlSingle to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(SqlSingle p) { return p.IsNull ? (UInt64?)null : ToUInt64(p.Value); } + /// Converts the value from SqlString to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(SqlString p) { return p.IsNull ? (UInt64?)null : ToUInt64(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent UInt64? value. + [CLSCompliant(false)] + public static UInt64? ToNullableUInt64(object p) + { + if (p == null) return null; + + if (p is UInt64?) return (UInt64?)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.Byte : return ToNullableUInt64((Byte) p); + case TypeCode.UInt16 : return ToNullableUInt64((UInt16) p); + case TypeCode.UInt32 : return ToNullableUInt64((UInt32) p); + case TypeCode.UInt64 : return ToNullableUInt64((UInt64) p); + case TypeCode.SByte : return ToNullableUInt64((SByte) p); + case TypeCode.Int16 : return ToNullableUInt64((Int16) p); + case TypeCode.Int32 : return ToNullableUInt64((Int32) p); + case TypeCode.Int64 : return ToNullableUInt64((Int64) p); + case TypeCode.Single : return ToNullableUInt64((Single) p); + case TypeCode.Double : return ToNullableUInt64((Double) p); + case TypeCode.Decimal : return ToNullableUInt64((Decimal)p); + case TypeCode.Char : return ToNullableUInt64((Char) p); + case TypeCode.String : return ToNullableUInt64((String) p); + case TypeCode.Boolean : return ToNullableUInt64((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToNullableUInt64((Boolean?) p); + if (p is Byte?) return ToNullableUInt64((Byte?) p); + if (p is Char?) return ToNullableUInt64((Char?) p); + if (p is Decimal?) return ToNullableUInt64((Decimal?) p); + if (p is Double?) return ToNullableUInt64((Double?) p); + if (p is Int16?) return ToNullableUInt64((Int16?) p); + if (p is Int32?) return ToNullableUInt64((Int32?) p); + if (p is Int64?) return ToNullableUInt64((Int64?) p); + if (p is SByte?) return ToNullableUInt64((SByte?) p); + if (p is Single?) return ToNullableUInt64((Single?) p); + if (p is UInt16?) return ToNullableUInt64((UInt16?) p); + if (p is UInt32?) return ToNullableUInt64((UInt32?) p); + } + + // Other Types + // + if (p is Binary) return ToNullableUInt64((Binary) p); + if (p is Byte[]) return ToNullableUInt64((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToNullableUInt64((SqlBoolean)p); + if (p is SqlByte) return ToNullableUInt64((SqlByte) p); + if (p is SqlDecimal) return ToNullableUInt64((SqlDecimal)p); + if (p is SqlDouble) return ToNullableUInt64((SqlDouble) p); + if (p is SqlInt16) return ToNullableUInt64((SqlInt16) p); + if (p is SqlInt32) return ToNullableUInt64((SqlInt32) p); + if (p is SqlInt64) return ToNullableUInt64((SqlInt64) p); + if (p is SqlMoney) return ToNullableUInt64((SqlMoney) p); + if (p is SqlSingle) return ToNullableUInt64((SqlSingle) p); + if (p is SqlString) return ToNullableUInt64((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(UInt64?)); + } + + #endregion + + #endregion + + #region Sql Types + + #region SqlBinary + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Guid to an equivalent SqlBinary value. + public static SqlBinary ToSqlBinary(Guid p) { return p == Guid.Empty? SqlBinary.Null : new SqlGuid(p).ToSqlBinary(); } + + // Nullable Types + // + /// Converts the value from Guid? to an equivalent SqlBinary value. + public static SqlBinary ToSqlBinary(Guid? p) { return p.HasValue ? new SqlGuid(p.Value).ToSqlBinary(): SqlBinary.Null; } + + // Sql Types + // + /// Converts the value from SqlBytes to an equivalent SqlBinary value. + public static SqlBinary ToSqlBinary(SqlBytes p) { return p.ToSqlBinary(); } + /// Converts the value from SqlGuid to an equivalent SqlBinary value. + public static SqlBinary ToSqlBinary(SqlGuid p) { return p.ToSqlBinary(); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlBinary value. + public static SqlBinary ToSqlBinary(Binary p) { return p == null ? SqlBinary.Null : p.ToArray(); } + /// Converts the value from Byte[] to an equivalent SqlBinary value. + public static SqlBinary ToSqlBinary(Byte[] p) { return p; } + + // From Object + // + /// Converts the value from Object to an equivalent SqlBinary value. + public static SqlBinary ToSqlBinary(object p) + { + if (p == null || p is DBNull) return SqlBinary.Null; + + if (p is SqlBinary) return (SqlBinary)p; + + // Simple Types + // + if (p is Guid) return ToSqlBinary((Guid) p); + + // Nullable Types + // + var type = p.GetType(); + + if (type.IsGenericType) + { + if (p is Guid?) return ToSqlBinary((Guid?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBytes) return ToSqlBinary((SqlBytes)p); + if (p is SqlGuid) return ToSqlBinary((SqlGuid) p); + } + + // Other Types + // + if (p is Binary) return ToSqlBinary((Binary) p); + if (p is Byte[]) return ToSqlBinary((Byte[]) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlBinary)); + } + +#endif + + #endregion + + #region SqlBoolean + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Boolean p) { return p; } + /// Converts the value from Byte to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Byte p) { return p != 0; } + /// Converts the value from Char to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Char p) { return ToBoolean(p); } + /// Converts the value from Decimal to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Decimal p) { return p != 0; } + /// Converts the value from Double to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Double p) { return p != 0; } + /// Converts the value from Int16 to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Int16 p) { return p != 0; } + /// Converts the value from Int32 to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Int32 p) { return p != 0; } + /// Converts the value from Int64 to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Int64 p) { return p != 0; } + /// Converts the value from SByte to an equivalent SqlBoolean value. + [CLSCompliant(false)] + public static SqlBoolean ToSqlBoolean(SByte p) { return p != 0; } + /// Converts the value from Single to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Single p) { return p != 0; } + /// Converts the value from String to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(String p) { return p == null? SqlBoolean.Null : p.Length == 1 ? ToBoolean(p[0]) : Boolean.Parse(p); } + /// Converts the value from UInt16 to an equivalent SqlBoolean value. + [CLSCompliant(false)] + public static SqlBoolean ToSqlBoolean(UInt16 p) { return p != 0; } + /// Converts the value from UInt32 to an equivalent SqlBoolean value. + [CLSCompliant(false)] + public static SqlBoolean ToSqlBoolean(UInt32 p) { return p != 0; } + /// Converts the value from UInt64 to an equivalent SqlBoolean value. + [CLSCompliant(false)] + public static SqlBoolean ToSqlBoolean(UInt64 p) { return p != 0; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Boolean? p) { return p.HasValue ? p.Value : SqlBoolean.Null; } + /// Converts the value from Byte? to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Byte? p) { return p.HasValue ? p.Value != 0 : SqlBoolean.Null; } + /// Converts the value from Char? to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Char? p) { return p.HasValue && ToBoolean(p.Value); } + /// Converts the value from Decimal? to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Decimal? p) { return p.HasValue ? p.Value != 0 : SqlBoolean.Null; } + /// Converts the value from Double? to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Double? p) { return p.HasValue ? p.Value != 0 : SqlBoolean.Null; } + /// Converts the value from Int16? to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Int16? p) { return p.HasValue ? p.Value != 0 : SqlBoolean.Null; } + /// Converts the value from Int32? to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Int32? p) { return p.HasValue ? p.Value != 0 : SqlBoolean.Null; } + /// Converts the value from Int64? to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Int64? p) { return p.HasValue ? p.Value != 0 : SqlBoolean.Null; } + /// Converts the value from SByte? to an equivalent SqlBoolean value. + [CLSCompliant(false)] + public static SqlBoolean ToSqlBoolean(SByte? p) { return p.HasValue ? p.Value != 0 : SqlBoolean.Null; } + /// Converts the value from Single? to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Single? p) { return p.HasValue ? p.Value != 0 : SqlBoolean.Null; } + /// Converts the value from UInt16? to an equivalent SqlBoolean value. + [CLSCompliant(false)] + public static SqlBoolean ToSqlBoolean(UInt16? p) { return p.HasValue ? p.Value != 0 : SqlBoolean.Null; } + /// Converts the value from UInt32? to an equivalent SqlBoolean value. + [CLSCompliant(false)] + public static SqlBoolean ToSqlBoolean(UInt32? p) { return p.HasValue ? p.Value != 0 : SqlBoolean.Null; } + /// Converts the value from UInt64? to an equivalent SqlBoolean value. + [CLSCompliant(false)] + public static SqlBoolean ToSqlBoolean(UInt64? p) { return p.HasValue ? p.Value != 0 : SqlBoolean.Null; } + + // Sql Types + // + /// Converts the value from SqlByte to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(SqlByte p) { return p.IsNull ? SqlBoolean.Null : ToBoolean(p.Value); } + /// Converts the value from SqlDecimal to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(SqlDecimal p) { return p.IsNull ? SqlBoolean.Null : ToBoolean(p.Value); } + /// Converts the value from SqlDouble to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(SqlDouble p) { return p.IsNull ? SqlBoolean.Null : ToBoolean(p.Value); } + /// Converts the value from SqlInt16 to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(SqlInt16 p) { return p.IsNull ? SqlBoolean.Null : ToBoolean(p.Value); } + /// Converts the value from SqlInt32 to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(SqlInt32 p) { return p.IsNull ? SqlBoolean.Null : ToBoolean(p.Value); } + /// Converts the value from SqlInt64 to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(SqlInt64 p) { return p.IsNull ? SqlBoolean.Null : ToBoolean(p.Value); } + /// Converts the value from SqlMoney to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(SqlMoney p) { return p.IsNull ? SqlBoolean.Null : ToBoolean(p.Value); } + /// Converts the value from SqlSingle to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(SqlSingle p) { return p.IsNull ? SqlBoolean.Null : ToBoolean(p.Value); } + /// Converts the value from SqlString to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(SqlString p) { return p.IsNull ? SqlBoolean.Null : ToBoolean(p.Value); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Binary p) { return p == null || p.Length == 0 ? SqlBoolean.Null : BitConverter.ToBoolean(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(Byte[] p) { return p == null || p.Length == 0 ? SqlBoolean.Null : BitConverter.ToBoolean(p, 0); } + + // From Object + // + /// Converts the value from Object to an equivalent SqlBoolean value. + public static SqlBoolean ToSqlBoolean(object p) + { + if (p == null) return SqlBoolean.Null; + + if (p is SqlBoolean) return (SqlBoolean)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlBoolean.Null; + case TypeCode.String : return ToSqlBoolean((String) p); + case TypeCode.Boolean : return ToSqlBoolean((Boolean) p); + case TypeCode.Char : return ToSqlBoolean((Char) p); + case TypeCode.SByte : return ToSqlBoolean((SByte) p); + case TypeCode.Int16 : return ToSqlBoolean((Int16) p); + case TypeCode.Int32 : return ToSqlBoolean((Int32) p); + case TypeCode.Int64 : return ToSqlBoolean((Int64) p); + case TypeCode.Byte : return ToSqlBoolean((Byte) p); + case TypeCode.UInt16 : return ToSqlBoolean((UInt16) p); + case TypeCode.UInt32 : return ToSqlBoolean((UInt32) p); + case TypeCode.UInt64 : return ToSqlBoolean((UInt64) p); + case TypeCode.Single : return ToSqlBoolean((Single) p); + case TypeCode.Double : return ToSqlBoolean((Double) p); + case TypeCode.Decimal : return ToSqlBoolean((Decimal) p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSqlBoolean((Boolean?) p); + if (p is Byte?) return ToSqlBoolean((Byte?) p); + if (p is Char?) return ToSqlBoolean((Char?) p); + if (p is Decimal?) return ToSqlBoolean((Decimal?) p); + if (p is Double?) return ToSqlBoolean((Double?) p); + if (p is Int16?) return ToSqlBoolean((Int16?) p); + if (p is Int32?) return ToSqlBoolean((Int32?) p); + if (p is Int64?) return ToSqlBoolean((Int64?) p); + if (p is SByte?) return ToSqlBoolean((SByte?) p); + if (p is Single?) return ToSqlBoolean((Single?) p); + if (p is UInt16?) return ToSqlBoolean((UInt16?) p); + if (p is UInt32?) return ToSqlBoolean((UInt32?) p); + if (p is UInt64?) return ToSqlBoolean((UInt64?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlByte) return ToSqlBoolean((SqlByte) p); + if (p is SqlDecimal) return ToSqlBoolean((SqlDecimal)p); + if (p is SqlDouble) return ToSqlBoolean((SqlDouble) p); + if (p is SqlInt16) return ToSqlBoolean((SqlInt16) p); + if (p is SqlInt32) return ToSqlBoolean((SqlInt32) p); + if (p is SqlInt64) return ToSqlBoolean((SqlInt64) p); + if (p is SqlMoney) return ToSqlBoolean((SqlMoney) p); + if (p is SqlSingle) return ToSqlBoolean((SqlSingle) p); + if (p is SqlString) return ToSqlBoolean((SqlString) p); + } + + // Other Types + // + if (p is Binary) return ToSqlBoolean((Binary) p); + if (p is Byte[]) return ToSqlBoolean((Byte[]) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlBoolean)); + } + +#endif + + #endregion + + #region SqlByte + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Boolean p) { return p ? (SqlByte)1 : (SqlByte)0; } + /// Converts the value from Byte to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Byte p) { return p; } + /// Converts the value from Char to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Char p) { return checked((Byte)p); } + /// Converts the value from Decimal to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Decimal p) { return checked((Byte)p); } + /// Converts the value from Double to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Double p) { return checked((Byte)p); } + /// Converts the value from Int16 to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Int16 p) { return checked((Byte)p); } + /// Converts the value from Int32 to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Int32 p) { return checked((Byte)p); } + /// Converts the value from Int64 to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Int64 p) { return checked((Byte)p); } + /// Converts the value from SByte to an equivalent SqlByte value. + [CLSCompliant(false)] + public static SqlByte ToSqlByte(SByte p) { return checked((Byte)p); } + /// Converts the value from Single to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Single p) { return checked((Byte)p); } + /// Converts the value from String to an equivalent SqlByte value. + public static SqlByte ToSqlByte(String p) { return p == null? SqlByte.Null : Byte.Parse(p); } + /// Converts the value from UInt16 to an equivalent SqlByte value. + [CLSCompliant(false)] + public static SqlByte ToSqlByte(UInt16 p) { return checked((Byte)p); } + /// Converts the value from UInt32 to an equivalent SqlByte value. + [CLSCompliant(false)] + public static SqlByte ToSqlByte(UInt32 p) { return checked((Byte)p); } + /// Converts the value from UInt64 to an equivalent SqlByte value. + [CLSCompliant(false)] + public static SqlByte ToSqlByte(UInt64 p) { return checked((Byte)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Boolean? p) { return p.HasValue && p.Value ? (SqlByte)1: (SqlByte)0; } + /// Converts the value from Byte? to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Byte? p) { return p.HasValue ? p.Value : SqlByte.Null; } + /// Converts the value from Char? to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Char? p) { return p.HasValue ? checked((Byte)p.Value) : SqlByte.Null; } + /// Converts the value from Decimal? to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Decimal? p) { return p.HasValue ? checked((Byte)p.Value) : SqlByte.Null; } + /// Converts the value from Double? to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Double? p) { return p.HasValue ? checked((Byte)p.Value) : SqlByte.Null; } + /// Converts the value from Int16? to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Int16? p) { return p.HasValue ? checked((Byte)p.Value) : SqlByte.Null; } + /// Converts the value from Int32? to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Int32? p) { return p.HasValue ? checked((Byte)p.Value) : SqlByte.Null; } + /// Converts the value from Int64? to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Int64? p) { return p.HasValue ? checked((Byte)p.Value) : SqlByte.Null; } + /// Converts the value from SByte? to an equivalent SqlByte value. + [CLSCompliant(false)] + public static SqlByte ToSqlByte(SByte? p) { return p.HasValue ? checked((Byte)p.Value) : SqlByte.Null; } + /// Converts the value from Single? to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Single? p) { return p.HasValue ? checked((Byte)p.Value) : SqlByte.Null; } + /// Converts the value from UInt16? to an equivalent SqlByte value. + [CLSCompliant(false)] + public static SqlByte ToSqlByte(UInt16? p) { return p.HasValue ? checked((Byte)p.Value) : SqlByte.Null; } + /// Converts the value from UInt32? to an equivalent SqlByte value. + [CLSCompliant(false)] + public static SqlByte ToSqlByte(UInt32? p) { return p.HasValue ? checked((Byte)p.Value) : SqlByte.Null; } + /// Converts the value from UInt64? to an equivalent SqlByte value. + [CLSCompliant(false)] + public static SqlByte ToSqlByte(UInt64? p) { return p.HasValue ? checked((Byte)p.Value) : SqlByte.Null; } + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent SqlByte value. + public static SqlByte ToSqlByte(SqlBoolean p) { return p.ToSqlByte(); } + /// Converts the value from SqlDecimal to an equivalent SqlByte value. + public static SqlByte ToSqlByte(SqlDecimal p) { return p.ToSqlByte(); } + /// Converts the value from SqlDouble to an equivalent SqlByte value. + public static SqlByte ToSqlByte(SqlDouble p) { return p.ToSqlByte(); } + /// Converts the value from SqlInt16 to an equivalent SqlByte value. + public static SqlByte ToSqlByte(SqlInt16 p) { return p.ToSqlByte(); } + /// Converts the value from SqlInt32 to an equivalent SqlByte value. + public static SqlByte ToSqlByte(SqlInt32 p) { return p.ToSqlByte(); } + /// Converts the value from SqlInt64 to an equivalent SqlByte value. + public static SqlByte ToSqlByte(SqlInt64 p) { return p.ToSqlByte(); } + /// Converts the value from SqlMoney to an equivalent SqlByte value. + public static SqlByte ToSqlByte(SqlMoney p) { return p.ToSqlByte(); } + /// Converts the value from SqlSingle to an equivalent SqlByte value. + public static SqlByte ToSqlByte(SqlSingle p) { return p.ToSqlByte(); } + /// Converts the value from SqlString to an equivalent SqlByte value. + public static SqlByte ToSqlByte(SqlString p) { return p.ToSqlByte(); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Binary p) { return p == null || p.Length == 0 ? SqlByte.Null : p.ToArray()[0]; } + /// Converts the value from Byte[] to an equivalent SqlByte value. + public static SqlByte ToSqlByte(Byte[] p) { return p == null || p.Length == 0 ? SqlByte.Null : p[0]; } + + // From Object + // + /// Converts the value from Object to an equivalent SqlByte value. + public static SqlByte ToSqlByte(object p) + { + if (p == null) return SqlByte.Null; + + if (p is SqlByte) return (SqlByte)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlByte.Null; + case TypeCode.Byte : return ToSqlByte((Byte) p); + case TypeCode.SByte : return ToSqlByte((SByte) p); + case TypeCode.Int16 : return ToSqlByte((Int16) p); + case TypeCode.Int32 : return ToSqlByte((Int32) p); + case TypeCode.Int64 : return ToSqlByte((Int64) p); + case TypeCode.UInt16 : return ToSqlByte((UInt16) p); + case TypeCode.UInt32 : return ToSqlByte((UInt32) p); + case TypeCode.UInt64 : return ToSqlByte((UInt64) p); + case TypeCode.Single : return ToSqlByte((Single) p); + case TypeCode.Double : return ToSqlByte((Double) p); + case TypeCode.Decimal : return ToSqlByte((Decimal)p); + case TypeCode.Char : return ToSqlByte((Char) p); + case TypeCode.String : return ToSqlByte((String) p); + case TypeCode.Boolean : return ToSqlByte((Boolean)p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSqlByte((Boolean?) p); + if (p is Byte?) return ToSqlByte((Byte?) p); + if (p is Char?) return ToSqlByte((Char?) p); + if (p is Decimal?) return ToSqlByte((Decimal?) p); + if (p is Double?) return ToSqlByte((Double?) p); + if (p is Int16?) return ToSqlByte((Int16?) p); + if (p is Int32?) return ToSqlByte((Int32?) p); + if (p is Int64?) return ToSqlByte((Int64?) p); + if (p is SByte?) return ToSqlByte((SByte?) p); + if (p is Single?) return ToSqlByte((Single?) p); + if (p is UInt16?) return ToSqlByte((UInt16?) p); + if (p is UInt32?) return ToSqlByte((UInt32?) p); + if (p is UInt64?) return ToSqlByte((UInt64?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToSqlByte((SqlBoolean)p); + if (p is SqlDecimal) return ToSqlByte((SqlDecimal)p); + if (p is SqlDouble) return ToSqlByte((SqlDouble) p); + if (p is SqlInt16) return ToSqlByte((SqlInt16) p); + if (p is SqlInt32) return ToSqlByte((SqlInt32) p); + if (p is SqlInt64) return ToSqlByte((SqlInt64) p); + if (p is SqlMoney) return ToSqlByte((SqlMoney) p); + if (p is SqlSingle) return ToSqlByte((SqlSingle) p); + if (p is SqlString) return ToSqlByte((SqlString) p); + } + + // Other Types + // + if (p is Binary) return ToSqlByte((Binary) p); + if (p is Byte[]) return ToSqlByte((Byte[]) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlByte)); + } + +#endif + + #endregion + + #region SqlBytes + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Boolean p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from Byte to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Byte p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from Char to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Char p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from DateTime to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(DateTime p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from DateTimeOffset to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(DateTimeOffset p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from Double to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Double p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from Guid to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Guid p) { return p == Guid.Empty ? SqlBytes.Null: new SqlBytes(p.ToByteArray()); } + /// Converts the value from Int16 to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Int16 p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from Int32 to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Int32 p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from Int64 to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Int64 p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from SByte to an equivalent SqlBytes value. + [CLSCompliant(false)] + public static SqlBytes ToSqlBytes(SByte p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from Single to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Single p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from String to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(String p) { return p == null ? SqlBytes.Null : new SqlBytes(ToByteArray(p)); } + /// Converts the value from TimeSpan to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(TimeSpan p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from UInt16 to an equivalent SqlBytes value. + [CLSCompliant(false)] + public static SqlBytes ToSqlBytes(UInt16 p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from UInt32 to an equivalent SqlBytes value. + [CLSCompliant(false)] + public static SqlBytes ToSqlBytes(UInt32 p) { return new SqlBytes(ToByteArray(p)); } + /// Converts the value from UInt64 to an equivalent SqlBytes value. + [CLSCompliant(false)] + public static SqlBytes ToSqlBytes(UInt64 p) { return new SqlBytes(ToByteArray(p)); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Boolean? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from Byte? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Byte? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from Char? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Char? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from DateTime? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(DateTime? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from DateTimeOffset? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(DateTimeOffset? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from Decimal? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Decimal? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from Double? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Double? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from Guid? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Guid? p) { return p.HasValue ? new SqlBytes(p.Value.ToByteArray()) : SqlBytes.Null; } + /// Converts the value from Int16? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Int16? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from Int32? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Int32? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from Int64? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Int64? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from SByte? to an equivalent SqlBytes value. + [CLSCompliant(false)] + public static SqlBytes ToSqlBytes(SByte? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from Single? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Single? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from TimeSpan? to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(TimeSpan? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from UInt16? to an equivalent SqlBytes value. + [CLSCompliant(false)] + public static SqlBytes ToSqlBytes(UInt16? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from UInt32? to an equivalent SqlBytes value. + [CLSCompliant(false)] + public static SqlBytes ToSqlBytes(UInt32? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + /// Converts the value from UInt64? to an equivalent SqlBytes value. + [CLSCompliant(false)] + public static SqlBytes ToSqlBytes(UInt64? p) { return p.HasValue ? ToSqlBytes(p.Value) : SqlBytes.Null; } + + // Sql Types + // + /// Converts the value from SqlBinary to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(SqlBinary p) { return p.IsNull ? SqlBytes.Null : new SqlBytes(p); } + /// Converts the value from SqlGuid to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(SqlGuid p) { return p.IsNull ? SqlBytes.Null : new SqlBytes(p.ToByteArray()); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Binary p) { return p == null ? SqlBytes.Null : new SqlBytes(p.ToArray()); } + /// Converts the value from Byte[] to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Byte[] p) { return p == null ? SqlBytes.Null : new SqlBytes(p); } + /// Converts the value from Stream to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(Stream p) { return p == null ? SqlBytes.Null : new SqlBytes(p); } + + // From Object + // + /// Converts the value from Object to an equivalent SqlBytes value. + public static SqlBytes ToSqlBytes(object p) + { + if (p == null) return SqlBytes.Null; + + if (p is SqlBytes) return (SqlBytes)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlBytes.Null; + case TypeCode.String : return ToSqlBytes((String) p); + case TypeCode.Byte : return ToSqlBytes((Byte) p); + case TypeCode.SByte : return ToSqlBytes((SByte) p); + case TypeCode.DateTime : return ToSqlBytes((DateTime)p); + case TypeCode.Int16 : return ToSqlBytes((Int16) p); + case TypeCode.Int32 : return ToSqlBytes((Int32) p); + case TypeCode.Int64 : return ToSqlBytes((Int64) p); + case TypeCode.UInt16 : return ToSqlBytes((UInt16) p); + case TypeCode.UInt32 : return ToSqlBytes((UInt32) p); + case TypeCode.UInt64 : return ToSqlBytes((UInt64) p); + case TypeCode.Single : return ToSqlBytes((Single) p); + case TypeCode.Double : return ToSqlBytes((Double) p); + case TypeCode.Boolean : return ToSqlBytes((Boolean) p); + case TypeCode.Char : return ToSqlBytes((Char) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToSqlBytes((DateTimeOffset) p); + if (p is Guid) return ToSqlBytes((Guid) p); + if (p is TimeSpan) return ToSqlBytes((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSqlBytes((Boolean?) p); + if (p is Byte?) return ToSqlBytes((Byte?) p); + if (p is Char?) return ToSqlBytes((Char?) p); + if (p is DateTime?) return ToSqlBytes((DateTime?) p); + if (p is DateTimeOffset?) return ToSqlBytes((DateTimeOffset?)p); + if (p is Decimal?) return ToSqlBytes((Decimal?) p); + if (p is Double?) return ToSqlBytes((Double?) p); + if (p is Guid?) return ToSqlBytes((Guid?) p); + if (p is Int16?) return ToSqlBytes((Int16?) p); + if (p is Int32?) return ToSqlBytes((Int32?) p); + if (p is Int64?) return ToSqlBytes((Int64?) p); + if (p is SByte?) return ToSqlBytes((SByte?) p); + if (p is Single?) return ToSqlBytes((Single?) p); + if (p is TimeSpan?) return ToSqlBytes((TimeSpan?) p); + if (p is UInt16?) return ToSqlBytes((UInt16?) p); + if (p is UInt32?) return ToSqlBytes((UInt32?) p); + if (p is UInt64?) return ToSqlBytes((UInt64?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBinary) return ToSqlBytes((SqlBinary) p); + if (p is SqlGuid) return ToSqlBytes((SqlGuid) p); + } + + // Other Types + // + if (p is Binary) return ToSqlBytes((Binary) p); + if (p is Byte[]) return ToSqlBytes((Byte[]) p); + if (p is Stream) return ToSqlBytes((Stream) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlBytes)); + } + +#endif + + #endregion + + #region SqlChars + +#if !SILVERLIGHT + +#endif + + #endregion + + #region SqlDateTime + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from DateTime to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(DateTime p) { return p; } + /// Converts the value from DateTimeOffset to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(DateTimeOffset p) { return p.LocalDateTime; } + /// Converts the value from Double to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(Double p) { return DateTime.MinValue + TimeSpan.FromDays (p); } + /// Converts the value from Int64 to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(Int64 p) { return DateTime.MinValue + TimeSpan.FromTicks(p); } + /// Converts the value from String to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(String p) { return p == null ? SqlDateTime.Null : DateTime.Parse(p, null, DateTimeStyles.NoCurrentDateDefault); } + /// Converts the value from TimeSpan to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(TimeSpan p) { return DateTime.MinValue + p; } + + // Nullable Types + // + /// Converts the value from DateTime? to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(DateTime? p) { return p.HasValue ? p.Value : SqlDateTime.Null; } + /// Converts the value from DateTimeOffset? to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(DateTimeOffset? p) { return p.HasValue ? p.Value.LocalDateTime : SqlDateTime.Null; } + /// Converts the value from Double? to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(Double? p) { return p.HasValue ? DateTime.MinValue + TimeSpan.FromDays (p.Value): SqlDateTime.Null; } + /// Converts the value from Int64? to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(Int64? p) { return p.HasValue ? DateTime.MinValue + TimeSpan.FromTicks(p.Value): SqlDateTime.Null; } + /// Converts the value from TimeSpan? to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(TimeSpan? p) { return p.HasValue ? DateTime.MinValue + p.Value : SqlDateTime.Null; } + + // Sql Types + // + /// Converts the value from SqlDouble to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(SqlDouble p) { return p.IsNull ? SqlDateTime.Null : DateTime.MinValue + TimeSpan.FromDays (p.Value); } + /// Converts the value from SqlInt64 to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(SqlInt64 p) { return p.IsNull ? SqlDateTime.Null : DateTime.MinValue + TimeSpan.FromTicks(p.Value); } + /// Converts the value from SqlString to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(SqlString p) { return p.IsNull ? SqlDateTime.Null : ToDateTime(p.Value); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(Binary p) { return p == null || p.Length == 0 ? SqlDateTime.Null : DateTime.FromBinary(ToInt64(p.ToArray())); } + /// Converts the value from Byte[] to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(Byte[] p) { return p == null || p.Length == 0 ? SqlDateTime.Null : DateTime.FromBinary(ToInt64(p)); } + + // From Object + // + /// Converts the value from Object to an equivalent SqlDateTime value. + public static SqlDateTime ToSqlDateTime(object p) + { + if (p == null) return SqlDateTime.Null; + + if (p is SqlDateTime) return (SqlDateTime)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlDateTime.Null; + case TypeCode.DateTime : return ToSqlDateTime((DateTime) p); + case TypeCode.String : return ToSqlDateTime((String) p); + case TypeCode.Int64 : return ToSqlDateTime((Int64) p); + case TypeCode.Double : return ToSqlDateTime((Double) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToSqlDateTime((DateTimeOffset) p); + if (p is TimeSpan) return ToSqlDateTime((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is DateTime?) return ToSqlDateTime((DateTime?) p); + if (p is DateTimeOffset?) return ToSqlDateTime((DateTimeOffset?)p); + if (p is Double?) return ToSqlDateTime((Double?) p); + if (p is Int64?) return ToSqlDateTime((Int64?) p); + if (p is TimeSpan?) return ToSqlDateTime((TimeSpan?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlDouble) return ToSqlDateTime((SqlDouble) p); + if (p is SqlInt64) return ToSqlDateTime((SqlInt64) p); + if (p is SqlString) return ToSqlDateTime((SqlString) p); + } + + // Other Types + // + if (p is Binary) return ToSqlDateTime((Binary) p); + if (p is Byte[]) return ToSqlDateTime((Byte[]) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlDateTime)); + } + +#endif + + #endregion + + #region SqlDecimal + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Boolean p) { return p ? (SqlDecimal)1 : (SqlDecimal)0; } + /// Converts the value from Byte to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Byte p) { return p; } + /// Converts the value from Char to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Char p) { return p; } + /// Converts the value from Decimal to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Decimal p) { return p; } + /// Converts the value from Double to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Double p) { return checked((Decimal)p); } + /// Converts the value from Int16 to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Int64 p) { return p; } + /// Converts the value from SByte to an equivalent SqlDecimal value. + [CLSCompliant(false)] + public static SqlDecimal ToSqlDecimal(SByte p) { return p; } + /// Converts the value from Single to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Single p) { return checked((Decimal)p); } + /// Converts the value from String to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(String p) { return p == null? SqlDecimal.Null : Decimal.Parse(p); } + /// Converts the value from UInt16 to an equivalent SqlDecimal value. + [CLSCompliant(false)] + public static SqlDecimal ToSqlDecimal(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent SqlDecimal value. + [CLSCompliant(false)] + public static SqlDecimal ToSqlDecimal(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent SqlDecimal value. + [CLSCompliant(false)] + public static SqlDecimal ToSqlDecimal(UInt64 p) { return p; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Boolean? p) { return p.HasValue && p.Value ? (SqlDecimal)1: (SqlDecimal)0; } + /// Converts the value from Byte? to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Byte? p) { return p.HasValue ? p.Value : SqlDecimal.Null; } + /// Converts the value from Char? to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Char? p) { return p.HasValue ? p.Value : SqlDecimal.Null; } + /// Converts the value from Decimal? to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Decimal? p) { return p.HasValue ? p.Value : SqlDecimal.Null; } + /// Converts the value from Double? to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Double? p) { return p.HasValue ? checked((Decimal)p.Value) : SqlDecimal.Null; } + /// Converts the value from Int16? to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Int16? p) { return p.HasValue ? p.Value : SqlDecimal.Null; } + /// Converts the value from Int32? to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Int32? p) { return p.HasValue ? p.Value : SqlDecimal.Null; } + /// Converts the value from Int64? to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Int64? p) { return p.HasValue ? p.Value : SqlDecimal.Null; } + /// Converts the value from SByte? to an equivalent SqlDecimal value. + [CLSCompliant(false)] + public static SqlDecimal ToSqlDecimal(SByte? p) { return p.HasValue ? p.Value : SqlDecimal.Null; } + /// Converts the value from Single? to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Single? p) { return p.HasValue ? checked((Decimal)p.Value) : SqlDecimal.Null; } + /// Converts the value from UInt16? to an equivalent SqlDecimal value. + [CLSCompliant(false)] + public static SqlDecimal ToSqlDecimal(UInt16? p) { return p.HasValue ? p.Value : SqlDecimal.Null; } + /// Converts the value from UInt32? to an equivalent SqlDecimal value. + [CLSCompliant(false)] + public static SqlDecimal ToSqlDecimal(UInt32? p) { return p.HasValue ? p.Value : SqlDecimal.Null; } + /// Converts the value from UInt64? to an equivalent SqlDecimal value. + [CLSCompliant(false)] + public static SqlDecimal ToSqlDecimal(UInt64? p) { return p.HasValue ? p.Value : SqlDecimal.Null; } + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(SqlBoolean p) { return p.ToSqlDecimal(); } + /// Converts the value from SqlByte to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(SqlByte p) { return p.ToSqlDecimal(); } + /// Converts the value from SqlDouble to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(SqlDouble p) { return p.ToSqlDecimal(); } + /// Converts the value from SqlInt16 to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(SqlInt16 p) { return p.ToSqlDecimal(); } + /// Converts the value from SqlInt32 to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(SqlInt32 p) { return p.ToSqlDecimal(); } + /// Converts the value from SqlInt64 to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(SqlInt64 p) { return p.ToSqlDecimal(); } + /// Converts the value from SqlMoney to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(SqlMoney p) { return p.ToSqlDecimal(); } + /// Converts the value from SqlSingle to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(SqlSingle p) { return p.ToSqlDecimal(); } + /// Converts the value from SqlString to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(SqlString p) { return p.ToSqlDecimal(); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Binary p) { return p == null || p.Length == 0 ? SqlDecimal.Null : ToDecimal(p); } + /// Converts the value from Byte[] to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(Byte[] p) { return p == null || p.Length == 0 ? SqlDecimal.Null : ToDecimal(p); } + + // From Object + // + /// Converts the value from Object to an equivalent SqlDecimal value. + public static SqlDecimal ToSqlDecimal(object p) + { + if (p == null) return SqlDecimal.Null; + + if (p is SqlDecimal) return (SqlDecimal)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlDecimal.Null; + case TypeCode.SByte : return ToSqlDecimal((SByte) p); + case TypeCode.Int16 : return ToSqlDecimal((Int16) p); + case TypeCode.Int32 : return ToSqlDecimal((Int32) p); + case TypeCode.Int64 : return ToSqlDecimal((Int64) p); + case TypeCode.Byte : return ToSqlDecimal((Byte) p); + case TypeCode.UInt16 : return ToSqlDecimal((UInt16) p); + case TypeCode.UInt32 : return ToSqlDecimal((UInt32) p); + case TypeCode.Char : return ToSqlDecimal((Char) p); + case TypeCode.UInt64 : return ToSqlDecimal((UInt64) p); + case TypeCode.Decimal : return ToSqlDecimal((Decimal) p); + case TypeCode.Single : return ToSqlDecimal((Single) p); + case TypeCode.Double : return ToSqlDecimal((Double) p); + case TypeCode.String : return ToSqlDecimal((String) p); + case TypeCode.Boolean : return ToSqlDecimal((Boolean) p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSqlDecimal((Boolean?) p); + if (p is Byte?) return ToSqlDecimal((Byte?) p); + if (p is Char?) return ToSqlDecimal((Char?) p); + if (p is Decimal?) return ToSqlDecimal((Decimal?) p); + if (p is Double?) return ToSqlDecimal((Double?) p); + if (p is Int16?) return ToSqlDecimal((Int16?) p); + if (p is Int32?) return ToSqlDecimal((Int32?) p); + if (p is Int64?) return ToSqlDecimal((Int64?) p); + if (p is SByte?) return ToSqlDecimal((SByte?) p); + if (p is Single?) return ToSqlDecimal((Single?) p); + if (p is UInt16?) return ToSqlDecimal((UInt16?) p); + if (p is UInt32?) return ToSqlDecimal((UInt32?) p); + if (p is UInt64?) return ToSqlDecimal((UInt64?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToSqlDecimal((SqlBoolean)p); + if (p is SqlByte) return ToSqlDecimal((SqlByte) p); + if (p is SqlDouble) return ToSqlDecimal((SqlDouble) p); + if (p is SqlInt16) return ToSqlDecimal((SqlInt16) p); + if (p is SqlInt32) return ToSqlDecimal((SqlInt32) p); + if (p is SqlInt64) return ToSqlDecimal((SqlInt64) p); + if (p is SqlMoney) return ToSqlDecimal((SqlMoney) p); + if (p is SqlSingle) return ToSqlDecimal((SqlSingle) p); + if (p is SqlString) return ToSqlDecimal((SqlString) p); + } + + // Other Types + // + if (p is Binary) return ToSqlDecimal((Binary) p); + if (p is Byte[]) return ToSqlDecimal((Byte[]) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlDecimal)); + } + +#endif + + #endregion + + #region SqlDouble + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Boolean p) { return p ? (SqlDouble)1 : (SqlDouble)0; } + /// Converts the value from Byte to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Byte p) { return p; } + /// Converts the value from Char to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Char p) { return p; } + /// Converts the value from DateTime to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(DateTime p) { return (p - DateTime.MinValue).TotalDays; } + /// Converts the value from DateTimeOffset to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(DateTimeOffset p) { return (p - DateTimeOffset.MinValue).TotalDays; } + /// Converts the value from Decimal to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Decimal p) { return checked((Double)p); } + /// Converts the value from Double to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Double p) { return p; } + /// Converts the value from Int16 to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Int64 p) { return p; } + /// Converts the value from SByte to an equivalent SqlDouble value. + [CLSCompliant(false)] + public static SqlDouble ToSqlDouble(SByte p) { return p; } + /// Converts the value from Single to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Single p) { return p; } + /// Converts the value from String to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(String p) { return p == null? SqlDouble.Null : Double.Parse(p); } + /// Converts the value from TimeSpan to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(TimeSpan p) { return p.TotalDays; } + /// Converts the value from UInt16 to an equivalent SqlDouble value. + [CLSCompliant(false)] + public static SqlDouble ToSqlDouble(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent SqlDouble value. + [CLSCompliant(false)] + public static SqlDouble ToSqlDouble(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent SqlDouble value. + [CLSCompliant(false)] + public static SqlDouble ToSqlDouble(UInt64 p) { return p; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Boolean? p) { return p.HasValue && p.Value ? (SqlDouble)1: (SqlDouble)0; } + /// Converts the value from Byte? to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Byte? p) { return p.HasValue ? p.Value : SqlDouble.Null; } + /// Converts the value from Char? to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Char? p) { return p.HasValue ? p.Value : SqlDouble.Null; } + /// Converts the value from DateTime? to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(DateTime? p) { return p.HasValue ? (p.Value - DateTime.MinValue).TotalDays : SqlDouble.Null; } + /// Converts the value from DateTimeOffset? to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(DateTimeOffset? p) { return p.HasValue ? (p.Value - DateTimeOffset.MinValue).TotalDays : SqlDouble.Null; } + /// Converts the value from Decimal? to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Decimal? p) { return p.HasValue ? checked((Double)p.Value) : SqlDouble.Null; } + /// Converts the value from Double? to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Double? p) { return p.HasValue ? p.Value : SqlDouble.Null; } + /// Converts the value from Int16? to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Int16? p) { return p.HasValue ? p.Value : SqlDouble.Null; } + /// Converts the value from Int32? to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Int32? p) { return p.HasValue ? p.Value : SqlDouble.Null; } + /// Converts the value from Int64? to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Int64? p) { return p.HasValue ? p.Value : SqlDouble.Null; } + /// Converts the value from SByte? to an equivalent SqlDouble value. + [CLSCompliant(false)] + public static SqlDouble ToSqlDouble(SByte? p) { return p.HasValue ? p.Value : SqlDouble.Null; } + /// Converts the value from Single? to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Single? p) { return p.HasValue ? p.Value : SqlDouble.Null; } + /// Converts the value from TimeSpan? to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(TimeSpan? p) { return p.HasValue ? p.Value.TotalDays : SqlDouble.Null; } + /// Converts the value from UInt16? to an equivalent SqlDouble value. + [CLSCompliant(false)] + public static SqlDouble ToSqlDouble(UInt16? p) { return p.HasValue ? p.Value : SqlDouble.Null; } + /// Converts the value from UInt32? to an equivalent SqlDouble value. + [CLSCompliant(false)] + public static SqlDouble ToSqlDouble(UInt32? p) { return p.HasValue ? p.Value : SqlDouble.Null; } + /// Converts the value from UInt64? to an equivalent SqlDouble value. + [CLSCompliant(false)] + public static SqlDouble ToSqlDouble(UInt64? p) { return p.HasValue ? p.Value : SqlDouble.Null; } + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(SqlBoolean p) { return p.ToSqlDouble(); } + /// Converts the value from SqlByte to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(SqlByte p) { return p.ToSqlDouble(); } + /// Converts the value from SqlDateTime to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(SqlDateTime p) { return p.IsNull? SqlDouble.Null: ToDouble(p.Value); } + /// Converts the value from SqlDecimal to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(SqlDecimal p) { return p.ToSqlDouble(); } + /// Converts the value from SqlInt16 to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(SqlInt16 p) { return p.ToSqlDouble(); } + /// Converts the value from SqlInt32 to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(SqlInt32 p) { return p.ToSqlDouble(); } + /// Converts the value from SqlInt64 to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(SqlInt64 p) { return p.ToSqlDouble(); } + /// Converts the value from SqlMoney to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(SqlMoney p) { return p.ToSqlDouble(); } + /// Converts the value from SqlSingle to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(SqlSingle p) { return p.ToSqlDouble(); } + /// Converts the value from SqlString to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(SqlString p) { return p.ToSqlDouble(); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Binary p) { return p == null || p.Length == 0 ? SqlDouble.Null : BitConverter.ToDouble(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(Byte[] p) { return p == null || p.Length == 0 ? SqlDouble.Null : BitConverter.ToDouble(p, 0); } + + // From Object + // + /// Converts the value from Object to an equivalent SqlDouble value. + public static SqlDouble ToSqlDouble(object p) + { + if (p == null) return SqlDouble.Null; + + if (p is SqlDouble) return (SqlDouble)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlDouble.Null; + case TypeCode.DateTime : return ToSqlDouble((DateTime) p); + case TypeCode.SByte : return ToSqlDouble((SByte) p); + case TypeCode.Int16 : return ToSqlDouble((Int16) p); + case TypeCode.Int32 : return ToSqlDouble((Int32) p); + case TypeCode.Int64 : return ToSqlDouble((Int64) p); + case TypeCode.Byte : return ToSqlDouble((Byte) p); + case TypeCode.UInt16 : return ToSqlDouble((UInt16) p); + case TypeCode.UInt32 : return ToSqlDouble((UInt32) p); + case TypeCode.Char : return ToSqlDouble((Char) p); + case TypeCode.UInt64 : return ToSqlDouble((UInt64) p); + case TypeCode.Single : return ToSqlDouble((Single) p); + case TypeCode.Double : return ToSqlDouble((Double) p); + case TypeCode.Decimal : return ToSqlDouble((Decimal) p); + case TypeCode.String : return ToSqlDouble((String) p); + case TypeCode.Boolean : return ToSqlDouble((Boolean) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToSqlDouble((DateTimeOffset) p); + if (p is TimeSpan) return ToSqlDouble((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSqlDouble((Boolean?) p); + if (p is Byte?) return ToSqlDouble((Byte?) p); + if (p is Char?) return ToSqlDouble((Char?) p); + if (p is DateTime?) return ToSqlDouble((DateTime?) p); + if (p is DateTimeOffset?) return ToSqlDouble((DateTimeOffset?)p); + if (p is Decimal?) return ToSqlDouble((Decimal?) p); + if (p is Double?) return ToSqlDouble((Double?) p); + if (p is Int16?) return ToSqlDouble((Int16?) p); + if (p is Int32?) return ToSqlDouble((Int32?) p); + if (p is Int64?) return ToSqlDouble((Int64?) p); + if (p is SByte?) return ToSqlDouble((SByte?) p); + if (p is Single?) return ToSqlDouble((Single?) p); + if (p is TimeSpan?) return ToSqlDouble((TimeSpan?) p); + if (p is UInt16?) return ToSqlDouble((UInt16?) p); + if (p is UInt32?) return ToSqlDouble((UInt32?) p); + if (p is UInt64?) return ToSqlDouble((UInt64?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToSqlDouble((SqlBoolean) p); + if (p is SqlByte) return ToSqlDouble((SqlByte) p); + if (p is SqlDateTime) return ToSqlDouble((SqlDateTime) p); + if (p is SqlDecimal) return ToSqlDouble((SqlDecimal) p); + if (p is SqlInt16) return ToSqlDouble((SqlInt16) p); + if (p is SqlInt32) return ToSqlDouble((SqlInt32) p); + if (p is SqlInt64) return ToSqlDouble((SqlInt64) p); + if (p is SqlMoney) return ToSqlDouble((SqlMoney) p); + if (p is SqlSingle) return ToSqlDouble((SqlSingle) p); + if (p is SqlString) return ToSqlDouble((SqlString) p); + } + + // Other Types + // + if (p is Binary) return ToSqlDouble((Binary) p); + if (p is Byte[]) return ToSqlDouble((Byte[]) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlDouble)); + } + +#endif + + #endregion + + #region SqlGuid + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Guid to an equivalent SqlGuid value. + public static SqlGuid ToSqlGuid(Guid p) { return p; } + /// Converts the value from String to an equivalent SqlGuid value. + public static SqlGuid ToSqlGuid(String p) { return p == null ? SqlGuid.Null : new Guid(p); } + + // Nullable Types + // + /// Converts the value from Guid? to an equivalent SqlGuid value. + public static SqlGuid ToSqlGuid(Guid? p) { return p.HasValue ? p.Value : SqlGuid.Null; } + + // Sql Types + // + /// Converts the value from SqlBinary to an equivalent SqlGuid value. + public static SqlGuid ToSqlGuid(SqlBinary p) { return p.IsNull ? SqlGuid.Null : p.ToSqlGuid().Value; } + /// Converts the value from SqlString to an equivalent SqlGuid value. + public static SqlGuid ToSqlGuid(SqlString p) { return p.IsNull ? SqlGuid.Null : new Guid(p.Value); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlGuid value. + public static SqlGuid ToSqlGuid(Binary p) { return p == null ? SqlGuid.Null : new Guid(p.ToArray()); } + /// Converts the value from Byte[] to an equivalent SqlGuid value. + public static SqlGuid ToSqlGuid(Byte[] p) { return p == null ? SqlGuid.Null : new Guid(p); } + /// Converts the value from Type to an equivalent SqlGuid value. + public static SqlGuid ToSqlGuid(Type p) { return p == null ? SqlGuid.Null : p.GUID; } + + // From Object + // + /// Converts the value from Object to an equivalent SqlGuid value. + public static SqlGuid ToSqlGuid(object p) + { + if (p == null) return SqlGuid.Null; + + if (p is SqlGuid) return (SqlGuid)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlGuid.Null; + case TypeCode.String : return ToSqlGuid((String) p); + } + + // Simple Types + // + if (p is Guid) return ToSqlGuid((Guid) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Guid?) return ToSqlGuid((Guid?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBinary) return ToSqlGuid((SqlBinary)p); + if (p is SqlString) return ToSqlGuid((SqlString)p); + } + + // Other Types + // + if (p is Binary) return ToSqlGuid((Binary) p); + if (p is Byte[]) return ToSqlGuid((Byte[]) p); + if (p is Type) return ToSqlGuid((Type) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlGuid)); + } + +#endif + + #endregion + + #region SqlInt16 + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Boolean p) { return p ? (SqlInt16)1 : (SqlInt16)0; } + /// Converts the value from Byte to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Byte p) { return p; } + /// Converts the value from Char to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Char p) { return checked((Int16)p); } + /// Converts the value from Decimal to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Decimal p) { return checked((Int16)p); } + /// Converts the value from Double to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Double p) { return checked((Int16)p); } + /// Converts the value from Int16 to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Int32 p) { return checked((Int16)p); } + /// Converts the value from Int64 to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Int64 p) { return checked((Int16)p); } + /// Converts the value from SByte to an equivalent SqlInt16 value. + [CLSCompliant(false)] + public static SqlInt16 ToSqlInt16(SByte p) { return p; } + /// Converts the value from Single to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Single p) { return checked((Int16)p); } + /// Converts the value from String to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(String p) { return p == null? SqlInt16.Null : Int16.Parse(p); } + /// Converts the value from UInt16 to an equivalent SqlInt16 value. + [CLSCompliant(false)] + public static SqlInt16 ToSqlInt16(UInt16 p) { return checked((Int16)p); } + /// Converts the value from UInt32 to an equivalent SqlInt16 value. + [CLSCompliant(false)] + public static SqlInt16 ToSqlInt16(UInt32 p) { return checked((Int16)p); } + /// Converts the value from UInt64 to an equivalent SqlInt16 value. + [CLSCompliant(false)] + public static SqlInt16 ToSqlInt16(UInt64 p) { return checked((Int16)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Boolean? p) { return p.HasValue && p.Value ? (SqlInt16)1: (SqlInt16)0; } + /// Converts the value from Byte? to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Byte? p) { return p.HasValue ? p.Value : SqlInt16.Null; } + /// Converts the value from Char? to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Char? p) { return p.HasValue ? checked((Int16)p.Value) : SqlInt16.Null; } + /// Converts the value from Decimal? to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Decimal? p) { return p.HasValue ? checked((Int16)p.Value) : SqlInt16.Null; } + /// Converts the value from Double? to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Double? p) { return p.HasValue ? checked((Int16)p.Value) : SqlInt16.Null; } + /// Converts the value from Int16? to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Int16? p) { return p.HasValue ? p.Value : SqlInt16.Null; } + /// Converts the value from Int32? to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Int32? p) { return p.HasValue ? checked((Int16)p.Value) : SqlInt16.Null; } + /// Converts the value from Int64? to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Int64? p) { return p.HasValue ? checked((Int16)p.Value) : SqlInt16.Null; } + /// Converts the value from SByte? to an equivalent SqlInt16 value. + [CLSCompliant(false)] + public static SqlInt16 ToSqlInt16(SByte? p) { return p.HasValue ? p.Value : SqlInt16.Null; } + /// Converts the value from Single? to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Single? p) { return p.HasValue ? checked((Int16)p.Value) : SqlInt16.Null; } + /// Converts the value from UInt16? to an equivalent SqlInt16 value. + [CLSCompliant(false)] + public static SqlInt16 ToSqlInt16(UInt16? p) { return p.HasValue ? checked((Int16)p.Value) : SqlInt16.Null; } + /// Converts the value from UInt32? to an equivalent SqlInt16 value. + [CLSCompliant(false)] + public static SqlInt16 ToSqlInt16(UInt32? p) { return p.HasValue ? checked((Int16)p.Value) : SqlInt16.Null; } + /// Converts the value from UInt64? to an equivalent SqlInt16 value. + [CLSCompliant(false)] + public static SqlInt16 ToSqlInt16(UInt64? p) { return p.HasValue ? checked((Int16)p.Value) : SqlInt16.Null; } + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(SqlBoolean p) { return p.ToSqlInt16(); } + /// Converts the value from SqlByte to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(SqlByte p) { return p.ToSqlInt16(); } + /// Converts the value from SqlDecimal to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(SqlDecimal p) { return p.ToSqlInt16(); } + /// Converts the value from SqlDouble to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(SqlDouble p) { return p.ToSqlInt16(); } + /// Converts the value from SqlInt32 to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(SqlInt32 p) { return p.ToSqlInt16(); } + /// Converts the value from SqlInt64 to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(SqlInt64 p) { return p.ToSqlInt16(); } + /// Converts the value from SqlMoney to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(SqlMoney p) { return p.ToSqlInt16(); } + /// Converts the value from SqlSingle to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(SqlSingle p) { return p.ToSqlInt16(); } + /// Converts the value from SqlString to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(SqlString p) { return p.ToSqlInt16(); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Binary p) { return p == null || p.Length == 0 ? SqlInt16.Null : BitConverter.ToInt16(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(Byte[] p) { return p == null || p.Length == 0 ? SqlInt16.Null : BitConverter.ToInt16(p, 0); } + + // From Object + // + /// Converts the value from Object to an equivalent SqlInt16 value. + public static SqlInt16 ToSqlInt16(object p) + { + if (p == null) return SqlInt16.Null; + + if (p is SqlInt16) return (SqlInt16)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlInt16.Null; + case TypeCode.SByte : return ToSqlInt16((SByte) p); + case TypeCode.Int16 : return ToSqlInt16((Int16) p); + case TypeCode.Byte : return ToSqlInt16((Byte) p); + case TypeCode.Int32 : return ToSqlInt16((Int32) p); + case TypeCode.Int64 : return ToSqlInt16((Int64) p); + case TypeCode.UInt16 : return ToSqlInt16((UInt16) p); + case TypeCode.UInt32 : return ToSqlInt16((UInt32) p); + case TypeCode.UInt64 : return ToSqlInt16((UInt64) p); + case TypeCode.Single : return ToSqlInt16((Single) p); + case TypeCode.Double : return ToSqlInt16((Double) p); + case TypeCode.Decimal : return ToSqlInt16((Decimal) p); + case TypeCode.Char : return ToSqlInt16((Char) p); + case TypeCode.String : return ToSqlInt16((String) p); + case TypeCode.Boolean : return ToSqlInt16((Boolean) p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSqlInt16((Boolean?) p); + if (p is Byte?) return ToSqlInt16((Byte?) p); + if (p is Char?) return ToSqlInt16((Char?) p); + if (p is Decimal?) return ToSqlInt16((Decimal?) p); + if (p is Double?) return ToSqlInt16((Double?) p); + if (p is Int16?) return ToSqlInt16((Int16?) p); + if (p is Int32?) return ToSqlInt16((Int32?) p); + if (p is Int64?) return ToSqlInt16((Int64?) p); + if (p is SByte?) return ToSqlInt16((SByte?) p); + if (p is Single?) return ToSqlInt16((Single?) p); + if (p is UInt16?) return ToSqlInt16((UInt16?) p); + if (p is UInt32?) return ToSqlInt16((UInt32?) p); + if (p is UInt64?) return ToSqlInt16((UInt64?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToSqlInt16((SqlBoolean)p); + if (p is SqlByte) return ToSqlInt16((SqlByte) p); + if (p is SqlDecimal) return ToSqlInt16((SqlDecimal)p); + if (p is SqlDouble) return ToSqlInt16((SqlDouble) p); + if (p is SqlInt32) return ToSqlInt16((SqlInt32) p); + if (p is SqlInt64) return ToSqlInt16((SqlInt64) p); + if (p is SqlMoney) return ToSqlInt16((SqlMoney) p); + if (p is SqlSingle) return ToSqlInt16((SqlSingle) p); + if (p is SqlString) return ToSqlInt16((SqlString) p); + } + + // Other Types + // + if (p is Binary) return ToSqlInt16((Binary) p); + if (p is Byte[]) return ToSqlInt16((Byte[]) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlInt16)); + } + +#endif + + #endregion + + #region SqlInt32 + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Boolean p) { return p ? (SqlInt32)1 : (SqlInt32)0; } + /// Converts the value from Byte to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Byte p) { return p; } + /// Converts the value from Char to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Char p) { return p; } + /// Converts the value from Decimal to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Decimal p) { return checked((Int32)p); } + /// Converts the value from Double to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Double p) { return checked((Int32)p); } + /// Converts the value from Int16 to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Int64 p) { return checked((Int32)p); } + /// Converts the value from SByte to an equivalent SqlInt32 value. + [CLSCompliant(false)] + public static SqlInt32 ToSqlInt32(SByte p) { return p; } + /// Converts the value from Single to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Single p) { return checked((Int32)p); } + /// Converts the value from String to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(String p) { return p == null? SqlInt32.Null : Int32.Parse(p); } + /// Converts the value from UInt16 to an equivalent SqlInt32 value. + [CLSCompliant(false)] + public static SqlInt32 ToSqlInt32(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent SqlInt32 value. + [CLSCompliant(false)] + public static SqlInt32 ToSqlInt32(UInt32 p) { return checked((Int32)p); } + /// Converts the value from UInt64 to an equivalent SqlInt32 value. + [CLSCompliant(false)] + public static SqlInt32 ToSqlInt32(UInt64 p) { return checked((Int32)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Boolean? p) { return p.HasValue && p.Value ? (SqlInt32)1: (SqlInt32)0; } + /// Converts the value from Byte? to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Byte? p) { return p.HasValue ? p.Value : SqlInt32.Null; } + /// Converts the value from Char? to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Char? p) { return p.HasValue ? p.Value : SqlInt32.Null; } + /// Converts the value from Decimal? to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Decimal? p) { return p.HasValue ? checked((Int32)p.Value) : SqlInt32.Null; } + /// Converts the value from Double? to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Double? p) { return p.HasValue ? checked((Int32)p.Value) : SqlInt32.Null; } + /// Converts the value from Int16? to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Int16? p) { return p.HasValue ? p.Value : SqlInt32.Null; } + /// Converts the value from Int32? to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Int32? p) { return p.HasValue ? p.Value : SqlInt32.Null; } + /// Converts the value from Int64? to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Int64? p) { return p.HasValue ? checked((Int32)p.Value) : SqlInt32.Null; } + /// Converts the value from SByte? to an equivalent SqlInt32 value. + [CLSCompliant(false)] + public static SqlInt32 ToSqlInt32(SByte? p) { return p.HasValue ? p.Value : SqlInt32.Null; } + /// Converts the value from Single? to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Single? p) { return p.HasValue ? checked((Int32)p.Value) : SqlInt32.Null; } + /// Converts the value from UInt16? to an equivalent SqlInt32 value. + [CLSCompliant(false)] + public static SqlInt32 ToSqlInt32(UInt16? p) { return p.HasValue ? p.Value : SqlInt32.Null; } + /// Converts the value from UInt32? to an equivalent SqlInt32 value. + [CLSCompliant(false)] + public static SqlInt32 ToSqlInt32(UInt32? p) { return p.HasValue ? checked((Int32)p.Value) : SqlInt32.Null; } + /// Converts the value from UInt64? to an equivalent SqlInt32 value. + [CLSCompliant(false)] + public static SqlInt32 ToSqlInt32(UInt64? p) { return p.HasValue ? checked((Int32)p.Value) : SqlInt32.Null; } + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(SqlBoolean p) { return p.ToSqlInt32(); } + /// Converts the value from SqlByte to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(SqlByte p) { return p.ToSqlInt32(); } + /// Converts the value from SqlDecimal to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(SqlDecimal p) { return p.ToSqlInt32(); } + /// Converts the value from SqlDouble to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(SqlDouble p) { return p.ToSqlInt32(); } + /// Converts the value from SqlInt16 to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(SqlInt16 p) { return p.ToSqlInt32(); } + /// Converts the value from SqlInt64 to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(SqlInt64 p) { return p.ToSqlInt32(); } + /// Converts the value from SqlMoney to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(SqlMoney p) { return p.ToSqlInt32(); } + /// Converts the value from SqlSingle to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(SqlSingle p) { return p.ToSqlInt32(); } + /// Converts the value from SqlString to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(SqlString p) { return p.ToSqlInt32(); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Binary p) { return p == null || p.Length == 0 ? SqlInt32.Null : BitConverter.ToInt32(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(Byte[] p) { return p == null || p.Length == 0 ? SqlInt32.Null : BitConverter.ToInt32(p, 0); } + + // From Object + // + /// Converts the value from Object to an equivalent SqlInt32 value. + public static SqlInt32 ToSqlInt32(object p) + { + if (p == null) return SqlInt32.Null; + + if (p is SqlInt32) return (SqlInt32)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlInt32.Null; + case TypeCode.SByte : return ToSqlInt32((SByte) p); + case TypeCode.Int16 : return ToSqlInt32((Int16) p); + case TypeCode.Int32 : return ToSqlInt32((Int32) p); + case TypeCode.Byte : return ToSqlInt32((Byte) p); + case TypeCode.UInt16 : return ToSqlInt32((UInt16) p); + case TypeCode.Char : return ToSqlInt32((Char) p); + case TypeCode.Int64 : return ToSqlInt32((Int64) p); + case TypeCode.UInt32 : return ToSqlInt32((UInt32) p); + case TypeCode.UInt64 : return ToSqlInt32((UInt64) p); + case TypeCode.Single : return ToSqlInt32((Single) p); + case TypeCode.Double : return ToSqlInt32((Double) p); + case TypeCode.Decimal : return ToSqlInt32((Decimal) p); + case TypeCode.String : return ToSqlInt32((String) p); + case TypeCode.Boolean : return ToSqlInt32((Boolean) p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSqlInt32((Boolean?) p); + if (p is Byte?) return ToSqlInt32((Byte?) p); + if (p is Char?) return ToSqlInt32((Char?) p); + if (p is Decimal?) return ToSqlInt32((Decimal?) p); + if (p is Double?) return ToSqlInt32((Double?) p); + if (p is Int16?) return ToSqlInt32((Int16?) p); + if (p is Int32?) return ToSqlInt32((Int32?) p); + if (p is Int64?) return ToSqlInt32((Int64?) p); + if (p is SByte?) return ToSqlInt32((SByte?) p); + if (p is Single?) return ToSqlInt32((Single?) p); + if (p is UInt16?) return ToSqlInt32((UInt16?) p); + if (p is UInt32?) return ToSqlInt32((UInt32?) p); + if (p is UInt64?) return ToSqlInt32((UInt64?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToSqlInt32((SqlBoolean)p); + if (p is SqlByte) return ToSqlInt32((SqlByte) p); + if (p is SqlDecimal) return ToSqlInt32((SqlDecimal)p); + if (p is SqlDouble) return ToSqlInt32((SqlDouble) p); + if (p is SqlInt16) return ToSqlInt32((SqlInt16) p); + if (p is SqlInt64) return ToSqlInt32((SqlInt64) p); + if (p is SqlMoney) return ToSqlInt32((SqlMoney) p); + if (p is SqlSingle) return ToSqlInt32((SqlSingle) p); + if (p is SqlString) return ToSqlInt32((SqlString) p); + } + + // Other Types + // + if (p is Binary) return ToSqlInt32((Binary) p); + if (p is Byte[]) return ToSqlInt32((Byte[]) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlInt32)); + } + +#endif + + #endregion + + #region SqlInt64 + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Boolean p) { return p ? (SqlInt64)1 : (SqlInt64)0; } + /// Converts the value from Byte to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Byte p) { return p; } + /// Converts the value from Char to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Char p) { return p; } + /// Converts the value from DateTime to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(DateTime p) { return (p - DateTime.MinValue).Ticks; } + /// Converts the value from DateTimeOffset to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(DateTimeOffset p) { return (p - DateTime.MinValue).Ticks; } + /// Converts the value from Decimal to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Decimal p) { return checked((Int64)p); } + /// Converts the value from Double to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Double p) { return checked((Int64)p); } + /// Converts the value from Int16 to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Int64 p) { return p; } + /// Converts the value from SByte to an equivalent SqlInt64 value. + [CLSCompliant(false)] + public static SqlInt64 ToSqlInt64(SByte p) { return p; } + /// Converts the value from Single to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Single p) { return checked((Int64)p); } + /// Converts the value from String to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(String p) { return p == null? SqlInt64.Null : Int64.Parse(p); } + /// Converts the value from TimeSpan to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(TimeSpan p) { return p.Ticks; } + /// Converts the value from UInt16 to an equivalent SqlInt64 value. + [CLSCompliant(false)] + public static SqlInt64 ToSqlInt64(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent SqlInt64 value. + [CLSCompliant(false)] + public static SqlInt64 ToSqlInt64(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent SqlInt64 value. + [CLSCompliant(false)] + public static SqlInt64 ToSqlInt64(UInt64 p) { return checked((Int64)p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Boolean? p) { return p.HasValue && p.Value ? (SqlInt64)1: (SqlInt64)0; } + /// Converts the value from Byte? to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Byte? p) { return p.HasValue ? p.Value : SqlInt64.Null; } + /// Converts the value from Char? to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Char? p) { return p.HasValue ? p.Value : SqlInt64.Null; } + /// Converts the value from DateTime? to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(DateTime? p) { return p.HasValue ? (p.Value - DateTime.MinValue).Ticks : 0; } + /// Converts the value from DateTimeOffset? to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(DateTimeOffset? p) { return p.HasValue ? (p.Value - DateTime.MinValue).Ticks : 0; } + /// Converts the value from Decimal? to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Decimal? p) { return p.HasValue ? checked((Int64)p.Value) : SqlInt64.Null; } + /// Converts the value from Double? to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Double? p) { return p.HasValue ? checked((Int64)p.Value) : SqlInt64.Null; } + /// Converts the value from Int16? to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Int16? p) { return p.HasValue ? p.Value : SqlInt64.Null; } + /// Converts the value from Int32? to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Int32? p) { return p.HasValue ? p.Value : SqlInt64.Null; } + /// Converts the value from Int64? to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Int64? p) { return p.HasValue ? p.Value : SqlInt64.Null; } + /// Converts the value from SByte? to an equivalent SqlInt64 value. + [CLSCompliant(false)] + public static SqlInt64 ToSqlInt64(SByte? p) { return p.HasValue ? p.Value : SqlInt64.Null; } + /// Converts the value from Single? to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Single? p) { return p.HasValue ? checked((Int64)p.Value) : SqlInt64.Null; } + /// Converts the value from TimeSpan? to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(TimeSpan? p) { return p.HasValue ? p.Value.Ticks : 0; } + /// Converts the value from UInt16? to an equivalent SqlInt64 value. + [CLSCompliant(false)] + public static SqlInt64 ToSqlInt64(UInt16? p) { return p.HasValue ? p.Value : SqlInt64.Null; } + /// Converts the value from UInt32? to an equivalent SqlInt64 value. + [CLSCompliant(false)] + public static SqlInt64 ToSqlInt64(UInt32? p) { return p.HasValue ? p.Value : SqlInt64.Null; } + /// Converts the value from UInt64? to an equivalent SqlInt64 value. + [CLSCompliant(false)] + public static SqlInt64 ToSqlInt64(UInt64? p) { return p.HasValue ? checked((Int64)p.Value) : SqlInt64.Null; } + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(SqlBoolean p) { return p.ToSqlInt64(); } + /// Converts the value from SqlByte to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(SqlByte p) { return p.ToSqlInt64(); } + /// Converts the value from SqlDateTime to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(SqlDateTime p) { return p.IsNull? SqlInt64.Null: ToInt64(p.Value); } + /// Converts the value from SqlDecimal to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(SqlDecimal p) { return p.ToSqlInt64(); } + /// Converts the value from SqlDouble to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(SqlDouble p) { return p.ToSqlInt64(); } + /// Converts the value from SqlInt16 to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(SqlInt16 p) { return p.ToSqlInt64(); } + /// Converts the value from SqlInt32 to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(SqlInt32 p) { return p.ToSqlInt64(); } + /// Converts the value from SqlMoney to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(SqlMoney p) { return p.ToSqlInt64(); } + /// Converts the value from SqlSingle to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(SqlSingle p) { return p.ToSqlInt64(); } + /// Converts the value from SqlString to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(SqlString p) { return p.ToSqlInt64(); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Binary p) { return p == null || p.Length == 0 ? SqlInt64.Null : BitConverter.ToInt64(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(Byte[] p) { return p == null || p.Length == 0 ? SqlInt64.Null : BitConverter.ToInt64(p, 0); } + + // From Object + // + /// Converts the value from Object to an equivalent SqlInt64 value. + public static SqlInt64 ToSqlInt64(object p) + { + if (p == null) return SqlInt64.Null; + + if (p is SqlInt64) return (SqlInt64)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlInt64.Null; + case TypeCode.DateTime : return ToSqlInt64((DateTime)p); + case TypeCode.SByte : return ToSqlInt64((SByte) p); + case TypeCode.Int16 : return ToSqlInt64((Int16) p); + case TypeCode.Int32 : return ToSqlInt64((Int32) p); + case TypeCode.Int64 : return ToSqlInt64((Int64) p); + case TypeCode.Byte : return ToSqlInt64((Byte) p); + case TypeCode.UInt16 : return ToSqlInt64((UInt16) p); + case TypeCode.UInt32 : return ToSqlInt64((UInt32) p); + case TypeCode.Char : return ToSqlInt64((Char) p); + case TypeCode.UInt64 : return ToSqlInt64((UInt64) p); + case TypeCode.Single : return ToSqlInt64((Single) p); + case TypeCode.Double : return ToSqlInt64((Double) p); + case TypeCode.Decimal : return ToSqlInt64((Decimal) p); + case TypeCode.String : return ToSqlInt64((String) p); + case TypeCode.Boolean : return ToSqlInt64((Boolean) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToSqlInt64((DateTimeOffset) p); + if (p is TimeSpan) return ToSqlInt64((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSqlInt64((Boolean?) p); + if (p is Byte?) return ToSqlInt64((Byte?) p); + if (p is Char?) return ToSqlInt64((Char?) p); + if (p is DateTime?) return ToSqlInt64((DateTime?) p); + if (p is DateTimeOffset?) return ToSqlInt64((DateTimeOffset?)p); + if (p is Decimal?) return ToSqlInt64((Decimal?) p); + if (p is Double?) return ToSqlInt64((Double?) p); + if (p is Int16?) return ToSqlInt64((Int16?) p); + if (p is Int32?) return ToSqlInt64((Int32?) p); + if (p is Int64?) return ToSqlInt64((Int64?) p); + if (p is SByte?) return ToSqlInt64((SByte?) p); + if (p is Single?) return ToSqlInt64((Single?) p); + if (p is TimeSpan?) return ToSqlInt64((TimeSpan?) p); + if (p is UInt16?) return ToSqlInt64((UInt16?) p); + if (p is UInt32?) return ToSqlInt64((UInt32?) p); + if (p is UInt64?) return ToSqlInt64((UInt64?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToSqlInt64((SqlBoolean) p); + if (p is SqlByte) return ToSqlInt64((SqlByte) p); + if (p is SqlDateTime) return ToSqlInt64((SqlDateTime) p); + if (p is SqlDecimal) return ToSqlInt64((SqlDecimal) p); + if (p is SqlDouble) return ToSqlInt64((SqlDouble) p); + if (p is SqlInt16) return ToSqlInt64((SqlInt16) p); + if (p is SqlInt32) return ToSqlInt64((SqlInt32) p); + if (p is SqlMoney) return ToSqlInt64((SqlMoney) p); + if (p is SqlSingle) return ToSqlInt64((SqlSingle) p); + if (p is SqlString) return ToSqlInt64((SqlString) p); + } + + // Other Types + // + if (p is Binary) return ToSqlInt64((Binary) p); + if (p is Byte[]) return ToSqlInt64((Byte[]) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlInt64)); + } + +#endif + + #endregion + + #region SqlMoney + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Boolean p) { return p ? (SqlMoney)1 : (SqlMoney)0; } + /// Converts the value from Byte to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Byte p) { return p; } + /// Converts the value from Char to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Char p) { return p; } + /// Converts the value from Decimal to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Decimal p) { return p; } + /// Converts the value from Double to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Double p) { return checked((Decimal)p); } + /// Converts the value from Int16 to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Int64 p) { return p; } + /// Converts the value from SByte to an equivalent SqlMoney value. + [CLSCompliant(false)] + public static SqlMoney ToSqlMoney(SByte p) { return p; } + /// Converts the value from Single to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Single p) { return checked((Decimal)p); } + /// Converts the value from String to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(String p) { return p == null? SqlMoney.Null : Decimal.Parse(p); } + /// Converts the value from UInt16 to an equivalent SqlMoney value. + [CLSCompliant(false)] + public static SqlMoney ToSqlMoney(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent SqlMoney value. + [CLSCompliant(false)] + public static SqlMoney ToSqlMoney(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent SqlMoney value. + [CLSCompliant(false)] + public static SqlMoney ToSqlMoney(UInt64 p) { return p; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Boolean? p) { return p.HasValue && p.Value ? (SqlMoney)1: (SqlMoney)0; } + /// Converts the value from Byte? to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Byte? p) { return p.HasValue ? p.Value : SqlMoney.Null; } + /// Converts the value from Char? to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Char? p) { return p.HasValue ? p.Value : SqlMoney.Null; } + /// Converts the value from Decimal? to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Decimal? p) { return p.HasValue ? p.Value : SqlMoney.Null; } + /// Converts the value from Double? to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Double? p) { return p.HasValue ? checked((Decimal)p.Value) : SqlMoney.Null; } + /// Converts the value from Int16? to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Int16? p) { return p.HasValue ? p.Value : SqlMoney.Null; } + /// Converts the value from Int32? to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Int32? p) { return p.HasValue ? p.Value : SqlMoney.Null; } + /// Converts the value from Int64? to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Int64? p) { return p.HasValue ? p.Value : SqlMoney.Null; } + /// Converts the value from SByte? to an equivalent SqlMoney value. + [CLSCompliant(false)] + public static SqlMoney ToSqlMoney(SByte? p) { return p.HasValue ? p.Value : SqlMoney.Null; } + /// Converts the value from Single? to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Single? p) { return p.HasValue ? checked((Decimal)p.Value) : SqlMoney.Null; } + /// Converts the value from UInt16? to an equivalent SqlMoney value. + [CLSCompliant(false)] + public static SqlMoney ToSqlMoney(UInt16? p) { return p.HasValue ? p.Value : SqlMoney.Null; } + /// Converts the value from UInt32? to an equivalent SqlMoney value. + [CLSCompliant(false)] + public static SqlMoney ToSqlMoney(UInt32? p) { return p.HasValue ? p.Value : SqlMoney.Null; } + /// Converts the value from UInt64? to an equivalent SqlMoney value. + [CLSCompliant(false)] + public static SqlMoney ToSqlMoney(UInt64? p) { return p.HasValue ? p.Value : SqlMoney.Null; } + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(SqlBoolean p) { return p.ToSqlMoney(); } + /// Converts the value from SqlByte to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(SqlByte p) { return p.ToSqlMoney(); } + /// Converts the value from SqlDecimal to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(SqlDecimal p) { return p.ToSqlMoney(); } + /// Converts the value from SqlDouble to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(SqlDouble p) { return p.ToSqlMoney(); } + /// Converts the value from SqlInt16 to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(SqlInt16 p) { return p.ToSqlMoney(); } + /// Converts the value from SqlInt32 to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(SqlInt32 p) { return p.ToSqlMoney(); } + /// Converts the value from SqlInt64 to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(SqlInt64 p) { return p.ToSqlMoney(); } + /// Converts the value from SqlSingle to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(SqlSingle p) { return p.ToSqlMoney(); } + /// Converts the value from SqlString to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(SqlString p) { return p.ToSqlMoney(); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Binary p) { return p == null || p.Length == 0 ? SqlMoney.Null : ToDecimal(p); } + /// Converts the value from Byte[] to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(Byte[] p) { return p == null || p.Length == 0 ? SqlMoney.Null : ToDecimal(p); } + + // From Object + // + /// Converts the value from Object to an equivalent SqlMoney value. + public static SqlMoney ToSqlMoney(object p) + { + if (p == null) return SqlMoney.Null; + + if (p is SqlMoney) return (SqlMoney)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlMoney.Null; + case TypeCode.SByte : return ToSqlMoney((SByte) p); + case TypeCode.Int16 : return ToSqlMoney((Int16) p); + case TypeCode.Int32 : return ToSqlMoney((Int32) p); + case TypeCode.Int64 : return ToSqlMoney((Int64) p); + case TypeCode.Byte : return ToSqlMoney((Byte) p); + case TypeCode.UInt16 : return ToSqlMoney((UInt16) p); + case TypeCode.UInt32 : return ToSqlMoney((UInt32) p); + case TypeCode.Char : return ToSqlMoney((Char) p); + case TypeCode.UInt64 : return ToSqlMoney((UInt64) p); + case TypeCode.Decimal : return ToSqlMoney((Decimal) p); + case TypeCode.Single : return ToSqlMoney((Single) p); + case TypeCode.Double : return ToSqlMoney((Double) p); + case TypeCode.String : return ToSqlMoney((String) p); + case TypeCode.Boolean : return ToSqlMoney((Boolean) p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSqlMoney((Boolean?) p); + if (p is Byte?) return ToSqlMoney((Byte?) p); + if (p is Char?) return ToSqlMoney((Char?) p); + if (p is Decimal?) return ToSqlMoney((Decimal?) p); + if (p is Double?) return ToSqlMoney((Double?) p); + if (p is Int16?) return ToSqlMoney((Int16?) p); + if (p is Int32?) return ToSqlMoney((Int32?) p); + if (p is Int64?) return ToSqlMoney((Int64?) p); + if (p is SByte?) return ToSqlMoney((SByte?) p); + if (p is Single?) return ToSqlMoney((Single?) p); + if (p is UInt16?) return ToSqlMoney((UInt16?) p); + if (p is UInt32?) return ToSqlMoney((UInt32?) p); + if (p is UInt64?) return ToSqlMoney((UInt64?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToSqlMoney((SqlBoolean)p); + if (p is SqlByte) return ToSqlMoney((SqlByte) p); + if (p is SqlDecimal) return ToSqlMoney((SqlDecimal)p); + if (p is SqlDouble) return ToSqlMoney((SqlDouble) p); + if (p is SqlInt16) return ToSqlMoney((SqlInt16) p); + if (p is SqlInt32) return ToSqlMoney((SqlInt32) p); + if (p is SqlInt64) return ToSqlMoney((SqlInt64) p); + if (p is SqlSingle) return ToSqlMoney((SqlSingle) p); + if (p is SqlString) return ToSqlMoney((SqlString) p); + } + + // Other Types + // + if (p is Binary) return ToSqlMoney((Binary) p); + if (p is Byte[]) return ToSqlMoney((Byte[]) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlMoney)); + } + +#endif + + #endregion + + #region SqlSingle + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Boolean p) { return p ? (SqlSingle)1 : (SqlSingle)0; } + /// Converts the value from Byte to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Byte p) { return p; } + /// Converts the value from Char to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Char p) { return p; } + /// Converts the value from Decimal to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Decimal p) { return checked((Single)p); } + /// Converts the value from Double to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Double p) { return checked((Single)p); } + /// Converts the value from Int16 to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Int16 p) { return p; } + /// Converts the value from Int32 to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Int32 p) { return p; } + /// Converts the value from Int64 to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Int64 p) { return p; } + /// Converts the value from SByte to an equivalent SqlSingle value. + [CLSCompliant(false)] + public static SqlSingle ToSqlSingle(SByte p) { return p; } + /// Converts the value from Single to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Single p) { return p; } + /// Converts the value from String to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(String p) { return p == null? SqlSingle.Null : Single.Parse(p); } + /// Converts the value from UInt16 to an equivalent SqlSingle value. + [CLSCompliant(false)] + public static SqlSingle ToSqlSingle(UInt16 p) { return p; } + /// Converts the value from UInt32 to an equivalent SqlSingle value. + [CLSCompliant(false)] + public static SqlSingle ToSqlSingle(UInt32 p) { return p; } + /// Converts the value from UInt64 to an equivalent SqlSingle value. + [CLSCompliant(false)] + public static SqlSingle ToSqlSingle(UInt64 p) { return p; } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Boolean? p) { return p.HasValue && p.Value ? (SqlSingle)1: (SqlSingle)0; } + /// Converts the value from Byte? to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Byte? p) { return p.HasValue ? p.Value : SqlSingle.Null; } + /// Converts the value from Char? to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Char? p) { return p.HasValue ? p.Value : SqlSingle.Null; } + /// Converts the value from Decimal? to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Decimal? p) { return p.HasValue ? checked((Single)p.Value) : SqlSingle.Null; } + /// Converts the value from Double? to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Double? p) { return p.HasValue ? checked((Single)p.Value) : SqlSingle.Null; } + /// Converts the value from Int16? to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Int16? p) { return p.HasValue ? p.Value : SqlSingle.Null; } + /// Converts the value from Int32? to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Int32? p) { return p.HasValue ? p.Value : SqlSingle.Null; } + /// Converts the value from Int64? to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Int64? p) { return p.HasValue ? p.Value : SqlSingle.Null; } + /// Converts the value from SByte? to an equivalent SqlSingle value. + [CLSCompliant(false)] + public static SqlSingle ToSqlSingle(SByte? p) { return p.HasValue ? p.Value : SqlSingle.Null; } + /// Converts the value from Single? to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Single? p) { return p.HasValue ? p.Value : SqlSingle.Null; } + /// Converts the value from UInt16? to an equivalent SqlSingle value. + [CLSCompliant(false)] + public static SqlSingle ToSqlSingle(UInt16? p) { return p.HasValue ? p.Value : SqlSingle.Null; } + /// Converts the value from UInt32? to an equivalent SqlSingle value. + [CLSCompliant(false)] + public static SqlSingle ToSqlSingle(UInt32? p) { return p.HasValue ? p.Value : SqlSingle.Null; } + /// Converts the value from UInt64? to an equivalent SqlSingle value. + [CLSCompliant(false)] + public static SqlSingle ToSqlSingle(UInt64? p) { return p.HasValue ? p.Value : SqlSingle.Null; } + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(SqlBoolean p) { return p.ToSqlSingle(); } + /// Converts the value from SqlByte to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(SqlByte p) { return p.ToSqlSingle(); } + /// Converts the value from SqlDecimal to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(SqlDecimal p) { return p.ToSqlSingle(); } + /// Converts the value from SqlDouble to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(SqlDouble p) { return p.ToSqlSingle(); } + /// Converts the value from SqlInt16 to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(SqlInt16 p) { return p.ToSqlSingle(); } + /// Converts the value from SqlInt32 to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(SqlInt32 p) { return p.ToSqlSingle(); } + /// Converts the value from SqlInt64 to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(SqlInt64 p) { return p.ToSqlSingle(); } + /// Converts the value from SqlMoney to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(SqlMoney p) { return p.ToSqlSingle(); } + /// Converts the value from SqlString to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(SqlString p) { return p.ToSqlSingle(); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Binary p) { return p == null || p.Length == 0 ? SqlSingle.Null : BitConverter.ToSingle(p.ToArray(), 0); } + /// Converts the value from Byte[] to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(Byte[] p) { return p == null || p.Length == 0 ? SqlSingle.Null : BitConverter.ToSingle(p, 0); } + + // From Object + // + /// Converts the value from Object to an equivalent SqlSingle value. + public static SqlSingle ToSqlSingle(object p) + { + if (p == null) return SqlSingle.Null; + + if (p is SqlSingle) return (SqlSingle)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlSingle.Null; + case TypeCode.SByte : return ToSqlSingle((SByte) p); + case TypeCode.Int16 : return ToSqlSingle((Int16) p); + case TypeCode.Int32 : return ToSqlSingle((Int32) p); + case TypeCode.Int64 : return ToSqlSingle((Int64) p); + case TypeCode.Byte : return ToSqlSingle((Byte) p); + case TypeCode.UInt16 : return ToSqlSingle((UInt16) p); + case TypeCode.UInt32 : return ToSqlSingle((UInt32) p); + case TypeCode.Char : return ToSqlSingle((Char) p); + case TypeCode.UInt64 : return ToSqlSingle((UInt64) p); + case TypeCode.Single : return ToSqlSingle((Single) p); + case TypeCode.Double : return ToSqlSingle((Double) p); + case TypeCode.Decimal : return ToSqlSingle((Decimal) p); + case TypeCode.String : return ToSqlSingle((String) p); + case TypeCode.Boolean : return ToSqlSingle((Boolean) p); + } + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSqlSingle((Boolean?) p); + if (p is Byte?) return ToSqlSingle((Byte?) p); + if (p is Char?) return ToSqlSingle((Char?) p); + if (p is Decimal?) return ToSqlSingle((Decimal?) p); + if (p is Double?) return ToSqlSingle((Double?) p); + if (p is Int16?) return ToSqlSingle((Int16?) p); + if (p is Int32?) return ToSqlSingle((Int32?) p); + if (p is Int64?) return ToSqlSingle((Int64?) p); + if (p is SByte?) return ToSqlSingle((SByte?) p); + if (p is Single?) return ToSqlSingle((Single?) p); + if (p is UInt16?) return ToSqlSingle((UInt16?) p); + if (p is UInt32?) return ToSqlSingle((UInt32?) p); + if (p is UInt64?) return ToSqlSingle((UInt64?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToSqlSingle((SqlBoolean)p); + if (p is SqlByte) return ToSqlSingle((SqlByte) p); + if (p is SqlDecimal) return ToSqlSingle((SqlDecimal)p); + if (p is SqlDouble) return ToSqlSingle((SqlDouble) p); + if (p is SqlInt16) return ToSqlSingle((SqlInt16) p); + if (p is SqlInt32) return ToSqlSingle((SqlInt32) p); + if (p is SqlInt64) return ToSqlSingle((SqlInt64) p); + if (p is SqlMoney) return ToSqlSingle((SqlMoney) p); + if (p is SqlString) return ToSqlSingle((SqlString) p); + } + + // Other Types + // + if (p is Binary) return ToSqlSingle((Binary) p); + if (p is Byte[]) return ToSqlSingle((Byte[]) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlSingle)); + } + +#endif + + #endregion + + #region SqlString + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from Boolean to an equivalent SqlString value. + public static SqlString ToSqlString(Boolean p) { return p.ToString(); } + /// Converts the value from Byte to an equivalent SqlString value. + public static SqlString ToSqlString(Byte p) { return p.ToString(); } + /// Converts the value from Char to an equivalent SqlString value. + public static SqlString ToSqlString(Char p) { return p.ToString(); } + /// Converts the value from DateTime to an equivalent SqlString value. + public static SqlString ToSqlString(DateTime p) { return p.ToString(); } + /// Converts the value from DateTimeOffset to an equivalent SqlString value. + public static SqlString ToSqlString(DateTimeOffset p) { return p.ToString(); } + /// Converts the value from Decimal to an equivalent SqlString value. + public static SqlString ToSqlString(Decimal p) { return p.ToString(); } + /// Converts the value from Double to an equivalent SqlString value. + public static SqlString ToSqlString(Double p) { return p.ToString(); } + /// Converts the value from Guid to an equivalent SqlString value. + public static SqlString ToSqlString(Guid p) { return p.ToString(); } + /// Converts the value from Int16 to an equivalent SqlString value. + public static SqlString ToSqlString(Int16 p) { return p.ToString(); } + /// Converts the value from Int32 to an equivalent SqlString value. + public static SqlString ToSqlString(Int32 p) { return p.ToString(); } + /// Converts the value from Int64 to an equivalent SqlString value. + public static SqlString ToSqlString(Int64 p) { return p.ToString(); } + /// Converts the value from SByte to an equivalent SqlString value. + [CLSCompliant(false)] + public static SqlString ToSqlString(SByte p) { return p.ToString(); } + /// Converts the value from Single to an equivalent SqlString value. + public static SqlString ToSqlString(Single p) { return p.ToString(); } + /// Converts the value from String to an equivalent SqlString value. + public static SqlString ToSqlString(String p) { return p ?? SqlString.Null; } + /// Converts the value from TimeSpan to an equivalent SqlString value. + public static SqlString ToSqlString(TimeSpan p) { return p.ToString(); } + /// Converts the value from UInt16 to an equivalent SqlString value. + [CLSCompliant(false)] + public static SqlString ToSqlString(UInt16 p) { return p.ToString(); } + /// Converts the value from UInt32 to an equivalent SqlString value. + [CLSCompliant(false)] + public static SqlString ToSqlString(UInt32 p) { return p.ToString(); } + /// Converts the value from UInt64 to an equivalent SqlString value. + [CLSCompliant(false)] + public static SqlString ToSqlString(UInt64 p) { return p.ToString(); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent SqlString value. + public static SqlString ToSqlString(Boolean? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from Byte? to an equivalent SqlString value. + public static SqlString ToSqlString(Byte? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from Char? to an equivalent SqlString value. + public static SqlString ToSqlString(Char? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from DateTime? to an equivalent SqlString value. + public static SqlString ToSqlString(DateTime? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from DateTimeOffset? to an equivalent SqlString value. + public static SqlString ToSqlString(DateTimeOffset? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from Decimal? to an equivalent SqlString value. + public static SqlString ToSqlString(Decimal? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from Double? to an equivalent SqlString value. + public static SqlString ToSqlString(Double? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from Guid? to an equivalent SqlString value. + public static SqlString ToSqlString(Guid? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from Int16? to an equivalent SqlString value. + public static SqlString ToSqlString(Int16? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from Int32? to an equivalent SqlString value. + public static SqlString ToSqlString(Int32? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from Int64? to an equivalent SqlString value. + public static SqlString ToSqlString(Int64? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from SByte? to an equivalent SqlString value. + [CLSCompliant(false)] + public static SqlString ToSqlString(SByte? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from Single? to an equivalent SqlString value. + public static SqlString ToSqlString(Single? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from TimeSpan? to an equivalent SqlString value. + public static SqlString ToSqlString(TimeSpan? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from UInt16? to an equivalent SqlString value. + [CLSCompliant(false)] + public static SqlString ToSqlString(UInt16? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from UInt32? to an equivalent SqlString value. + [CLSCompliant(false)] + public static SqlString ToSqlString(UInt32? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + /// Converts the value from UInt64? to an equivalent SqlString value. + [CLSCompliant(false)] + public static SqlString ToSqlString(UInt64? p) { return p.HasValue ? p.Value.ToString() : SqlString.Null; } + + // Sql Types + // + /// Converts the value from SqlBoolean to an equivalent SqlString value. + public static SqlString ToSqlString(SqlBoolean p) { return p.ToSqlString(); } + /// Converts the value from SqlByte to an equivalent SqlString value. + public static SqlString ToSqlString(SqlByte p) { return p.ToSqlString(); } + /// Converts the value from SqlChars to an equivalent SqlString value. + public static SqlString ToSqlString(SqlChars p) { return p.ToSqlString(); } + /// Converts the value from SqlDecimal to an equivalent SqlString value. + public static SqlString ToSqlString(SqlDecimal p) { return p.ToSqlString(); } + /// Converts the value from SqlDouble to an equivalent SqlString value. + public static SqlString ToSqlString(SqlDouble p) { return p.ToSqlString(); } + /// Converts the value from SqlGuid to an equivalent SqlString value. + public static SqlString ToSqlString(SqlGuid p) { return p.ToSqlString(); } + /// Converts the value from SqlInt16 to an equivalent SqlString value. + public static SqlString ToSqlString(SqlInt16 p) { return p.ToSqlString(); } + /// Converts the value from SqlInt32 to an equivalent SqlString value. + public static SqlString ToSqlString(SqlInt32 p) { return p.ToSqlString(); } + /// Converts the value from SqlInt64 to an equivalent SqlString value. + public static SqlString ToSqlString(SqlInt64 p) { return p.ToSqlString(); } + /// Converts the value from SqlMoney to an equivalent SqlString value. + public static SqlString ToSqlString(SqlMoney p) { return p.ToSqlString(); } + /// Converts the value from SqlSingle to an equivalent SqlString value. + public static SqlString ToSqlString(SqlSingle p) { return p.ToSqlString(); } + /// Converts the value from SqlXml to an equivalent SqlString value. + public static SqlString ToSqlString(SqlXml p) { return p.IsNull ? SqlString.Null : p.Value; } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlString value. + public static SqlString ToSqlString(Binary p) { return ToSqlString(p.ToArray()); } + /// Converts the value from Byte[] to an equivalent SqlString value. + public static SqlString ToSqlString(Byte[] p) { return p == null ? SqlString.Null : System.Text.Encoding.UTF8.GetString(p, 0, p.Length); } + /// Converts the value from Type to an equivalent SqlString value. + public static SqlString ToSqlString(Type p) { return p == null ? SqlString.Null : p.FullName; } + /// Converts the value from XElement to an equivalent SqlString value. + public static SqlString ToSqlString(XElement p) { return p == null ? SqlString.Null : p.ToString(); } + /// Converts the value from XmlDocument to an equivalent SqlString value. + public static SqlString ToSqlString(XmlDocument p) { return p == null ? SqlString.Null : p.InnerXml; } + + // From Object + // + /// Converts the value from Object to an equivalent SqlString value. + public static SqlString ToSqlString(object p) + { + if (p == null) return SqlString.Null; + + if (p is SqlString) return (SqlString)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlString.Null; + case TypeCode.SByte : return ToSqlString((SByte) p); + case TypeCode.Int16 : return ToSqlString((Int16) p); + case TypeCode.Int32 : return ToSqlString((Int32) p); + case TypeCode.Int64 : return ToSqlString((Int64) p); + case TypeCode.Byte : return ToSqlString((Byte) p); + case TypeCode.UInt16 : return ToSqlString((UInt16) p); + case TypeCode.UInt32 : return ToSqlString((UInt32) p); + case TypeCode.UInt64 : return ToSqlString((UInt64) p); + case TypeCode.Single : return ToSqlString((Single) p); + case TypeCode.Double : return ToSqlString((Double) p); + case TypeCode.Boolean : return ToSqlString((Boolean) p); + case TypeCode.Decimal : return ToSqlString((Decimal) p); + case TypeCode.Char : return ToSqlString((Char) p); + case TypeCode.DateTime : return ToSqlString((DateTime) p); + case TypeCode.String : return ToSqlString((String) p); + } + + // Simple Types + // + if (p is DateTimeOffset) return ToSqlString((DateTimeOffset) p); + if (p is Guid) return ToSqlString((Guid) p); + if (p is TimeSpan) return ToSqlString((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToSqlString((Boolean?) p); + if (p is Byte?) return ToSqlString((Byte?) p); + if (p is Char?) return ToSqlString((Char?) p); + if (p is DateTime?) return ToSqlString((DateTime?) p); + if (p is DateTimeOffset?) return ToSqlString((DateTimeOffset?)p); + if (p is Decimal?) return ToSqlString((Decimal?) p); + if (p is Double?) return ToSqlString((Double?) p); + if (p is Guid?) return ToSqlString((Guid?) p); + if (p is Int16?) return ToSqlString((Int16?) p); + if (p is Int32?) return ToSqlString((Int32?) p); + if (p is Int64?) return ToSqlString((Int64?) p); + if (p is SByte?) return ToSqlString((SByte?) p); + if (p is Single?) return ToSqlString((Single?) p); + if (p is TimeSpan?) return ToSqlString((TimeSpan?) p); + if (p is UInt16?) return ToSqlString((UInt16?) p); + if (p is UInt32?) return ToSqlString((UInt32?) p); + if (p is UInt64?) return ToSqlString((UInt64?) p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBoolean) return ToSqlString((SqlBoolean) p); + if (p is SqlByte) return ToSqlString((SqlByte) p); + if (p is SqlChars) return ToSqlString((SqlChars) p); + if (p is SqlDecimal) return ToSqlString((SqlDecimal) p); + if (p is SqlDouble) return ToSqlString((SqlDouble) p); + if (p is SqlGuid) return ToSqlString((SqlGuid) p); + if (p is SqlInt16) return ToSqlString((SqlInt16) p); + if (p is SqlInt32) return ToSqlString((SqlInt32) p); + if (p is SqlInt64) return ToSqlString((SqlInt64) p); + if (p is SqlMoney) return ToSqlString((SqlMoney) p); + if (p is SqlSingle) return ToSqlString((SqlSingle) p); + if (p is SqlXml) return ToSqlString((SqlXml) p); + } + + // Other Types + // + if (p is Binary) return ToSqlString((Binary) p); + if (p is Byte[]) return ToSqlString((Byte[]) p); + if (p is Type) return ToSqlString((Type) p); + if (p is XElement) return ToSqlString((XElement) p); + if (p is XmlDocument) return ToSqlString((XmlDocument) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlString)); + } + +#endif + + #endregion + + #region SqlXml + +#if !SILVERLIGHT + + // Simple Types + // + /// Converts the value from String to an equivalent SqlXml value. + public static SqlXml ToSqlXml(String p) { return p == null ? SqlXml.Null : new SqlXml(new XmlTextReader(new StringReader(p))); } + + // Sql Types + // + /// Converts the value from SqlBinary to an equivalent SqlXml value. + public static SqlXml ToSqlXml(SqlBinary p) { return p.IsNull ? SqlXml.Null : new SqlXml(new MemoryStream(p.Value)); } + /// Converts the value from SqlBytes to an equivalent SqlXml value. + public static SqlXml ToSqlXml(SqlBytes p) { return p.IsNull ? SqlXml.Null : new SqlXml(p.Stream); } + /// Converts the value from SqlChars to an equivalent SqlXml value. + public static SqlXml ToSqlXml(SqlChars p) { return p.IsNull ? SqlXml.Null : new SqlXml(new XmlTextReader(new StringReader(p.ToSqlString().Value))); } + /// Converts the value from SqlString to an equivalent SqlXml value. + public static SqlXml ToSqlXml(SqlString p) { return p.IsNull ? SqlXml.Null : new SqlXml(new XmlTextReader(new StringReader(p.Value))); } + + // Other Types + // + /// Converts the value from Binary to an equivalent SqlXml value. + public static SqlXml ToSqlXml(Binary p) { return p == null ? SqlXml.Null : new SqlXml(new MemoryStream(p.ToArray())); } + /// Converts the value from Byte[] to an equivalent SqlXml value. + public static SqlXml ToSqlXml(Byte[] p) { return p == null ? SqlXml.Null : new SqlXml(new MemoryStream(p)); } + /// Converts the value from Char[] to an equivalent SqlXml value. + public static SqlXml ToSqlXml(Char[] p) { return p == null ? SqlXml.Null : new SqlXml(new XmlTextReader(new StringReader(new string(p)))); } + /// Converts the value from Stream to an equivalent SqlXml value. + public static SqlXml ToSqlXml(Stream p) { return p == null ? SqlXml.Null : new SqlXml(p); } + /// Converts the value from XElement to an equivalent SqlXml value. + public static SqlXml ToSqlXml(XElement p) { return p == null ? SqlXml.Null : new SqlXml(new XmlTextReader(new StringReader(p.ToString()))); } + /// Converts the value from XmlDocument to an equivalent SqlXml value. + public static SqlXml ToSqlXml(XmlDocument p) { return p == null ? SqlXml.Null : new SqlXml(new XmlTextReader(new StringReader(p.InnerXml))); } + /// Converts the value from XmlReader to an equivalent SqlXml value. + public static SqlXml ToSqlXml(XmlReader p) { return p == null ? SqlXml.Null : new SqlXml(p); } + + // From Object + // + /// Converts the value from Object to an equivalent SqlXml value. + public static SqlXml ToSqlXml(object p) + { + if (p == null) return SqlXml.Null; + + if (p is SqlXml) return (SqlXml)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return SqlXml.Null; + case TypeCode.String : return ToSqlXml((String)p); + } + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBinary) return ToSqlXml((SqlBinary) p); + if (p is SqlBytes) return ToSqlXml((SqlBytes) p); + if (p is SqlChars) return ToSqlXml((SqlChars) p); + if (p is SqlString) return ToSqlXml((SqlString) p); + } + + // Other Types + // + if (p is Binary) return ToSqlXml((Binary) p); + if (p is Byte[]) return ToSqlXml((Byte[]) p); + if (p is Char[]) return ToSqlXml((Char[]) p); + if (p is Stream) return ToSqlXml((Stream) p); + if (p is XElement) return ToSqlXml((XElement) p); + if (p is XmlDocument) return ToSqlXml((XmlDocument)p); + if (p is XmlReader) return ToSqlXml((XmlReader) p); + + throw CreateInvalidCastException(p.GetType(), typeof(SqlXml)); + } + +#endif + + #endregion + + #endregion + + #region Other Types + + #region Binary + + #endregion + + #region Byte[] + + // Simple Types + // + /// Converts the value from Boolean to an equivalent Byte[] value. + public static Byte[] ToByteArray(Boolean p) { return BitConverter.GetBytes(p); } + /// Converts the value from Byte to an equivalent Byte[] value. + public static Byte[] ToByteArray(Byte p) { return new[] { p }; } + /// Converts the value from Char to an equivalent Byte[] value. + public static Byte[] ToByteArray(Char p) { return BitConverter.GetBytes(p); } +#if !SILVERLIGHT + /// Converts the value from DateTime to an equivalent Byte[] value. + public static Byte[] ToByteArray(DateTime p) { return ToByteArray(p.ToBinary()); } +#endif +#if !SILVERLIGHT + /// Converts the value from DateTimeOffset to an equivalent Byte[] value. + public static Byte[] ToByteArray(DateTimeOffset p) { return ToByteArray(p.LocalDateTime.ToBinary()); } +#endif + /// Converts the value from Double to an equivalent Byte[] value. + public static Byte[] ToByteArray(Double p) { return BitConverter.GetBytes(p); } + /// Converts the value from Guid to an equivalent Byte[] value. + public static Byte[] ToByteArray(Guid p) { return p == Guid.Empty ? (Byte[])null : p.ToByteArray(); } + /// Converts the value from Int16 to an equivalent Byte[] value. + public static Byte[] ToByteArray(Int16 p) { return BitConverter.GetBytes(p); } + /// Converts the value from Int32 to an equivalent Byte[] value. + public static Byte[] ToByteArray(Int32 p) { return BitConverter.GetBytes(p); } + /// Converts the value from Int64 to an equivalent Byte[] value. + public static Byte[] ToByteArray(Int64 p) { return BitConverter.GetBytes(p); } + /// Converts the value from SByte to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Byte[] ToByteArray(SByte p) { return new[] { checked((Byte)p) }; } + /// Converts the value from Single to an equivalent Byte[] value. + public static Byte[] ToByteArray(Single p) { return BitConverter.GetBytes(p); } + /// Converts the value from String to an equivalent Byte[] value. + public static Byte[] ToByteArray(String p) { return p == null ? (Byte[])null : System.Text.Encoding.UTF8.GetBytes(p); } + /// Converts the value from TimeSpan to an equivalent Byte[] value. + public static Byte[] ToByteArray(TimeSpan p) { return ToByteArray(p.Ticks); } + /// Converts the value from UInt16 to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Byte[] ToByteArray(UInt16 p) { return BitConverter.GetBytes(p); } + /// Converts the value from UInt32 to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Byte[] ToByteArray(UInt32 p) { return BitConverter.GetBytes(p); } + /// Converts the value from UInt64 to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Byte[] ToByteArray(UInt64 p) { return BitConverter.GetBytes(p); } + + // Nullable Types + // + /// Converts the value from Boolean? to an equivalent Byte[] value. + public static Byte[] ToByteArray(Boolean? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from Byte? to an equivalent Byte[] value. + public static Byte[] ToByteArray(Byte? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from Char? to an equivalent Byte[] value. + public static Byte[] ToByteArray(Char? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } +#if !SILVERLIGHT + /// Converts the value from DateTime? to an equivalent Byte[] value. + public static Byte[] ToByteArray(DateTime? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } +#endif +#if !SILVERLIGHT + /// Converts the value from DateTimeOffset? to an equivalent Byte[] value. + public static Byte[] ToByteArray(DateTimeOffset? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } +#endif + /// Converts the value from Decimal? to an equivalent Byte[] value. + public static Byte[] ToByteArray(Decimal? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from Double? to an equivalent Byte[] value. + public static Byte[] ToByteArray(Double? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from Guid? to an equivalent Byte[] value. + public static Byte[] ToByteArray(Guid? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from Int16? to an equivalent Byte[] value. + public static Byte[] ToByteArray(Int16? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from Int32? to an equivalent Byte[] value. + public static Byte[] ToByteArray(Int32? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from Int64? to an equivalent Byte[] value. + public static Byte[] ToByteArray(Int64? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from SByte? to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Byte[] ToByteArray(SByte? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from Single? to an equivalent Byte[] value. + public static Byte[] ToByteArray(Single? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from TimeSpan? to an equivalent Byte[] value. + public static Byte[] ToByteArray(TimeSpan? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from UInt16? to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Byte[] ToByteArray(UInt16? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from UInt32? to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Byte[] ToByteArray(UInt32? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + /// Converts the value from UInt64? to an equivalent Byte[] value. + [CLSCompliant(false)] + public static Byte[] ToByteArray(UInt64? p) { return p.HasValue ? ToByteArray(p.Value) : (Byte[])null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Byte[] value. + public static Byte[] ToByteArray(Binary p) { return p == null ? (Byte[])null : p.ToArray(); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBinary to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlBinary p) { return p.IsNull ? (Byte[])null : p.Value; } + /// Converts the value from SqlBoolean to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlBoolean p) { return p.IsNull ? (Byte[])null : ToByteArray(p.Value); } + /// Converts the value from SqlByte to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlByte p) { return p.IsNull ? (Byte[])null : ToByteArray(p.Value); } + /// Converts the value from SqlBytes to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlBytes p) { return p.IsNull ? (Byte[])null : p.Value; } + /// Converts the value from SqlDecimal to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlDecimal p) { return p.IsNull ? (Byte[])null : ToByteArray(p.Value); } + /// Converts the value from SqlDouble to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlDouble p) { return p.IsNull ? (Byte[])null : ToByteArray(p.Value); } + /// Converts the value from SqlGuid to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlGuid p) { return p.IsNull ? (Byte[])null : p.ToByteArray(); } + /// Converts the value from SqlInt16 to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlInt16 p) { return p.IsNull ? (Byte[])null : ToByteArray(p.Value); } + /// Converts the value from SqlInt32 to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlInt32 p) { return p.IsNull ? (Byte[])null : ToByteArray(p.Value); } + /// Converts the value from SqlInt64 to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlInt64 p) { return p.IsNull ? (Byte[])null : ToByteArray(p.Value); } + /// Converts the value from SqlMoney to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlMoney p) { return p.IsNull ? (Byte[])null : ToByteArray(p.Value); } + /// Converts the value from SqlSingle to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlSingle p) { return p.IsNull ? (Byte[])null : ToByteArray(p.Value); } + /// Converts the value from SqlString to an equivalent Byte[] value. + public static Byte[] ToByteArray(SqlString p) { return p.IsNull ? (Byte[])null : ToByteArray(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Byte[] value. + public static Byte[] ToByteArray(object p) + { + if (p == null) return null; + + if (p is Byte[]) return (Byte[])p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.Decimal : return ToByteArray((Decimal) p); + case TypeCode.String : return ToByteArray((String) p); + case TypeCode.Byte : return ToByteArray((Byte) p); + case TypeCode.SByte : return ToByteArray((SByte) p); +#if !SILVERLIGHT + case TypeCode.DateTime : return ToByteArray((DateTime)p); +#endif + case TypeCode.Int16 : return ToByteArray((Int16) p); + case TypeCode.Int32 : return ToByteArray((Int32) p); + case TypeCode.Int64 : return ToByteArray((Int64) p); + case TypeCode.UInt16 : return ToByteArray((UInt16) p); + case TypeCode.UInt32 : return ToByteArray((UInt32) p); + case TypeCode.UInt64 : return ToByteArray((UInt64) p); + case TypeCode.Single : return ToByteArray((Single) p); + case TypeCode.Double : return ToByteArray((Double) p); + case TypeCode.Boolean : return ToByteArray((Boolean) p); + case TypeCode.Char : return ToByteArray((Char) p); + } + + // Simple Types + // +#if !SILVERLIGHT + if (p is DateTimeOffset) return ToByteArray((DateTimeOffset) p); +#endif + if (p is Guid) return ToByteArray((Guid) p); + if (p is TimeSpan) return ToByteArray((TimeSpan) p); + + // Nullable Types + // + if (type.IsGenericType) + { + if (p is Boolean?) return ToByteArray((Boolean?) p); + if (p is Byte?) return ToByteArray((Byte?) p); + if (p is Char?) return ToByteArray((Char?) p); +#if !SILVERLIGHT + if (p is DateTime?) return ToByteArray((DateTime?) p); +#endif +#if !SILVERLIGHT + if (p is DateTimeOffset?) return ToByteArray((DateTimeOffset?)p); +#endif + if (p is Decimal?) return ToByteArray((Decimal?) p); + if (p is Double?) return ToByteArray((Double?) p); + if (p is Guid?) return ToByteArray((Guid?) p); + if (p is Int16?) return ToByteArray((Int16?) p); + if (p is Int32?) return ToByteArray((Int32?) p); + if (p is Int64?) return ToByteArray((Int64?) p); + if (p is SByte?) return ToByteArray((SByte?) p); + if (p is Single?) return ToByteArray((Single?) p); + if (p is TimeSpan?) return ToByteArray((TimeSpan?) p); + if (p is UInt16?) return ToByteArray((UInt16?) p); + if (p is UInt32?) return ToByteArray((UInt32?) p); + if (p is UInt64?) return ToByteArray((UInt64?) p); + } + + // Other Types + // + if (p is Binary) return ToByteArray((Binary) p); + if (p is Char[]) return ToByteArray((Char[]) p); + if (p is Stream) return ToByteArray((Stream) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBinary) return ToByteArray((SqlBinary) p); + if (p is SqlBoolean) return ToByteArray((SqlBoolean) p); + if (p is SqlByte) return ToByteArray((SqlByte) p); + if (p is SqlBytes) return ToByteArray((SqlBytes) p); + if (p is SqlDecimal) return ToByteArray((SqlDecimal) p); + if (p is SqlDouble) return ToByteArray((SqlDouble) p); + if (p is SqlGuid) return ToByteArray((SqlGuid) p); + if (p is SqlInt16) return ToByteArray((SqlInt16) p); + if (p is SqlInt32) return ToByteArray((SqlInt32) p); + if (p is SqlInt64) return ToByteArray((SqlInt64) p); + if (p is SqlMoney) return ToByteArray((SqlMoney) p); + if (p is SqlSingle) return ToByteArray((SqlSingle) p); + if (p is SqlString) return ToByteArray((SqlString) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Byte[])); + } + + #endregion + + #region Char[] + + #endregion + + #region Stream + + // Simple Types + // + /// Converts the value from Guid to an equivalent Stream value. + public static Stream ToStream(Guid p) { return p == Guid.Empty ? Stream.Null : new MemoryStream(p.ToByteArray()); } + + // Nullable Types + // + /// Converts the value from Guid? to an equivalent Stream value. + public static Stream ToStream(Guid? p) { return p.HasValue ? new MemoryStream(p.Value.ToByteArray()) : Stream.Null; } + + // Other Types + // + /// Converts the value from Binary to an equivalent Stream value. + public static Stream ToStream(Binary p) { return p == null ? Stream.Null : new MemoryStream(p.ToArray()); } + /// Converts the value from Byte[] to an equivalent Stream value. + public static Stream ToStream(Byte[] p) { return p == null ? Stream.Null : new MemoryStream(p); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlBinary to an equivalent Stream value. + public static Stream ToStream(SqlBinary p) { return p.IsNull ? Stream.Null : new MemoryStream(p.Value); } + /// Converts the value from SqlBytes to an equivalent Stream value. + public static Stream ToStream(SqlBytes p) { return p.IsNull ? Stream.Null : p.Stream; } + /// Converts the value from SqlGuid to an equivalent Stream value. + public static Stream ToStream(SqlGuid p) { return p.IsNull ? Stream.Null : new MemoryStream(p.Value.ToByteArray()); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Stream value. + public static Stream ToStream(object p) + { + if (p == null || p is DBNull) return Stream.Null; + + if (p is Stream) return (Stream)p; + + // Simple Types + // + if (p is Guid) return ToStream((Guid) p); + + // Nullable Types + // + var type = p.GetType(); + + if (type.IsGenericType) + { + if (p is Guid?) return ToStream((Guid?) p); + } + + // Other Types + // + if (p is Binary) return ToStream((Binary) p); + if (p is Byte[]) return ToStream((Byte[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlBinary) return ToStream((SqlBinary)p); + if (p is SqlBytes) return ToStream((SqlBytes) p); + if (p is SqlGuid) return ToStream((SqlGuid) p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Stream)); + } + + #endregion + + #region Type + + // Simple Types + // +#if !SILVERLIGHT + /// Converts the value from Guid to an equivalent Type value. + public static Type ToType(Guid p) { return p == Guid.Empty ? (Type)null : Type.GetTypeFromCLSID(p); } +#endif + /// Converts the value from String to an equivalent Type value. + public static Type ToType(String p) { return p == null ? (Type)null : Type.GetType(p); } + + // Nullable Types + // +#if !SILVERLIGHT + /// Converts the value from Guid? to an equivalent Type value. + public static Type ToType(Guid? p) { return p.HasValue ? Type.GetTypeFromCLSID(p.Value) : (Type)null; } +#endif + + // Other Types + // +#if !SILVERLIGHT + /// Converts the value from Binary to an equivalent Type value. + public static Type ToType(Binary p) { return p == null ? (Type)null : Type.GetTypeFromCLSID(ToGuid(p.ToArray())); } +#endif +#if !SILVERLIGHT + /// Converts the value from Byte[] to an equivalent Type value. + public static Type ToType(Byte[] p) { return p == null ? (Type)null : Type.GetTypeFromCLSID(ToGuid(p)); } +#endif + /// Converts the value from Char[] to an equivalent Type value. + public static Type ToType(Char[] p) { return p == null ? (Type)null : Type.GetType(new string(p)); } + +#if !SILVERLIGHT + + // Sql Types + // + /// Converts the value from SqlChars to an equivalent Type value. + public static Type ToType(SqlChars p) { return p.IsNull ? (Type)null : Type.GetType(new string(p.Value)); } + /// Converts the value from SqlGuid to an equivalent Type value. + public static Type ToType(SqlGuid p) { return p.IsNull ? (Type)null : Type.GetTypeFromCLSID(p.Value); } + /// Converts the value from SqlString to an equivalent Type value. + public static Type ToType(SqlString p) { return p.IsNull ? (Type)null : Type.GetType(p.Value); } + +#endif + + // From Object + // + /// Converts the value from Object to an equivalent Type value. + public static Type ToType(object p) + { + if (p == null) return null; + + if (p is Type) return (Type)p; + + var type = p.GetType(); + + // Primitive types + // + switch (Type.GetTypeCode(type)) + { + case TypeCode.DBNull : return null; + case TypeCode.String : return ToType((String)p); + } + + // Simple Types + // +#if !SILVERLIGHT + if (p is Guid) return ToType((Guid) p); +#endif + + // Nullable Types + // + if (type.IsGenericType) + { +#if !SILVERLIGHT + if (p is Guid?) return ToType((Guid?) p); +#endif + } + + // Other Types + // +#if !SILVERLIGHT + if (p is Binary) return ToType((Binary) p); +#endif +#if !SILVERLIGHT + if (p is Byte[]) return ToType((Byte[]) p); +#endif + if (p is Char[]) return ToType((Char[]) p); + +#if !SILVERLIGHT + + // Sql Types + // + if (p is INullable) + { + if (p is SqlChars) return ToType((SqlChars) p); + if (p is SqlGuid) return ToType((SqlGuid) p); + if (p is SqlString) return ToType((SqlString)p); + } + +#endif + + throw CreateInvalidCastException(p.GetType(), typeof(Type)); + } + + #endregion + + #region XmlDocument + +#if !SILVERLIGHT + +#endif + + #endregion + + #region XmlReader + +#if !SILVERLIGHT + +#endif + + #endregion + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Common/Convert.tt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/Convert.tt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,978 @@ +<#@ template language="C#v3.5" debug="True" #> +<#@ output extension="generated.cs" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +//--------------------------------------------------------------------------------------------------- +// +// This code was generated by BLToolkit template for T4. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// +//--------------------------------------------------------------------------------------------------- +using System; +using System.Data.Linq; +using System.Data.SqlTypes; +using System.Globalization; +using System.IO; +using System.Xml; +#if !SILVERLIGHT +using System.Xml.Linq; +#endif + +namespace BLToolkit.Common +{ + using Properties; + + public partial class Convert + { +<# + GenerationEnvironment.Remove(GenerationEnvironment.Length - 2, 2); + + _types = + Set(_ => { _.Group = "Simple"; _.Method = "To" + _.Name; }, new[] + { + new ToType { Name = "Boolean", NullValue = "Configuration.NullableValues.Boolean", Froms = { { "Char", null } } }, + new ToType { Name = "Byte", NullValue = "Configuration.NullableValues.Byte" }, + new ToType { Name = "Char", NullValue = "Configuration.NullableValues.Char" }, + new ToType { Name = "DateTime", NullValue = "Configuration.NullableValues.DateTime" }, + new ToType { Name = "DateTimeOffset", NullValue = "DateTimeOffset.MinValue" }, + new ToType { Name = "Decimal", NullValue = "Configuration.NullableValues.Decimal", Froms = { { "Byte[]", null }, { "Binary", null } } }, + new ToType { Name = "Double", NullValue = "Configuration.NullableValues.Double" }, + new ToType { Name = "Guid", NullValue = "Configuration.NullableValues.Guid" }, + new ToType { Name = "Int16", NullValue = "Configuration.NullableValues.Int16" }, + new ToType { Name = "Int32", NullValue = "Configuration.NullableValues.Int32" }, + new ToType { Name = "Int64", NullValue = "Configuration.NullableValues.Int64" }, + new ToType { Name = "Single", NullValue = "Configuration.NullableValues.Single" }, + new ToType { Name = "String", NullValue = "Configuration.NullableValues.String", FromObjectReturn = "return p.ToString();" }, + new ToType { Name = "TimeSpan", NullValue = "Configuration.NullableValues.TimeSpan" }, + }.Concat(Set(_ => _.NonCompliant = true, new[] + { + new ToType { Name = "SByte", NullValue = "Configuration.NullableValues.SByte" }, + new ToType { Name = "UInt16", NullValue = "Configuration.NullableValues.UInt16" }, + new ToType { Name = "UInt32", NullValue = "Configuration.NullableValues.UInt32" }, + new ToType { Name = "UInt64", NullValue = "Configuration.NullableValues.UInt64" }, + }))) + .Concat(Set(_ => { _.Group = "Nullable"; _.Method = "ToNullable" + _.Name; _.Name += "?"; }, new[] + { + new ToType { Name = "Boolean" }, + new ToType { Name = "Byte" }, + new ToType { Name = "Char" }, + new ToType { Name = "DateTime" }, + new ToType { Name = "DateTimeOffset" }, + new ToType { Name = "Decimal" }, + new ToType { Name = "Double" }, + new ToType { Name = "Guid" }, + new ToType { Name = "Int16" }, + new ToType { Name = "Int32" }, + new ToType { Name = "Int64" }, + new ToType { Name = "Single" }, + new ToType { Name = "TimeSpan" }, + }.Concat(Set(_ => _.NonCompliant = true, new[] + { + new ToType { Name = "SByte" }, + new ToType { Name = "UInt16" }, + new ToType { Name = "UInt32" }, + new ToType { Name = "UInt64" }, + })))) + .Concat(Set(_ => { _.Group = "Sql"; _.Method = "To" + _.Name; _.NonSilverlightable = true; _.NullValue = _.Name + ".Null"; }, new[] + { + new ToType { Name = "SqlString" }, + new ToType { Name = "SqlByte" }, + new ToType { Name = "SqlInt16" }, + new ToType { Name = "SqlInt32" }, + new ToType { Name = "SqlInt64" }, + new ToType { Name = "SqlSingle" }, + new ToType { Name = "SqlDouble" }, + new ToType { Name = "SqlBoolean" }, + new ToType { Name = "SqlDecimal" }, + new ToType { Name = "SqlMoney" }, + new ToType { Name = "SqlDateTime" }, + new ToType { Name = "SqlGuid" }, + new ToType { Name = "SqlBinary" }, + new ToType { Name = "SqlBytes" }, + new ToType { Name = "SqlChars" }, + new ToType { Name = "SqlXml" }, + })) + .Concat(Set(_ => { _.Group = "Other"; }, new[] + { + new ToType { Name = "Type", Method = "ToType", NonSLMethods = { "Guid", "Guid?", "Binary", "Byte[]" } }, + new ToType { Name = "Stream", Method = "ToStream", NullValue = "Stream.Null" }, + new ToType { Name = "Byte[]", Method = "ToByteArray", NonSLMethods = { "DateTime", "DateTime?", "DateTimeOffset", "DateTimeOffset?" }, Froms = { { "Decimal", null }, { "Stream", null }, { "Char[]", null } } }, + new ToType { Name = "Char[]", Method = "ToCharArray", }, + new ToType { Name = "Binary", Method = "ToLinqBinary", }, + new ToType { Name = "XmlReader", Method = "ToXmlReader", NonSilverlightable = true }, + new ToType { Name = "XmlDocument", Method = "ToXmlDocument", NonSilverlightable = true }, + new ToType { Name = "XElement", Method = "ToXElement", NonSilverlightable = true }, + })) + .ToDictionary(_ => _.Name); + + + // To Boolean + // + ConvertFrom("String", "p == null? {2} : p.Length == 1 ? ToBoolean(p[0]) : Boolean.Parse(p)", "Boolean", "Boolean?", "SqlBoolean"); + ConvertFrom("Byte[]", "p == null || p.Length == 0 ? {2} : BitConverter.ToBoolean(p, 0)", "Boolean", "Boolean?", "SqlBoolean"); + ConvertFrom("Binary", "p == null || p.Length == 0 ? {2} : BitConverter.ToBoolean(p.ToArray(), 0)", "Boolean", "Boolean?", "SqlBoolean"); + + ConvertTo ("Boolean", "p.HasValue && p.Value", "Boolean?"); + ConvertToNull("Boolean", "p != 0", "p.HasValue && p.Value != 0", "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal"); + ConvertTo ("Boolean", "p.HasValue && ToBoolean(p.Value)", "Char?"); + ConvertTo ("Boolean", "!p.IsNull && p.Value", "SqlBoolean"); + ConvertTo ("Boolean", "!p.IsNull && ToBoolean(p.Value)", Sql("String", "Byte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money")); + + ConvertFrom("Boolean", "p", "Boolean?", "SqlBoolean"); + ConvertFrom("Char", "ToBoolean(p)", "Boolean?", "SqlBoolean"); + ConvertFrom("Char?", "p.HasValue && ToBoolean(p.Value)", "Boolean?", "SqlBoolean"); + + // To Boolean? + // + ConvertToNull("Boolean?", "p != 0", "p.HasValue ? p.Value != 0 : {2}", "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal"); + ConvertTo ("Boolean?", "p.IsNull ? {2} : p.Value", "SqlBoolean"); + ConvertTo ("Boolean?", "p.IsNull ? {2} : ToBoolean(p.Value)", Sql("String", "Byte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money")); + + // SqlBoolean + // + ConvertTo ("SqlBoolean", "p.HasValue ? p.Value : {2}", "Boolean?"); + ConvertToNull("SqlBoolean", "p != 0", "p.HasValue ? p.Value != 0 : {2}", "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal"); + ConvertTo ("SqlBoolean", "p.IsNull ? {2} : ToBoolean(p.Value)", Sql("String", "Byte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money")); + + // To Byte + // + ConvertNumber("Byte", + new string[] { "Byte" }, + new string[] { "SByte", "Int16", "Int32", "Int64", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal", "Char" }, + new string[] { "Byte" }, + new string[] { "String", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" }); + + ConvertFrom("Byte[]", "p == null || p.Length == 0 ? {2} : p[0]", "Byte", "Byte?", "SqlByte"); + ConvertFrom("Binary", "p == null || p.Length == 0 ? {2} : p.ToArray()[0]", "Byte", "Byte?", "SqlByte"); + + // To Char + // + ConvertNumber("Char", + new string[] { "Char" }, + new string[] { "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal" }, + new string[] { }, + new string[] { "String", "Byte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" }); + + ConvertFrom("String", "string.IsNullOrEmpty(p)? ({0})0 : p[0]", "Char", "Char?"); + + // To DateTime + // + ConvertTo(new[] { "DateTime", "SqlDateTime" }, "p.HasValue ? p.Value : {2}", "DateTime?"); + ConvertTo(new[] { "DateTime?", "SqlDateTime" }, "p", "DateTime"); + ConvertTo(new[] { "DateTime", "DateTime?" }, "p.IsNull ? {2} : p.Value", "SqlDateTime"); + + ConvertFrom("String", "p == null ? {2} : {3}.Parse(p, null, DateTimeStyles.NoCurrentDateDefault)", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("TimeSpan", "{3}.MinValue + p", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("Int64", "{3}.MinValue + TimeSpan.FromTicks(p)", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("Double", "{3}.MinValue + TimeSpan.FromDays (p)", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("DateTimeOffset", "p.LocalDateTime", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("DateTimeOffset?", "p.HasValue ? p.Value.LocalDateTime : {2}", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("TimeSpan?", "p.HasValue ? {3}.MinValue + p.Value : {2}", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("Int64?", "p.HasValue ? {3}.MinValue + TimeSpan.FromTicks(p.Value): {2}", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("Double?", "p.HasValue ? {3}.MinValue + TimeSpan.FromDays (p.Value): {2}", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("SqlDateTime", "p.IsNull ? {2} : p.Value", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("SqlString", "p.IsNull ? {2} : To{3}(p.Value)", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("SqlInt64", "p.IsNull ? {2} : {3}.MinValue + TimeSpan.FromTicks(p.Value)", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("SqlDouble", "p.IsNull ? {2} : {3}.MinValue + TimeSpan.FromDays (p.Value)", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("Byte[]", "p == null || p.Length == 0 ? {2} : {3}.FromBinary(ToInt64(p))", "DateTime", "DateTime?", "SqlDateTime"); + ConvertFrom("Binary", "p == null || p.Length == 0 ? {2} : {3}.FromBinary(ToInt64(p.ToArray()))", "DateTime", "DateTime?", "SqlDateTime"); + + // To DateTimeOffset + // + ConvertTo("DateTimeOffset", "p.HasValue ? p.Value : {2}", "DateTimeOffset?"); + ConvertTo("DateTimeOffset?", "p", "DateTimeOffset"); + + ConvertFrom("TimeSpan", "{3}.MinValue + p", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("Int64", "{3}.MinValue + TimeSpan.FromTicks(p)", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("Double", "{3}.MinValue + TimeSpan.FromDays (p)", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("DateTime", "p", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("DateTime?", "p.HasValue ? p.Value : {2}", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("TimeSpan?", "p.HasValue ? {3}.MinValue + p.Value : {2}", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("Int64?", "p.HasValue ? {3}.MinValue + TimeSpan.FromTicks(p.Value): {2}", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("Double?", "p.HasValue ? {3}.MinValue + TimeSpan.FromDays (p.Value): {2}", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("SqlDateTime", "p.IsNull ? {2} : p.Value", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("SqlString", "p.IsNull ? {2} : ToDateTimeOffset(p.Value)", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("SqlInt64", "p.IsNull ? {2} : {3}.MinValue + TimeSpan.FromTicks(p.Value)", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("SqlDouble", "p.IsNull ? {2} : {3}.MinValue + TimeSpan.FromDays (p.Value)", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("Byte[]", "p == null || p.Length == 0 ? {2} : new {0}(ToDateTime(p))", "DateTimeOffset", "DateTimeOffset?"); + ConvertFrom("Binary", "p == null || p.Length == 0 ? {2} : new {0}(ToDateTime(p.ToArray()))", "DateTimeOffset", "DateTimeOffset?"); + + // To Decimal + // + ConvertNumber("Decimal", + new string[] { "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "Char", "UInt64", "Decimal" }, + new string[] { "Single", "Double" }, + new string[] { "Byte", "Int16", "Int32", "Int64", "Decimal", "Money" }, + new string[] { "String", "Single", "Double", "Boolean" }); + + ConvertNumber("Money", + new string[] { "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "Char", "UInt64", "Decimal" }, + new string[] { "Single", "Double" }, + new string[] { "Byte", "Int16", "Int32", "Int64", "Decimal", "Money" }, + new string[] { "String", "Single", "Double", "Boolean" }); + + ConvertTo(new[] { "Decimal?", "SqlDecimal", "SqlMoney" }, "p == null || p.Length == 0 ? {2} : ToDecimal(p)", "Byte[]", "Binary"); + + // To Double + // + ConvertTo(new[] { "Double", "Double?", "SqlDouble" }, "(p - {1}.MinValue).TotalDays", "DateTime", "DateTimeOffset"); + ConvertTo("SqlDouble", "p.IsNull? {0}.Null: ToDouble(p.Value)", "SqlDateTime"); + + ConvertNumber("Double", + new string[] { "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "Char", "UInt64", "Single", "Double" }, + new string[] { "Decimal" }, + new string[] { "Byte", "Int16", "Int32", "Int64", "Single", "Double" }, + new string[] { "String", "Decimal", "Money", "Boolean", "DateTime" }); + + ConvertTo(new[] { "Double", "Double?", "SqlDouble" }, "p.HasValue ? (p.Value - {4}.MinValue).TotalDays : {2}", "DateTime?", "DateTimeOffset?"); + + ConvertFrom("TimeSpan", "p.TotalDays", "Double", "Double?", "SqlDouble"); + ConvertFrom("TimeSpan?", "p.HasValue ? p.Value.TotalDays : {2}", "Double", "Double?", "SqlDouble"); + + // To Guid + // + ConvertTo(new[] { "Guid", "SqlGuid" }, "p.HasValue ? p.Value : {2}", "Guid?"); + ConvertTo(new[] { "Guid?", "SqlGuid" }, "p", "Guid"); + ConvertTo(new[] { "Guid", "Guid?" }, "p.IsNull ? {2} : p.Value", "SqlGuid"); + + ConvertTo(new[] { "Guid", "Guid?", "SqlGuid" }, "p == null ? {2} : new Guid(p)", "String", "Byte[]"); + + ConvertFrom("SqlGuid", "p.IsNull ? {2} : p.Value", "Guid", "Guid?", "SqlGuid"); + ConvertFrom("SqlString", "p.IsNull ? {2} : new Guid(p.Value)", "Guid", "Guid?", "SqlGuid"); + ConvertFrom("SqlBinary", "p.IsNull ? {2} : p.ToSqlGuid().Value", "Guid", "Guid?", "SqlGuid"); + ConvertFrom("Binary", "p == null ? {2} : new Guid(p.ToArray())", "Guid", "Guid?", "SqlGuid"); + ConvertFrom("Type", "p == null ? {2} : p.GUID", "Guid", "Guid?", "SqlGuid"); + + // To Int16 + // + ConvertNumber("Int16", + new string[] { "SByte", "Int16", "Byte" }, + new string[] { "Int32", "Int64", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal", "Char" }, + new string[] { "Byte", "Int16" }, + new string[] { "String", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" }); + + // To Int32 + // + ConvertNumber("Int32", + new string[] { "SByte", "Int16", "Int32", "Byte", "UInt16", "Char" }, + new string[] { "Int64", "UInt32", "UInt64", "Single", "Double", "Decimal" }, + new string[] { "Byte", "Int16", "Int32" }, + new string[] { "String", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" }); + + // To Int64 + // + ConvertTo("Int64", "(p - DateTime.MinValue).Ticks", "DateTime", "DateTimeOffset"); + ConvertTo("Int64?", "(p - DateTime.MinValue).Ticks", "DateTime", "DateTimeOffset"); + ConvertTo("SqlInt64", "(p - DateTime.MinValue).Ticks", "DateTime", "DateTimeOffset"); + ConvertTo("SqlInt64", "p.IsNull? {0}.Null: ToInt64(p.Value)", "SqlDateTime"); + + ConvertNumber("Int64", + new string[] { "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "Char" }, + new string[] { "UInt64", "Single", "Double", "Decimal" }, + new string[] { "Byte", "Int16", "Int32", "Int64" }, + new string[] { "String", "Single", "Double", "Decimal", "Money", "Boolean", "DateTime" }); + + ConvertTo("Int64", " p.HasValue ? (p.Value - DateTime.MinValue).Ticks : 0", "DateTime?", "DateTimeOffset?"); + ConvertTo("Int64?", "p.HasValue ? (p.Value - DateTime.MinValue).Ticks : 0", "DateTime?", "DateTimeOffset?"); + ConvertTo("SqlInt64", "p.HasValue ? (p.Value - DateTime.MinValue).Ticks : 0", "DateTime?", "DateTimeOffset?"); + + ConvertFrom("TimeSpan", "p.Ticks", "Int64", "Int64?", "SqlInt64"); + ConvertFrom("TimeSpan?", "p.HasValue ? p.Value.Ticks : 0", "Int64", "Int64?", "SqlInt64"); + + // To SByte + // + ConvertNumber("SByte", + new string[] { "SByte" }, + new string[] { "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal", "Char" }, + new string[] { }, + new string[] { "String", "Byte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" }); + + ConvertFrom("Byte[]", "p == null || p.Length == 0 ? {2} : checked(({0})p[0])", "SByte", "SByte?"); + ConvertFrom("Binary", "p == null || p.Length == 0 ? {2} : checked(({0})p.ToArray()[0])", "SByte", "SByte?"); + + // To Single + // + ConvertNumber("Single", + new string[] { "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "Char", "UInt64", "Single" }, + new string[] { "Double", "Decimal" }, + new string[] { "Byte", "Int16", "Int32", "Int64", "Single" }, + new string[] { "String", "Double", "Decimal", "Money", "Boolean" }); + + // To String + // + ConvertToNull(new[] { "String", "SqlString" }, + "p.To{3}()", + "p.HasValue ? p.Value.To{3}() : {2}", + "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64", + "Single", "Double", "Boolean", "Decimal", "Char", "TimeSpan", "DateTime", "DateTimeOffset", "Guid"); + + ConvertTo(new[] { "String", "SqlString" }, "p == null ? {2} : p.FullName", "Type"); + ConvertTo(new[] { "String", "SqlString" }, "p == null ? {2} : System.Text.Encoding.UTF8.GetString(p, 0, p.Length)", "Byte[]"); + ConvertTo(new[] { "String", "SqlString" }, "To{0}(p.ToArray())", "Binary"); + + ConvertTo(new[] { "String", "SqlString" }, "p.To{0}()", + Sql("String", "Byte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean", "Guid")); + + ConvertTo( "String", "p.IsNull ? {2} : p.ToSqlString().Value", "SqlChars"); + ConvertTo(new[] { "String", "SqlString" }, "p.IsNull ? {2} : p.Value", "SqlXml"); + ConvertTo(new[] { "String", "SqlString" }, "p == null ? {2} : p.InnerXml", "XmlDocument"); + ConvertTo(new[] { "String", "SqlString" }, "p == null ? {2} : p.ToString()", "XElement"); + + ConvertTo("SqlString", "p ?? {2}", "String"); + ConvertTo("SqlString", "p.To{0}()", "SqlChars"); + + // To TimeSpan + // + ConvertTo("TimeSpan", "p.HasValue ? p.Value : {2}", "TimeSpan?"); + ConvertTo("TimeSpan?", "p", "TimeSpan"); + + ConvertFrom("DateTime", "p - DateTime.MinValue", "TimeSpan", "TimeSpan?"); + ConvertFrom("DateTimeOffset", "p - DateTimeOffset.MinValue", "TimeSpan", "TimeSpan?"); + ConvertFrom("Int64", "TimeSpan.FromTicks(p)", "TimeSpan", "TimeSpan?"); + ConvertFrom("Double", "TimeSpan.FromDays (p)", "TimeSpan", "TimeSpan?"); + ConvertFrom("DateTime?", "p.HasValue ? p.Value - DateTime.MinValue : {2}", "TimeSpan", "TimeSpan?"); + ConvertFrom("DateTimeOffset?", "p.HasValue ? p.Value - DateTimeOffset.MinValue : {2}", "TimeSpan", "TimeSpan?"); + ConvertFrom("Int64?", "p.HasValue ? {3}.FromTicks(p.Value) : {2}", "TimeSpan", "TimeSpan?"); + ConvertFrom("Double?", "p.HasValue ? {3}.FromDays (p.Value) : {2}", "TimeSpan", "TimeSpan?"); + ConvertFrom("SqlString", "p.IsNull ? {2} : {3}.Parse(p.Value)", "TimeSpan", "TimeSpan?"); + ConvertFrom("SqlDateTime", "p.IsNull ? {2} : p.Value - DateTime.MinValue", "TimeSpan", "TimeSpan?"); + ConvertFrom("SqlInt64", "p.IsNull ? {2} : {3}.FromTicks(p.Value)", "TimeSpan", "TimeSpan?"); + ConvertFrom("SqlDouble", "p.IsNull ? {2} : {3}.FromDays(p.Value)", "TimeSpan", "TimeSpan?"); + ConvertFrom("Byte[]", "p == null || p.Length == 0? {2} : {3}.FromTicks(ToInt64(p))", "TimeSpan", "TimeSpan?"); + ConvertFrom("Binary", "p == null || p.Length == 0? {2} : {3}.FromTicks(ToInt64(p.ToArray()))", "TimeSpan", "TimeSpan?"); + + // To UInt16 + // + ConvertNumber("UInt16", + new string[] { "UInt16", "Byte" }, + new string[] { "SByte", "Int16", "Int32", "Int64", "UInt32", "UInt64", "Single", "Double", "Decimal", "Char" }, + new string[] { "Byte" }, + new string[] { "String", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" }); + + // To UInt32 + // + ConvertNumber("UInt32", + new string[] { "Byte", "UInt16", "UInt32" }, + new string[] { "SByte", "Int16", "Int32", "Int64", "UInt64", "Single", "Double", "Decimal", "Char" }, + new string[] { "Byte" }, + new string[] { "String", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" }); + + // To UInt64 + // + ConvertNumber("UInt64", + new string[] { "Byte", "UInt16", "UInt32", "UInt64" }, + new string[] { "SByte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Char" }, + new string[] { "Byte" }, + new string[] { "String", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" }); + + // To SqlBinary + // + ConvertTo("SqlBinary", "p", "Byte[]"); + ConvertTo("SqlBinary", "p == null ? {2} : p.ToArray()", "Binary"); + ConvertTo("SqlBinary", "p == Guid.Empty? {2} : new SqlGuid(p).To{0}()", "Guid"); + ConvertTo("SqlBinary", "p.HasValue ? new SqlGuid(p.Value).ToSqlBinary(): {2}", "Guid?"); + ConvertTo("SqlBinary", "p.To{0}()", "SqlBytes" , "SqlGuid"); + + // To SqlXml + // + ConvertTo("SqlXml", "p == null ? {2} : new {0}(new XmlTextReader(new StringReader(p)))", "String"); + ConvertTo("SqlXml", "p == null ? {2} : new {0}(p)", "Stream", "XmlReader"); + ConvertTo("SqlXml", "p == null ? {2} : new {0}(new XmlTextReader(new StringReader(p.InnerXml)))", "XmlDocument"); + ConvertTo("SqlXml", "p == null ? {2} : new {0}(new XmlTextReader(new StringReader(p.ToString())))", "XElement"); + ConvertTo("SqlXml", "p == null ? {2} : new {0}(new XmlTextReader(new StringReader(new string(p))))", "Char[]"); + ConvertTo("SqlXml", "p == null ? {2} : new {0}(new MemoryStream(p))", "Byte[]"); + ConvertTo("SqlXml", "p == null ? {2} : new {0}(new MemoryStream(p.ToArray()))", "Binary"); + ConvertTo("SqlXml", "p.IsNull ? {2} : new {0}(new XmlTextReader(new StringReader(p.Value)))", "SqlString"); + ConvertTo("SqlXml", "p.IsNull ? {2} : new {0}(new XmlTextReader(new StringReader(p.ToSqlString().Value)))", "SqlChars"); + ConvertTo("SqlXml", "p.IsNull ? {2} : new {0}(new MemoryStream(p.Value))", "SqlBinary"); + ConvertTo("SqlXml", "p.IsNull ? {2} : new {0}(p.Stream)", "SqlBytes"); + + // To Stream + // + ConvertTo("Stream", "p == Guid.Empty ? {2} : new MemoryStream(p.ToByteArray())", "Guid"); + ConvertTo("Stream", "p == null ? {2} : new MemoryStream(p)", "Byte[]"); + ConvertTo("Stream", "p == null ? {2} : new MemoryStream(p.ToArray())", "Binary"); + ConvertTo("Stream", "p.HasValue ? new MemoryStream(p.Value.ToByteArray()) : {2}", "Guid?"); + ConvertTo("Stream", "p.IsNull ? {2} : p.Stream", "SqlBytes"); + ConvertTo("Stream", "p.IsNull ? {2} : new MemoryStream(p.Value)", "SqlBinary"); + ConvertTo("Stream", "p.IsNull ? {2} : new MemoryStream(p.Value.ToByteArray())", "SqlGuid"); + + // To Type + // + ConvertTo("Type", "p == null ? {2} : Type.GetType(p)", "String"); + ConvertTo("Type", "p == null ? {2} : Type.GetType(new string(p))", "Char[]"); + ConvertTo("Type", "p == null ? {2} : Type.GetTypeFromCLSID(ToGuid(p))", "Byte[]"); + ConvertTo("Type", "p == null ? {2} : Type.GetTypeFromCLSID(ToGuid(p.ToArray()))", "Binary"); + ConvertTo("Type", "p == Guid.Empty ? {2} : Type.GetTypeFromCLSID(p)", "Guid"); + ConvertTo("Type", "p.HasValue ? Type.GetTypeFromCLSID(p.Value) : {2}", "Guid?"); + ConvertTo("Type", "p.IsNull ? {2} : Type.GetType(p.Value)", "SqlString"); + ConvertTo("Type", "p.IsNull ? {2} : Type.GetType(new string(p.Value))", "SqlChars"); + ConvertTo("Type", "p.IsNull ? {2} : Type.GetTypeFromCLSID(p.Value)", "SqlGuid"); + + // To Byte[] + // + ConvertTo("Byte[]", "p == null ? {2} : System.Text.Encoding.UTF8.GetBytes(p)", "String"); + ConvertTo("Byte[]", "new[] {{ p }}", "Byte"); + ConvertTo("Byte[]", "new[] {{ checked((Byte)p) }}", "SByte"); + ConvertTo("Byte[]", "ToByteArray(p.ToBinary())", "DateTime"); + ConvertTo("Byte[]", "ToByteArray(p.LocalDateTime.ToBinary())", "DateTimeOffset"); + ConvertTo("Byte[]", "p == null ? {2} : p.ToArray()", "Binary"); + ConvertTo("Byte[]", "ToByteArray(p.Ticks)", "TimeSpan"); + ConvertTo("Byte[]", "p == Guid.Empty ? {2} : p.ToByteArray()", "Guid"); + + ConvertTo("Byte[]", "BitConverter.GetBytes(p)", + "Int16", "Int32", "Int64", "UInt16", "UInt32", "UInt64", "Single", "Double", "Boolean", "Char"); + ConvertTo("Byte[]", "p.HasValue ? ToByteArray(p.Value) : {2}", + "SByte?", "Int16?", "Int32?", "Int64?", "Byte?", "UInt16?", "UInt32?", "UInt64?", "Single?", "Double?", "Boolean?", "Decimal?", "Char?", "DateTime?", "DateTimeOffset?", "TimeSpan?", "Guid?"); + + ConvertTo("Byte[]", "p.IsNull ? {2} : p.Value", "SqlBinary", "SqlBytes"); + ConvertTo("Byte[]", "p.IsNull ? {2} : p.ToByteArray()", "SqlGuid"); + ConvertTo("Byte[]", "p.IsNull ? {2} : ToByteArray(p.Value)", + "SqlString", "SqlByte", "SqlInt16", "SqlInt32", "SqlInt64", "SqlSingle", "SqlDouble", "SqlDecimal", "SqlMoney", "SqlBoolean"); + + // To SqlBytes + // + ConvertTo("SqlBytes", "p == null ? {2} : new {0}(p)", "Byte[]", "Stream"); + ConvertTo("SqlBytes", "p == null ? {2} : new {0}(p.ToArray())", "Binary"); + ConvertTo("SqlBytes", "p == Guid.Empty ? {2}: new {0}(p.ToByteArray())", "Guid"); + ConvertTo("SqlBytes", "p.HasValue ? new {0}(p.Value.ToByteArray()) : {2}", "Guid?"); + ConvertTo("SqlBytes", "p.IsNull ? {2} : new {0}(p)", "SqlBinary"); + ConvertTo("SqlBytes", "p.IsNull ? {2} : new {0}(p.ToByteArray())", "SqlGuid"); + + ConvertTo("SqlBytes", "p == null ? {2} : new {0}(ToByteArray(p))", "String"); + + ConvertTo("SqlBytes", "new {0}(ToByteArray(p))", + "Byte", "SByte", "DateTime", "DateTimeOffset", "TimeSpan", "Int16", "Int32", "Int64", "UInt16", "UInt32", "UInt64", "Single", "Double", "Boolean", "Char"); + ConvertTo("SqlBytes", "p.HasValue ? ToSqlBytes(p.Value) : {2}", + "SByte?", "Int16?", "Int32?", "Int64?", "Byte?", "UInt16?", "UInt32?", "UInt64?", "Single?", "Double?", "Boolean?", "Decimal?", "Char?", "DateTime?", "DateTimeOffset?", "TimeSpan?", "Guid?"); + + ConvertTo("Byte[]", "p.IsNull ? {2} : ToSqlBytes(p.Value)", + "SqlString", "SqlByte", "SqlInt16", "SqlInt32", "SqlInt64", "SqlSingle", "SqlDouble", "SqlDecimal", "SqlMoney", "SqlBoolean"); + + + + string[] numberTypes1 = new string[] { "Int16", "Int32", "Int64", "UInt16", "UInt32", "UInt64", "Char", "Single", "Double", "SqlByte", "SqlInt16", "SqlInt32", "SqlInt64", "SqlSingle", "SqlDouble", "SqlDecimal", "SqlMoney" }; + string[] numberTypes2 = Add(numberTypes1, "SByte", "Byte"); + string[] numberTypes1n = numberTypes1.Where(_ => !_.StartsWith("Sql")).Select(_ => _ + "?").ToArray(); + string[] numberTypes2n = numberTypes2.Where(_ => !_.StartsWith("Sql")).Select(_ => _ + "?").ToArray(); + + // From String + // + ConvertFrom("String", "p == null? {2} : {3}.Parse(p)", + Add(Add(numberTypes2, numberTypes2n), "Decimal", "DateTimeOffset", "TimeSpan", "Decimal?", "DateTimeOffset?", "TimeSpan?")); + + // From Boolean + // + ConvertFrom("Boolean", "p ? ({0})1 : ({0})0", Add(Add(numberTypes2, numberTypes2n), "Decimal", "Decimal?")); + + // From Boolean? + // + ConvertFrom("Boolean?", "p.HasValue && p.Value ? ({0})1: ({0})0", Add(Add(numberTypes2, numberTypes2n), "Decimal", "Decimal?")); + + // From Byte[] + // + ConvertFrom("Byte[]", "p == null || p.Length == 0 ? {2} : BitConverter.To{3}(p, 0)", Add(numberTypes1, numberTypes1n)); + + // From Binary + // + ConvertFrom("Binary", "p == null || p.Length == 0 ? {2} : BitConverter.To{3}(p.ToArray(), 0)", Add(numberTypes1, numberTypes1n)); + + Generate(); +#> + } +} +<#+ +class ToType +{ + public string Group; + public string Name; + public string Method; + public bool NonCompliant; + public bool NonSilverlightable; // :) + public string NullValue; + public string FromObjectReturn; + + public Dictionary Froms = new Dictionary(); + public HashSet NonSLMethods = new HashSet(); +} + +Dictionary _types; + +void ConvertTo(string toType, string convertText, params string[] fromTypes) +{ + foreach (string fromType in fromTypes) + { + if (toType == fromType) + continue; + + if (!_types.ContainsKey(fromType)) + throw new InvalidOperationException(fromType); + + if (!_types[toType].Froms.ContainsKey(fromType)) + _types[toType].Froms.Add(fromType, string.Format( + convertText, + toType, + fromType, + _types[toType].NullValue ?? "(" + toType + ")null", + toType. TrimEnd('?').Replace("Sql", "").Replace("Money", "Decimal"), + fromType.TrimEnd('?').Replace("Sql", "").Replace("Money", "Decimal"))); + } +} + +void ConvertTo(string[] toTypes, string convertText, params string[] fromTypes) +{ + foreach (var t in toTypes) + ConvertTo(t, convertText, fromTypes); +} + +void ConvertFrom(string fromType, string convertText, params string[] toTypes) +{ + foreach (string toType in toTypes) + ConvertTo(toType, convertText, fromType); +} + +void ConvertToNull(string toType, string convertText, string convertTextNull, params string[] fromTypes) +{ + ConvertTo(toType, convertText, fromTypes); + ConvertTo(toType, convertTextNull, fromTypes.Select(_ => _ + "?").ToArray()); +} + +void ConvertToNull(string[] toTypes, string convertText, string convertTextNull, params string[] fromTypes) +{ + foreach (var t in toTypes) + ConvertToNull(t, convertText, convertTextNull, fromTypes); +} + +void ConvertNumber(string toType, string[] types1, string[] types2, string[] types3, string[] types4) +{ + if (toType != "Money") + { + ConvertToNull(toType, + "p", + "p.HasValue ? p.Value : {2}", + types1); + ConvertToNull(toType, + "checked(({0})p)", + "p.HasValue ? checked(({0})p.Value) : {2}", + types2); + ConvertTo(toType, "p.IsNull ? {2} : p.Value", Sql(types3)); + ConvertTo(toType, "p.IsNull ? {2} : To{0}(p.Value)", Sql(types4)); + + ConvertToNull(toType + "?", + "p", + "p.HasValue ? p.Value : {2}", + types1); + ConvertToNull(toType + "?", + "checked(({0})p)", + "p.HasValue ? checked(({0})p.Value) : {2}", + types2); + ConvertTo(toType + "?", "p.IsNull ? {2} : p.Value", Sql(types3)); + ConvertTo(toType + "?", "p.IsNull ? {2} : To{3}(p.Value)", Sql(types4)); + } + + if (_types.ContainsKey("Sql" + toType)) + { + ConvertToNull("Sql" + toType, + "p", + "p.HasValue ? p.Value : {2}", + types1); + ConvertToNull("Sql" + toType, + "checked(({3})p)", + "p.HasValue ? checked(({3})p.Value) : {2}", + types2); + ConvertTo("Sql" + toType, "p.To{0}()", Sql(types3)); + ConvertTo("Sql" + toType, "p.To{0}()", Sql(types4)); + } +} + +string[] Sql(params string[] types) +{ + return types.Select(_ => "Sql" + _).ToArray(); +} + +string[] Add(string[] str1, params string[] str2) +{ + return str1.Concat(str2).ToArray(); +} + +IEnumerable Set(Action action, IEnumerable types) +{ + foreach (var t in types) + { + action(t); + yield return t; + } +} + +string LenDiff(int max, string str) +{ + var s = ""; + + while (max-- > str.Length) + s += " "; + + return s; +} + +Dictionary _groupOrder = new Dictionary +{ + { "Simple", 1 }, + { "Nullable", 2 }, + { "Sql", 3 }, + { "Other", 4 }, +}; + +HashSet _codedTypes = new HashSet +{ + "Boolean", "Char", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "Decimal", "DateTime", "String", +}; + +void Generate() +{ + PushIndent("\t\t"); + + foreach (var gr in _types.Values.Select(_ => _.Group).Distinct()) + { + WriteLine(""); + WriteLine("#region {0} Types", gr); + + foreach (var to in + from t in _types.Values + where t.Group == gr + orderby t.Name + select t) + { + WriteLine(""); + WriteLine("#region {0}", to.Name); + + var froms = from f in to.Froms.Keys select f; + + if (to.NonSilverlightable) + { + ClearIndent(); + WriteLine(""); + WriteLine("#if !SILVERLIGHT"); + PushIndent("\t\t"); + + froms = + from f in froms + orderby _groupOrder[_types[f].Group], _types[f].Name + select f; + } + else + { + froms = + from f in froms + orderby _types[f].NonSilverlightable, _groupOrder[_types[f].Group], _types[f].Name + select f; + } + + var group = ""; + var sl = false; + var len = froms.Concat(new[] { "" }).Select(_ => _.Length).Max(); + var lcode = to.Froms.Values.Concat(new[] { "" }).Select(_ => (_ ?? "").Length).Max(); + + foreach (var f in froms) + { + var code = to.Froms[f]; + + if (code == null) + continue; + + var fr = _types[f]; + + if (!to.NonSilverlightable && sl != fr.NonSilverlightable) + { + sl = fr.NonSilverlightable; + + ClearIndent(); + WriteLine(""); + WriteLine("#if !SILVERLIGHT"); + PushIndent("\t\t"); + } + + if (fr.Group != group) + { + group = fr.Group; + + WriteLine(""); + WriteLine("// {0} Types", group); + WriteLine("//"); + } + + if (to.NonSLMethods.Contains(fr.Name)) + { + ClearIndent(); + WriteLine("#if !SILVERLIGHT"); + PushIndent("\t\t"); + } + + WriteLine("/// Converts the value from {0} to an equivalent {1} value.", fr.Name, to.Name); + + if (to.NonCompliant || fr.NonCompliant) + WriteLine("[CLSCompliant(false)]"); + + WriteLine("public static {0} {1}({2}{3} p) {{ return {4};{5} }}", + to.Name, to.Method, fr.Name, LenDiff(len, fr.Name), code, LenDiff(lcode, code)); + + if (to.NonSLMethods.Contains(fr.Name)) + { + ClearIndent(); + WriteLine("#endif"); + PushIndent("\t\t"); + } + } + + if (sl) + { + ClearIndent(); + WriteLine(""); + WriteLine("#endif"); + PushIndent("\t\t"); + } + + // From Object + // + if (to.Froms.Count > 0) + { + WriteLine(""); + WriteLine("// From Object"); + WriteLine("//"); + + WriteLine("/// Converts the value from Object to an equivalent {0} value.", to.Name); + + if (to.NonCompliant) + WriteLine("[CLSCompliant(false)]"); + + WriteLine("public static {0} {1}(object p)", to.Name, to.Method); + WriteLine("{"); + + PushIndent("\t"); + + var defType = false; + + var tc = + from f in to.Froms.Keys + where _codedTypes.Contains(f) + select f; + + if (tc.Any()) + { + WriteLine("if (p == null) return {0};", to.NullValue ?? "null"); + WriteLine(""); + + if (!_codedTypes.Contains(to.Name)) + { + WriteLine("if (p is {0}) return ({0})p;", to.Name); + WriteLine(""); + } + + defType = true; + + WriteLine("var type = p.GetType();"); + WriteLine(""); + WriteLine("// Primitive types"); + WriteLine("//"); + WriteLine("switch (Type.GetTypeCode(type))"); + WriteLine("{"); + PushIndent("\t"); + + len = new[] { to.Name, "DBNull" }.Concat(tc).Select(_ => _.Length).Max(); + + WriteLine("case TypeCode.DBNull{0} : return {1};", LenDiff(len, "DBNull"), to.NullValue ?? "null"); + + if (_codedTypes.Contains(to.Name)) + WriteLine("case TypeCode.{0}{1} : return ({0})p;", to.Name, LenDiff(len, to.Name)); + + foreach (var t in tc) + { + if (to.NonSLMethods.Contains(t)) + { + ClearIndent(); + WriteLine("#if !SILVERLIGHT"); + PushIndent("\t\t"); + PushIndent("\t"); + PushIndent("\t"); + } + + WriteLine("case TypeCode.{0}{1} : return {2}(({0}){1}p);", t, LenDiff(len, t), to.Method); + + if (to.NonSLMethods.Contains(t)) + { + ClearIndent(); + WriteLine("#endif"); + PushIndent("\t\t"); + PushIndent("\t"); + PushIndent("\t"); + } + } + + PopIndent(); + WriteLine("}"); + } + else + { + WriteLine("if (p == null || p is DBNull) return {0};", to.NullValue ?? "null"); + WriteLine(""); + WriteLine("if (p is {0}) return ({0})p;", to.Name); + } + + tc = + from f in to.Froms.Keys + where !_codedTypes.Contains(f) + select f; + + if (to.NonSilverlightable) + { + tc = + from f in tc + orderby _groupOrder[_types[f].Group], _types[f].Name + select f; + } + else + { + tc = + from f in tc + orderby _types[f].NonSilverlightable, _groupOrder[_types[f].Group], _types[f].Name + select f; + } + + var openGroupBlock = false; + + group = ""; + sl = false; + len = new[] { "" }.Concat(tc).Select(_ => _.Length).Max(); + + foreach (var f in tc) + { + var fr = _types[f]; + + if (!to.NonSilverlightable && sl != fr.NonSilverlightable) + { + sl = fr.NonSilverlightable; + + ClearIndent(); + WriteLine(""); + WriteLine("#if !SILVERLIGHT"); + PushIndent("\t\t"); + PushIndent("\t"); + } + + if (fr.Group != group) + { + group = fr.Group; + + if (openGroupBlock) + { + openGroupBlock = false; + PopIndent(); + WriteLine("}"); + } + + WriteLine(""); + WriteLine("// {0} Types", group); + WriteLine("//"); + + if (group == "Nullable") + { + openGroupBlock = true; + + if (!defType) + { + defType = true; + WriteLine("var type = p.GetType();"); + WriteLine(""); + } + + WriteLine("if (type.IsGenericType)"); + WriteLine("{"); + + PushIndent("\t"); + } + else if (group == "Sql") + { + openGroupBlock = true; + + WriteLine("if (p is INullable)"); + WriteLine("{"); + + PushIndent("\t"); + } + } + + if (to.NonSLMethods.Contains(fr.Name)) + { + ClearIndent(); + WriteLine("#if !SILVERLIGHT"); + PushIndent("\t\t"); + PushIndent("\t"); + if (openGroupBlock) + PushIndent("\t"); + } + + WriteLine("if (p is {0}){1} return {2}(({0}){1}p);", fr.Name, LenDiff(len, fr.Name), to.Method); + + if (to.NonSLMethods.Contains(fr.Name)) + { + ClearIndent(); + WriteLine("#endif"); + PushIndent("\t\t"); + PushIndent("\t"); + if (openGroupBlock) + PushIndent("\t"); + } + } + + if (openGroupBlock) + { + PopIndent(); + WriteLine("}"); + } + + if (sl) + { + ClearIndent(); + WriteLine(""); + WriteLine("#endif"); + PushIndent("\t\t"); + PushIndent("\t"); + } + + if (_codedTypes.Contains(to.Name)) + { + WriteLine(""); + WriteLine("if (p is IConvertible) return ((IConvertible)p).To{0}(null);", to.Name); + } + + WriteLine(""); + + if (to.FromObjectReturn != null) + WriteLine(to.FromObjectReturn); + else + WriteLine("throw CreateInvalidCastException(p.GetType(), typeof({0}));", to.Name); + + PopIndent(); + + WriteLine("}"); + } + + if (to.NonSilverlightable) + { + ClearIndent(); + WriteLine(""); + WriteLine("#endif"); + PushIndent("\t\t"); + } + + WriteLine(""); + WriteLine("#endregion"); + } + + WriteLine(""); + WriteLine("#endregion"); + } + + ClearIndent(); +} +#> diff -r 000000000000 -r f990fcb411a9 Source/Common/ConvertT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/ConvertT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,151 @@ +using System; +using System.Reflection; +using System.Threading; + +namespace BLToolkit.Common +{ + using Reflection; + + /// + /// Converts a base data type to another base data type. + /// + /// Destination data type. + /// Source data type. + public static class Convert + { + /// + /// Represents a method that converts an object from one type to another type. + /// + /// A value to convert to the target type. + /// The that represents the converted . + public delegate T ConvertMethod(P p); + + /// Converts an array of one type to an array of another type. + /// An array of the target type containing the converted elements from the source array. + /// The one-dimensional, zero-based to convert to a target type. + /// array is null.-or-converter is null. + public static T[] FromArray(P[] src) + { + var arr = new T[src.Length]; + + for (var i = 0; i < arr.Length; i++) + arr[i] = From(src[i]); + + return arr; + } + + /// + /// Converter instance. + /// + public static ConvertMethod From = GetConverter(); + + /// + /// Initializes converter instance. + /// + ///Converter instance. + public static ConvertMethod GetConverter() + { + var from = typeof(P); + var to = typeof(T); + + // Convert to the same type. + // + if (to == from) + return (ConvertMethod)(object)(Convert.ConvertMethod)SameType; + + if (from.IsEnum) + from = Enum.GetUnderlyingType(from); + + if (to.IsEnum) + to = Enum.GetUnderlyingType(to); + + if (TypeHelper.IsSameOrParent(to, from)) + return Assignable; + + string methodName; + + if (TypeHelper.IsNullable(to)) + methodName = "ToNullable" + to.GetGenericArguments()[0].Name; + else if (to.IsArray) + methodName = "To" + to.GetElementType().Name + "Array"; + else if (to.Name == "Binary") + methodName = "ToLinq" + to.Name; + else + methodName = "To" + to.Name; + + var mi = typeof(Convert).GetMethod(methodName, + BindingFlags.Public | BindingFlags.Static | BindingFlags.ExactBinding, + null, new[] { from }, null) ?? FindTypeCastOperator(to) ?? FindTypeCastOperator(from); + + if (mi == null && TypeHelper.IsNullable(to)) + { + // To-nullable conversion. + // We have to use reflection to enforce some constraints. + // + var toType = to.GetGenericArguments()[0]; + var fromType = TypeHelper.IsNullable(from)? from.GetGenericArguments()[0]: from; + + methodName = TypeHelper.IsNullable(from) ? "FromNullable" : "From"; + + mi = typeof(NullableConvert<,>) + .MakeGenericType(toType, fromType) + .GetMethod(methodName, BindingFlags.Public | BindingFlags.Static); + } + + if (mi != null) + return (ConvertMethod)Delegate.CreateDelegate(typeof(ConvertMethod), mi); + + return Default; + } + + private static MethodInfo FindTypeCastOperator(Type t) + { + foreach (var mi in t.GetMethods(BindingFlags.Public | BindingFlags.Static)) + { + if (mi.IsSpecialName && mi.ReturnType == typeof(T) && (mi.Name == "op_Implicit" || mi.Name == "op_Explicit")) + { + var parameters = mi.GetParameters(); + + if (1 == parameters.Length && parameters[0].ParameterType == typeof(P)) + return mi; + } + } + + return null; + } + + private static P SameType (P p) { return p; } + private static T Assignable(P p) { return (T)(object)p; } + private static T Default (P p) { return (T)System.Convert.ChangeType(p, typeof(T), Thread.CurrentThread.CurrentCulture); } + } + + /// + /// Converts a base data type to another base data type. + /// + /// Destination data type. + public static class ConvertTo + { + /// Returns an whose value is equivalent to the specified value. + /// The that represents the converted . + /// A value to convert to the target type. + public static T From

(P p) + { + return Convert.From(p); + } + } + + internal static class NullableConvert + where T: struct + where P: struct + { + public static T? FromNullable(P? p) + { + return p.HasValue? From(p.Value): null; + } + + public static T? From(P p) + { + return Convert.From(p); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Common/EntityBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/EntityBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,131 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Runtime.InteropServices; + +using BLToolkit.ComponentModel; +using BLToolkit.Mapping; +using BLToolkit.Validation; + +namespace BLToolkit.Common +{ + [Serializable, Trimmable, ComVisible(true), JetBrains.Annotations.UsedImplicitly] + public abstract class EntityBase : ICustomTypeDescriptor + { + #region Protected members + + protected virtual ICustomTypeDescriptor CreateTypeDescriptor() + { + return new CustomTypeDescriptorImpl(GetType()); + } + + #endregion + + #region ICustomTypeDescriptor Members + + private static readonly Hashtable _hashDescriptors = new Hashtable(); + + [NonSerialized] + private ICustomTypeDescriptor _typeDescriptor; + private ICustomTypeDescriptor TypeDescriptor + { + get + { + if (_typeDescriptor == null) + { + Type key = GetType(); + + _typeDescriptor = (ICustomTypeDescriptor)_hashDescriptors[key]; + + if (_typeDescriptor == null) + _hashDescriptors[key] = _typeDescriptor = CreateTypeDescriptor(); + } + + return _typeDescriptor; + } + } + + AttributeCollection ICustomTypeDescriptor.GetAttributes() + { + return TypeDescriptor.GetAttributes(); + } + + string ICustomTypeDescriptor.GetClassName() + { + return TypeDescriptor.GetClassName(); + } + + string ICustomTypeDescriptor.GetComponentName() + { + return TypeDescriptor.GetComponentName(); + } + + TypeConverter ICustomTypeDescriptor.GetConverter() + { + return TypeDescriptor.GetConverter(); + } + + EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() + { + return TypeDescriptor.GetDefaultEvent(); + } + + PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() + { + return TypeDescriptor.GetDefaultProperty(); + } + + object ICustomTypeDescriptor.GetEditor(Type editorBaseType) + { + return TypeDescriptor.GetEditor(editorBaseType); + } + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) + { + return TypeDescriptor.GetEvents(attributes); + } + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents() + { + return TypeDescriptor.GetEvents(); + } + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) + { + return TypeDescriptor.GetProperties(attributes); + } + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() + { + return TypeDescriptor.GetProperties(); + } + + object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) + { + // Do not relay this call to TypeDescriptor. We are the owner. + // + return this; + } + + #endregion + + #region Validation + + public virtual void Validate() + { + Validator.Validate(this); + } + + public virtual bool IsValid(string fieldName) + { + return Validator.IsValid(this, fieldName); + } + + public virtual string[] GetErrorMessages(string fieldName) + { + return Validator.GetErrorMessages(this, fieldName); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Common/EntityBaseT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/EntityBaseT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,29 @@ +using System; + +using BLToolkit.Reflection; + +namespace BLToolkit.Common +{ + [Serializable] + public abstract class EntityBase : EntityBase + where T : EntityBase + { + #region CreateInstance + + public static T CreateInstance() + { + return TypeAccessor.CreateInstanceEx(); + } + + #endregion + + #region Clone + + public virtual T Clone() + { + return (T)TypeAccessor.Copy(this); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Common/IOperable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/IOperable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using System; + +namespace BLToolkit.Common +{ + public interface IOperable + { + T Addition (T op1, T op2); + T Subtraction (T op1, T op2); + T Multiply (T op1, T op2); + T Division (T op1, T op2); + T Modulus (T op1, T op2); + + T BitwiseAnd (T op1, T op2); + T BitwiseOr (T op1, T op2); + T ExclusiveOr (T op1, T op2); + + T UnaryNegation (T op); + T OnesComplement (T op); + + bool Equality (T op1, T op2); + bool Inequality (T op1, T op2); + bool GreaterThan (T op1, T op2); + bool GreaterThanOrEqual(T op1, T op2); + bool LessThan (T op1, T op2); + bool LessThanOrEqual (T op1, T op2); + } +} + diff -r 000000000000 -r f990fcb411a9 Source/Common/NameOrIndexParameter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/NameOrIndexParameter.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,139 @@ +using System; +using System.Linq; +using BLToolkit.Properties; + +namespace BLToolkit.Common +{ + ///

+ /// This argument adapter class allows either names (strings) or + /// indices (ints) to be passed to a function. + /// + [System.Diagnostics.DebuggerStepThrough] + public struct NameOrIndexParameter + { + public NameOrIndexParameter(string name) + { + if (null == name) + throw new ArgumentNullException("name"); + + if (name.Length == 0) + throw new ArgumentException(Resources.NameOrIndexParameter_BadName, "name"); + + _name = name; + _index = 0; + } + + public NameOrIndexParameter(int index) + { + if (index < 0) + throw new ArgumentException(Resources.NameOrIndexParameter_BadIndex, "index"); + + _name = null; + _index = index; + } + + public static implicit operator NameOrIndexParameter(string name) + { + return new NameOrIndexParameter(name); + } + + public static implicit operator NameOrIndexParameter(int index) + { + return new NameOrIndexParameter(index); + } + + #region Public properties + + public bool ByName + { + get { return null != _name; } + } + + private readonly string _name; + public string Name + { + get + { + if (null == _name) + throw new InvalidOperationException( + "This instance was initialized by index"); + + return _name; + } + } + + private readonly int _index; + public int Index + { + get + { + if (null != _name) + throw new InvalidOperationException( + "This instance was initialized by name"); + + return _index; + } + } + + #endregion + + #region Static methods + + public static NameOrIndexParameter[] FromStringArray(string[] names) + { + return names.Select(name => new NameOrIndexParameter(name)).ToArray(); + } + + public static NameOrIndexParameter[] FromIndexArray(int[] indices) + { + return indices.Select(index => new NameOrIndexParameter(index)).ToArray(); + } + + #endregion + + #region System.Object members + + public override bool Equals(object obj) + { + if (obj is NameOrIndexParameter) + { + var nip = (NameOrIndexParameter)obj; + + if (null != _name && null != nip._name && _name == nip._name) + return true; // Same name + + if (null == _name && null == nip._name && _index == nip._index) + return true; // Same index + + return false; + } + + if (obj is string) + { + var name = (string)obj; + return (null != _name && _name == name); + } + + if (obj is int) + { + var index = (int)obj; + return (null == _name && _index == index); + } + + return false; + } + + public override int GetHashCode() + { + return (null != _name) ? _name.GetHashCode() : _index.GetHashCode(); + } + + public override string ToString() + { + return _name ?? "#" + _index; + } + + #endregion + + } +} diff -r 000000000000 -r f990fcb411a9 Source/Common/Operator.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/Operator.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1405 @@ +using System; +using System.Data.SqlTypes; + +namespace BLToolkit.Common +{ + public static class Operator + { + public static IOperable Op = GetOperable(); + private static IOperable GetOperable() + { + Type t = typeof(T); + + // Scalar types. + // + if (t == typeof(String)) return (IOperable)new S(); + + if (t == typeof(SByte)) return (IOperable)new S8(); + if (t == typeof(Int16)) return (IOperable)new S16(); + if (t == typeof(Int32)) return (IOperable)new S32(); + if (t == typeof(Int64)) return (IOperable)new S64(); + + if (t == typeof(Byte)) return (IOperable)new U8(); + if (t == typeof(UInt16)) return (IOperable)new U16(); + if (t == typeof(UInt32)) return (IOperable)new U32(); + if (t == typeof(UInt64)) return (IOperable)new U64(); + + if (t == typeof(bool)) return (IOperable)new B(); + if (t == typeof(Char)) return (IOperable)new C(); + if (t == typeof(Single)) return (IOperable)new R4(); + if (t == typeof(Double)) return (IOperable)new R8(); + + if (t == typeof(Decimal)) return (IOperable)new D(); + if (t == typeof(DateTime)) return (IOperable)new DT(); + if (t == typeof(TimeSpan)) return (IOperable)new TS(); + if (t == typeof(Guid)) return (IOperable)new G(); + + // Nullable types. + // + if (t == typeof(SByte?)) return (IOperable)new NS8(); + if (t == typeof(Int16?)) return (IOperable)new NS16(); + if (t == typeof(Int32?)) return (IOperable)new NS32(); + if (t == typeof(Int64?)) return (IOperable)new NS64(); + + if (t == typeof(Byte?)) return (IOperable)new NU8(); + if (t == typeof(UInt16?)) return (IOperable)new NU16(); + if (t == typeof(UInt32?)) return (IOperable)new NU32(); + if (t == typeof(UInt64?)) return (IOperable)new NU64(); + + if (t == typeof(bool?)) return (IOperable)new NB(); + if (t == typeof(Char?)) return (IOperable)new NC(); + if (t == typeof(Single?)) return (IOperable)new NR4(); + if (t == typeof(Double?)) return (IOperable)new NR8(); + + if (t == typeof(Decimal?)) return (IOperable)new ND(); + if (t == typeof(DateTime?)) return (IOperable)new NDT(); + if (t == typeof(TimeSpan?)) return (IOperable)new NTS(); + if (t == typeof(Guid?)) return (IOperable)new NG(); + + // Sql types. + // + if (t == typeof(SqlString)) return (IOperable)new DBS(); + + if (t == typeof(SqlByte)) return (IOperable)new DBU8(); + if (t == typeof(SqlInt16)) return (IOperable)new DBS16(); + if (t == typeof(SqlInt32)) return (IOperable)new DBS32(); + if (t == typeof(SqlInt64)) return (IOperable)new DBS64(); + + if (t == typeof(SqlSingle)) return (IOperable)new DBR4(); + if (t == typeof(SqlDouble)) return (IOperable)new DBR8(); + if (t == typeof(SqlDecimal)) return (IOperable)new DBD(); + if (t == typeof(SqlMoney)) return (IOperable)new DBM(); + + if (t == typeof(SqlBoolean)) return (IOperable)new DBB(); + if (t == typeof(SqlBinary)) return (IOperable)new DBBin(); + if (t == typeof(SqlDateTime)) return (IOperable)new DBDT(); + if (t == typeof(SqlGuid)) return (IOperable)new DBG(); + + return new Default(); + } + + public static T Addition (T op1, T op2) { return Op.Addition (op1, op2); } + public static T Subtraction (T op1, T op2) { return Op.Subtraction (op1, op2); } + public static T Multiply (T op1, T op2) { return Op.Multiply (op1, op2); } + public static T Division (T op1, T op2) { return Op.Division (op1, op2); } + public static T Modulus (T op1, T op2) { return Op.Modulus (op1, op2); } + + public static T BitwiseAnd (T op1, T op2) { return Op.BitwiseAnd (op1, op2); } + public static T BitwiseOr (T op1, T op2) { return Op.BitwiseOr (op1, op2); } + public static T ExclusiveOr (T op1, T op2) { return Op.ExclusiveOr (op1, op2); } + + public static T UnaryNegation (T op) { return Op.UnaryNegation (op); } + public static T OnesComplement (T op) { return Op.OnesComplement (op); } + + public static bool Equality (T op1, T op2) { return Op.Equality (op1, op2); } + public static bool Inequality (T op1, T op2) { return Op.Inequality (op1, op2); } + public static bool GreaterThan (T op1, T op2) { return Op.GreaterThan (op1, op2); } + public static bool GreaterThanOrEqual(T op1, T op2) { return Op.GreaterThanOrEqual(op1, op2); } + public static bool LessThan (T op1, T op2) { return Op.LessThan (op1, op2); } + public static bool LessThanOrEqual (T op1, T op2) { return Op.LessThanOrEqual (op1, op2); } + + #region Default + + private class Default : IOperable + { + public Q Addition (Q op1, Q op2) { throw new InvalidOperationException(); } + public Q Subtraction (Q op1, Q op2) { throw new InvalidOperationException(); } + public Q Multiply (Q op1, Q op2) { throw new InvalidOperationException(); } + public Q Division (Q op1, Q op2) { throw new InvalidOperationException(); } + public Q Modulus (Q op1, Q op2) { throw new InvalidOperationException(); } + + public Q BitwiseAnd (Q op1, Q op2) { throw new InvalidOperationException(); } + public Q BitwiseOr (Q op1, Q op2) { throw new InvalidOperationException(); } + public Q ExclusiveOr (Q op1, Q op2) { throw new InvalidOperationException(); } + + public Q UnaryNegation (Q op) { throw new InvalidOperationException(); } + public Q OnesComplement (Q op) { throw new InvalidOperationException(); } + + public bool Equality (Q op1, Q op2) { throw new InvalidOperationException(); } + public bool Inequality (Q op1, Q op2) { throw new InvalidOperationException(); } + public bool GreaterThan (Q op1, Q op2) { throw new InvalidOperationException(); } + public bool GreaterThanOrEqual(Q op1, Q op2) { throw new InvalidOperationException(); } + public bool LessThan (Q op1, Q op2) { throw new InvalidOperationException(); } + public bool LessThanOrEqual (Q op1, Q op2) { throw new InvalidOperationException(); } + } + + #endregion + + #region Scalar Types. + + #region String + + private class S : IOperable + { + public String Addition (String op1, String op2) { return (op1 + op2); } + public String Subtraction (String op1, String op2) { throw new InvalidOperationException(); } + public String Multiply (String op1, String op2) { throw new InvalidOperationException(); } + public String Division (String op1, String op2) { throw new InvalidOperationException(); } + public String Modulus (String op1, String op2) { throw new InvalidOperationException(); } + + public String BitwiseAnd (String op1, String op2) { throw new InvalidOperationException(); } + public String BitwiseOr (String op1, String op2) { throw new InvalidOperationException(); } + public String ExclusiveOr (String op1, String op2) { throw new InvalidOperationException(); } + + public String UnaryNegation (String op) { throw new InvalidOperationException(); } + public String OnesComplement (String op) { throw new InvalidOperationException(); } + + public bool Equality (String op1, String op2) { return op1 == op2; } + public bool Inequality (String op1, String op2) { return op1 != op2; } + public bool GreaterThan (String op1, String op2) { throw new InvalidOperationException(); } + public bool GreaterThanOrEqual(String op1, String op2) { throw new InvalidOperationException(); } + public bool LessThan (String op1, String op2) { throw new InvalidOperationException(); } + public bool LessThanOrEqual (String op1, String op2) { throw new InvalidOperationException(); } + } + + #endregion + + #region SByte + + private class S8 : IOperable + { + public SByte Addition (SByte op1, SByte op2) { return (SByte)(op1 + op2); } + public SByte Subtraction (SByte op1, SByte op2) { return (SByte)(op1 - op2); } + public SByte Multiply (SByte op1, SByte op2) { return (SByte)(op1 * op2); } + public SByte Division (SByte op1, SByte op2) { return (SByte)(op1 / op2); } + public SByte Modulus (SByte op1, SByte op2) { return (SByte)(op1 % op2); } + + public SByte BitwiseAnd (SByte op1, SByte op2) { return (SByte)(op1 & op2); } + public SByte BitwiseOr (SByte op1, SByte op2) { return (SByte)(op1 | op2); } + public SByte ExclusiveOr (SByte op1, SByte op2) { return (SByte)(op1 ^ op2); } + + public SByte UnaryNegation (SByte op) { return (SByte)(-op); } + public SByte OnesComplement (SByte op) { return (SByte)(~op); } + + public bool Equality (SByte op1, SByte op2) { return op1 == op2; } + public bool Inequality (SByte op1, SByte op2) { return op1 != op2; } + public bool GreaterThan (SByte op1, SByte op2) { return op1 > op2; } + public bool GreaterThanOrEqual(SByte op1, SByte op2) { return op1 >= op2; } + public bool LessThan (SByte op1, SByte op2) { return op1 < op2; } + public bool LessThanOrEqual (SByte op1, SByte op2) { return op1 <= op2; } + } + + #endregion + + #region Int16 + + private class S16 : IOperable + { + public Int16 Addition (Int16 op1, Int16 op2) { return (Int16)(op1 + op2); } + public Int16 Subtraction (Int16 op1, Int16 op2) { return (Int16)(op1 - op2); } + public Int16 Multiply (Int16 op1, Int16 op2) { return (Int16)(op1 * op2); } + public Int16 Division (Int16 op1, Int16 op2) { return (Int16)(op1 / op2); } + public Int16 Modulus (Int16 op1, Int16 op2) { return (Int16)(op1 % op2); } + + public Int16 BitwiseAnd (Int16 op1, Int16 op2) { return (Int16)(op1 & op2); } + public Int16 BitwiseOr (Int16 op1, Int16 op2) { return (Int16)(op1 | op2); } + public Int16 ExclusiveOr (Int16 op1, Int16 op2) { return (Int16)(op1 ^ op2); } + + public Int16 UnaryNegation (Int16 op) { return (Int16)(-op); } + public Int16 OnesComplement (Int16 op) { return (Int16)(~op); } + + public bool Equality (Int16 op1, Int16 op2) { return op1 == op2; } + public bool Inequality (Int16 op1, Int16 op2) { return op1 != op2; } + public bool GreaterThan (Int16 op1, Int16 op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Int16 op1, Int16 op2) { return op1 >= op2; } + public bool LessThan (Int16 op1, Int16 op2) { return op1 < op2; } + public bool LessThanOrEqual (Int16 op1, Int16 op2) { return op1 <= op2; } + } + + #endregion + + #region Int32 + + private class S32 : IOperable + { + public Int32 Addition (Int32 op1, Int32 op2) { return (op1 + op2); } + public Int32 Subtraction (Int32 op1, Int32 op2) { return (op1 - op2); } + public Int32 Multiply (Int32 op1, Int32 op2) { return (op1 * op2); } + public Int32 Division (Int32 op1, Int32 op2) { return (op1 / op2); } + public Int32 Modulus (Int32 op1, Int32 op2) { return (op1 % op2); } + + public Int32 BitwiseAnd (Int32 op1, Int32 op2) { return (op1 & op2); } + public Int32 BitwiseOr (Int32 op1, Int32 op2) { return (op1 | op2); } + public Int32 ExclusiveOr (Int32 op1, Int32 op2) { return (op1 ^ op2); } + + public Int32 UnaryNegation (Int32 op) { return (-op); } + public Int32 OnesComplement (Int32 op) { return (~op); } + + public bool Equality (Int32 op1, Int32 op2) { return op1 == op2; } + public bool Inequality (Int32 op1, Int32 op2) { return op1 != op2; } + public bool GreaterThan (Int32 op1, Int32 op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Int32 op1, Int32 op2) { return op1 >= op2; } + public bool LessThan (Int32 op1, Int32 op2) { return op1 < op2; } + public bool LessThanOrEqual (Int32 op1, Int32 op2) { return op1 <= op2; } + } + + #endregion + + #region Int64 + + private class S64 : IOperable + { + public Int64 Addition (Int64 op1, Int64 op2) { return (op1 + op2); } + public Int64 Subtraction (Int64 op1, Int64 op2) { return (op1 - op2); } + public Int64 Multiply (Int64 op1, Int64 op2) { return (op1 * op2); } + public Int64 Division (Int64 op1, Int64 op2) { return (op1 / op2); } + public Int64 Modulus (Int64 op1, Int64 op2) { return (op1 % op2); } + + public Int64 BitwiseAnd (Int64 op1, Int64 op2) { return (op1 & op2); } + public Int64 BitwiseOr (Int64 op1, Int64 op2) { return (op1 | op2); } + public Int64 ExclusiveOr (Int64 op1, Int64 op2) { return (op1 ^ op2); } + + public Int64 UnaryNegation (Int64 op) { return (-op); } + public Int64 OnesComplement (Int64 op) { return (~op); } + + public bool Equality (Int64 op1, Int64 op2) { return op1 == op2; } + public bool Inequality (Int64 op1, Int64 op2) { return op1 != op2; } + public bool GreaterThan (Int64 op1, Int64 op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Int64 op1, Int64 op2) { return op1 >= op2; } + public bool LessThan (Int64 op1, Int64 op2) { return op1 < op2; } + public bool LessThanOrEqual (Int64 op1, Int64 op2) { return op1 <= op2; } + } + + #endregion + + #region Byte + + private class U8 : IOperable + { + public Byte Addition (Byte op1, Byte op2) { return (Byte)(op1 + op2); } + public Byte Subtraction (Byte op1, Byte op2) { return (Byte)(op1 - op2); } + public Byte Multiply (Byte op1, Byte op2) { return (Byte)(op1 * op2); } + public Byte Division (Byte op1, Byte op2) { return (Byte)(op1 / op2); } + public Byte Modulus (Byte op1, Byte op2) { return (Byte)(op1 % op2); } + + public Byte BitwiseAnd (Byte op1, Byte op2) { return (Byte)(op1 & op2); } + public Byte BitwiseOr (Byte op1, Byte op2) { return (Byte)(op1 | op2); } + public Byte ExclusiveOr (Byte op1, Byte op2) { return (Byte)(op1 ^ op2); } + + public Byte UnaryNegation (Byte op) { throw new InvalidOperationException(); } + public Byte OnesComplement (Byte op) { return (Byte)(~op); } + + public bool Equality (Byte op1, Byte op2) { return op1 == op2; } + public bool Inequality (Byte op1, Byte op2) { return op1 != op2; } + public bool GreaterThan (Byte op1, Byte op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Byte op1, Byte op2) { return op1 >= op2; } + public bool LessThan (Byte op1, Byte op2) { return op1 < op2; } + public bool LessThanOrEqual (Byte op1, Byte op2) { return op1 <= op2; } + } + + #endregion + + #region UInt16 + + private class U16 : IOperable + { + public UInt16 Addition (UInt16 op1, UInt16 op2) { return (UInt16)(op1 + op2); } + public UInt16 Subtraction (UInt16 op1, UInt16 op2) { return (UInt16)(op1 - op2); } + public UInt16 Multiply (UInt16 op1, UInt16 op2) { return (UInt16)(op1 * op2); } + public UInt16 Division (UInt16 op1, UInt16 op2) { return (UInt16)(op1 / op2); } + public UInt16 Modulus (UInt16 op1, UInt16 op2) { return (UInt16)(op1 % op2); } + + public UInt16 BitwiseAnd (UInt16 op1, UInt16 op2) { return (UInt16)(op1 & op2); } + public UInt16 BitwiseOr (UInt16 op1, UInt16 op2) { return (UInt16)(op1 | op2); } + public UInt16 ExclusiveOr (UInt16 op1, UInt16 op2) { return (UInt16)(op1 ^ op2); } + + public UInt16 UnaryNegation (UInt16 op) { throw new InvalidOperationException(); } + public UInt16 OnesComplement (UInt16 op) { return (UInt16)(~op); } + + public bool Equality (UInt16 op1, UInt16 op2) { return op1 == op2; } + public bool Inequality (UInt16 op1, UInt16 op2) { return op1 != op2; } + public bool GreaterThan (UInt16 op1, UInt16 op2) { return op1 > op2; } + public bool GreaterThanOrEqual(UInt16 op1, UInt16 op2) { return op1 >= op2; } + public bool LessThan (UInt16 op1, UInt16 op2) { return op1 < op2; } + public bool LessThanOrEqual (UInt16 op1, UInt16 op2) { return op1 <= op2; } + } + + #endregion + + #region UInt32 + + private class U32 : IOperable + { + public UInt32 Addition (UInt32 op1, UInt32 op2) { return (op1 + op2); } + public UInt32 Subtraction (UInt32 op1, UInt32 op2) { return (op1 - op2); } + public UInt32 Multiply (UInt32 op1, UInt32 op2) { return (op1 * op2); } + public UInt32 Division (UInt32 op1, UInt32 op2) { return (op1 / op2); } + public UInt32 Modulus (UInt32 op1, UInt32 op2) { return (op1 % op2); } + + public UInt32 BitwiseAnd (UInt32 op1, UInt32 op2) { return (op1 & op2); } + public UInt32 BitwiseOr (UInt32 op1, UInt32 op2) { return (op1 | op2); } + public UInt32 ExclusiveOr (UInt32 op1, UInt32 op2) { return (op1 ^ op2); } + + public UInt32 UnaryNegation (UInt32 op) { throw new InvalidOperationException(); } + public UInt32 OnesComplement (UInt32 op) { return (~op); } + + public bool Equality (UInt32 op1, UInt32 op2) { return op1 == op2; } + public bool Inequality (UInt32 op1, UInt32 op2) { return op1 != op2; } + public bool GreaterThan (UInt32 op1, UInt32 op2) { return op1 > op2; } + public bool GreaterThanOrEqual(UInt32 op1, UInt32 op2) { return op1 >= op2; } + public bool LessThan (UInt32 op1, UInt32 op2) { return op1 < op2; } + public bool LessThanOrEqual (UInt32 op1, UInt32 op2) { return op1 <= op2; } + } + + #endregion + + #region UInt64 + + private class U64 : IOperable + { + public UInt64 Addition (UInt64 op1, UInt64 op2) { return (op1 + op2); } + public UInt64 Subtraction (UInt64 op1, UInt64 op2) { return (op1 - op2); } + public UInt64 Multiply (UInt64 op1, UInt64 op2) { return (op1 * op2); } + public UInt64 Division (UInt64 op1, UInt64 op2) { return (op1 / op2); } + public UInt64 Modulus (UInt64 op1, UInt64 op2) { return (op1 % op2); } + + public UInt64 BitwiseAnd (UInt64 op1, UInt64 op2) { return (op1 & op2); } + public UInt64 BitwiseOr (UInt64 op1, UInt64 op2) { return (op1 | op2); } + public UInt64 ExclusiveOr (UInt64 op1, UInt64 op2) { return (op1 ^ op2); } + + public UInt64 UnaryNegation (UInt64 op) { throw new InvalidOperationException(); } + public UInt64 OnesComplement (UInt64 op) { return (~op); } + + public bool Equality (UInt64 op1, UInt64 op2) { return op1 == op2; } + public bool Inequality (UInt64 op1, UInt64 op2) { return op1 != op2; } + public bool GreaterThan (UInt64 op1, UInt64 op2) { return op1 > op2; } + public bool GreaterThanOrEqual(UInt64 op1, UInt64 op2) { return op1 >= op2; } + public bool LessThan (UInt64 op1, UInt64 op2) { return op1 < op2; } + public bool LessThanOrEqual (UInt64 op1, UInt64 op2) { return op1 <= op2; } + } + + #endregion + + #region Boolean + + private class B : IOperable + { + public Boolean Addition (Boolean op1, Boolean op2) { throw new InvalidOperationException(); } + public Boolean Subtraction (Boolean op1, Boolean op2) { throw new InvalidOperationException(); } + public Boolean Multiply (Boolean op1, Boolean op2) { throw new InvalidOperationException(); } + public Boolean Division (Boolean op1, Boolean op2) { throw new InvalidOperationException(); } + public Boolean Modulus (Boolean op1, Boolean op2) { throw new InvalidOperationException(); } + + public Boolean BitwiseAnd (Boolean op1, Boolean op2) { return (op1 & op2); } + public Boolean BitwiseOr (Boolean op1, Boolean op2) { return (op1 | op2); } + public Boolean ExclusiveOr (Boolean op1, Boolean op2) { return (op1 ^ op2); } + + public Boolean UnaryNegation (Boolean op) { throw new InvalidOperationException(); } + public Boolean OnesComplement (Boolean op) { return !op; } + + public bool Equality (Boolean op1, Boolean op2) { return op1 == op2; } + public bool Inequality (Boolean op1, Boolean op2) { return op1 != op2; } + public bool GreaterThan (Boolean op1, Boolean op2) { throw new InvalidOperationException(); } + public bool GreaterThanOrEqual(Boolean op1, Boolean op2) { throw new InvalidOperationException(); } + public bool LessThan (Boolean op1, Boolean op2) { throw new InvalidOperationException(); } + public bool LessThanOrEqual (Boolean op1, Boolean op2) { throw new InvalidOperationException(); } + } + + #endregion + + #region Char + + private class C : IOperable + { + public Char Addition (Char op1, Char op2) { return (Char)(op1 + op2); } + public Char Subtraction (Char op1, Char op2) { return (Char)(op1 - op2); } + public Char Multiply (Char op1, Char op2) { return (Char)(op1 * op2); } + public Char Division (Char op1, Char op2) { return (Char)(op1 / op2); } + public Char Modulus (Char op1, Char op2) { return (Char)(op1 % op2); } + + public Char BitwiseAnd (Char op1, Char op2) { return (Char)(op1 & op2); } + public Char BitwiseOr (Char op1, Char op2) { return (Char)(op1 | op2); } + public Char ExclusiveOr (Char op1, Char op2) { return (Char)(op1 ^ op2); } + + public Char UnaryNegation (Char op) { return (Char)(-op); } + public Char OnesComplement (Char op) { return (Char)(~op); } + + public bool Equality (Char op1, Char op2) { return op1 == op2; } + public bool Inequality (Char op1, Char op2) { return op1 != op2; } + public bool GreaterThan (Char op1, Char op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Char op1, Char op2) { return op1 >= op2; } + public bool LessThan (Char op1, Char op2) { return op1 < op2; } + public bool LessThanOrEqual (Char op1, Char op2) { return op1 <= op2; } + } + + #endregion + + #region Single + + private class R4 : IOperable + { + public Single Addition (Single op1, Single op2) { return (op1 + op2); } + public Single Subtraction (Single op1, Single op2) { return (op1 - op2); } + public Single Multiply (Single op1, Single op2) { return (op1 * op2); } + public Single Division (Single op1, Single op2) { return (op1 / op2); } + public Single Modulus (Single op1, Single op2) { return (op1 % op2); } + + public Single BitwiseAnd (Single op1, Single op2) { throw new InvalidOperationException(); } + public Single BitwiseOr (Single op1, Single op2) { throw new InvalidOperationException(); } + public Single ExclusiveOr (Single op1, Single op2) { throw new InvalidOperationException(); } + + public Single UnaryNegation (Single op) { return (-op); } + public Single OnesComplement (Single op) { throw new InvalidOperationException(); } + + public bool Equality (Single op1, Single op2) { return op1 == op2; } + public bool Inequality (Single op1, Single op2) { return op1 != op2; } + public bool GreaterThan (Single op1, Single op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Single op1, Single op2) { return op1 >= op2; } + public bool LessThan (Single op1, Single op2) { return op1 < op2; } + public bool LessThanOrEqual (Single op1, Single op2) { return op1 <= op2; } + } + + #endregion + + #region Double + + private class R8 : IOperable + { + public Double Addition (Double op1, Double op2) { return (op1 + op2); } + public Double Subtraction (Double op1, Double op2) { return (op1 - op2); } + public Double Multiply (Double op1, Double op2) { return (op1 * op2); } + public Double Division (Double op1, Double op2) { return (op1 / op2); } + public Double Modulus (Double op1, Double op2) { return (op1 % op2); } + + public Double BitwiseAnd (Double op1, Double op2) { throw new InvalidOperationException(); } + public Double BitwiseOr (Double op1, Double op2) { throw new InvalidOperationException(); } + public Double ExclusiveOr (Double op1, Double op2) { throw new InvalidOperationException(); } + + public Double UnaryNegation (Double op) { return (-op); } + public Double OnesComplement (Double op) { throw new InvalidOperationException(); } + + public bool Equality (Double op1, Double op2) { return op1 == op2; } + public bool Inequality (Double op1, Double op2) { return op1 != op2; } + public bool GreaterThan (Double op1, Double op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Double op1, Double op2) { return op1 >= op2; } + public bool LessThan (Double op1, Double op2) { return op1 < op2; } + public bool LessThanOrEqual (Double op1, Double op2) { return op1 <= op2; } + } + + #endregion + + #region Decimal + + private class D : IOperable + { + public Decimal Addition (Decimal op1, Decimal op2) { return (op1 + op2); } + public Decimal Subtraction (Decimal op1, Decimal op2) { return (op1 - op2); } + public Decimal Multiply (Decimal op1, Decimal op2) { return (op1 * op2); } + public Decimal Division (Decimal op1, Decimal op2) { return (op1 / op2); } + public Decimal Modulus (Decimal op1, Decimal op2) { return (op1 % op2); } + + public Decimal BitwiseAnd (Decimal op1, Decimal op2) { throw new InvalidOperationException(); } + public Decimal BitwiseOr (Decimal op1, Decimal op2) { throw new InvalidOperationException(); } + public Decimal ExclusiveOr (Decimal op1, Decimal op2) { throw new InvalidOperationException(); } + + public Decimal UnaryNegation (Decimal op) { return (-op); } + public Decimal OnesComplement (Decimal op) { throw new InvalidOperationException(); } + + public bool Equality (Decimal op1, Decimal op2) { return op1 == op2; } + public bool Inequality (Decimal op1, Decimal op2) { return op1 != op2; } + public bool GreaterThan (Decimal op1, Decimal op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Decimal op1, Decimal op2) { return op1 >= op2; } + public bool LessThan (Decimal op1, Decimal op2) { return op1 < op2; } + public bool LessThanOrEqual (Decimal op1, Decimal op2) { return op1 <= op2; } + } + + #endregion + + #region DateTime + + private class DT : IOperable + { + public DateTime Addition (DateTime op1, DateTime op2) { throw new InvalidOperationException(); } + public DateTime Subtraction (DateTime op1, DateTime op2) { throw new InvalidOperationException(); } + public DateTime Multiply (DateTime op1, DateTime op2) { throw new InvalidOperationException(); } + public DateTime Division (DateTime op1, DateTime op2) { throw new InvalidOperationException(); } + public DateTime Modulus (DateTime op1, DateTime op2) { throw new InvalidOperationException(); } + + public DateTime BitwiseAnd (DateTime op1, DateTime op2) { throw new InvalidOperationException(); } + public DateTime BitwiseOr (DateTime op1, DateTime op2) { throw new InvalidOperationException(); } + public DateTime ExclusiveOr (DateTime op1, DateTime op2) { throw new InvalidOperationException(); } + + public DateTime UnaryNegation (DateTime op) { throw new InvalidOperationException(); } + public DateTime OnesComplement(DateTime op) { throw new InvalidOperationException(); } + + public bool Equality (DateTime op1, DateTime op2) { return op1 == op2; } + public bool Inequality (DateTime op1, DateTime op2) { return op1 != op2; } + public bool GreaterThan (DateTime op1, DateTime op2) { return op1 > op2; } + public bool GreaterThanOrEqual(DateTime op1, DateTime op2) { return op1 >= op2; } + public bool LessThan (DateTime op1, DateTime op2) { return op1 < op2; } + public bool LessThanOrEqual (DateTime op1, DateTime op2) { return op1 <= op2; } + } + + #endregion + + #region TimeSpan + + private class TS : IOperable + { + public TimeSpan Addition (TimeSpan op1, TimeSpan op2) { return (op1 + op2); } + public TimeSpan Subtraction (TimeSpan op1, TimeSpan op2) { return (op1 - op2); } + public TimeSpan Multiply (TimeSpan op1, TimeSpan op2) { throw new InvalidOperationException(); } + public TimeSpan Division (TimeSpan op1, TimeSpan op2) { throw new InvalidOperationException(); } + public TimeSpan Modulus (TimeSpan op1, TimeSpan op2) { throw new InvalidOperationException(); } + + public TimeSpan BitwiseAnd (TimeSpan op1, TimeSpan op2) { throw new InvalidOperationException(); } + public TimeSpan BitwiseOr (TimeSpan op1, TimeSpan op2) { throw new InvalidOperationException(); } + public TimeSpan ExclusiveOr (TimeSpan op1, TimeSpan op2) { throw new InvalidOperationException(); } + + public TimeSpan UnaryNegation (TimeSpan op) { return (-op); } + public TimeSpan OnesComplement(TimeSpan op) { throw new InvalidOperationException(); } + + public bool Equality (TimeSpan op1, TimeSpan op2) { return op1 == op2; } + public bool Inequality (TimeSpan op1, TimeSpan op2) { return op1 != op2; } + public bool GreaterThan (TimeSpan op1, TimeSpan op2) { return op1 > op2; } + public bool GreaterThanOrEqual(TimeSpan op1, TimeSpan op2) { return op1 >= op2; } + public bool LessThan (TimeSpan op1, TimeSpan op2) { return op1 < op2; } + public bool LessThanOrEqual (TimeSpan op1, TimeSpan op2) { return op1 <= op2; } + } + + #endregion + + #region Guid + + private class G : IOperable + { + public Guid Addition (Guid op1, Guid op2) { throw new InvalidOperationException(); } + public Guid Subtraction (Guid op1, Guid op2) { throw new InvalidOperationException(); } + public Guid Multiply (Guid op1, Guid op2) { throw new InvalidOperationException(); } + public Guid Division (Guid op1, Guid op2) { throw new InvalidOperationException(); } + public Guid Modulus (Guid op1, Guid op2) { throw new InvalidOperationException(); } + + public Guid BitwiseAnd (Guid op1, Guid op2) { throw new InvalidOperationException(); } + public Guid BitwiseOr (Guid op1, Guid op2) { throw new InvalidOperationException(); } + public Guid ExclusiveOr (Guid op1, Guid op2) { throw new InvalidOperationException(); } + + public Guid UnaryNegation (Guid op) { throw new InvalidOperationException(); } + public Guid OnesComplement (Guid op) { throw new InvalidOperationException(); } + + public bool Equality (Guid op1, Guid op2) { return op1 == op2; } + public bool Inequality (Guid op1, Guid op2) { return op1 != op2; } + public bool GreaterThan (Guid op1, Guid op2) { throw new InvalidOperationException(); } + public bool GreaterThanOrEqual(Guid op1, Guid op2) { throw new InvalidOperationException(); } + public bool LessThan (Guid op1, Guid op2) { throw new InvalidOperationException(); } + public bool LessThanOrEqual (Guid op1, Guid op2) { throw new InvalidOperationException(); } + } + + #endregion + + #endregion + + #region Nullable Types. + + #region SByte + + private class NS8 : IOperable + { + public SByte? Addition (SByte? op1, SByte? op2) { return (SByte?)(op1 + op2); } + public SByte? Subtraction (SByte? op1, SByte? op2) { return (SByte?)(op1 - op2); } + public SByte? Multiply (SByte? op1, SByte? op2) { return (SByte?)(op1 * op2); } + public SByte? Division (SByte? op1, SByte? op2) { return (SByte?)(op1 / op2); } + public SByte? Modulus (SByte? op1, SByte? op2) { return (SByte?)(op1 % op2); } + + public SByte? BitwiseAnd (SByte? op1, SByte? op2) { return (SByte?)(op1 & op2); } + public SByte? BitwiseOr (SByte? op1, SByte? op2) { return (SByte?)(op1 | op2); } + public SByte? ExclusiveOr (SByte? op1, SByte? op2) { return (SByte?)(op1 ^ op2); } + + public SByte? UnaryNegation (SByte? op) { return (SByte)(- op); } + public SByte? OnesComplement (SByte? op) { return (SByte)(~op); } + + public bool Equality (SByte? op1, SByte? op2) { return op1 == op2; } + public bool Inequality (SByte? op1, SByte? op2) { return op1 != op2; } + public bool GreaterThan (SByte? op1, SByte? op2) { return op1 > op2; } + public bool GreaterThanOrEqual(SByte? op1, SByte? op2) { return op1 >= op2; } + public bool LessThan (SByte? op1, SByte? op2) { return op1 < op2; } + public bool LessThanOrEqual (SByte? op1, SByte? op2) { return op1 <= op2; } + } + + #endregion + + #region Int16 + + private class NS16 : IOperable + { + public Int16? Addition (Int16? op1, Int16? op2) { return (Int16?)(op1 + op2); } + public Int16? Subtraction (Int16? op1, Int16? op2) { return (Int16?)(op1 - op2); } + public Int16? Multiply (Int16? op1, Int16? op2) { return (Int16?)(op1 * op2); } + public Int16? Division (Int16? op1, Int16? op2) { return (Int16?)(op1 / op2); } + public Int16? Modulus (Int16? op1, Int16? op2) { return (Int16?)(op1 % op2); } + + public Int16? BitwiseAnd (Int16? op1, Int16? op2) { return (Int16?)(op1 & op2); } + public Int16? BitwiseOr (Int16? op1, Int16? op2) { return (Int16?)(op1 | op2); } + public Int16? ExclusiveOr (Int16? op1, Int16? op2) { return (Int16?)(op1 ^ op2); } + + public Int16? UnaryNegation (Int16? op) { return (Int16)(- op); } + public Int16? OnesComplement (Int16? op) { return (Int16)(~op); } + + public bool Equality (Int16? op1, Int16? op2) { return op1 == op2; } + public bool Inequality (Int16? op1, Int16? op2) { return op1 != op2; } + public bool GreaterThan (Int16? op1, Int16? op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Int16? op1, Int16? op2) { return op1 >= op2; } + public bool LessThan (Int16? op1, Int16? op2) { return op1 < op2; } + public bool LessThanOrEqual (Int16? op1, Int16? op2) { return op1 <= op2; } + } + + #endregion + + #region Int32 + + private class NS32 : IOperable + { + public Int32? Addition (Int32? op1, Int32? op2) { return (op1 + op2); } + public Int32? Subtraction (Int32? op1, Int32? op2) { return (op1 - op2); } + public Int32? Multiply (Int32? op1, Int32? op2) { return (op1 * op2); } + public Int32? Division (Int32? op1, Int32? op2) { return (op1 / op2); } + public Int32? Modulus (Int32? op1, Int32? op2) { return (op1 % op2); } + + public Int32? BitwiseAnd (Int32? op1, Int32? op2) { return (op1 & op2); } + public Int32? BitwiseOr (Int32? op1, Int32? op2) { return (op1 | op2); } + public Int32? ExclusiveOr (Int32? op1, Int32? op2) { return (op1 ^ op2); } + + public Int32? UnaryNegation (Int32? op) { return (- op); } + public Int32? OnesComplement (Int32? op) { return (~op); } + + public bool Equality (Int32? op1, Int32? op2) { return op1 == op2; } + public bool Inequality (Int32? op1, Int32? op2) { return op1 != op2; } + public bool GreaterThan (Int32? op1, Int32? op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Int32? op1, Int32? op2) { return op1 >= op2; } + public bool LessThan (Int32? op1, Int32? op2) { return op1 < op2; } + public bool LessThanOrEqual (Int32? op1, Int32? op2) { return op1 <= op2; } + } + + #endregion + + #region Int64 + + private class NS64 : IOperable + { + public Int64? Addition (Int64? op1, Int64? op2) { return (op1 + op2); } + public Int64? Subtraction (Int64? op1, Int64? op2) { return (op1 - op2); } + public Int64? Multiply (Int64? op1, Int64? op2) { return (op1 * op2); } + public Int64? Division (Int64? op1, Int64? op2) { return (op1 / op2); } + public Int64? Modulus (Int64? op1, Int64? op2) { return (op1 % op2); } + + public Int64? BitwiseAnd (Int64? op1, Int64? op2) { return (op1 & op2); } + public Int64? BitwiseOr (Int64? op1, Int64? op2) { return (op1 | op2); } + public Int64? ExclusiveOr (Int64? op1, Int64? op2) { return (op1 ^ op2); } + + public Int64? UnaryNegation (Int64? op) { return (- op); } + public Int64? OnesComplement (Int64? op) { return (~op); } + + public bool Equality (Int64? op1, Int64? op2) { return op1 == op2; } + public bool Inequality (Int64? op1, Int64? op2) { return op1 != op2; } + public bool GreaterThan (Int64? op1, Int64? op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Int64? op1, Int64? op2) { return op1 >= op2; } + public bool LessThan (Int64? op1, Int64? op2) { return op1 < op2; } + public bool LessThanOrEqual (Int64? op1, Int64? op2) { return op1 <= op2; } + } + + #endregion + + #region Byte + + private class NU8 : IOperable + { + public Byte? Addition (Byte? op1, Byte? op2) { return (Byte?)(op1 + op2); } + public Byte? Subtraction (Byte? op1, Byte? op2) { return (Byte?)(op1 - op2); } + public Byte? Multiply (Byte? op1, Byte? op2) { return (Byte?)(op1 * op2); } + public Byte? Division (Byte? op1, Byte? op2) { return (Byte?)(op1 / op2); } + public Byte? Modulus (Byte? op1, Byte? op2) { return (Byte?)(op1 % op2); } + + public Byte? BitwiseAnd (Byte? op1, Byte? op2) { return (Byte?)(op1 & op2); } + public Byte? BitwiseOr (Byte? op1, Byte? op2) { return (Byte?)(op1 | op2); } + public Byte? ExclusiveOr (Byte? op1, Byte? op2) { return (Byte?)(op1 ^ op2); } + + public Byte? UnaryNegation (Byte? op) { throw new InvalidOperationException(); } + public Byte? OnesComplement (Byte? op) { return (Byte?)(~op); } + + public bool Equality (Byte? op1, Byte? op2) { return op1 == op2; } + public bool Inequality (Byte? op1, Byte? op2) { return op1 != op2; } + public bool GreaterThan (Byte? op1, Byte? op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Byte? op1, Byte? op2) { return op1 >= op2; } + public bool LessThan (Byte? op1, Byte? op2) { return op1 < op2; } + public bool LessThanOrEqual (Byte? op1, Byte? op2) { return op1 <= op2; } + } + + #endregion + + #region UInt16 + + private class NU16 : IOperable + { + public UInt16? Addition (UInt16? op1, UInt16? op2) { return (UInt16?)(op1 + op2); } + public UInt16? Subtraction (UInt16? op1, UInt16? op2) { return (UInt16?)(op1 - op2); } + public UInt16? Multiply (UInt16? op1, UInt16? op2) { return (UInt16?)(op1 * op2); } + public UInt16? Division (UInt16? op1, UInt16? op2) { return (UInt16?)(op1 / op2); } + public UInt16? Modulus (UInt16? op1, UInt16? op2) { return (UInt16?)(op1 % op2); } + + public UInt16? BitwiseAnd (UInt16? op1, UInt16? op2) { return (UInt16?)(op1 & op2); } + public UInt16? BitwiseOr (UInt16? op1, UInt16? op2) { return (UInt16?)(op1 | op2); } + public UInt16? ExclusiveOr (UInt16? op1, UInt16? op2) { return (UInt16?)(op1 ^ op2); } + + public UInt16? UnaryNegation (UInt16? op) { throw new InvalidOperationException(); } + public UInt16? OnesComplement (UInt16? op) { return (UInt16?)(~op); } + + public bool Equality (UInt16? op1, UInt16? op2) { return op1 == op2; } + public bool Inequality (UInt16? op1, UInt16? op2) { return op1 != op2; } + public bool GreaterThan (UInt16? op1, UInt16? op2) { return op1 > op2; } + public bool GreaterThanOrEqual(UInt16? op1, UInt16? op2) { return op1 >= op2; } + public bool LessThan (UInt16? op1, UInt16? op2) { return op1 < op2; } + public bool LessThanOrEqual (UInt16? op1, UInt16? op2) { return op1 <= op2; } + } + + #endregion + + #region UInt32 + + private class NU32 : IOperable + { + public UInt32? Addition (UInt32? op1, UInt32? op2) { return (op1 + op2); } + public UInt32? Subtraction (UInt32? op1, UInt32? op2) { return (op1 - op2); } + public UInt32? Multiply (UInt32? op1, UInt32? op2) { return (op1 * op2); } + public UInt32? Division (UInt32? op1, UInt32? op2) { return (op1 / op2); } + public UInt32? Modulus (UInt32? op1, UInt32? op2) { return (op1 % op2); } + + public UInt32? BitwiseAnd (UInt32? op1, UInt32? op2) { return (op1 & op2); } + public UInt32? BitwiseOr (UInt32? op1, UInt32? op2) { return (op1 | op2); } + public UInt32? ExclusiveOr (UInt32? op1, UInt32? op2) { return (op1 ^ op2); } + + public UInt32? UnaryNegation (UInt32? op) { throw new InvalidOperationException(); } + public UInt32? OnesComplement (UInt32? op) { return (~op); } + + public bool Equality (UInt32? op1, UInt32? op2) { return op1 == op2; } + public bool Inequality (UInt32? op1, UInt32? op2) { return op1 != op2; } + public bool GreaterThan (UInt32? op1, UInt32? op2) { return op1 > op2; } + public bool GreaterThanOrEqual(UInt32? op1, UInt32? op2) { return op1 >= op2; } + public bool LessThan (UInt32? op1, UInt32? op2) { return op1 < op2; } + public bool LessThanOrEqual (UInt32? op1, UInt32? op2) { return op1 <= op2; } + } + + #endregion + + #region UInt64 + + private class NU64 : IOperable + { + public UInt64? Addition (UInt64? op1, UInt64? op2) { return (op1 + op2); } + public UInt64? Subtraction (UInt64? op1, UInt64? op2) { return (op1 - op2); } + public UInt64? Multiply (UInt64? op1, UInt64? op2) { return (op1 * op2); } + public UInt64? Division (UInt64? op1, UInt64? op2) { return (op1 / op2); } + public UInt64? Modulus (UInt64? op1, UInt64? op2) { return (op1 % op2); } + + public UInt64? BitwiseAnd (UInt64? op1, UInt64? op2) { return (op1 & op2); } + public UInt64? BitwiseOr (UInt64? op1, UInt64? op2) { return (op1 | op2); } + public UInt64? ExclusiveOr (UInt64? op1, UInt64? op2) { return (op1 ^ op2); } + + public UInt64? UnaryNegation (UInt64? op) { throw new InvalidOperationException(); } + public UInt64? OnesComplement (UInt64? op) { return (~op); } + + public bool Equality (UInt64? op1, UInt64? op2) { return op1 == op2; } + public bool Inequality (UInt64? op1, UInt64? op2) { return op1 != op2; } + public bool GreaterThan (UInt64? op1, UInt64? op2) { return op1 > op2; } + public bool GreaterThanOrEqual(UInt64? op1, UInt64? op2) { return op1 >= op2; } + public bool LessThan (UInt64? op1, UInt64? op2) { return op1 < op2; } + public bool LessThanOrEqual (UInt64? op1, UInt64? op2) { return op1 <= op2; } + } + + #endregion + + #region Boolean + + private class NB : IOperable + { + public Boolean? Addition (Boolean? op1, Boolean? op2) { throw new InvalidOperationException(); } + public Boolean? Subtraction (Boolean? op1, Boolean? op2) { throw new InvalidOperationException(); } + public Boolean? Multiply (Boolean? op1, Boolean? op2) { throw new InvalidOperationException(); } + public Boolean? Division (Boolean? op1, Boolean? op2) { throw new InvalidOperationException(); } + public Boolean? Modulus (Boolean? op1, Boolean? op2) { throw new InvalidOperationException(); } + + public Boolean? BitwiseAnd (Boolean? op1, Boolean? op2) { return (op1 & op2); } + public Boolean? BitwiseOr (Boolean? op1, Boolean? op2) { return (op1 | op2); } + public Boolean? ExclusiveOr (Boolean? op1, Boolean? op2) { return (op1 ^ op2); } + + public Boolean? UnaryNegation (Boolean? op) { throw new InvalidOperationException(); } + public Boolean? OnesComplement(Boolean? op) { return !op; } + + public bool Equality (Boolean? op1, Boolean? op2) { return op1 == op2; } + public bool Inequality (Boolean? op1, Boolean? op2) { return op1 != op2; } + public bool GreaterThan (Boolean? op1, Boolean? op2) { throw new InvalidOperationException(); } + public bool GreaterThanOrEqual(Boolean? op1, Boolean? op2) { throw new InvalidOperationException(); } + public bool LessThan (Boolean? op1, Boolean? op2) { throw new InvalidOperationException(); } + public bool LessThanOrEqual (Boolean? op1, Boolean? op2) { throw new InvalidOperationException(); } + } + + #endregion + + #region Char + + private class NC : IOperable + { + public Char? Addition (Char? op1, Char? op2) { return (Char?)(op1 + op2); } + public Char? Subtraction (Char? op1, Char? op2) { return (Char?)(op1 - op2); } + public Char? Multiply (Char? op1, Char? op2) { return (Char?)(op1 * op2); } + public Char? Division (Char? op1, Char? op2) { return (Char?)(op1 / op2); } + public Char? Modulus (Char? op1, Char? op2) { return (Char?)(op1 % op2); } + + public Char? BitwiseAnd (Char? op1, Char? op2) { return (Char?)(op1 & op2); } + public Char? BitwiseOr (Char? op1, Char? op2) { return (Char?)(op1 | op2); } + public Char? ExclusiveOr (Char? op1, Char? op2) { return (Char?)(op1 ^ op2); } + + public Char? UnaryNegation (Char? op) { return (Char?)(-op); } + public Char? OnesComplement (Char? op) { return (Char?)(~op); } + + public bool Equality (Char? op1, Char? op2) { return op1 == op2; } + public bool Inequality (Char? op1, Char? op2) { return op1 != op2; } + public bool GreaterThan (Char? op1, Char? op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Char? op1, Char? op2) { return op1 >= op2; } + public bool LessThan (Char? op1, Char? op2) { return op1 < op2; } + public bool LessThanOrEqual (Char? op1, Char? op2) { return op1 <= op2; } + } + + #endregion + + #region Single + + private class NR4 : IOperable + { + public Single? Addition (Single? op1, Single? op2) { return (op1 + op2); } + public Single? Subtraction (Single? op1, Single? op2) { return (op1 - op2); } + public Single? Multiply (Single? op1, Single? op2) { return (op1 * op2); } + public Single? Division (Single? op1, Single? op2) { return (op1 / op2); } + public Single? Modulus (Single? op1, Single? op2) { return (op1 % op2); } + + public Single? BitwiseAnd (Single? op1, Single? op2) { throw new InvalidOperationException(); } + public Single? BitwiseOr (Single? op1, Single? op2) { throw new InvalidOperationException(); } + public Single? ExclusiveOr (Single? op1, Single? op2) { throw new InvalidOperationException(); } + + public Single? UnaryNegation (Single? op) { return (- op); } + public Single? OnesComplement (Single? op) { throw new InvalidOperationException(); } + + public bool Equality (Single? op1, Single? op2) { return op1 == op2; } + public bool Inequality (Single? op1, Single? op2) { return op1 != op2; } + public bool GreaterThan (Single? op1, Single? op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Single? op1, Single? op2) { return op1 >= op2; } + public bool LessThan (Single? op1, Single? op2) { return op1 < op2; } + public bool LessThanOrEqual (Single? op1, Single? op2) { return op1 <= op2; } + } + + #endregion + + #region Double + + private class NR8 : IOperable + { + public Double? Addition (Double? op1, Double? op2) { return (op1 + op2); } + public Double? Subtraction (Double? op1, Double? op2) { return (op1 - op2); } + public Double? Multiply (Double? op1, Double? op2) { return (op1 * op2); } + public Double? Division (Double? op1, Double? op2) { return (op1 / op2); } + public Double? Modulus (Double? op1, Double? op2) { return (op1 % op2); } + + public Double? BitwiseAnd (Double? op1, Double? op2) { throw new InvalidOperationException(); } + public Double? BitwiseOr (Double? op1, Double? op2) { throw new InvalidOperationException(); } + public Double? ExclusiveOr (Double? op1, Double? op2) { throw new InvalidOperationException(); } + + public Double? UnaryNegation (Double? op) { return (- op); } + public Double? OnesComplement (Double? op) { throw new InvalidOperationException(); } + + public bool Equality (Double? op1, Double? op2) { return op1 == op2; } + public bool Inequality (Double? op1, Double? op2) { return op1 != op2; } + public bool GreaterThan (Double? op1, Double? op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Double? op1, Double? op2) { return op1 >= op2; } + public bool LessThan (Double? op1, Double? op2) { return op1 < op2; } + public bool LessThanOrEqual (Double? op1, Double? op2) { return op1 <= op2; } + } + + #endregion + + #region Decimal + + private class ND : IOperable + { + public Decimal? Addition (Decimal? op1, Decimal? op2) { return (op1 + op2); } + public Decimal? Subtraction (Decimal? op1, Decimal? op2) { return (op1 - op2); } + public Decimal? Multiply (Decimal? op1, Decimal? op2) { return (op1 * op2); } + public Decimal? Division (Decimal? op1, Decimal? op2) { return (op1 / op2); } + public Decimal? Modulus (Decimal? op1, Decimal? op2) { return (op1 % op2); } + + public Decimal? BitwiseAnd (Decimal? op1, Decimal? op2) { throw new InvalidOperationException(); } + public Decimal? BitwiseOr (Decimal? op1, Decimal? op2) { throw new InvalidOperationException(); } + public Decimal? ExclusiveOr (Decimal? op1, Decimal? op2) { throw new InvalidOperationException(); } + + public Decimal? UnaryNegation (Decimal? op) { return (- op); } + public Decimal? OnesComplement(Decimal? op) { throw new InvalidOperationException(); } + + public bool Equality (Decimal? op1, Decimal? op2) { return op1 == op2; } + public bool Inequality (Decimal? op1, Decimal? op2) { return op1 != op2; } + public bool GreaterThan (Decimal? op1, Decimal? op2) { return op1 > op2; } + public bool GreaterThanOrEqual(Decimal? op1, Decimal? op2) { return op1 >= op2; } + public bool LessThan (Decimal? op1, Decimal? op2) { return op1 < op2; } + public bool LessThanOrEqual (Decimal? op1, Decimal? op2) { return op1 <= op2; } + } + + #endregion + + #region DateTime + + private class NDT : IOperable + { + public DateTime? Addition (DateTime? op1, DateTime? op2) { throw new InvalidOperationException(); } + public DateTime? Subtraction (DateTime? op1, DateTime? op2) { throw new InvalidOperationException(); } + public DateTime? Multiply (DateTime? op1, DateTime? op2) { throw new InvalidOperationException(); } + public DateTime? Division (DateTime? op1, DateTime? op2) { throw new InvalidOperationException(); } + public DateTime? Modulus (DateTime? op1, DateTime? op2) { throw new InvalidOperationException(); } + + public DateTime? BitwiseAnd (DateTime? op1, DateTime? op2) { throw new InvalidOperationException(); } + public DateTime? BitwiseOr (DateTime? op1, DateTime? op2) { throw new InvalidOperationException(); } + public DateTime? ExclusiveOr (DateTime? op1, DateTime? op2) { throw new InvalidOperationException(); } + + public DateTime? UnaryNegation (DateTime? op) { throw new InvalidOperationException(); } + public DateTime? OnesComplement(DateTime? op) { throw new InvalidOperationException(); } + + public bool Equality (DateTime? op1, DateTime? op2) { return op1 == op2; } + public bool Inequality (DateTime? op1, DateTime? op2) { return op1 != op2; } + public bool GreaterThan (DateTime? op1, DateTime? op2) { return op1 > op2; } + public bool GreaterThanOrEqual (DateTime? op1, DateTime? op2) { return op1 >= op2; } + public bool LessThan (DateTime? op1, DateTime? op2) { return op1 < op2; } + public bool LessThanOrEqual (DateTime? op1, DateTime? op2) { return op1 <= op2; } + } + + #endregion + + #region TimeSpan + + private class NTS : IOperable + { + public TimeSpan? Addition (TimeSpan? op1, TimeSpan? op2) { return (op1 + op2); } + public TimeSpan? Subtraction (TimeSpan? op1, TimeSpan? op2) { return (op1 - op2); } + public TimeSpan? Multiply (TimeSpan? op1, TimeSpan? op2) { throw new InvalidOperationException(); } + public TimeSpan? Division (TimeSpan? op1, TimeSpan? op2) { throw new InvalidOperationException(); } + public TimeSpan? Modulus (TimeSpan? op1, TimeSpan? op2) { throw new InvalidOperationException(); } + + public TimeSpan? BitwiseAnd (TimeSpan? op1, TimeSpan? op2) { throw new InvalidOperationException(); } + public TimeSpan? BitwiseOr (TimeSpan? op1, TimeSpan? op2) { throw new InvalidOperationException(); } + public TimeSpan? ExclusiveOr (TimeSpan? op1, TimeSpan? op2) { throw new InvalidOperationException(); } + + public TimeSpan? UnaryNegation (TimeSpan? op) { return (- op); } + public TimeSpan? OnesComplement(TimeSpan? op) { throw new InvalidOperationException(); } + + public bool Equality (TimeSpan? op1, TimeSpan? op2) { return op1 == op2; } + public bool Inequality (TimeSpan? op1, TimeSpan? op2) { return op1 != op2; } + public bool GreaterThan (TimeSpan? op1, TimeSpan? op2) { return op1 > op2; } + public bool GreaterThanOrEqual (TimeSpan? op1, TimeSpan? op2) { return op1 >= op2; } + public bool LessThan (TimeSpan? op1, TimeSpan? op2) { return op1 < op2; } + public bool LessThanOrEqual (TimeSpan? op1, TimeSpan? op2) { return op1 <= op2; } + } + + #endregion + + #region Guid? + + private class NG : IOperable + { + public Guid? Addition (Guid? op1, Guid? op2) { throw new InvalidOperationException(); } + public Guid? Subtraction (Guid? op1, Guid? op2) { throw new InvalidOperationException(); } + public Guid? Multiply (Guid? op1, Guid? op2) { throw new InvalidOperationException(); } + public Guid? Division (Guid? op1, Guid? op2) { throw new InvalidOperationException(); } + public Guid? Modulus (Guid? op1, Guid? op2) { throw new InvalidOperationException(); } + + public Guid? BitwiseAnd (Guid? op1, Guid? op2) { throw new InvalidOperationException(); } + public Guid? BitwiseOr (Guid? op1, Guid? op2) { throw new InvalidOperationException(); } + public Guid? ExclusiveOr (Guid? op1, Guid? op2) { throw new InvalidOperationException(); } + + public Guid? UnaryNegation (Guid? op) { throw new InvalidOperationException(); } + public Guid? OnesComplement (Guid? op) { throw new InvalidOperationException(); } + + public bool Equality (Guid? op1, Guid? op2) { return op1 == op2; } + public bool Inequality (Guid? op1, Guid? op2) { return op1 != op2; } + public bool GreaterThan (Guid? op1, Guid? op2) { throw new InvalidOperationException(); } + public bool GreaterThanOrEqual(Guid? op1, Guid? op2) { throw new InvalidOperationException(); } + public bool LessThan (Guid? op1, Guid? op2) { throw new InvalidOperationException(); } + public bool LessThanOrEqual (Guid? op1, Guid? op2) { throw new InvalidOperationException(); } + } + + #endregion + + #endregion + + #region Sql types. + + #region SqlString + + private class DBS : IOperable + { + public SqlString Addition (SqlString op1, SqlString op2) { return (op1 + op2); } + public SqlString Subtraction (SqlString op1, SqlString op2) { throw new InvalidOperationException(); } + public SqlString Multiply (SqlString op1, SqlString op2) { throw new InvalidOperationException(); } + public SqlString Division (SqlString op1, SqlString op2) { throw new InvalidOperationException(); } + public SqlString Modulus (SqlString op1, SqlString op2) { throw new InvalidOperationException(); } + + public SqlString BitwiseAnd (SqlString op1, SqlString op2) { throw new InvalidOperationException(); } + public SqlString BitwiseOr (SqlString op1, SqlString op2) { throw new InvalidOperationException(); } + public SqlString ExclusiveOr (SqlString op1, SqlString op2) { throw new InvalidOperationException(); } + + public SqlString UnaryNegation (SqlString op) { throw new InvalidOperationException(); } + public SqlString OnesComplement(SqlString op) { throw new InvalidOperationException(); } + + public bool Equality (SqlString op1, SqlString op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlString op1, SqlString op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlString op1, SqlString op2) { throw new InvalidOperationException(); } + public bool GreaterThanOrEqual (SqlString op1, SqlString op2) { throw new InvalidOperationException(); } + public bool LessThan (SqlString op1, SqlString op2) { throw new InvalidOperationException(); } + public bool LessThanOrEqual (SqlString op1, SqlString op2) { throw new InvalidOperationException(); } + } + + #endregion + + #region SqlByte + + private class DBU8 : IOperable + { + public SqlByte Addition (SqlByte op1, SqlByte op2) { return (op1 + op2); } + public SqlByte Subtraction (SqlByte op1, SqlByte op2) { return (op1 - op2); } + public SqlByte Multiply (SqlByte op1, SqlByte op2) { return (op1 * op2); } + public SqlByte Division (SqlByte op1, SqlByte op2) { return (op1 / op2); } + public SqlByte Modulus (SqlByte op1, SqlByte op2) { return (op1 % op2); } + + public SqlByte BitwiseAnd (SqlByte op1, SqlByte op2) { return (op1 & op2); } + public SqlByte BitwiseOr (SqlByte op1, SqlByte op2) { return (op1 | op2); } + public SqlByte ExclusiveOr (SqlByte op1, SqlByte op2) { return (op1 ^ op2); } + + public SqlByte UnaryNegation (SqlByte op) { throw new InvalidOperationException(); } + public SqlByte OnesComplement (SqlByte op) { return (~op); } + + public bool Equality (SqlByte op1, SqlByte op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlByte op1, SqlByte op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlByte op1, SqlByte op2) { return (op1 > op2).IsTrue; } + public bool GreaterThanOrEqual(SqlByte op1, SqlByte op2) { return (op1 >= op2).IsTrue; } + public bool LessThan (SqlByte op1, SqlByte op2) { return (op1 < op2).IsTrue; } + public bool LessThanOrEqual (SqlByte op1, SqlByte op2) { return (op1 <= op2).IsTrue; } + } + + #endregion + + #region Int16 + + private class DBS16 : IOperable + { + public SqlInt16 Addition (SqlInt16 op1, SqlInt16 op2) { return (op1 + op2); } + public SqlInt16 Subtraction (SqlInt16 op1, SqlInt16 op2) { return (op1 - op2); } + public SqlInt16 Multiply (SqlInt16 op1, SqlInt16 op2) { return (op1 * op2); } + public SqlInt16 Division (SqlInt16 op1, SqlInt16 op2) { return (op1 / op2); } + public SqlInt16 Modulus (SqlInt16 op1, SqlInt16 op2) { return (op1 % op2); } + + public SqlInt16 BitwiseAnd (SqlInt16 op1, SqlInt16 op2) { return (op1 & op2); } + public SqlInt16 BitwiseOr (SqlInt16 op1, SqlInt16 op2) { return (op1 | op2); } + public SqlInt16 ExclusiveOr (SqlInt16 op1, SqlInt16 op2) { return (op1 ^ op2); } + + public SqlInt16 UnaryNegation (SqlInt16 op) { return (-op); } + public SqlInt16 OnesComplement(SqlInt16 op) { return (~op); } + + public bool Equality (SqlInt16 op1, SqlInt16 op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlInt16 op1, SqlInt16 op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlInt16 op1, SqlInt16 op2) { return (op1 > op2).IsTrue; } + public bool GreaterThanOrEqual(SqlInt16 op1, SqlInt16 op2) { return (op1 >= op2).IsTrue; } + public bool LessThan (SqlInt16 op1, SqlInt16 op2) { return (op1 < op2).IsTrue; } + public bool LessThanOrEqual (SqlInt16 op1, SqlInt16 op2) { return (op1 <= op2).IsTrue; } + } + + #endregion + + #region SqlInt32 + + private class DBS32 : IOperable + { + public SqlInt32 Addition (SqlInt32 op1, SqlInt32 op2) { return (op1 + op2); } + public SqlInt32 Subtraction (SqlInt32 op1, SqlInt32 op2) { return (op1 - op2); } + public SqlInt32 Multiply (SqlInt32 op1, SqlInt32 op2) { return (op1 * op2); } + public SqlInt32 Division (SqlInt32 op1, SqlInt32 op2) { return (op1 / op2); } + public SqlInt32 Modulus (SqlInt32 op1, SqlInt32 op2) { return (op1 % op2); } + + public SqlInt32 BitwiseAnd (SqlInt32 op1, SqlInt32 op2) { return (op1 & op2); } + public SqlInt32 BitwiseOr (SqlInt32 op1, SqlInt32 op2) { return (op1 | op2); } + public SqlInt32 ExclusiveOr (SqlInt32 op1, SqlInt32 op2) { return (op1 ^ op2); } + + public SqlInt32 UnaryNegation (SqlInt32 op) { return (-op); } + public SqlInt32 OnesComplement(SqlInt32 op) { return (~op); } + + public bool Equality (SqlInt32 op1, SqlInt32 op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlInt32 op1, SqlInt32 op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlInt32 op1, SqlInt32 op2) { return (op1 > op2).IsTrue; } + public bool GreaterThanOrEqual(SqlInt32 op1, SqlInt32 op2) { return (op1 >= op2).IsTrue; } + public bool LessThan (SqlInt32 op1, SqlInt32 op2) { return (op1 < op2).IsTrue; } + public bool LessThanOrEqual (SqlInt32 op1, SqlInt32 op2) { return (op1 <= op2).IsTrue; } + } + + #endregion + + #region SqlInt64 + + private class DBS64 : IOperable + { + public SqlInt64 Addition (SqlInt64 op1, SqlInt64 op2) { return (op1 + op2); } + public SqlInt64 Subtraction (SqlInt64 op1, SqlInt64 op2) { return (op1 - op2); } + public SqlInt64 Multiply (SqlInt64 op1, SqlInt64 op2) { return (op1 * op2); } + public SqlInt64 Division (SqlInt64 op1, SqlInt64 op2) { return (op1 / op2); } + public SqlInt64 Modulus (SqlInt64 op1, SqlInt64 op2) { return (op1 % op2); } + + public SqlInt64 BitwiseAnd (SqlInt64 op1, SqlInt64 op2) { return (op1 & op2); } + public SqlInt64 BitwiseOr (SqlInt64 op1, SqlInt64 op2) { return (op1 | op2); } + public SqlInt64 ExclusiveOr (SqlInt64 op1, SqlInt64 op2) { return (op1 ^ op2); } + + public SqlInt64 UnaryNegation (SqlInt64 op) { return (-op); } + public SqlInt64 OnesComplement(SqlInt64 op) { return (~op); } + + public bool Equality (SqlInt64 op1, SqlInt64 op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlInt64 op1, SqlInt64 op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlInt64 op1, SqlInt64 op2) { return (op1 > op2).IsTrue; } + public bool GreaterThanOrEqual(SqlInt64 op1, SqlInt64 op2) { return (op1 >= op2).IsTrue; } + public bool LessThan (SqlInt64 op1, SqlInt64 op2) { return (op1 < op2).IsTrue; } + public bool LessThanOrEqual (SqlInt64 op1, SqlInt64 op2) { return (op1 <= op2).IsTrue; } + } + + #endregion + + #region SqlBoolean + + private class DBB : IOperable + { + public SqlBoolean Addition (SqlBoolean op1, SqlBoolean op2) { throw new InvalidOperationException(); } + public SqlBoolean Subtraction (SqlBoolean op1, SqlBoolean op2) { throw new InvalidOperationException(); } + public SqlBoolean Multiply (SqlBoolean op1, SqlBoolean op2) { throw new InvalidOperationException(); } + public SqlBoolean Division (SqlBoolean op1, SqlBoolean op2) { throw new InvalidOperationException(); } + public SqlBoolean Modulus (SqlBoolean op1, SqlBoolean op2) { throw new InvalidOperationException(); } + + public SqlBoolean BitwiseAnd (SqlBoolean op1, SqlBoolean op2) { return (op1 & op2); } + public SqlBoolean BitwiseOr (SqlBoolean op1, SqlBoolean op2) { return (op1 | op2); } + public SqlBoolean ExclusiveOr (SqlBoolean op1, SqlBoolean op2) { return (op1 ^ op2); } + + public SqlBoolean UnaryNegation (SqlBoolean op) { throw new InvalidOperationException(); } + public SqlBoolean OnesComplement(SqlBoolean op) { return !op; } + + public bool Equality (SqlBoolean op1, SqlBoolean op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlBoolean op1, SqlBoolean op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlBoolean op1, SqlBoolean op2) { throw new InvalidOperationException(); } + public bool GreaterThanOrEqual (SqlBoolean op1, SqlBoolean op2) { throw new InvalidOperationException(); } + public bool LessThan (SqlBoolean op1, SqlBoolean op2) { throw new InvalidOperationException(); } + public bool LessThanOrEqual (SqlBoolean op1, SqlBoolean op2) { throw new InvalidOperationException(); } + } + + #endregion + + #region SqlSingle + + private class DBR4 : IOperable + { + public SqlSingle Addition (SqlSingle op1, SqlSingle op2) { return (op1 + op2); } + public SqlSingle Subtraction (SqlSingle op1, SqlSingle op2) { return (op1 - op2); } + public SqlSingle Multiply (SqlSingle op1, SqlSingle op2) { return (op1 * op2); } + public SqlSingle Division (SqlSingle op1, SqlSingle op2) { return (op1 / op2); } + public SqlSingle Modulus (SqlSingle op1, SqlSingle op2) { throw new InvalidOperationException(); } + + public SqlSingle BitwiseAnd (SqlSingle op1, SqlSingle op2) { throw new InvalidOperationException(); } + public SqlSingle BitwiseOr (SqlSingle op1, SqlSingle op2) { throw new InvalidOperationException(); } + public SqlSingle ExclusiveOr (SqlSingle op1, SqlSingle op2) { throw new InvalidOperationException(); } + + public SqlSingle UnaryNegation (SqlSingle op) { return (-op); } + public SqlSingle OnesComplement(SqlSingle op) { throw new InvalidOperationException(); } + + public bool Equality (SqlSingle op1, SqlSingle op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlSingle op1, SqlSingle op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlSingle op1, SqlSingle op2) { return (op1 > op2).IsTrue; } + public bool GreaterThanOrEqual (SqlSingle op1, SqlSingle op2) { return (op1 >= op2).IsTrue; } + public bool LessThan (SqlSingle op1, SqlSingle op2) { return (op1 < op2).IsTrue; } + public bool LessThanOrEqual (SqlSingle op1, SqlSingle op2) { return (op1 <= op2).IsTrue; } + } + + #endregion + + #region SqlDouble + + private class DBR8 : IOperable + { + public SqlDouble Addition (SqlDouble op1, SqlDouble op2) { return (op1 + op2); } + public SqlDouble Subtraction (SqlDouble op1, SqlDouble op2) { return (op1 - op2); } + public SqlDouble Multiply (SqlDouble op1, SqlDouble op2) { return (op1 * op2); } + public SqlDouble Division (SqlDouble op1, SqlDouble op2) { return (op1 / op2); } + public SqlDouble Modulus (SqlDouble op1, SqlDouble op2) { throw new InvalidOperationException(); } + + public SqlDouble BitwiseAnd (SqlDouble op1, SqlDouble op2) { throw new InvalidOperationException(); } + public SqlDouble BitwiseOr (SqlDouble op1, SqlDouble op2) { throw new InvalidOperationException(); } + public SqlDouble ExclusiveOr (SqlDouble op1, SqlDouble op2) { throw new InvalidOperationException(); } + + public SqlDouble UnaryNegation (SqlDouble op) { return (-op); } + public SqlDouble OnesComplement(SqlDouble op) { throw new InvalidOperationException(); } + + public bool Equality (SqlDouble op1, SqlDouble op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlDouble op1, SqlDouble op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlDouble op1, SqlDouble op2) { return (op1 > op2).IsTrue; } + public bool GreaterThanOrEqual (SqlDouble op1, SqlDouble op2) { return (op1 >= op2).IsTrue; } + public bool LessThan (SqlDouble op1, SqlDouble op2) { return (op1 < op2).IsTrue; } + public bool LessThanOrEqual (SqlDouble op1, SqlDouble op2) { return (op1 <= op2).IsTrue; } + } + + #endregion + + #region SqlDecimal + + private class DBD : IOperable + { + public SqlDecimal Addition (SqlDecimal op1, SqlDecimal op2) { return (op1 + op2); } + public SqlDecimal Subtraction (SqlDecimal op1, SqlDecimal op2) { return (op1 - op2); } + public SqlDecimal Multiply (SqlDecimal op1, SqlDecimal op2) { return (op1 * op2); } + public SqlDecimal Division (SqlDecimal op1, SqlDecimal op2) { return (op1 / op2); } + public SqlDecimal Modulus (SqlDecimal op1, SqlDecimal op2) { throw new InvalidOperationException(); } + + public SqlDecimal BitwiseAnd (SqlDecimal op1, SqlDecimal op2) { throw new InvalidOperationException(); } + public SqlDecimal BitwiseOr (SqlDecimal op1, SqlDecimal op2) { throw new InvalidOperationException(); } + public SqlDecimal ExclusiveOr (SqlDecimal op1, SqlDecimal op2) { throw new InvalidOperationException(); } + + public SqlDecimal UnaryNegation (SqlDecimal op) { return (-op); } + public SqlDecimal OnesComplement(SqlDecimal op) { throw new InvalidOperationException(); } + + public bool Equality (SqlDecimal op1, SqlDecimal op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlDecimal op1, SqlDecimal op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlDecimal op1, SqlDecimal op2) { return (op1 > op2).IsTrue; } + public bool GreaterThanOrEqual (SqlDecimal op1, SqlDecimal op2) { return (op1 >= op2).IsTrue; } + public bool LessThan (SqlDecimal op1, SqlDecimal op2) { return (op1 < op2).IsTrue; } + public bool LessThanOrEqual (SqlDecimal op1, SqlDecimal op2) { return (op1 <= op2).IsTrue; } + } + + #endregion + + #region SqlMoney + + private class DBM : IOperable + { + public SqlMoney Addition (SqlMoney op1, SqlMoney op2) { return (op1 + op2); } + public SqlMoney Subtraction (SqlMoney op1, SqlMoney op2) { return (op1 - op2); } + public SqlMoney Multiply (SqlMoney op1, SqlMoney op2) { return (op1 * op2); } + public SqlMoney Division (SqlMoney op1, SqlMoney op2) { return (op1 / op2); } + public SqlMoney Modulus (SqlMoney op1, SqlMoney op2) { throw new InvalidOperationException(); } + + public SqlMoney BitwiseAnd (SqlMoney op1, SqlMoney op2) { throw new InvalidOperationException(); } + public SqlMoney BitwiseOr (SqlMoney op1, SqlMoney op2) { throw new InvalidOperationException(); } + public SqlMoney ExclusiveOr (SqlMoney op1, SqlMoney op2) { throw new InvalidOperationException(); } + + public SqlMoney UnaryNegation (SqlMoney op) { return (-op); } + public SqlMoney OnesComplement(SqlMoney op) { throw new InvalidOperationException(); } + + public bool Equality (SqlMoney op1, SqlMoney op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlMoney op1, SqlMoney op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlMoney op1, SqlMoney op2) { return (op1 > op2).IsTrue; } + public bool GreaterThanOrEqual(SqlMoney op1, SqlMoney op2) { return (op1 >= op2).IsTrue; } + public bool LessThan (SqlMoney op1, SqlMoney op2) { return (op1 < op2).IsTrue; } + public bool LessThanOrEqual (SqlMoney op1, SqlMoney op2) { return (op1 <= op2).IsTrue; } + } + + #endregion + + #region SqlDateTime + + private class DBDT : IOperable + { + public SqlDateTime Addition (SqlDateTime op1, SqlDateTime op2) { throw new InvalidOperationException(); } + public SqlDateTime Subtraction (SqlDateTime op1, SqlDateTime op2) { throw new InvalidOperationException(); } + public SqlDateTime Multiply (SqlDateTime op1, SqlDateTime op2) { throw new InvalidOperationException(); } + public SqlDateTime Division (SqlDateTime op1, SqlDateTime op2) { throw new InvalidOperationException(); } + public SqlDateTime Modulus (SqlDateTime op1, SqlDateTime op2) { throw new InvalidOperationException(); } + + public SqlDateTime BitwiseAnd (SqlDateTime op1, SqlDateTime op2) { throw new InvalidOperationException(); } + public SqlDateTime BitwiseOr (SqlDateTime op1, SqlDateTime op2) { throw new InvalidOperationException(); } + public SqlDateTime ExclusiveOr (SqlDateTime op1, SqlDateTime op2) { throw new InvalidOperationException(); } + + public SqlDateTime UnaryNegation (SqlDateTime op) { throw new InvalidOperationException(); } + public SqlDateTime OnesComplement(SqlDateTime op) { throw new InvalidOperationException(); } + + public bool Equality (SqlDateTime op1, SqlDateTime op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlDateTime op1, SqlDateTime op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlDateTime op1, SqlDateTime op2) { return (op1 > op2).IsTrue; } + public bool GreaterThanOrEqual (SqlDateTime op1, SqlDateTime op2) { return (op1 >= op2).IsTrue; } + public bool LessThan (SqlDateTime op1, SqlDateTime op2) { return (op1 < op2).IsTrue; } + public bool LessThanOrEqual (SqlDateTime op1, SqlDateTime op2) { return (op1 <= op2).IsTrue; } + } + + #endregion + + #region SqlBinary + + private class DBBin : IOperable + { + public SqlBinary Addition (SqlBinary op1, SqlBinary op2) { return (op1 + op2); } + public SqlBinary Subtraction (SqlBinary op1, SqlBinary op2) { throw new InvalidOperationException(); } + public SqlBinary Multiply (SqlBinary op1, SqlBinary op2) { throw new InvalidOperationException(); } + public SqlBinary Division (SqlBinary op1, SqlBinary op2) { throw new InvalidOperationException(); } + public SqlBinary Modulus (SqlBinary op1, SqlBinary op2) { throw new InvalidOperationException(); } + + public SqlBinary BitwiseAnd (SqlBinary op1, SqlBinary op2) { throw new InvalidOperationException(); } + public SqlBinary BitwiseOr (SqlBinary op1, SqlBinary op2) { throw new InvalidOperationException(); } + public SqlBinary ExclusiveOr (SqlBinary op1, SqlBinary op2) { throw new InvalidOperationException(); } + + public SqlBinary UnaryNegation (SqlBinary op) { throw new InvalidOperationException(); } + public SqlBinary OnesComplement(SqlBinary op) { throw new InvalidOperationException(); } + + public bool Equality (SqlBinary op1, SqlBinary op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlBinary op1, SqlBinary op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlBinary op1, SqlBinary op2) { return (op1 > op2).IsTrue; } + public bool GreaterThanOrEqual (SqlBinary op1, SqlBinary op2) { return (op1 >= op2).IsTrue; } + public bool LessThan (SqlBinary op1, SqlBinary op2) { return (op1 < op2).IsTrue; } + public bool LessThanOrEqual (SqlBinary op1, SqlBinary op2) { return (op1 <= op2).IsTrue; } + } + + #endregion + + #region SqlGuid + + private class DBG : IOperable + { + public SqlGuid Addition (SqlGuid op1, SqlGuid op2) { throw new InvalidOperationException(); } + public SqlGuid Subtraction (SqlGuid op1, SqlGuid op2) { throw new InvalidOperationException(); } + public SqlGuid Multiply (SqlGuid op1, SqlGuid op2) { throw new InvalidOperationException(); } + public SqlGuid Division (SqlGuid op1, SqlGuid op2) { throw new InvalidOperationException(); } + public SqlGuid Modulus (SqlGuid op1, SqlGuid op2) { throw new InvalidOperationException(); } + + public SqlGuid BitwiseAnd (SqlGuid op1, SqlGuid op2) { throw new InvalidOperationException(); } + public SqlGuid BitwiseOr (SqlGuid op1, SqlGuid op2) { throw new InvalidOperationException(); } + public SqlGuid ExclusiveOr (SqlGuid op1, SqlGuid op2) { throw new InvalidOperationException(); } + + public SqlGuid UnaryNegation (SqlGuid op) { throw new InvalidOperationException(); } + public SqlGuid OnesComplement (SqlGuid op) { throw new InvalidOperationException(); } + + public bool Equality (SqlGuid op1, SqlGuid op2) { return (op1 == op2).IsTrue; } + public bool Inequality (SqlGuid op1, SqlGuid op2) { return (op1 != op2).IsTrue; } + public bool GreaterThan (SqlGuid op1, SqlGuid op2) { return (op1 > op2).IsTrue; } + public bool GreaterThanOrEqual(SqlGuid op1, SqlGuid op2) { return (op1 >= op2).IsTrue; } + public bool LessThan (SqlGuid op1, SqlGuid op2) { return (op1 < op2).IsTrue; } + public bool LessThanOrEqual (SqlGuid op1, SqlGuid op2) { return (op1 <= op2).IsTrue; } + } + + #endregion + + #endregion + } + + public static class Operator + { + public static T Addition (T a, T b) { return Operator.Op.Addition (a, b); } + public static T Subtraction (T a, T b) { return Operator.Op.Subtraction (a, b); } + public static T Multiply (T a, T b) { return Operator.Op.Multiply (a, b); } + public static T Division (T a, T b) { return Operator.Op.Division (a, b); } + public static T Modulus (T a, T b) { return Operator.Op.Modulus (a, b); } + + public static T BitwiseAnd (T a, T b) { return Operator.Op.BitwiseAnd (a, b); } + public static T BitwiseOr (T a, T b) { return Operator.Op.BitwiseOr (a, b); } + public static T ExclusiveOr (T a, T b) { return Operator.Op.ExclusiveOr (a, b); } + + public static T UnaryNegation (T a) { return Operator.Op.UnaryNegation (a); } + public static T OnesComplement (T a) { return Operator.Op.OnesComplement (a); } + + public static bool Equality (T a, T b) { return Operator.Op.Equality (a, b); } + public static bool Inequality (T a, T b) { return Operator.Op.Inequality (a, b); } + public static bool GreaterThan (T a, T b) { return Operator.Op.GreaterThan (a, b); } + public static bool GreaterThanOrEqual(T a, T b) { return Operator.Op.GreaterThanOrEqual(a, b); } + public static bool LessThan (T a, T b) { return Operator.Op.LessThan (a, b); } + public static bool LessThanOrEqual (T a, T b) { return Operator.Op.LessThanOrEqual (a, b); } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Common/Tuple.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Common/Tuple.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,127 @@ +using System; + +namespace BLToolkit.Common +{ + [Obsolete("Use System.Tuple")] + public struct Tuple + { + public Tuple(T1 field1, T2 field2) + { + Field1 = field1; + Field2 = field2; + } + + public readonly T1 Field1; + public readonly T2 Field2; + + public override int GetHashCode() + { + int hash1 = Field1 == null ? 0 : Field1.GetHashCode(); + int hash2 = Field2 == null ? 0 : Field2.GetHashCode(); + + return ((hash1 << 5) + hash1) ^ hash2; + } + + public override bool Equals(object obj) + { + if (obj is Tuple) + { + Tuple t = (Tuple)obj; + + return + (Field1 == null ? t.Field1 == null : Field1.Equals(t.Field1)) && + (Field2 == null ? t.Field2 == null : Field2.Equals(t.Field2)); + } + + return false; + } + } + + [Obsolete("Use System.Tuple")] + public struct Tuple + { + public Tuple(T1 field1, T2 field2, T3 field3) + { + Field1 = field1; + Field2 = field2; + Field3 = field3; + } + + public readonly T1 Field1; + public readonly T2 Field2; + public readonly T3 Field3; + + public override int GetHashCode() + { + int hash1 = Field1 == null ? 0 : Field1.GetHashCode(); + int hash2 = Field2 == null ? 0 : Field2.GetHashCode(); + + hash1 = ((hash1 << 5) + hash1) ^ hash2; + hash2 = Field3 == null ? 0 : Field3.GetHashCode(); + + return ((hash1 << 5) + hash1) ^ hash2; + } + + public override bool Equals(object obj) + { + if (obj is Tuple) + { + Tuple t = (Tuple)obj; + + return + (Field1 == null ? t.Field1 == null : Field1.Equals(t.Field1)) && + (Field2 == null ? t.Field2 == null : Field2.Equals(t.Field2)) && + (Field3 == null ? t.Field3 == null : Field3.Equals(t.Field3)); + } + + return false; + } + } + + [Obsolete("Use System.Tuple")] + public struct Tuple + { + public Tuple(T1 field1, T2 field2, T3 field3, T4 field4) + { + Field1 = field1; + Field2 = field2; + Field3 = field3; + Field4 = field4; + } + + public readonly T1 Field1; + public readonly T2 Field2; + public readonly T3 Field3; + public readonly T4 Field4; + + public override int GetHashCode() + { + int hash1 = Field1 == null ? 0 : Field1.GetHashCode(); + int hash2 = Field2 == null ? 0 : Field2.GetHashCode(); + + hash1 = ((hash1 << 5) + hash1) ^ hash2; + hash2 = Field3 == null ? 0 : Field3.GetHashCode(); + + hash1 = ((hash1 << 5) + hash1) ^ hash2; + hash2 = Field4 == null ? 0 : Field4.GetHashCode(); + + return ((hash1 << 5) + hash1) ^ hash2; + } + + public override bool Equals(object obj) + { + if (obj is Tuple) + { + Tuple t = (Tuple)obj; + + return + (Field1 == null ? t.Field1 == null : Field1.Equals(t.Field1)) && + (Field2 == null ? t.Field2 == null : Field2.Equals(t.Field2)) && + (Field3 == null ? t.Field3 == null : Field3.Equals(t.Field3)) && + (Field4 == null ? t.Field4 == null : Field4.Equals(t.Field4)); + } + + return false; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Compile3.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Compile3.bat Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ +..\Tools\SvnRevision\SvnRevision.exe .. Templates\BLToolkitConstants.Revision.cs.template Properties\Revision.generated.cs + +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe /target:Clean BLToolkit.3.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe /target:Clean BLToolkit.3.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.3.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe BLToolkit.3.csproj /property:Configuration=Release +pause \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Compile4.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Compile4.bat Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /target:Clean BLToolkit.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /target:Clean BLToolkit.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.4.csproj /property:Configuration=Release + +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /target:Clean BLToolkit.Data.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /target:Clean BLToolkit.Data.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.Data.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.Data.4.csproj /property:Configuration=Release + +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /target:Clean BLToolkit.CP.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /target:Clean BLToolkit.CP.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.CP.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.CP.4.csproj /property:Configuration=Release + +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /target:Clean BLToolkit.SL.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /target:Clean BLToolkit.SL.4.csproj /property:Configuration=Release +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.SL.4.csproj /property:Configuration=Debug +%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe BLToolkit.SL.4.csproj /property:Configuration=Release + +pause \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/BindingListImpl.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/BindingListImpl.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,876 @@ +using System; + +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Diagnostics; + +using BLToolkit.EditableObjects; +using BLToolkit.Reflection; + +namespace BLToolkit.ComponentModel +{ + public class BindingListImpl: IBindingListView, ICancelAddNew, INotifyCollectionChanged + { + #region Init + + public BindingListImpl(IList list, Type itemType) + { + if (list == null) throw new ArgumentNullException("list"); + if (itemType == null) throw new ArgumentNullException("itemType"); + + _list = list; + _itemType = itemType; + + AddInternal(_list); + } + + #endregion + + #region Protected Members + + private readonly IList _list; + private readonly Type _itemType; + + private void ApplySort(IComparer comparer) + { + if (_list is ISortable) + ((ISortable)_list).Sort(0, _list.Count, comparer); + else if (_list is ArrayList) + ((ArrayList)_list).Sort(0, _list.Count, comparer); + else if (_list is Array) + Array.Sort((Array)_list, comparer); + else + { + object[] items = new object[_list.Count]; + + _list.CopyTo(items, 0); + Array.Sort(items, comparer); + + for (int i = 0; i < _list.Count; i++) + _list[i] = items[i]; + } + + _isSorted = true; + } + + #endregion + + #region IBindingList Members + + #region Command + + private int _newItemIndex = -1; + private INotifyObjectEdit _newObject; + + public object AddNew() + { + if (AllowNew == false) + throw new NotSupportedException(); + + EndNew(); + + object o = TypeAccessor.CreateInstanceEx(_itemType); + _newObject = o as INotifyObjectEdit; + + if (_newObject != null) + _newObject.ObjectEdit += NewObject_ObjectEdit; + + _newItemIndex = _list.Add(o); + OnAddItem(o, _newItemIndex); + + Debug.WriteLine(string.Format("AddNew - ({0})", o.GetType().Name)); + + return o; + } + + void NewObject_ObjectEdit(object sender, ObjectEditEventArgs args) + { + if (sender == _newObject) + { + switch (args.EditType) + { + case ObjectEditType.End: EndNew(); break; + case ObjectEditType.Cancel: CancelNew(_newItemIndex); break; + default: return; + } + } + } + + public bool AllowNew + { + get { return !_list.IsFixedSize; } + } + + public bool AllowEdit + { + get { return !_list.IsReadOnly; } + } + + public bool AllowRemove + { + get { return !_list.IsFixedSize; } + } + + #endregion + + #region Change Notification + + private bool _notifyChanges = true; + public bool NotifyChanges + { + get { return _notifyChanges; } + set { _notifyChanges = value; } + } + + public bool SupportsChangeNotification + { + get { return true; } + } + + public event ListChangedEventHandler ListChanged; + + private void FireListChangedEvent(object sender, ListChangedEventArgs e) + { + if (_notifyChanges && ListChanged != null) + ListChanged(sender, e); + } + + protected virtual void OnListChanged(EditableListChangedEventArgs e) + { + FireListChangedEvent(this, e); + } + + protected void OnListChanged(ListChangedType listChangedType, int index) + { + OnListChanged(new EditableListChangedEventArgs(listChangedType, index)); + } + + private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (_notifyChanges && sender != null) + { + int indexOfSender = _list.IndexOf(sender); + + if (indexOfSender >= 0) + { + MemberAccessor ma = TypeAccessor.GetAccessor(sender.GetType())[e.PropertyName]; + + if (ma != null) + OnListChanged(new EditableListChangedEventArgs(indexOfSender, ma.PropertyDescriptor)); + else + OnListChanged(new EditableListChangedEventArgs(ListChangedType.ItemChanged, indexOfSender)); + + // Do not fire an event for OnCollectionChanged here. + + if (_isSorted && _list.Count > 1) + { + int newIndex = GetItemSortedPosition(indexOfSender, sender); + + if (newIndex != indexOfSender) + { + _list.RemoveAt(indexOfSender); + _list.Insert(newIndex, sender); + + OnMoveItem(sender, indexOfSender, newIndex); + } + } + } + } + } + + #endregion + + #region Sorting + + public bool SupportsSorting + { + get { return true; } + } + + [NonSerialized] + private bool _isSorted; + public bool IsSorted + { + get { return _isSorted; } + } + + [NonSerialized] + private PropertyDescriptor _sortProperty; + public PropertyDescriptor SortProperty + { + get { return _sortProperty; } + } + + [NonSerialized] + private ListSortDirection _sortDirection; + public ListSortDirection SortDirection + { + get { return _sortDirection; } + } + + public void ApplySort(PropertyDescriptor property, ListSortDirection direction) + { + Debug.WriteLine(string.Format("Begin ApplySort(\"{0}\", {1})", property.Name, direction)); + + _sortProperty = property; + _sortDirection = direction; + _sortDescriptions = null; + + ApplySort(GetSortComparer(_sortProperty, _sortDirection)); + + if (_list.Count > 0) + OnReset(); + + Debug.WriteLine(string.Format("End ApplySort(\"{0}\", {1})", property.Name, direction)); + } + + public void RemoveSort() + { + _isSorted = false; + _sortProperty = null; + _sortDescriptions = null; + + OnReset(); + } + + #endregion + + #region Searching + + public bool SupportsSearching + { + get { return true; } + } + + public int Find(PropertyDescriptor property, object key) + { + if (property == null) throw new ArgumentException("property"); + + if (key != null) + for (int i = 0; i < _list.Count; i++) + if (key.Equals(property.GetValue(_list[i]))) + return i; + + return -1; + } + + #endregion + + #region Indexes + + public void AddIndex(PropertyDescriptor property) + { + } + + public void RemoveIndex(PropertyDescriptor property) + { + } + + #endregion + + #endregion + + #region ICancelAddNew Members + + public void CancelNew(int itemIndex) + { + if (itemIndex >= 0 && itemIndex == _newItemIndex) + { + _list.RemoveAt(itemIndex); + OnRemoveItem(_newObject, itemIndex); + EndNew(); + } + } + + public void EndNew(int itemIndex) + { + if (itemIndex == _newItemIndex) + EndNew(); + } + + public void EndNew() + { + _newItemIndex = -1; + + if (_newObject != null) + _newObject.ObjectEdit -= NewObject_ObjectEdit; + + _newObject = null; + } + + #endregion + + #region IList Members + + public int Add(object value) + { + int index; + + if (!_isSorted) + index = _list.Add(value); + else + { + index = GetSortedInsertIndex(value); + _list.Insert(index, value); + } + + AddInternal(value); + OnAddItem(value, index); + + return index; + } + + public void Clear() + { + if (_list.Count > 0) + { + RemoveInternal(_list); + + _list.Clear(); + OnReset(); + } + } + + public bool Contains(object value) + { + return _list.Contains(value); + } + + public int IndexOf(object value) + { + return _list.IndexOf(value); + } + + public void Insert(int index, object value) + { + if (_isSorted) + index = GetSortedInsertIndex(value); + + _list.Insert(index, value); + AddInternal(value); + + OnAddItem(value, index); + } + + public bool IsFixedSize + { + get { return _list.IsFixedSize; } + } + + public bool IsReadOnly + { + get { return _list.IsReadOnly; } + } + + public void Remove(object value) + { + int index = IndexOf(value); + + if (index >= 0) + RemoveInternal(value); + + _list.Remove(value); + + if (index >= 0) + OnRemoveItem(value, index); + } + + public void RemoveAt(int index) + { + object value = this[index]; + + RemoveInternal(value); + + _list.RemoveAt(index); + + OnRemoveItem(value, index); + } + + public object this[int index] + { + get { return _list[index]; } + set + { + object o = _list[index]; + + if (o != value) + { + RemoveInternal(o); + + _list[index] = value; + + AddInternal(value); + + OnChangeItem(o, value, index); + + if (_isSorted) + { + int newIndex = GetItemSortedPosition(index, value); + + if (newIndex != index) + { + _list.RemoveAt(index); + _list.Insert(newIndex, value); + } + + OnMoveItem(value, index, newIndex); + } + } + } + } + + #endregion + + #region ICollection Members + + public void CopyTo(Array array, int index) + { + _list.CopyTo(array, index); + } + + public int Count + { + get { return _list.Count; } + } + + public bool IsSynchronized + { + get { return _list.IsSynchronized; } + } + + public object SyncRoot + { + get { return _list.SyncRoot; } + } + + #endregion + + #region IEnumerable Members + + public IEnumerator GetEnumerator() + { + return _list.GetEnumerator(); + } + + #endregion + + #region SortPropertyComparer + + class SortPropertyComparer : IComparer + { + readonly PropertyDescriptor _property; + readonly ListSortDirection _direction; + + public SortPropertyComparer(PropertyDescriptor property, ListSortDirection direction) + { + _property = property; + _direction = direction; + } + + public int Compare(object x, object y) + { + object a = _property.GetValue(x); + object b = _property.GetValue(y); + + int n = Comparer.Default.Compare(a, b); + + return _direction == ListSortDirection.Ascending? n: -n; + } + } + + #endregion + + #region IComparer Accessor + + public IComparer GetSortComparer() + { + if (_isSorted) + { + if (_sortDescriptions != null) + return GetSortComparer(_sortDescriptions); + + return GetSortComparer(_sortProperty, _sortDirection); + } + + return null; + } + + private IComparer GetSortComparer(PropertyDescriptor sortProperty, ListSortDirection sortDirection) + { + if (_sortSubstitutions.ContainsKey(sortProperty.Name)) + sortProperty = ((SortSubstitutionPair)_sortSubstitutions[sortProperty.Name]).Substitute; + + return new SortPropertyComparer(sortProperty, sortDirection); + } + + private IComparer GetSortComparer(ListSortDescriptionCollection sortDescriptions) + { + bool needSubstitution = false; + + if (_sortSubstitutions.Count > 0) + { + foreach (ListSortDescription sortDescription in sortDescriptions) + { + if (_sortSubstitutions.ContainsKey(sortDescription.PropertyDescriptor.Name)) + { + needSubstitution = true; + break; + } + } + + if (needSubstitution) + { + ListSortDescription[] sorts = new ListSortDescription[sortDescriptions.Count]; + sortDescriptions.CopyTo(sorts, 0); + + for (int i = 0; i < sorts.Length; i++) + if (_sortSubstitutions.ContainsKey(sorts[i].PropertyDescriptor.Name)) + sorts[i] = new ListSortDescription(((SortSubstitutionPair)_sortSubstitutions[sorts[i].PropertyDescriptor.Name]).Substitute, + sorts[i].SortDirection); + + sortDescriptions = new ListSortDescriptionCollection(sorts); + } + } + + return new SortListPropertyComparer(sortDescriptions); + } + + #endregion + + #region IBindingListView Members + + public bool SupportsAdvancedSorting + { + get { return true; } + } + + public void ApplySort(ListSortDescriptionCollection sorts) + { + _sortDescriptions = sorts; + + _isSorted = true; + _sortProperty = null; + + ApplySort(GetSortComparer(sorts)); + + if (_list.Count > 0) + OnReset(); + } + + [NonSerialized] + private ListSortDescriptionCollection _sortDescriptions; + public ListSortDescriptionCollection SortDescriptions + { + get { return _sortDescriptions; } + } + + public bool SupportsFiltering + { + get { return false; } + } + + public string Filter + { + get { throw new NotImplementedException("The method 'BindingListImpl.get_Filter' is not implemented."); } + set { throw new NotImplementedException("The method 'BindingListImpl.set_Filter' is not implemented."); } + } + + public void RemoveFilter() + { + throw new NotImplementedException("The method 'BindingListImpl.RemoveFilter()' is not implemented."); + } + + #endregion + + #region SortListPropertyComparer + + class SortListPropertyComparer : IComparer + { + readonly ListSortDescriptionCollection _sorts; + + public SortListPropertyComparer(ListSortDescriptionCollection sorts) + { + _sorts = sorts; + } + + public int Compare(object x, object y) + { + for (int i = 0; i < _sorts.Count; i++) + { + PropertyDescriptor property = _sorts[i].PropertyDescriptor; + + object a = property.GetValue(x); + object b = property.GetValue(y); + + int n = Comparer.Default.Compare(a, b); + + if (n != 0) + return _sorts[i].SortDirection == ListSortDirection.Ascending? n: -n; + } + + return 0; + } + } + + #endregion + + #region Sorting enhancement + + private readonly Hashtable _sortSubstitutions = new Hashtable(); + + private class SortSubstitutionPair + { + public SortSubstitutionPair(PropertyDescriptor original, PropertyDescriptor substitute) + { + Original = original; + Substitute = substitute; + } + + public readonly PropertyDescriptor Original; + public readonly PropertyDescriptor Substitute; + } + + public void CreateSortSubstitution(string originalProperty, string substituteProperty) + { + TypeAccessor typeAccessor = TypeAccessor.GetAccessor(_itemType); + + PropertyDescriptor originalDescriptor = typeAccessor.PropertyDescriptors[originalProperty]; + PropertyDescriptor substituteDescriptor = typeAccessor.PropertyDescriptors[substituteProperty]; + + if (originalDescriptor == null) throw new InvalidOperationException("Can not retrieve PropertyDescriptor for original property: " + originalProperty); + if (substituteDescriptor == null) throw new InvalidOperationException("Can not retrieve PropertyDescriptor for substitute property: " + substituteProperty); + + _sortSubstitutions[originalProperty] = new SortSubstitutionPair(originalDescriptor, substituteDescriptor); + } + + public void RemoveSortSubstitution(string originalProperty) + { + _sortSubstitutions.Remove(originalProperty); + } + + #endregion + + #region Sort enforcement + + public int GetItemSortedPosition(int index, object sender) + { + IComparer comparer = GetSortComparer(); + + if (comparer == null) + return index; + + if ((index > 0 && comparer.Compare(_list[index - 1], sender) > 0) || + (index < _list.Count - 1 && comparer.Compare(_list[index + 1], sender) < 0)) + { + for (int i = 0; i < _list.Count; i++) + { + if (i != index && comparer.Compare(_list[i], sender) > 0) + { + if (i > index) + return i - 1; + + return i; + } + } + + return _list.Count - 1; + } + + return index; + } + + public int GetSortedInsertIndex(object value) + { + IComparer comparer = GetSortComparer(); + + if (comparer == null) + return -1; + + for (int i = 0; i < _list.Count; i++) + if (comparer.Compare(_list[i], value) > 0) + return i; + + return _list.Count; + } + + #endregion + + #region Misc/Range Operations + + public void Move(int newIndex, int oldIndex) + { + if (oldIndex != newIndex) + { + EndNew(); + + object o = _list[oldIndex]; + + _list.RemoveAt(oldIndex); + if (!_isSorted) + _list.Insert(newIndex, o); + else + _list.Insert(newIndex = GetSortedInsertIndex(o), o); + + OnMoveItem(o, oldIndex, newIndex); + } + } + + public void AddRange(ICollection c) + { + foreach (object o in c) + { + if (!_isSorted) + _list.Add(o); + else + _list.Insert(GetSortedInsertIndex(o), o); + } + + AddInternal(c); + + OnReset(); + } + + public void InsertRange(int index, ICollection c) + { + if (c.Count == 0) + return; + + foreach (object o in c) + { + if (!_isSorted) + _list.Insert(index++, o); + else + _list.Insert(GetSortedInsertIndex(o), o); + } + + AddInternal(c); + + OnReset(); + } + + public void RemoveRange(int index, int count) + { + object[] toRemove = new object[count]; + + for (int i = index; i < _list.Count && i < index + count; i++) + toRemove[i - index] = _list[i]; + + RemoveInternal(toRemove); + + foreach (object o in toRemove) + _list.Remove(o); + + OnReset(); + } + + public void SetRange(int index, ICollection c) + { + int cCount = c.Count; + + if (index < 0 || index >= _list.Count - cCount) + throw new ArgumentOutOfRangeException("index"); + + bool oldNotifyChanges = _notifyChanges; + _notifyChanges = false; + + int i = index; + foreach (object newObject in c) + { + RemoveInternal(_list[i + index]); + _list[i + index] = newObject; + } + + AddInternal(c); + + if (_isSorted) + ApplySort(GetSortComparer()); + + _notifyChanges = oldNotifyChanges; + OnReset(); + } + + #endregion + + #region Add/Remove Internal + + private void AddInternal(object value) + { + EndNew(); + + if (value is INotifyPropertyChanged) + ((INotifyPropertyChanged)value).PropertyChanged += + ItemPropertyChanged; + } + + private void RemoveInternal(object value) + { + EndNew(); + + if (value is INotifyPropertyChanged) + ((INotifyPropertyChanged)value).PropertyChanged -= + ItemPropertyChanged; + } + + private void AddInternal(IEnumerable e) + { + foreach (object o in e) + AddInternal(o); + } + + private void RemoveInternal(IEnumerable e) + { + foreach (object o in e) + RemoveInternal(o); + } + + private void OnAddItem(object item, int index) + { + OnListChanged(new EditableListChangedEventArgs(ListChangedType.ItemAdded, index)); + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index)); + } + + private void OnRemoveItem(object item, int index) + { + OnListChanged(new EditableListChangedEventArgs(ListChangedType.ItemDeleted, index)); + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index)); + } + + private void OnMoveItem(object item, int oldIndex, int newIndex) + { + OnListChanged(new EditableListChangedEventArgs(newIndex, oldIndex)); + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, item, newIndex, oldIndex)); + } + + private void OnChangeItem(object oldValue, object newValue, int index) + { + OnListChanged(new EditableListChangedEventArgs(ListChangedType.ItemChanged, index)); + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, oldValue, newValue, index)); + } + + private void OnReset() + { + OnListChanged(new EditableListChangedEventArgs(ListChangedType.Reset)); + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); + } + + #endregion + + #region INotifyCollectionChanged Members + + public event NotifyCollectionChangedEventHandler CollectionChanged; + + private void FireCollectionChangedEvent(object sender, NotifyCollectionChangedEventArgs ea) + { + if (_notifyChanges && CollectionChanged != null) + CollectionChanged(sender, ea); + } + + protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs ea) + { + FireCollectionChangedEvent(this, ea); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/CustomTypeDescriptorImpl.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/CustomTypeDescriptorImpl.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,229 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Reflection; + +using BLToolkit.Reflection; + +namespace BLToolkit.ComponentModel +{ + public class CustomTypeDescriptorImpl : ICustomTypeDescriptor + { + #region Constructors + + public CustomTypeDescriptorImpl() + { + _typeDescriptionProvider = CreateTypeDescriptionProvider(GetType()); + } + + public CustomTypeDescriptorImpl(Type type) + { + _typeDescriptionProvider = CreateTypeDescriptionProvider(type); + } + + public CustomTypeDescriptorImpl(ITypeDescriptionProvider typeDescriptionProvider) + { + _typeDescriptionProvider = typeDescriptionProvider; + } + + private readonly ITypeDescriptionProvider _typeDescriptionProvider; + + protected virtual ITypeDescriptionProvider CreateTypeDescriptionProvider(Type type) + { + return TypeAccessor.GetAccessor(type); + } + + #endregion + + #region ICustomTypeDescriptor Members + + AttributeCollection _attributes; + AttributeCollection ICustomTypeDescriptor.GetAttributes() + { + if (_attributes == null) + _attributes = _typeDescriptionProvider.GetAttributes(); + + return _attributes; + } + + string ICustomTypeDescriptor.GetClassName() + { + return _typeDescriptionProvider.ClassName; + } + + string ICustomTypeDescriptor.GetComponentName() + { + return _typeDescriptionProvider.ComponentName; + } + + TypeConverter _converter; + TypeConverter ICustomTypeDescriptor.GetConverter() + { + if (_converter == null) + { + TypeConverterAttribute attr = + _td.GetAttributes()[typeof(TypeConverterAttribute)] as TypeConverterAttribute; + + if (attr != null && !string.IsNullOrEmpty(attr.ConverterTypeName)) + { + Type type = GetTypeByName(attr.ConverterTypeName); + + if (type != null && typeof(TypeConverter).IsAssignableFrom(type)) + _converter = (TypeConverter)CreateInstance(type); + } + + if (_converter == null) + _converter = new TypeConverter(); + } + + return _converter; + } + + bool _readDefaultEvent; + EventDescriptor _defaultEvent; + EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() + { + if (_readDefaultEvent == false) + { + _readDefaultEvent = true; + + DefaultEventAttribute attr = + _td.GetAttributes()[typeof(DefaultEventAttribute)] as DefaultEventAttribute; + + if (attr != null && !string.IsNullOrEmpty(attr.Name)) + _defaultEvent = _typeDescriptionProvider.GetEvent(attr.Name); + } + + return _defaultEvent; + } + + bool _readDefaultProperty; + PropertyDescriptor _defaultProperty; + PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() + { + if (_readDefaultProperty == false) + { + _readDefaultProperty = true; + + DefaultPropertyAttribute attr = + _td.GetAttributes()[typeof(DefaultPropertyAttribute)] as DefaultPropertyAttribute; + + if (attr != null && !string.IsNullOrEmpty(attr.Name)) + _defaultProperty = _typeDescriptionProvider.GetProperty(attr.Name); + } + + return _defaultProperty; + } + + Hashtable _editors; + object ICustomTypeDescriptor.GetEditor(Type editorBaseType) + { + if (_editors == null) + _editors = new Hashtable(); + + object editor = _editors[editorBaseType]; + + if (editor == null) + { + if (_editors.Contains(editorBaseType)) + return null; + + foreach (Attribute attr in _td.GetAttributes()) + { + if (attr is EditorAttribute) + { + EditorAttribute ea = (EditorAttribute)attr; + + if (ea.EditorBaseTypeName != null && + ea.EditorTypeName != null && + editorBaseType == GetTypeByName(ea.EditorBaseTypeName)) + { + Type type = GetTypeByName(ea.EditorTypeName); + + if (type != null) + { + editor = CreateInstance(type); + break; + } + } + } + } + + _editors[editorBaseType] = editor; + } + + return editor; + } + + EventDescriptorCollection _events; + EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) + { + if (_events == null) + _events = _typeDescriptionProvider.GetEvents(); + + return _events; + } + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents() + { + return _td.GetEvents(null); + } + + PropertyDescriptorCollection _properties; + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) + { + if (_properties == null) + _properties = _typeDescriptionProvider.GetProperties(); + + return _properties; + } + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() + { + return _td.GetProperties(null); + } + + object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) + { + return this; + } + + #endregion + + #region Protected Members + + private Type GetTypeByName(string typeName) + { + if (string.IsNullOrEmpty(typeName)) + return null; + + Type type = Type.GetType(typeName); + + if (type != null) + return type; + + int idx = typeName.IndexOf(','); + + if (idx != -1) + typeName = typeName.Substring(0, idx); + + return _typeDescriptionProvider.OriginalType.Assembly.GetType(typeName); + } + + private object CreateInstance(Type type) + { + ConstructorInfo ci = type.GetConstructor(new Type[]{ typeof(Type) }); + + return ci != null? + Activator.CreateInstance(type, new object[] { _typeDescriptionProvider.OriginalType }): + Activator.CreateInstance(type); + } + + private ICustomTypeDescriptor _td + { + get { return this; } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/Assembly.bmp Binary file Source/ComponentModel/Design/Assembly.bmp has changed diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/GetTypeDialog.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/Design/GetTypeDialog.Designer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,148 @@ +namespace BLToolkit.ComponentModel.Design +{ + partial class GetTypeDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GetTypeDialog)); + System.Windows.Forms.Label labelRebuild; + this._treeView = new System.Windows.Forms.TreeView(); + this.imageList = new System.Windows.Forms.ImageList(this.components); + this._systemCheckBox = new System.Windows.Forms.CheckBox(); + this._okButton = new System.Windows.Forms.Button(); + this._cancelButton = new System.Windows.Forms.Button(); + labelRebuild = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // _treeView + // + this._treeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._treeView.ImageIndex = 0; + this._treeView.ImageList = this.imageList; + this._treeView.Location = new System.Drawing.Point(14, 48); + this._treeView.Name = "_treeView"; + this._treeView.SelectedImageIndex = 0; + this._treeView.Size = new System.Drawing.Size(523, 345); + this._treeView.TabIndex = 0; + this._treeView.DoubleClick += new System.EventHandler(this.treeView_DoubleClick); + this._treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView_AfterSelect); + // + // imageList + // + this.imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList.ImageStream"))); + this.imageList.TransparentColor = System.Drawing.Color.Magenta; + this.imageList.Images.SetKeyName(0, "None.bmp"); + this.imageList.Images.SetKeyName(1, "Assembly.bmp"); + this.imageList.Images.SetKeyName(2, "Namespace.bmp"); + this.imageList.Images.SetKeyName(3, "Object.bmp"); + // + // _systemCheckBox + // + this._systemCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this._systemCheckBox.AutoSize = true; + this._systemCheckBox.Checked = true; + this._systemCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this._systemCheckBox.Location = new System.Drawing.Point(14, 409); + this._systemCheckBox.Name = "_systemCheckBox"; + this._systemCheckBox.Size = new System.Drawing.Size(330, 20); + this._systemCheckBox.TabIndex = 1; + this._systemCheckBox.Text = "Hide assemblies that begin with Microsoft or System."; + this._systemCheckBox.UseVisualStyleBackColor = true; + this._systemCheckBox.CheckedChanged += new System.EventHandler(this.systemCheckBox_CheckedChanged); + // + // labelRebuild + // + labelRebuild.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + labelRebuild.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + labelRebuild.Location = new System.Drawing.Point(11, 9); + labelRebuild.Name = "labelRebuild"; + labelRebuild.Size = new System.Drawing.Size(525, 32); + labelRebuild.TabIndex = 5; + labelRebuild.Text = "If your object type does not appear, close the dialog and rebuild the project tha" + + "t contains your object.\r\n\r\n"; + // + // _okButton + // + this._okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this._okButton.DialogResult = System.Windows.Forms.DialogResult.OK; + this._okButton.Location = new System.Drawing.Point(350, 404); + this._okButton.Name = "_okButton"; + this._okButton.Size = new System.Drawing.Size(87, 29); + this._okButton.TabIndex = 3; + this._okButton.Text = "OK"; + this._okButton.UseVisualStyleBackColor = true; + // + // _cancelButton + // + this._cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this._cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this._cancelButton.Location = new System.Drawing.Point(450, 404); + this._cancelButton.Name = "_cancelButton"; + this._cancelButton.Size = new System.Drawing.Size(87, 29); + this._cancelButton.TabIndex = 4; + this._cancelButton.Text = "Cancel"; + this._cancelButton.UseVisualStyleBackColor = true; + // + // GetTypeDialog + // + this.AcceptButton = this._okButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 16F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this._cancelButton; + this.ClientSize = new System.Drawing.Size(547, 442); + this.Controls.Add(labelRebuild); + this.Controls.Add(this._systemCheckBox); + this.Controls.Add(this._cancelButton); + this.Controls.Add(this._okButton); + this.Controls.Add(this._treeView); + this.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size(555, 275); + this.Name = "GetTypeDialog"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Select the Type"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button _okButton; + private System.Windows.Forms.Button _cancelButton; + private System.Windows.Forms.ImageList imageList; + private System.Windows.Forms.TreeView _treeView; + private System.Windows.Forms.CheckBox _systemCheckBox; + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/GetTypeDialog.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/Design/GetTypeDialog.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,141 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel.Design; +using System.Diagnostics; +using System.Reflection; +using System.Windows.Forms; + +namespace BLToolkit.ComponentModel.Design +{ + public partial class GetTypeDialog : Form + { + public GetTypeDialog(IServiceProvider serviceProvider, Type baseType, Predicate filter) + { + _serviceProvider = serviceProvider; + _baseType = baseType; + _filter = filter; + + InitializeComponent(); + + LoadTypes(); + } + + private readonly IServiceProvider _serviceProvider; + private readonly Type _baseType; + private readonly Predicate _filter; + + private Type _resultType; + public Type ResultType + { + get { return _resultType; } + } + + delegate TypePicker.TypeNode GetTypeNode(Type t); + + private void LoadTypes() + { + Cursor = Cursors.WaitCursor; + + try + { + _treeView.Nodes.Clear(); + + var assemblyNodes = new Dictionary(); + var namespaceNodes = new Dictionary(); + var typeNodes = new Dictionary(); + var service = (ITypeDiscoveryService)_serviceProvider.GetService(typeof(ITypeDiscoveryService)); + var cTypes = service.GetTypes(_baseType, _systemCheckBox.Checked); + var types = new List(cTypes.Count); + + foreach (Type type in cTypes) + types.Add(type); + + types.Sort((a, b) => + a.Assembly == b.Assembly ? + string.Compare(a.FullName, b.FullName) : + string.Compare(a.Assembly.FullName, b.Assembly.FullName)); + + foreach (var type in types) + { + if (_filter != null && _filter(type) == false) + continue; + + var assembly = type.Assembly; + + TreeNode assemblyNode; + + if (!assemblyNodes.TryGetValue(assembly, out assemblyNode)) + { + assemblyNodes[assembly] = assemblyNode = + _treeView.Nodes.Add(assembly.FullName, assembly.GetName().Name, 1, 1); + } + + var @namespace = type.Namespace ?? string.Empty; + var namespaceKey = assembly.FullName + ", " + @namespace; + + TreeNode namespaceNode; + + if (!namespaceNodes.TryGetValue(namespaceKey, out namespaceNode)) + { + namespaceNodes[namespaceKey] = namespaceNode = + assemblyNode.Nodes.Add(namespaceKey, @namespace, 2, 2); + } + + GetTypeNode getTypeNode = null; getTypeNode = t => + { + TypePicker.TypeNode node; + + if (typeNodes.TryGetValue(t, out node)) + return node; + + if (t.DeclaringType == null) + { + namespaceNode.Nodes.Add(node = new TypePicker.TypeNode(t.Name, t, false)); + } + else + { + TreeNode parent = getTypeNode(t.DeclaringType); + + parent.Nodes.Add(node = new TypePicker.TypeNode(t.Name, t, false)); + } + + typeNodes.Add(t, node); + + return node; + }; + + getTypeNode(type).IsSelectable = true; + } + } + catch (Exception ex) + { + Debug.WriteLine(ex.Message); + } + finally + { + Cursor = Cursors.Default; + } + } + + private void systemCheckBox_CheckedChanged(object sender, EventArgs e) + { + LoadTypes(); + } + + private void treeView_AfterSelect(object sender, TreeViewEventArgs e) + { + var node = e.Node as TypePicker.TypeNode; + + _resultType = node != null && node.IsSelectable? node.Type: null; + + _okButton.Enabled = _resultType != null; + } + + private void treeView_DoubleClick(object sender, EventArgs e) + { + _okButton.PerformClick(); + } + + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/GetTypeDialog.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/Design/GetTypeDialog.resx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABE + CwAAAk1TRnQBSQFMAgEBBAEAAQkBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA + AwABIAMAAQEBAAEgBgABIP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAPAAHzAeABzAH/ + +AAB8wHgAcwB/wGZATsBCAH/AfMB4AHMAf8gAAHIAskB/wOiAf8DhQH/A4EB/wOaAf8BwAK/Af+4AAHz + AeABzAH/AbUBawE9Af8B2AGbAWMB/wGZATsBCAH/AfMB4AHMAf8UAAPmAf8CsQGwAf8DnwH/A5YB/wOB + Af8DgQH/A40B/wOPAf8BmwGcAZsB/wPeAf9gAAOIAf8DOwH/DAADOwH/A4gB/ywAAZcBgQF3Af8BlwGB + AXcB/wHYAZsBYwL/Ac0BmQH/AekBtAGBAf8B2AGbAWMB/wGZATsBCAH/AfMB4AHMAf8QAAO3Af8DpwH/ + A6AB/wHLAsoB/wPuAf8D7gH/A90B/wOcAf8BkAKRAf8BmwKcAf8kAAF8AWMBTwH/AXUBXAFIAf8BdAFZ + AUUB/wFuAVMBPgH/AW0BUAE7Af8BagFPATsB/wFpAVABPAH/AWgBUAE6Af8BaQFRATkB/xQAA4gB/wMS + Af8UAAMSAf8DiAH/KAABlwGBAXcB/wQAAfMB4AHMAf8B2AGbAWMC/wHNAZkB/wHpAbQBgQH/AdgBmwFj + Af8BmQE7AQgB/wwAA9YB/wOuAf8DpwH/A+cB/wwAA58B/wODAf8DnAH/A48B/wPAAf8cAAGDAXQBZAH/ + Ae0B5wHiAf8BvwGnAZsB/wG4AZ4BkAH/AbIBlwGJAf8BrAGPAYEB/wGlAYgBgQH/AZ0BgwF7Af8BnAGB + AXUB/wGXAYEBbwH/AWsBTgE/Af8QAANVAf8DEgH/FAADEgH/A1UB/ygAAZcBgQF3Af8IAAHzAeABzAH/ + AdgBmwFjAv8BzQGZAf8ByQF7AUsB/wHzAeABzAH/DAADvwH/Aa0CrgH/A9MB/wwAA6gB/wGMAY0BjAH/ + A58B/wPdAf8DjQH/A5oB/wgAAc0BvAGvAf8BtgGcAY4B/wGoAYsBgQH/CAABjgF9AW0B/wH0Ae4B6QH/ + Ae0B5gHjAf8B6QHgAdwB/wHkAdoB0wH/Ad4B0gHMAf8B2gHKAcMB/wHYAcUBvQH/AdQBvgGyAf8BlwGB + AXYB/wFqAVABOAH/EAADVQH/AxIB/xQAAxIB/wNVAf8YAAG3Ad8B7gH/DAABlwGBAXcB/wwAAfEBxwHO + Af8B2AGbAWMB/wHzAeABzAH/EAADswH/AaMBpAGjAf8D8gH/CAACqQGoAf8DlgH/A6gB/wQAA+4B/wOB + Af8DgQH/CAAB3QHNAcYB/wHGAbABpQH/AbcBnAGOAf8BxgGwAaQB/wGpAY8BgQH/AZYBgQF3Af8B9gHy + AfEB/wHxAewB6QH/Ae8B5gHiAf8B6QHgAd0B/wHkAdkB1QH/AeEB0QHKAf8B2QHLAcUB/wHWAcUBvAH/ + AZwBgwF3Af8BbQFQATsB/xAAAxIB/wO/Af8UAAO/Af8DEgH/FAABtwHfAe4B/wEWAYABngH/AbcB3wHu + Af8IAAGXAYEBdwH/CAAB/AHcAfsB/wGNATUBjAH/AfEBxwHOAf8UAAO3Af8DqQH/A/MB/wQAA7sB/wOh + Af8DsQH/CAAD7gH/A4EB/wOFAf8IAAHuAegB4QH/AdoBzAHGAf8ByAG6Aa4B/wgAAaABigGAAf8B+QL3 + Af8B9gHxAfIB/wHzAe0B6AH/AewB6AHjAf8B5gHgAdsB/wHlAdkB0wH/Ad4B0gHMAf8B3AHLAcIB/wGh + AYgBfAH/AWsBUAE8Af8MAAMSAf8DbAH/HAADbAH/AxIB/wwAAbcB3wHuAf8BFgGAAZ4B/wEkAbYB7gH/ + ARYBgAGeAf8BtwHfAe4B/wQAAZcBgQF3Af8EAAH8AdwB+wH/AbMBRAGyAf8B3AF4AdsB/wGNATUBjAH/ + AfwB3AH7Af8QAAPLAf8DuwH/A+MB/wPFAf8DrAH/A7sB/wwAAcoBywHKAf8DlgH/AaIBowGiAf8cAAGp + AZUBhAH/Af0B+gH8Af8B+QL3Af8B9wH0AfAB/wHyAe0B6gH/Ae0B5wHiAf8B6wHhAdoB/wHjAdgB1AH/ + AeIB0gHLAf8BogGLAYEB/wFsAVIBOgH/EAADOwH/A7oB/xQAA7oB/wM7Af8MAAG3Ad8B7gH/ARYBgAGe + Af8BVwHLAfEB/wE8AcAB7wH/ATcBvgHvAf8BFAFqAYEB/wGXAYEBdwH/AZcBgQF3Af8BlwGBAXcB/wHZ + AXQB2AH/AfoBrQH6Af8B+wGYAfoB/wHcAXgB2wH/AY0BNQGMAf8B/AHcAfsB/wwAA+IB/wPDAf8DvAH/ + AbICsQH/A8UB/wwAA+cB/wOgAf8DnwH/AskByAH/HAABsQGcAY0F/wH6AvwB/wH6AvgB/wH2AfEB8gH/ + AfIB7QHsAf8B8AHnAeMB/wHoAd8B2wH/AeIB2QHVAf8B4QHSAckB/wF0AVYBRQH/EAADVQH/AzsB/xQA + AzsB/wNVAf8MAAEcAaoB4QH/AYUB4QH1Af8BcwHXAfQB/wFYAcsB8QH/ATwBwAHwAf8BJQG1Ae4B/wEU + AWoBgQH/AbcB3wHuAf8EAAH8AdwB+wH/AdMBbQHSAf8B+gGtAfoB/wH7AZgB+gH/AdwBeAHbAf8BjQE1 + AYwB/xAAA9EB/wO3Af8DvAH/A+AB/wPzAf8D8gH/AdMB0gHTAf8DpwH/A6cB/wKxAbAB/yQAAbQBoQGS + Af8BrQGbAYoB/wGnAZABgQH/AaABiQGBAf8BmAGBAXcB/wGPAX8BawH/AYcBdwFjAf8BgQFvAV0B/wGA + AWcBUwH/FAADVQH/AzsB/xQAAzsB/wNVAf8MAAG3Ad8B7gH/ARwBqgHhAf8BhgHhAfUB/wF0AdYB8wH/ + AVgBywHyAf8BPQHAAfAB/wEkAbUB7QH/ARQBagGBAf8BtwHfAe4B/wQAAfwB3AH7Af8B0wFtAdIB/wH6 + Aa0B+gH/AdMBbQHSAf8B/AHcAfsB/xAAA/EB/wPRAf8DwwH/ArsBugH/A6kB/wGkAaMBpAH/A64B/wOu + Af8DtwH/A+YB/1wAA4gB/wM7Af8UAAM7Af8DiAH/EAABtwHfAe4B/wEcAaoB4QH/AYUB4AH1Af8BdAHW + AfMB/wFYAcsB8gH/ATwBwAHvAf8BJQG1Ae0B/wEUAWoBgQH/AbcB3wHuAf8EAAH8AdwB+wH/AdMBbQHS + Af8B/AHcAfsB/xwAA+IB/wPLAf8DtwH/A7MB/wO/Af8D1gH/aAADiAH/AzsB/wwAAzsB/wOIAf8YAAG3 + Ad8B7gH/ARwBqgHhAf8BhgHhAfQB/wFzAdYB9AH/AVgBywHxAf8BHwGYAcgB/wG3Ad8B7gH/DAAB/AHc + AfsB/9gAAbcB3wHuAf8BHAGqAeEB/wGFAeEB9QH/AR8BmAHIAf8BtwHfAe4B//AAAbcB3wHuAf8BHAGq + AeEB/wG3Ad8B7gH/JAABQgFNAT4HAAE+AwABKAMAAUADAAEgAwABAQEAAQEGAAEBFgAD/4EAB/8B7wf/ + AccB+AEfBf8BgwHgAQcC/wH5Ac8B/gEBAeABBwH8AQEB8wHnAf4BgQHDAYMB+AEAAfMB5wH+AcEBxwED + ARgBAAHzAecB7gHjAcYBIwIAAfMB5wHGAccBxAFjARgBAAHnAfMBggGDAcAB4wH4AQAB8wHnAQABAQHB + AcMB+AEAAfMB5wEAAYEB4AEHAfwBAQHzAecBAAFBAeABBwL/AfMB5wGAASMB+AEfAv8B+QHPAcABdwb/ + AeAH/wHxAf8L + + + + False + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/Namespace.bmp Binary file Source/ComponentModel/Design/Namespace.bmp has changed diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/None.bmp Binary file Source/ComponentModel/Design/None.bmp has changed diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/Object.bmp Binary file Source/ComponentModel/Design/Object.bmp has changed diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/ObjectViewTypeEditor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/Design/ObjectViewTypeEditor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,18 @@ +using System; + +using BLToolkit.Reflection; + +namespace BLToolkit.ComponentModel.Design +{ + public class ObjectViewTypeEditor : TypeEditor + { + protected override bool FilterTypeList(Type type) + { + return + type.IsPublic && + !type.IsInterface && + !type.ContainsGenericParameters && + TypeHelper.IsSameOrParent(typeof(IObjectView), type); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/ObjectViewTypeNameEditor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/Design/ObjectViewTypeNameEditor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Globalization; +using System.ComponentModel; + +namespace BLToolkit.ComponentModel.Design +{ + public class ObjectViewTypeNameEditor : ObjectViewTypeEditor + { + public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) + { + TypeTypeConverter converter = new TypeTypeConverter(); + + value = converter.ConvertFrom(context, CultureInfo.CurrentCulture, value); + value = base.EditValue(context, provider, value); + value = converter.ConvertTo (context, CultureInfo.CurrentCulture, value, typeof(string)); + + return value; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/TypeEditor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/Design/TypeEditor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,74 @@ +using System; +using System.Drawing.Design; +using System.ComponentModel; +using System.ComponentModel.Design.Data; +using System.Data; +using System.Collections; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace BLToolkit.ComponentModel.Design +{ + public class TypeEditor : UITypeEditor + { + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + DataSourceProviderService dspService = + (DataSourceProviderService)provider.GetService(typeof(DataSourceProviderService)); + + if (dspService == null || !dspService.SupportsAddNewDataSource) + { + using (GetTypeDialog dlg = new GetTypeDialog(provider, typeof (object), FilterTypeList)) + { + IWin32Window dialogOwnerWindow = null; + IUIService uiService = (IUIService)provider.GetService(typeof(IUIService)); + + if (uiService != null) + dialogOwnerWindow = uiService.GetDialogOwnerWindow(); + + DialogResult result = dlg.ShowDialog(dialogOwnerWindow); + + return result == DialogResult.OK && dlg.ResultType != null? dlg.ResultType: value; + } + } + + return new TypePicker().PickType(provider, value as Type, FilterTypeList); + } + + protected virtual bool FilterTypeList(Type type) + { + return + type.IsPublic && + type.IsClass && + //!type.IsInterface && + !type.ContainsGenericParameters && + !typeof(ICollection).IsAssignableFrom(type) && + !typeof(Attribute). IsAssignableFrom(type) && + !typeof(Exception). IsAssignableFrom(type) && + !typeof(EventArgs). IsAssignableFrom(type) && + !typeof(Control). IsAssignableFrom(type) && + !typeof(DataTable). IsAssignableFrom(type) && + !typeof(DataView). IsAssignableFrom(type) && + !typeof(DataRow). IsAssignableFrom(type) && + !typeof(DataRowView).IsAssignableFrom(type) && + !typeof(DataSet). IsAssignableFrom(type); + } + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + if (context == null) + return UITypeEditorEditStyle.DropDown; + + var dspService = (DataSourceProviderService)context.GetService(typeof(DataSourceProviderService)); + + return dspService == null || !dspService.SupportsAddNewDataSource? + UITypeEditorEditStyle.Modal: UITypeEditorEditStyle.DropDown; + } + + public override bool IsDropDownResizable + { + get { return true; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/TypeNameEditor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/Design/TypeNameEditor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Globalization; +using System.ComponentModel; + +namespace BLToolkit.ComponentModel.Design +{ + public class TypeNameEditor : TypeEditor + { + public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) + { + TypeTypeConverter converter = new TypeTypeConverter(); + + value = converter.ConvertFrom(context, CultureInfo.CurrentCulture, value); + value = base.EditValue(context, provider, value); + value = converter.ConvertTo (context, CultureInfo.CurrentCulture, value, typeof(string)); + + return value; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/TypePicker.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/Design/TypePicker.Designer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,122 @@ +namespace BLToolkit.ComponentModel.Design +{ + partial class TypePicker + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.Windows.Forms.ImageList imageList; + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TypePicker)); + this.treeView = new System.Windows.Forms.TreeView(); + this.addNewLinkLabel = new BLToolkit.ComponentModel.Design.TypePicker.NewLink(); + this.addNewPanel = new System.Windows.Forms.Panel(); + this.addNewSplitPanel = new System.Windows.Forms.Panel(); + imageList = new System.Windows.Forms.ImageList(this.components); + this.addNewPanel.SuspendLayout(); + this.SuspendLayout(); + // + // treeView + // + this.treeView.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.treeView.Dock = System.Windows.Forms.DockStyle.Fill; + this.treeView.HotTracking = true; + this.treeView.ImageIndex = 0; + this.treeView.ImageList = imageList; + this.treeView.Location = new System.Drawing.Point(0, 0); + this.treeView.Name = "treeView"; + this.treeView.SelectedImageIndex = 0; + this.treeView.Size = new System.Drawing.Size(251, 243); + this.treeView.TabIndex = 0; + this.treeView.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView_NodeMouseClick); + // + // imageList + // + imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList.ImageStream"))); + imageList.TransparentColor = System.Drawing.Color.Magenta; + imageList.Images.SetKeyName(0, "None.bmp"); + imageList.Images.SetKeyName(1, "Assembly.bmp"); + imageList.Images.SetKeyName(2, "Namespace.bmp"); + imageList.Images.SetKeyName(3, "Object.bmp"); + // + // addNewLinkLabel + // + this.addNewLinkLabel.AutoSize = true; + this.addNewLinkLabel.ForeColor = System.Drawing.SystemColors.WindowText; + this.addNewLinkLabel.ImageList = imageList; + this.addNewLinkLabel.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline; + this.addNewLinkLabel.Location = new System.Drawing.Point(0, 3); + this.addNewLinkLabel.Name = "addNewLinkLabel"; + this.addNewLinkLabel.Padding = new System.Windows.Forms.Padding(5, 0, 0, 0); + this.addNewLinkLabel.Size = new System.Drawing.Size(100, 13); + this.addNewLinkLabel.TabIndex = 1; + this.addNewLinkLabel.TabStop = true; + this.addNewLinkLabel.Text = "Add Project Type..."; + this.addNewLinkLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.addNewLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.addNewLinkLabel_LinkClicked); + // + // addNewPanel + // + this.addNewPanel.BackColor = System.Drawing.SystemColors.Window; + this.addNewPanel.Controls.Add(this.addNewLinkLabel); + this.addNewPanel.Controls.Add(this.addNewSplitPanel); + this.addNewPanel.Dock = System.Windows.Forms.DockStyle.Bottom; + this.addNewPanel.Location = new System.Drawing.Point(0, 243); + this.addNewPanel.Name = "addNewPanel"; + this.addNewPanel.Size = new System.Drawing.Size(251, 20); + this.addNewPanel.TabIndex = 2; + // + // addNewSplitPanel + // + this.addNewSplitPanel.BackColor = System.Drawing.SystemColors.ControlDark; + this.addNewSplitPanel.Dock = System.Windows.Forms.DockStyle.Top; + this.addNewSplitPanel.Location = new System.Drawing.Point(0, 0); + this.addNewSplitPanel.Name = "addNewSplitPanel"; + this.addNewSplitPanel.Size = new System.Drawing.Size(251, 1); + this.addNewSplitPanel.TabIndex = 2; + // + // TypePicker + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.Controls.Add(this.treeView); + this.Controls.Add(this.addNewPanel); + this.Name = "TypePicker"; + this.Size = new System.Drawing.Size(251, 263); + this.Resize += new System.EventHandler(this.TypePicker_Resize); + this.addNewPanel.ResumeLayout(false); + this.addNewPanel.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TreeView treeView; + private NewLink addNewLinkLabel; + private System.Windows.Forms.Panel addNewPanel; + private System.Windows.Forms.Panel addNewSplitPanel; + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/TypePicker.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/Design/TypePicker.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,282 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.ComponentModel.Design.Data; +using System.Drawing; +using System.Reflection; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace BLToolkit.ComponentModel.Design +{ + [DesignTimeVisible(false)] + [ToolboxItem(false)] + public partial class TypePicker : UserControl + { + public TypePicker() + { + InitializeComponent(); + + if (!_size.IsEmpty) + Size = _size; + } + + ITypeResolutionService _typeResolutionService; + IWindowsFormsEditorService _windowsFormsEditorService; + IServiceProvider _serviceProvider; + + Type _resultType; + Predicate _filter; + + static Size _size; + + private T GetService() + { + return (T)_serviceProvider.GetService(typeof(T)); + } + + public Type PickType(IServiceProvider serviceProvider, Type type, Predicate filter) + { + _resultType = type; + _filter = filter; + + _serviceProvider = serviceProvider; + _typeResolutionService = GetService(); + _windowsFormsEditorService = GetService(); + + InitUI (); + AddTypes(); + + if (_windowsFormsEditorService != null) + _windowsFormsEditorService.DropDownControl(this); + + return _resultType; + } + + private void InitUI() + { + IUIService uiService = GetService(); + + if (uiService != null) + { + object color = uiService.Styles["VsColorPanelHyperLink"]; + + if (color is Color) + addNewLinkLabel.LinkColor = (Color)color; + + color = uiService.Styles["VsColorPanelHyperLinkPressed"]; + + if (color is Color) + addNewLinkLabel.ActiveLinkColor = (Color)color; + } + + // Add None node. + // + TreeNode node = new TypeNode("None"); + + treeView.Nodes.Add(node); + treeView.SelectedNode = node; + } + + private TypeNode GetTypeNode(DataSourceDescriptor ds) + { + Type type = null; + + if (_typeResolutionService != null) + type = _typeResolutionService.GetType(ds.TypeName); + + try + { + if (type == null) + type = Type.GetType(ds.TypeName, true); + } + catch + { + return null; + } + + if (_filter != null && _filter(type) == false) + return null; + + return new TypeNode(ds.Name, type); + } + + private void AddGroup(DataSourceGroup group) + { + TreeNode groupNode = null; + + foreach (DataSourceDescriptor d in group.DataSources) + { + if (d == null) + continue; + + TypeNode node = GetTypeNode(d); + + if (node == null) + continue; + + if (group.IsDefault) + { + treeView.Nodes.Add(node); + } + else + { + if (groupNode == null) + treeView.Nodes.Add(groupNode = new TreeNode(group.Name, 2, 2)); + + groupNode.Nodes.Add(node); + } + + if (_resultType == node.Type) + treeView.SelectedNode = node; + } + } + + private void AddTypes() + { + DataSourceProviderService dspService = GetService(); + + if (dspService == null || !dspService.SupportsAddNewDataSource) + return; + + DataSourceGroupCollection dataSources = null; + + try + { + dataSources = dspService.GetDataSources(); + } + catch (Exception ex) + { + IUIService ui = GetService(); + + string message = + "Cant retrieve Data Source Collection: " + ex.Message + + "\nCheck the 'Properties\\DataSources' folder of your project."; + + if (ui != null) + ui.ShowError(ex, message); + else + MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + if (dataSources == null) + return; + + foreach (DataSourceGroup group in dataSources) + if (group != null) + AddGroup(group); + } + + private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) + { + if (e.Node is TypeNode) + { + _resultType = ((TypeNode)e.Node).Type; + _windowsFormsEditorService.CloseDropDown(); + } + } + + private void addNewLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + using (GetTypeDialog dlg = new GetTypeDialog(_serviceProvider, typeof (object), _filter)) + { + IUIService uiService = GetService(); + IWin32Window owner = uiService == null? null: uiService.GetDialogOwnerWindow(); + DialogResult result = dlg.ShowDialog(owner); + + if (result == DialogResult.OK && dlg.ResultType != null) + { + _resultType = dlg.ResultType; + + SaveType(_resultType); + + _windowsFormsEditorService.CloseDropDown(); + } + } + } + + private void TypePicker_Resize(object sender, EventArgs e) + { + _size = Size; + } + + private void SaveType(Type type) + { + DataSourceProviderService dspService = GetService(); + + if (dspService == null || !dspService.SupportsAddNewDataSource) + return; + + try + { + const string vs9TypeName = "Microsoft.VSDesigner.VSDesignerPackage.IGenericObjectDataSourcesService, Microsoft.VSDesigner, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; + const string vs8TypeName = "Microsoft.VSDesigner.VSDesignerPackage.IGenericObjectDataSourcesService, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; + + Type serviceType = Type.GetType(vs9TypeName) ?? Type.GetType(vs8TypeName); + + if (serviceType == null) + return; + + object service = _serviceProvider.GetService(serviceType); + + if (service == null) + return; + + MethodInfo mi = serviceType.GetMethod("AddGenericObjectDataSource"); + + mi.Invoke(service, new object[] { _serviceProvider, null, type }); + } + catch (Exception ex) + { + IUIService ui = GetService(); + + if (ui != null) + ui.ShowError(ex); + else + MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + internal class TypeNode : TreeNode + { + public TypeNode(string name) + : base(name, 0, 0) + { + _isSelectable = true; + } + + public TypeNode(string name, Type type) + : this(name, type, true) + { + } + + public TypeNode(string name, Type type, bool isSelectable) + : base(name, 3, 3) + { + _type = type; + _isSelectable = isSelectable; + } + + private bool _isSelectable; + public bool IsSelectable + { + get { return _isSelectable; } + set { _isSelectable = value; } + } + + private readonly Type _type; + public Type Type + { + get { return _type; } + } + } + + class NewLink : LinkLabel + { + protected override bool IsInputKey(Keys key) + { + return key == Keys.Return? true: base.IsInputKey(key); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/Design/TypePicker.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/Design/TypePicker.resx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + False + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABE + CwAAAk1TRnQBSQFMAgEBBAEAAQkBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA + AwABIAMAAQEBAAEgBgABIP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAPAAHzAeABzAH/ + +AAB8wHgAcwB/wGZATcBBAH/AfMB4AHMAf8gAAHIAskB/wOiAf8DhQH/A4EB/wOaAf8BwAK/Af+4AAHz + AeABzAH/AbUBZwE5Af8B2AGbAV8B/wGZATcBBAH/AfMB4AHMAf8UAAPmAf8CsQGwAf8DnwH/A5YB/wOB + Af8DgAH/A40B/wOPAf8BmwGcAZsB/wPeAf9gAAOIAf8DNwH/DAADNwH/A4gB/ywAAZcBgQFzAf8BlwGB + AXMB/wHYAZsBXwL/Ac0BmQH/AekBtAGAAf8B2AGbAV8B/wGZATcBBAH/AfMB4AHMAf8QAAO3Af8DpwH/ + A6AB/wHLAsoB/wPuAf8D7gH/A90B/wOcAf8BkAKRAf8BmwKcAf8kAAF4AV8BSwH/AXEBWAFEAf8BcAFV + AUEB/wFqAU8BOgH/AWkBTAE3Af8BZgFLATcB/wFlAUwBOAH/AWQBTAE2Af8BZQFNATUB/xQAA4gB/wMO + Af8UAAMOAf8DiAH/KAABlwGBAXMB/wQAAfMB4AHMAf8B2AGbAV8C/wHNAZkB/wHpAbQBgAH/AdgBmwFf + Af8BmQE3AQQB/wwAA9YB/wOuAf8DpwH/A+cB/wwAA58B/wODAf8DnAH/A48B/wPAAf8cAAGDAXABYAH/ + Ae0B5wHiAf8BvwGnAZsB/wG4AZ4BkAH/AbIBlwGJAf8BrAGPAYEB/wGlAYgBfQH/AZ0BgwF3Af8BnAGB + AXEB/wGXAYABawH/AWcBSgE7Af8QAANRAf8DDgH/FAADDgH/A1EB/ygAAZcBgQFzAf8IAAHzAeABzAH/ + AdgBmwFfAv8BzQGZAf8ByQF3AUcB/wHzAeABzAH/DAADvwH/Aa0CrgH/A9MB/wwAA6gB/wGMAY0BjAH/ + A58B/wPdAf8DjQH/A5oB/wgAAc0BvAGvAf8BtgGcAY4B/wGoAYsBgQH/CAABjgF5AWkB/wH0Ae4B6QH/ + Ae0B5gHjAf8B6QHgAdwB/wHkAdoB0wH/Ad4B0gHMAf8B2gHKAcMB/wHYAcUBvQH/AdQBvgGyAf8BlwGB + AXIB/wFmAUwBNAH/EAADUQH/Aw4B/xQAAw4B/wNRAf8YAAG3Ad8B7gH/DAABlwGBAXMB/wwAAfEBxwHO + Af8B2AGbAV8B/wHzAeABzAH/EAADswH/AaMBpAGjAf8D8gH/CAACqQGoAf8DlgH/A6gB/wQAA+4B/wOA + Af8DgQH/CAAB3QHNAcYB/wHGAbABpQH/AbcBnAGOAf8BxgGwAaQB/wGpAY8BgQH/AZYBgQFzAf8B9gHy + AfEB/wHxAewB6QH/Ae8B5gHiAf8B6QHgAd0B/wHkAdkB1QH/AeEB0QHKAf8B2QHLAcUB/wHWAcUBvAH/ + AZwBgwFzAf8BaQFMATcB/xAAAw4B/wO/Af8UAAO/Af8DDgH/FAABtwHfAe4B/wESAXwBngH/AbcB3wHu + Af8IAAGXAYEBcwH/CAAB/AHcAfsB/wGNATEBjAH/AfEBxwHOAf8UAAO3Af8DqQH/A/MB/wQAA7sB/wOh + Af8DsQH/CAAD7gH/A4EB/wOFAf8IAAHuAegB4QH/AdoBzAHGAf8ByAG6Aa4B/wgAAaABigF8Af8B+QL3 + Af8B9gHxAfIB/wHzAe0B6AH/AewB6AHjAf8B5gHgAdsB/wHlAdkB0wH/Ad4B0gHMAf8B3AHLAcIB/wGh + AYgBeAH/AWcBTAE4Af8MAAMOAf8DaAH/HAADaAH/Aw4B/wwAAbcB3wHuAf8BEgF8AZ4B/wEgAbYB7gH/ + ARIBfAGeAf8BtwHfAe4B/wQAAZcBgQFzAf8EAAH8AdwB+wH/AbMBQAGyAf8B3AF0AdsB/wGNATEBjAH/ + AfwB3AH7Af8QAAPLAf8DuwH/A+MB/wPFAf8DrAH/A7sB/wwAAcoBywHKAf8DlgH/AaIBowGiAf8cAAGp + AZUBhAH/Af0B+gH8Af8B+QL3Af8B9wH0AfAB/wHyAe0B6gH/Ae0B5wHiAf8B6wHhAdoB/wHjAdgB1AH/ + AeIB0gHLAf8BogGLAX8B/wFoAU4BNgH/EAADNwH/A7oB/xQAA7oB/wM3Af8MAAG3Ad8B7gH/ARIBfAGe + Af8BUwHLAfEB/wE4AcAB7wH/ATMBvgHvAf8BEAFmAYEB/wGXAYEBcwH/AZcBgQFzAf8BlwGBAXMB/wHZ + AXAB2AH/AfoBrQH6Af8B+wGYAfoB/wHcAXQB2wH/AY0BMQGMAf8B/AHcAfsB/wwAA+IB/wPDAf8DvAH/ + AbICsQH/A8UB/wwAA+cB/wOgAf8DnwH/AskByAH/HAABsQGcAY0F/wH6AvwB/wH6AvgB/wH2AfEB8gH/ + AfIB7QHsAf8B8AHnAeMB/wHoAd8B2wH/AeIB2QHVAf8B4QHSAckB/wFwAVIBQQH/EAADUQH/AzcB/xQA + AzcB/wNRAf8MAAEYAaoB4QH/AYUB4QH1Af8BbwHXAfQB/wFUAcsB8QH/ATgBwAHwAf8BIQG1Ae4B/wEQ + AWYBgQH/AbcB3wHuAf8EAAH8AdwB+wH/AdMBaQHSAf8B+gGtAfoB/wH7AZgB+gH/AdwBdAHbAf8BjQEx + AYwB/xAAA9EB/wO3Af8DvAH/A+AB/wPzAf8D8gH/AdMB0gHTAf8DpwH/A6cB/wKxAbAB/yQAAbQBoQGS + Af8BrQGbAYoB/wGnAZABgQH/AaABiQF9Af8BmAGBAXMB/wGPAXsBZwH/AYcBcwFfAf8BgQFrAVkB/wF8 + AWMBTwH/FAADUQH/AzcB/xQAAzcB/wNRAf8MAAG3Ad8B7gH/ARgBqgHhAf8BhgHhAfUB/wFwAdYB8wH/ + AVQBywHyAf8BOQHAAfAB/wEgAbUB7QH/ARABZgGBAf8BtwHfAe4B/wQAAfwB3AH7Af8B0wFpAdIB/wH6 + Aa0B+gH/AdMBaQHSAf8B/AHcAfsB/xAAA/EB/wPRAf8DwwH/ArsBugH/A6kB/wGkAaMBpAH/A64B/wOu + Af8DtwH/A+YB/1wAA4gB/wM3Af8UAAM3Af8DiAH/EAABtwHfAe4B/wEYAaoB4QH/AYUB4AH1Af8BcAHW + AfMB/wFUAcsB8gH/ATgBwAHvAf8BIQG1Ae0B/wEQAWYBgQH/AbcB3wHuAf8EAAH8AdwB+wH/AdMBaQHS + Af8B/AHcAfsB/xwAA+IB/wPLAf8DtwH/A7MB/wO/Af8D1gH/aAADiAH/AzcB/wwAAzcB/wOIAf8YAAG3 + Ad8B7gH/ARgBqgHhAf8BhgHhAfQB/wFvAdYB9AH/AVQBywHxAf8BGwGYAcgB/wG3Ad8B7gH/DAAB/AHc + AfsB/9gAAbcB3wHuAf8BGAGqAeEB/wGFAeEB9QH/ARsBmAHIAf8BtwHfAe4B//AAAbcB3wHuAf8BGAGq + AeEB/wG3Ad8B7gH/JAABQgFNAT4HAAE+AwABKAMAAUADAAEgAwABAQEAAQEGAAEBFgAD/4EAB/8B7wf/ + AccB+AEfBf8BgwHgAQcC/wH5Ac8B/gEBAeABBwH8AQEB8wHnAf4BgQHDAYMB+AEAAfMB5wH+AcEBxwED + ARgBAAHzAecB7gHjAcYBIwIAAfMB5wHGAccBxAFjARgBAAHnAfMBggGDAcAB4wH4AQAB8wHnAQABAQHB + AcMB+AEAAfMB5wEAAYEB4AEHAfwBAQHzAecBAAFBAeABBwL/AfMB5wGAASMB+AEfAv8B+QHPAcABdwb/ + AeAH/wHxAf8L + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/INotifyObjectEdit.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/INotifyObjectEdit.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +using System; + +namespace BLToolkit.ComponentModel +{ + public delegate void ObjectEditEventHandler(object sender, ObjectEditEventArgs args); + + public interface INotifyObjectEdit + { + event ObjectEditEventHandler ObjectEdit; + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/IObjectView.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/IObjectView.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.ComponentModel +{ + public interface IObjectView + { + object Object { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/ISortable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/ISortable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +using System; +using System.Collections; + +namespace BLToolkit.ComponentModel +{ + public interface ISortable + { + void Sort(int index, int count, IComparer comparer); + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/ITypeDescriptionProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/ITypeDescriptionProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; +using System.ComponentModel; + +namespace BLToolkit.ComponentModel +{ + public interface ITypeDescriptionProvider + { + Type OriginalType { get; } + string ClassName { get; } + string ComponentName { get; } + + EventDescriptor GetEvent (string name); + PropertyDescriptor GetProperty (string name); + + AttributeCollection GetAttributes (); + EventDescriptorCollection GetEvents (); + PropertyDescriptorCollection GetProperties (); + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/MemberPropertyDescriptor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/MemberPropertyDescriptor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,87 @@ +using System; +using System.ComponentModel; + +using BLToolkit.Reflection; + +namespace BLToolkit.ComponentModel +{ + public class MemberPropertyDescriptor : PropertyDescriptor + { + public MemberPropertyDescriptor(Type componentType, string memberName) + : base(memberName, null) + { + _componentType = componentType; + _memberAccessor = TypeAccessor.GetAccessor(componentType)[memberName]; + } + + private readonly Type _componentType; + public override Type ComponentType + { + get { return _componentType; } + } + + public override Type PropertyType + { + get { return _memberAccessor.Type; } + } + + private readonly MemberAccessor _memberAccessor; + public MemberAccessor MemberAccessor + { + get { return _memberAccessor; } + } + + public override bool CanResetValue(object component) + { + if (PropertyType.IsValueType) + return TypeAccessor.GetNullValue(PropertyType) != null; + return PropertyType == typeof(string); + } + + public override void ResetValue(object component) + { + SetValue(component, TypeAccessor.GetNullValue(PropertyType)); + } + + public override object GetValue(object component) + { + return component != null? _memberAccessor.GetValue(component): null; + } + + public override void SetValue(object component, object value) + { + if (component != null) + _memberAccessor.SetValue(component, value); + } + + public override bool IsReadOnly + { + get { return !_memberAccessor.HasSetter; } + } + + public override bool ShouldSerializeValue(object component) + { + return false; + } + + private AttributeCollection _attributes; + public override AttributeCollection Attributes + { + get + { + if (_attributes == null) + { + object[] memberAttrs = _memberAccessor.GetAttributes(); + Attribute[] attrs = new Attribute[memberAttrs == null? 0: memberAttrs.Length]; + + if (memberAttrs != null) + memberAttrs.CopyTo(attrs, 0); + + _attributes = new AttributeCollection(attrs); + } + + return _attributes; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/ObjectBinder.bmp Binary file Source/ComponentModel/ObjectBinder.bmp has changed diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/ObjectBinder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/ObjectBinder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,547 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing.Design; +using System.Drawing; +using System.Windows.Forms; + +using BLToolkit.EditableObjects; +using BLToolkit.Reflection; + +namespace BLToolkit.ComponentModel +{ + /// + /// http://www.bltoolkit.net/Doc/ComponentModel/ObjectBinder.htm + /// + //[ComplexBindingProperties("DataSource", "DataMember")] + [ComplexBindingProperties("DataSource")] + [DefaultProperty("ItemType")] + [ToolboxItem(true)] + [ToolboxBitmap(typeof(ObjectBinder))] + public class ObjectBinder : Component, ITypedList, IBindingListView, ICancelAddNew + { + #region Constructors + + static readonly EditableArrayList _empty = new EditableArrayList(typeof(object)); + + public ObjectBinder() + { + } + + public ObjectBinder(IContainer container) + : this() + { + if (container != null) + container.Add(this); + } + + #endregion + + #region Public members + + private object _dataSource; + + [AttributeProvider(typeof(IListSource))] + [RefreshProperties(RefreshProperties.Repaint)] + [DefaultValue(null)] + [Category("Data")] + public object DataSource + { + get { return _dataSource; } + set + { + _dataSource = value; + + if (value is Type) ItemType = (Type)value; + else if (value is BindingSource) DataSource = ((BindingSource)value).DataSource; + else if (value is IList) List = (IList)value; + else if (value is IListSource) List = ((IListSource)value).GetList(); + else Object = value; + } + } + + private Type _itemType; + [RefreshProperties(RefreshProperties.Repaint)] + [DefaultValue(null)] + [Category("Data")] + [TypeConverter(typeof(TypeTypeConverter))] +#if !CLIENTPROFILE + [Editor(typeof(Design.TypeEditor), typeof(UITypeEditor))] +#endif + public Type ItemType + { + get { return _itemType; } + set + { + _itemType = value; + + List = null; + + OnListChanged(ListChangedType.PropertyDescriptorChanged, -1); + } + } + + private Type _objectViewType; + [RefreshProperties(RefreshProperties.Repaint)] + [DefaultValue(null)] + [Category("Data")] + [TypeConverter(typeof(TypeTypeConverter))] +#if !CLIENTPROFILE + [Editor(typeof(Design.ObjectViewTypeEditor), typeof(UITypeEditor))] +#endif + public Type ObjectViewType + { + get { return _objectViewType; } + set + { + _objectViewType = value; + + List = null; + + OnListChanged(ListChangedType.PropertyDescriptorChanged, -1); + } + } + + private object _object; + [Browsable(false)] + [RefreshProperties(RefreshProperties.Repaint)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object Object + { + get { return _object; } + set + { + if (value == null) + { + List = null; + } + else + { + EditableArrayList list = new EditableArrayList(value.GetType(), 1); + + list.Add(value, false); + + List = list; + _object = value; + } + } + } + + private bool _isListCreatedInternally; + private EditableArrayList _list = _empty; + [Browsable(false)] + [RefreshProperties(RefreshProperties.Repaint)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IList List + { + get { return _list; } + set + { + if (value == null) + { + if (_list != _empty) + _list.ListChanged -= ListChangedHandler; + + _list = _itemType == null? _empty: new EditableArrayList(_itemType); + _isListCreatedInternally = true; + } + else + { + EditableArrayList list; + + if (value is EditableArrayList) + { + list = (EditableArrayList)value; + + _isListCreatedInternally = false; + } + else + { + if (value.Count != 0 && _itemType == null) + list = EditableArrayList.Adapter(value); + else + list = EditableArrayList.Adapter(_itemType, value); + + _isListCreatedInternally = true; + } + + if (_itemType == null) + { + _itemType = list.ItemType; + } + else + { + if (list.ItemType != _itemType && !list.ItemType.IsSubclassOf(_itemType)) + throw new ArgumentException(string.Format( + "Item type {0} of the new list must be a subclass of {1}.", + list.ItemType, + _itemType)); + } + + if (_list != _empty) + { + _list.ListChanged -= ListChangedHandler; + + if (_disposeList || (_isListCreatedInternally && _disposeCreatedList)) + _list.Dispose(); + } + + _list = list; + } + + if (_list != _empty) + _list.ListChanged += ListChangedHandler; + + OnListChanged(ListChangedType.Reset, -1); + } + } + + private bool _disposeList; + [DefaultValue(false)] + [Category("Behavior")] + [Description("Determines whether ObjectBinder will invoke underlying List's dispose when being itself disposed.")] + public bool DisposeList + { + get { return _disposeList; } + set { _disposeList = value; } + } + + private bool _disposeCreatedList = true; + [DefaultValue(true)] + [Category("Behavior")] + [Description("Determines whether ObjectBinder will invoke underlying internally created List's dispose when being itself disposed")] + public bool DisposeCreatedList + { + get { return _disposeCreatedList; } + set { _disposeCreatedList = value; } + } + + private bool _allowNew = true; + [DefaultValue(true)] + [Category("Behavior")] + [Description("Determines whether new items can be added to the list.")] + public bool AllowNew + { + get { return _allowNew && _list.AllowNew; } + set { _allowNew = value; } + } + + private bool _allowEdit = true; + [DefaultValue(true)] + [Category("Behavior")] + [Description("Determines whether items in the list can be edited.")] + public bool AllowEdit + { + get { return _allowEdit && _list.AllowEdit; } + set { _allowEdit = value; } + } + + private bool _allowRemove = true; + [DefaultValue(true)] + [Category("Behavior")] + [Description("Determines whether items can be removed from the list.")] + public bool AllowRemove + { + get { return _allowRemove && _list.AllowRemove; } + set { _allowRemove = value; } + } + + private IsNullHandler _isNull; + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IsNullHandler IsNull + { + get { return _isNull; } + set { _isNull = value; } + } + + bool IBindingList.AllowNew { get { return AllowNew; } } + bool IBindingList.AllowEdit { get { return AllowEdit; } } + bool IBindingList.AllowRemove { get { return AllowRemove; } } + + #endregion + + #region Protected Members + + protected virtual void OnListChanged(ListChangedEventArgs e) + { + ListChangedEventHandler handler = (ListChangedEventHandler)Events[ListChangedEvent]; + if (handler != null) + handler(this, e); + } + + protected void OnListChanged(ListChangedType listChangedType, int newIndex) + { + OnListChanged(new ListChangedEventArgs(listChangedType, newIndex)); + } + + private void ListChangedHandler(object sender, ListChangedEventArgs e) + { + OnListChanged(e); + } + + protected override void Dispose(bool disposing) + { + if (_list != _empty) + { + _list.ListChanged -= ListChangedHandler; + + if (_disposeList || (_isListCreatedInternally && _disposeCreatedList)) + _list.Dispose(); + } + + _list = _empty; + + base.Dispose(disposing); + } + + #endregion + + #region ITypedList Members + + private static readonly Hashtable _descriptors = new Hashtable(); + + PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) + { + if (_itemType == null) + return new PropertyDescriptorCollection(new PropertyDescriptor[0]); + + string key = + _itemType + "." + + (_objectViewType == null? string.Empty: _objectViewType.ToString()) + "." + + (_isNull == null? "0": "1"); + + if (listAccessors != null) + foreach (PropertyDescriptor pd in listAccessors) + key += "." + pd.Name; + + PropertyDescriptorCollection pdc = (PropertyDescriptorCollection)_descriptors[key]; + + if (pdc == null) + { + pdc = _list.GetItemProperties(listAccessors, _objectViewType, _isNull, !DesignMode); + + if (!DesignMode) + _descriptors[key] = pdc; + } + + return pdc; + } + + string ITypedList.GetListName(PropertyDescriptor[] listAccessors) + { + return _list.GetListName(listAccessors); + } + + #endregion + + #region IBindingListView Members + + bool IBindingListView.SupportsAdvancedSorting + { + get { return _list.SupportsAdvancedSorting; } + } + + ListSortDescriptionCollection IBindingListView.SortDescriptions + { + get { return _list.SortDescriptions; } + } + + void IBindingListView.ApplySort(ListSortDescriptionCollection sorts) + { + _list.ApplySort(sorts); + } + + bool IBindingListView.SupportsFiltering + { + get { return _list.SupportsFiltering; } + } + + string IBindingListView.Filter + { + get { return _list.Filter; } + set { _list.Filter = value; } + } + + void IBindingListView.RemoveFilter() + { + _list.RemoveFilter(); + } + + #endregion + + #region ICancelAddNew Members + + void ICancelAddNew.CancelNew(int itemIndex) + { + _list.CancelNew(itemIndex); + } + + void ICancelAddNew.EndNew(int itemIndex) + { + _list.EndNew(itemIndex); + } + + #endregion + + #region IBindingList Members + + void IBindingList.AddIndex(PropertyDescriptor property) + { + _list.AddIndex(property); + } + + object IBindingList.AddNew() + { + return _list.AddNew(); + } + + void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction) + { + _list.ApplySort(property, direction); + } + + int IBindingList.Find(PropertyDescriptor property, object key) + { + return _list.Find(property, key); + } + + bool IBindingList.IsSorted + { + get { return _list.IsSorted; } + } + + private static readonly object ListChangedEvent = new object(); + + public event ListChangedEventHandler ListChanged + { + add { Events.AddHandler (ListChangedEvent, value); } + remove { Events.RemoveHandler(ListChangedEvent, value); } + } + + void IBindingList.RemoveIndex(PropertyDescriptor property) + { + _list.RemoveIndex(property); + } + + void IBindingList.RemoveSort() + { + _list.RemoveSort(); + } + + ListSortDirection IBindingList.SortDirection + { + get { return _list.SortDirection; } + } + + PropertyDescriptor IBindingList.SortProperty + { + get { return _list.SortProperty; } + } + + bool IBindingList.SupportsChangeNotification + { + get { return _list.SupportsChangeNotification; } + } + + bool IBindingList.SupportsSearching + { + get { return _list.SupportsSearching; } + } + + bool IBindingList.SupportsSorting + { + get { return _list.SupportsSorting; } + } + + #endregion + + #region IList Members + + int IList.Add(object value) + { + return _list.Add(value); + } + + void IList.Clear() + { + _list.Clear(); + } + + bool IList.Contains(object value) + { + return _list.Contains(value); + } + + int IList.IndexOf(object value) + { + return _list.IndexOf(value); + } + + void IList.Insert(int index, object value) + { + _list.Insert(index, value); + } + + bool IList.IsFixedSize + { + get { return _list.IsFixedSize; } + } + + bool IList.IsReadOnly + { + get { return _list.IsReadOnly; } + } + + void IList.Remove(object value) + { + _list.Remove(value); + } + + void IList.RemoveAt(int index) + { + _list.RemoveAt(index); + } + + object IList.this[int index] + { + get { return index == -1? null: _list[index]; } + set { _list[index] = value; } + } + + #endregion + + #region ICollection Members + + void ICollection.CopyTo(Array array, int index) + { + _list.CopyTo(array, index); + } + + int ICollection.Count + { + get { return _list.Count; } + } + + bool ICollection.IsSynchronized + { + get { return _list.IsSynchronized; } + } + + object ICollection.SyncRoot + { + get { return _list.SyncRoot; } + } + + #endregion + + #region IEnumerable Members + + IEnumerator IEnumerable.GetEnumerator() + { + return _list.GetEnumerator(); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/ObjectBinder.ico Binary file Source/ComponentModel/ObjectBinder.ico has changed diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/ObjectBinder.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/ObjectBinder.resx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/ObjectEditEventArgs.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/ObjectEditEventArgs.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; + +namespace BLToolkit.ComponentModel +{ + public class ObjectEditEventArgs + { + public ObjectEditEventArgs(ObjectEditType editType) + { + _editType = editType; + } + + private ObjectEditType _editType; + public ObjectEditType EditType + { + get { return _editType; } + set { _editType = value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/ObjectEditType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/ObjectEditType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +using System; + +namespace BLToolkit.ComponentModel +{ + public enum ObjectEditType + { + Begin, + End, + Cancel + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/ObjectHolder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/ObjectHolder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,139 @@ +using System; +using System.ComponentModel; + +using BLToolkit.Reflection; + +namespace BLToolkit.ComponentModel +{ + public class ObjectHolder : ICustomTypeDescriptor + { + public ObjectHolder(object obj, ObjectBinder objectBinder) + { + _object = obj; + _originalProperties = ((ITypedList)objectBinder).GetItemProperties(null); + } + + private readonly PropertyDescriptorCollection _originalProperties; + private PropertyDescriptorCollection _customProperties; + + private readonly object _object; + public object Object + { + get { return _object; } + } + + private ICustomTypeDescriptor _customTypeDescriptor; + private ICustomTypeDescriptor CustomTypeDescriptor + { + get + { + if (_customTypeDescriptor == null) + { + _customTypeDescriptor = _object is ICustomTypeDescriptor? + (ICustomTypeDescriptor)_object: + TypeAccessor.GetCustomTypeDescriptor(_object.GetType()); + } + + return _customTypeDescriptor; + } + } + + #region ICustomTypeDescriptor Members + + AttributeCollection ICustomTypeDescriptor.GetAttributes() + { + return CustomTypeDescriptor.GetAttributes(); + } + + string ICustomTypeDescriptor.GetClassName() + { + return CustomTypeDescriptor.GetClassName(); + } + + string ICustomTypeDescriptor.GetComponentName() + { + return CustomTypeDescriptor.GetComponentName(); + } + + TypeConverter ICustomTypeDescriptor.GetConverter() + { + return CustomTypeDescriptor.GetConverter(); + } + + EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() + { + return CustomTypeDescriptor.GetDefaultEvent(); + } + + PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() + { + return CustomTypeDescriptor.GetDefaultProperty(); + } + + object ICustomTypeDescriptor.GetEditor(Type editorBaseType) + { + return CustomTypeDescriptor.GetEditor(editorBaseType); + } + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) + { + return CustomTypeDescriptor.GetEvents(attributes); + } + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents() + { + return CustomTypeDescriptor.GetEvents(); + } + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) + { + if (_customProperties == null) + { + PropertyDescriptor[] properties = new PropertyDescriptor[_originalProperties.Count]; + + for (int i = 0; i < properties.Length; i++) + { + properties[i] = new ObjectPropertyDescriptor(_originalProperties[i]); + } + + _customProperties = new PropertyDescriptorCollection(properties); + } + + return _customProperties; + } + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() + { + return ((ICustomTypeDescriptor)this).GetProperties(null); + } + + object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) + { + return CustomTypeDescriptor.GetPropertyOwner(pd); + } + + #endregion + + #region ObjectPropertyDescriptor + + class ObjectPropertyDescriptor : PropertyDescriptorWrapper + { + public ObjectPropertyDescriptor(PropertyDescriptor pd) + : base(pd) + { + } + + public override object GetValue(object component) + { + return base.GetValue(((ObjectHolder)component).Object); + } + + public override void SetValue(object component, object value) + { + base.SetValue(((ObjectHolder)component).Object, value); + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/PropertyDescriptorWrapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/PropertyDescriptorWrapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,62 @@ +using System; +using System.ComponentModel; + +namespace BLToolkit.ComponentModel +{ + [System.Diagnostics.DebuggerStepThrough] + public abstract class PropertyDescriptorWrapper : PropertyDescriptor + { + protected PropertyDescriptorWrapper(PropertyDescriptor propertyDescriptor) + : base(propertyDescriptor) + { + if (propertyDescriptor == null) throw new ArgumentNullException("propertyDescriptor"); + + _pd = propertyDescriptor; + } + + private readonly PropertyDescriptor _pd; + + public override AttributeCollection Attributes { get { return _pd.Attributes; } } + public override string Category { get { return _pd.Category; } } + public override Type ComponentType { get { return _pd.ComponentType; } } + public override TypeConverter Converter { get { return _pd.Converter; } } + public override string Description { get { return _pd.Description; } } + public override bool DesignTimeOnly { get { return _pd.DesignTimeOnly; } } + public override string DisplayName { get { return _pd.DisplayName; } } + public override bool IsBrowsable { get { return _pd.IsBrowsable; } } + public override bool IsLocalizable { get { return _pd.IsLocalizable; } } + public override bool IsReadOnly { get { return _pd.IsReadOnly; } } + public override string Name { get { return _pd.Name; } } + public override Type PropertyType { get { return _pd.PropertyType; } } + + public override bool Equals (object obj) { return _pd.Equals(obj); } + public override object GetEditor (Type editorBaseType) { return _pd.GetEditor(editorBaseType); } + public override int GetHashCode () { return _pd.GetHashCode(); } + public override object GetValue (object component) { return _pd.GetValue(component); } + public override string ToString () { return _pd.ToString(); } + public override bool CanResetValue(object component) { return _pd.CanResetValue(component); } + + public override void ResetValue(object component) { _pd.ResetValue(component); } + public override void SetValue (object component, object value) { _pd.SetValue(component, value); } + + public override void AddValueChanged(object component, EventHandler handler) + { + _pd.AddValueChanged(component, handler); + } + + public override PropertyDescriptorCollection GetChildProperties(object instance, Attribute[] filter) + { + return _pd.GetChildProperties(instance, filter); + } + + public override bool ShouldSerializeValue(object component) + { + return _pd.ShouldSerializeValue(component); + } + + public override void RemoveValueChanged(object component, EventHandler handler) + { + _pd.RemoveValueChanged(component, handler); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/TypeDescriptorExtender.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/TypeDescriptorExtender.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,232 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Reflection; + +using BLToolkit.Reflection; + +namespace BLToolkit.ComponentModel +{ + public abstract class TypeDescriptorExtender : ICustomTypeDescriptor, ITypeDescriptionProvider + { + #region Constructors + + protected TypeDescriptorExtender(Type baseType) + { + if (baseType == null) + throw new ArgumentNullException("baseType"); + + _baseObject = TypeAccessor.CreateInstanceEx(baseType); + } + + protected TypeDescriptorExtender(object baseObject) + { + if (baseObject == null) + throw new ArgumentNullException("baseObject"); + + _baseObject = baseObject; + } + + #endregion + + #region Public Members + + private readonly object _baseObject; + public object BaseObject + { + get { return _baseObject; } + } + + #endregion + + #region Protected Members + + private static readonly Hashtable _hashDescriptors = new Hashtable(); + + [NonSerialized] + private ICustomTypeDescriptor _typeDescriptor; + private ICustomTypeDescriptor TypeDescriptor + { + get + { + if (_typeDescriptor == null) + { + Type key1 = GetType(); + Type key2 = _baseObject.GetType(); + + Hashtable tbl = (Hashtable)_hashDescriptors[key1]; + + if (tbl == null) + _hashDescriptors[key1] = tbl = new Hashtable(); + + _typeDescriptor = (ICustomTypeDescriptor)tbl[key2]; + + if (_typeDescriptor == null) + tbl[key2] = _typeDescriptor = CreateTypeDescriptor(); + } + + return _typeDescriptor; + } + } + + private ICustomTypeDescriptor CreateTypeDescriptor() + { + return new CustomTypeDescriptorImpl(this); + } + + #endregion + + #region ICustomTypeDescriptor Members + + AttributeCollection ICustomTypeDescriptor.GetAttributes() + { + return TypeDescriptor.GetAttributes(); + } + + string ICustomTypeDescriptor.GetClassName() + { + return TypeDescriptor.GetClassName(); + } + + string ICustomTypeDescriptor.GetComponentName() + { + return TypeDescriptor.GetComponentName(); + } + + TypeConverter ICustomTypeDescriptor.GetConverter() + { + return TypeDescriptor.GetConverter(); + } + + EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() + { + return TypeDescriptor.GetDefaultEvent(); + } + + PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() + { + return TypeDescriptor.GetDefaultProperty(); + } + + object ICustomTypeDescriptor.GetEditor(Type editorBaseType) + { + return TypeDescriptor.GetEditor(editorBaseType); + } + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) + { + return TypeDescriptor.GetEvents(attributes); + } + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents() + { + return TypeDescriptor.GetEvents(); + } + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) + { + return TypeDescriptor.GetProperties(attributes); + } + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() + { + return TypeDescriptor.GetProperties(); + } + + object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) + { + return TypeDescriptor.GetPropertyOwner(pd); + } + + #endregion + + #region ITypeDescriptionProvider Members + + [NonSerialized] + private ICustomTypeDescriptor _baseTypeDescriptor; + private ICustomTypeDescriptor BaseTypeDescriptor + { + get + { + if (_baseTypeDescriptor == null) + { + _baseTypeDescriptor = _baseObject as ICustomTypeDescriptor ?? + new CustomTypeDescriptorImpl(_baseObject.GetType()); + } + + return _baseTypeDescriptor; + } + } + + [NonSerialized] + private ITypeDescriptionProvider _provider; + private ITypeDescriptionProvider Provider + { + get + { + if (_provider == null) + _provider = TypeAccessor.GetAccessor(GetType()); + + return _provider; + } + } + + Type ITypeDescriptionProvider.OriginalType { get { return GetType(); } } + string ITypeDescriptionProvider.ClassName { get { return GetType().Name; } } + string ITypeDescriptionProvider.ComponentName { get { return GetType().Name; } } + + EventDescriptor ITypeDescriptionProvider.GetEvent(string name) + { + EventInfo ei = GetType().GetEvent(name); + + return ei != null ? Provider.GetEvent(name) : BaseTypeDescriptor.GetEvents()[name]; + } + + PropertyDescriptor ITypeDescriptionProvider.GetProperty(string name) + { + PropertyDescriptor pd = Provider.GetProperty(name); + + return pd ?? BaseTypeDescriptor.GetProperties()[name]; + } + + AttributeCollection ITypeDescriptionProvider.GetAttributes() + { + AttributeCollection col1 = Provider.GetAttributes(); + AttributeCollection col2 = BaseTypeDescriptor.GetAttributes(); + + Attribute[] attrs = new Attribute[col1.Count + col2.Count]; + + for (int i = 0; i < col1.Count; i++) + attrs[i] = col1[i]; + + for (int i = 0; i < col2.Count; i++) + attrs[col1.Count + i] = col2[i]; + + return new AttributeCollection(attrs); + } + + EventDescriptorCollection ITypeDescriptionProvider.GetEvents() + { + EventDescriptorCollection col1 = Provider.GetEvents(); + EventDescriptorCollection col2 = BaseTypeDescriptor.GetEvents(); + + EventDescriptorCollection col = new EventDescriptorCollection(new EventDescriptor[0]); + + foreach (EventDescriptor ed in col1) + col.Add(ed); + + foreach (EventDescriptor ed in col2) + if (col.Find(ed.Name, false) == null) + col.Add(ed); + + return col; + } + + PropertyDescriptorCollection ITypeDescriptionProvider.GetProperties() + { + throw new Exception("The method or operation is not implemented."); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/TypeDescriptorExtenderT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/TypeDescriptorExtenderT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ +using System; + +namespace BLToolkit.ComponentModel +{ + public abstract class TypeDescriptorExtender : TypeDescriptorExtender + { + protected TypeDescriptorExtender() + : base(typeof(T)) + { + } + + protected TypeDescriptorExtender(T t) + : base(t) + { + } + + public new T BaseObject + { + get { return (T)base.BaseObject; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/TypeTypeConverter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/TypeTypeConverter.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,139 @@ +using System; +using System.ComponentModel; +using System.Globalization; +using System.ComponentModel.Design; + +namespace BLToolkit.ComponentModel +{ + /// + /// Converts the value of an object into a . + /// + public class TypeTypeConverter: TypeConverter + { + // Human readable text for 'nothing selected'. + // + private const string NoType = "(none)"; + + /// + /// Returns whether this converter can convert an object of the given type to + /// a , using the specified context. + /// + /// An + /// that provides a format context. + /// A that represents the type + /// you want to convert from. + /// + /// if this converter can perform the conversion; + /// otherwise, . + /// + public override bool CanConvertFrom( + ITypeDescriptorContext context, + Type sourceType) + { + return sourceType == typeof(string) || + base.CanConvertFrom(context, sourceType); + } + + /// + /// Converts the given object to the corresponding , + /// using the specified context and culture information. + /// + /// The to + /// use as the current culture. + /// An + /// that provides a + /// format context. + /// The to convert. + /// + /// An that represents the converted value. + /// + /// The conversion cannot be + /// performed. + public override object ConvertFrom( + ITypeDescriptorContext context, + CultureInfo culture, + object value) + { + if (value == null) + return null; + + if (!(value is string)) + return base.ConvertFrom(context, culture, value); + + string str = (string)value; + + if (str.Length == 0 || str == NoType) + return null; + + // Try VisualStudio own service first. + // + ITypeResolutionService typeResolver = + (ITypeResolutionService)context.GetService(typeof(ITypeResolutionService)); + + if (typeResolver != null) + { + Type type = typeResolver.GetType(str); + + if (type != null) + return type; + } + + return Type.GetType(str); + } + + /// + /// Returns whether this converter can convert the object to the specified type, + /// using the specified context. + /// + /// An + /// that provides + /// a format context. + /// A that represents + /// the type you want to convert to. + /// + /// if this converter can perform the conversion; + /// otherwise, . + /// + public override bool CanConvertTo( + ITypeDescriptorContext context, + Type destinationType) + { + return destinationType == typeof(string) || + base.CanConvertTo(context, destinationType); + } + + /// + /// Converts the given value object to the specified type, using the specified + /// context and culture information. + /// + /// A . + /// If null is passed, the current culture is assumed. + /// An + /// that provides + /// a format context. + /// The to convert + /// the value parameter to. + /// The to convert. + /// + /// An that represents the converted value. + /// + /// The conversion cannot be + /// performed. + /// + /// The parameter is null. + public override object ConvertTo( + ITypeDescriptorContext context, + CultureInfo culture, + object value, + Type destinationType) + { + if (destinationType != typeof(string)) + return base.ConvertTo(context, culture, value, destinationType); + + if (value == null || value.ToString().Length == 0) + return NoType; + + return value.ToString(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ComponentModel/TypedListImpl.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/TypedListImpl.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,143 @@ +using System; +using System.ComponentModel; + +using BLToolkit.Reflection; + +namespace BLToolkit.ComponentModel +{ + public class TypedListImpl : ITypedList + { + public TypedListImpl(Type itemType) + { + if (itemType == null) throw new ArgumentNullException("itemType"); + + _itemType = itemType; + _typeAccessor = TypeAccessor.GetAccessor(itemType); + } + + private readonly Type _itemType; + private readonly TypeAccessor _typeAccessor; + + private NullValueProvider _getNullValue; + public NullValueProvider GetNullValue + { + get + { + if (_getNullValue == null) + _getNullValue = TypeAccessor.GetNullValue; + + return _getNullValue; + } + + set { _getNullValue = value; } + } + + #region ITypedList Members + + private PropertyDescriptorCollection _pdc; + + public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors) + { + return GetItemProperties(listAccessors, null, null, true); + } + + public PropertyDescriptorCollection GetItemProperties( + PropertyDescriptor[] listAccessors, + Type objectViewType, + IsNullHandler isNull, + bool cache) + { + PropertyDescriptorCollection pdc = null; + + if (listAccessors == null || listAccessors.Length == 0) + { + if (_pdc == null) + { + _pdc = _typeAccessor != null? + _typeAccessor.CreateExtendedPropertyDescriptors(objectViewType, isNull): + new PropertyDescriptorCollection(null); + } + + pdc = _pdc; + + if (!cache) + _pdc = null; + } + else + { + try + { + // Lets try to pick out the item type from the list type. + // + Type itemType = TypeHelper.GetListItemType( + listAccessors[listAccessors.Length - 1].PropertyType); + + if (itemType == typeof(object)) + { + TypeAccessor parentAccessor = _typeAccessor; + + foreach (PropertyDescriptor pd in listAccessors) + { + // We have to create an instance of the list to determine its item type + // + + // Create an instance of the parent. + // + object parentObject = parentAccessor.CreateInstanceEx(); + + // Create an instance of the list. + // + object listObject = pd.GetValue(parentObject); + + if (listObject == null) + { + // We failed. Item type can not be determined. + // + itemType = null; + + break; + } + + itemType = TypeHelper.GetListItemType(listObject); + + // Still bad. + // + if (itemType == typeof(object)) + break; + + parentAccessor = TypeAccessor.GetAccessor(itemType); + } + } + + if (itemType != null && itemType != typeof(object)) + { + TypeAccessor ta = TypeAccessor.GetAccessor(itemType); + + pdc = ta.CreateExtendedPropertyDescriptors(null, isNull); + } + } + catch + { + } + + if (pdc == null) + pdc = new PropertyDescriptorCollection(null); + } + + return pdc; + } + + public string GetListName(PropertyDescriptor[] listAccessors) + { + string name = _itemType.Name; + + if (listAccessors != null) + foreach (PropertyDescriptor pd in listAccessors) + name += "_" + pd.Name; + + return name; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Configuration/BLToolkitSection.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Configuration/BLToolkitSection.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,68 @@ +using System; +using System.Configuration; +using System.Security; + +namespace BLToolkit.Configuration +{ + /// + /// Implementation of custom configuration section. + /// + internal class BLToolkitSection : ConfigurationSection + { + private const string SectionName = "bltoolkit"; + private static readonly ConfigurationPropertyCollection _properties = + new ConfigurationPropertyCollection(); + + private static readonly ConfigurationProperty _propDataProviders = + new ConfigurationProperty("dataProviders", typeof(DataProviderElementCollection), + new DataProviderElementCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propDefaultConfiguration = + new ConfigurationProperty("defaultConfiguration", typeof(string), + null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propTypeFactory = + new ConfigurationProperty("typeFactory", typeof(TypeFactoryElement), + null, ConfigurationPropertyOptions.None); + + static BLToolkitSection() + { + _properties.Add(_propDataProviders); + _properties.Add(_propDefaultConfiguration); + _properties.Add(_propTypeFactory); + } + + public static BLToolkitSection Instance + { + get + { + try + { + return (BLToolkitSection)ConfigurationManager.GetSection(SectionName); + } + catch (SecurityException) + { + return null; + } + } + } + + protected override ConfigurationPropertyCollection Properties + { + get { return _properties; } + } + + public DataProviderElementCollection DataProviders + { + get { return (DataProviderElementCollection) base[_propDataProviders]; } + } + + public string DefaultConfiguration + { + get { return (string)base[_propDefaultConfiguration]; } + } + + public TypeFactoryElement TypeFactory + { + get { return (TypeFactoryElement)base[_propTypeFactory]; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Configuration/DataProviderElement.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Configuration/DataProviderElement.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,46 @@ +using System; +using System.Configuration; + +using BLToolkit.Data.DataProvider; + +namespace BLToolkit.Configuration +{ + internal class DataProviderElement : ElementBase + { + protected static readonly ConfigurationProperty _propTypeName = new ConfigurationProperty("type", typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired); + protected static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), string.Empty, ConfigurationPropertyOptions.None); + protected static readonly ConfigurationProperty _propDefault = new ConfigurationProperty("default", typeof(bool), false, ConfigurationPropertyOptions.None); + + public DataProviderElement() + { + _properties.Add(_propTypeName); + _properties.Add(_propName); + _properties.Add(_propDefault); + } + + /// + /// Gets or sets an assembly qualified type name of this data provider. + /// + public string TypeName + { + get { return (string)base[_propTypeName]; } + } + + /// + /// Gets or sets a name of this data provider. + /// If not set, is used. + /// + public string Name + { + get { return (string)base[_propName]; } + } + + /// + /// Gets a value indicating whether the provider is default. + /// + public bool Default + { + get { return (bool)base[_propDefault]; } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Configuration/DataProviderElementCollection.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Configuration/DataProviderElementCollection.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,17 @@ +using System; +using System.Configuration; + +namespace BLToolkit.Configuration +{ + [ConfigurationCollection(typeof(DataProviderElement))] + internal class DataProviderElementCollection : ElementCollectionBase + { + protected override object GetElementKey(DataProviderElement element) + { + // element.Name is optional and may be omitted. + // element.TypeName is required, but is not unique. + // + return string.Concat(element.Name, "/", element.TypeName); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Configuration/ElementBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Configuration/ElementBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,39 @@ +using System; +using System.Collections.Specialized; +using System.Configuration; + +namespace BLToolkit.Configuration +{ + internal abstract class ElementBase : ConfigurationElement + { + protected ConfigurationPropertyCollection _properties = new ConfigurationPropertyCollection(); + + protected override ConfigurationPropertyCollection Properties + { + get { return _properties; } + } + + /// + /// Gets a value indicating whether an unknown attribute is encountered during deserialization. + /// + /// + /// True when an unknown attribute is encountered while deserializing. + /// + /// The name of the unrecognized attribute. + /// The value of the unrecognized attribute. + protected override bool OnDeserializeUnrecognizedAttribute(string name, string value) + { + ConfigurationProperty property = new ConfigurationProperty(name, typeof(string), value); + _properties.Add(property); + base[property] = value; + Attributes.Add(name, value); + return true; + } + + private NameValueCollection _attributes; + public NameValueCollection Attributes + { + get { return _attributes ?? (_attributes = new NameValueCollection(StringComparer.OrdinalIgnoreCase));} + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Configuration/ElementCollectionBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Configuration/ElementCollectionBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,31 @@ +using System; +using System.Configuration; + +namespace BLToolkit.Configuration +{ + internal abstract class ElementCollectionBase: ConfigurationElementCollection + where T : ConfigurationElement, new() + { + protected override ConfigurationElement CreateNewElement() + { + return new T(); + } + + protected abstract object GetElementKey(T element); + + protected override sealed object GetElementKey(ConfigurationElement element) + { + return GetElementKey((T)element); + } + + public new T this[string name] + { + get { return (T)BaseGet(name); } + } + + public T this[int index] + { + get { return (T)BaseGet(index); } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Configuration/TypeFactoryElement.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Configuration/TypeFactoryElement.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,93 @@ +using System; +using System.Configuration; + +using BLToolkit.TypeBuilder; + +namespace BLToolkit.Configuration +{ + internal class TypeFactoryElement : ElementBase + { + protected static readonly ConfigurationProperty _propSaveTypes = + new ConfigurationProperty("saveTypes", typeof(bool), false, ConfigurationPropertyOptions.None); + protected static readonly ConfigurationProperty _propSealTypes = + new ConfigurationProperty("sealTypes", typeof(bool), true, ConfigurationPropertyOptions.None); + protected static readonly ConfigurationProperty _propLoadTypes = + new ConfigurationProperty("loadTypes", typeof(bool), false, ConfigurationPropertyOptions.None); + protected static readonly ConfigurationProperty _propAssemblyPath = + new ConfigurationProperty("assemblyPath", typeof(string), null, ConfigurationPropertyOptions.None); + protected static readonly ConfigurationProperty _propVersion = + new ConfigurationProperty("version", typeof(string), null, ConfigurationPropertyOptions.None); + protected static readonly ConfigurationProperty _propKeyFile = + new ConfigurationProperty("keyFile", typeof(string), null, ConfigurationPropertyOptions.None); + + public TypeFactoryElement() + { + _properties.Add(_propSaveTypes); + _properties.Add(_propSealTypes); + _properties.Add(_propLoadTypes); + _properties.Add(_propAssemblyPath); + _properties.Add(_propVersion); + _properties.Add(_propKeyFile); + } + + /// + /// Gets a value indicating whether the + /// will save generated assemblies to the disk. Default is . + /// + public bool SaveTypes + { + get { return (bool) base[_propSaveTypes]; } + } + + /// + /// Gets a value indicating whether the + /// will seal generated types. Default is . + /// + public bool SealTypes + { + get { return (bool) base[_propSealTypes]; } + } + + /// + /// Gets a value indicating whether the + /// will load types generated by BLTGen tool. Default is . + /// + public bool LoadTypes + { + get { return (bool) base[_propLoadTypes]; } + } + + /// + /// Gets a path to the global assembly. Default is . + /// + /// + public string AssemblyPath + { + get { return (string) base[_propAssemblyPath]; } + } + + /// + /// Gets the version of global assembly. Default is . + /// + /// + public Version Version + { + get + { + string strVersion = (string)base[_propVersion]; + + return string.IsNullOrEmpty(strVersion)? null: + new Version(strVersion); + } + } + + /// + /// Gets a path to the key file to sign global assembly. Default is . + /// + /// + public string KeyFile + { + get { return (string) base[_propKeyFile]; } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Data/DataException.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataException.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,135 @@ +using System; +using System.Runtime.Serialization; + +using BLToolkit.Data.DataProvider; + +namespace BLToolkit.Data +{ + /// + /// Defines the base class for the namespace exceptions. + /// + /// + /// This class is the base class for exceptions that may occur during + /// execution of the namespace members. + /// + [Serializable] + public class DataException : System.Data.DataException + { + /// + /// Initializes a new instance of the class. + /// + /// + /// This constructor initializes the + /// property of the new instance + /// to a system-supplied message that describes the error, + /// such as "BLToolkit Data error has occurred." + /// + public DataException() + : base("A BLToolkit Data error has occurred.") + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message. + /// + /// The message to display to the client when the + /// exception is thrown. + /// + public DataException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message and InnerException property. + /// + /// The message to display to the client when the + /// exception is thrown. + /// The InnerException, if any, that threw + /// the current exception. + /// + /// + public DataException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class + /// with the InnerException property. + /// + /// The InnerException, if any, that threw + /// the current exception. + /// + public DataException(Exception innerException) + : base(innerException.Message, innerException) + { + } + + /// + /// Initializes a new instance of the class + /// with serialized data. + /// + /// The object that holds the serialized object data. + /// The contextual information about the source or + /// destination. + /// This constructor is called during deserialization to + /// reconstitute the exception object transmitted over a stream. + protected DataException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + #region Internal + + private readonly DbManager _dbManager; + + static string GetMessage(DbManager dbManager, Exception innerException) + { + var obj = dbManager.DataProvider.Convert( + innerException, ConvertType.ExceptionToErrorMessage); + + return obj is Exception ? ((Exception)obj).Message : obj.ToString(); + } + + internal DataException(DbManager dbManager, Exception innerException) + : this(GetMessage(dbManager, innerException), innerException) + { + _dbManager = dbManager; + } + + #endregion + + #region Public Properties + + /// + /// Gets a number that identifies the type of error. + /// + public int? Number + { + get + { + var innerException = InnerException as DataException; + if (innerException != null) + return innerException.Number; + if (_dbManager == null) return null; + return _dbManager.DataProvider.Convert(InnerException, ConvertType.ExceptionToErrorNumber) as int?; + } + } + + public DataExceptionType DataExceptionType + { + get + { + if (_dbManager == null || Number == null) + return DataExceptionType.Undefined; + return _dbManager.DataProvider.ConvertErrorNumberToDataExceptionType(Number.Value); + } + } + + #endregion + } +} + diff -r 000000000000 -r f990fcb411a9 Source/Data/DataExceptionType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataExceptionType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,14 @@ +using System; + +namespace BLToolkit.Data +{ + public enum DataExceptionType + { + Undefined, + Deadlock, + Timeout, + ForeignKeyViolation, + UniqueIndexViolation, + ConstraintViolation, + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/AccessDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/AccessDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,298 @@ +using System; +using System.Data; +using System.Data.OleDb; +using System.Text.RegularExpressions; + +namespace BLToolkit.Data.DataProvider +{ + using Mapping; + using Sql.SqlProvider; + + public class AccessDataProvider : OleDbDataProvider + { + private static Regex _paramsExp; + + // Based on idea from http://qapi.blogspot.com/2006/12/deriveparameters-oledbprovider-ii.html + // + public override bool DeriveParameters(IDbCommand command) + { + if (command == null) + throw new ArgumentNullException("command"); + + if (command.CommandType != CommandType.StoredProcedure) + throw new InvalidOperationException("command.CommandType must be CommandType.StoredProcedure"); + + var conn = command.Connection as OleDbConnection; + + if (conn == null || conn.State != ConnectionState.Open) + throw new InvalidOperationException("Invalid connection state."); + + command.Parameters.Clear(); + + var dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Procedures, new object[]{null, null, command.CommandText}); + + if (dt.Rows.Count == 0) + { + // Jet does convert parameretless procedures to views. + // + dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Views, new object[]{null, null, command.CommandText}); + + if (dt.Rows.Count == 0) + throw new DataException(string.Format("Stored procedure '{0}' not found", command.CommandText)); + + // Do nothing. There is no parameters. + // + } + else + { + var col = dt.Columns["PROCEDURE_DEFINITION"]; + + if (col == null) + { + // Not really possible + // + return false; + } + + if (_paramsExp == null) + _paramsExp = new Regex(@"PARAMETERS ((\[(?[^\]]+)\]|(?[^\s]+))\s(?[^,;\s]+(\s\([^\)]+\))?)[,;]\s)*", RegexOptions.Compiled | RegexOptions.ExplicitCapture); + + var match = _paramsExp.Match((string)dt.Rows[0][col.Ordinal]); + var names = match.Groups["name"].Captures; + var types = match.Groups["type"].Captures; + + if (names.Count != types.Count) + { + // Not really possible + // + return false; + } + + var separators = new[] {' ', '(', ',', ')'}; + + for (var i = 0; i < names.Count; ++i) + { + var paramName = names[i].Value; + var rawType = types[i].Value.Split(separators, StringSplitOptions.RemoveEmptyEntries); + var p = new OleDbParameter(paramName, GetOleDbType(rawType[0])); + + if (rawType.Length > 2) + { + p.Precision = Common.Convert.ToByte(rawType[1]); + p.Scale = Common.Convert.ToByte(rawType[2]); + } + else if (rawType.Length > 1) + { + p.Size = Common.Convert.ToInt32(rawType[1]); + } + + command.Parameters.Add(p); + } + } + + return true; + } + + private static OleDbType GetOleDbType(string jetType) + { + switch (jetType.ToLower()) + { + case "byte": + case "tinyint": + case "integer1": + return OleDbType.TinyInt; + + case "short": + case "smallint": + case "integer2": + return OleDbType.SmallInt; + + case "int": + case "integer": + case "long": + case "integer4": + case "counter": + case "identity": + case "autoincrement": + return OleDbType.Integer; + + case "single": + case "real": + case "float4": + case "ieeesingle": + return OleDbType.Single; + + + case "double": + case "number": + case "double precision": + case "float": + case "float8": + case "ieeedouble": + return OleDbType.Double; + + case "currency": + case "money": + return OleDbType.Currency; + + case "dec": + case "decimal": + case "numeric": + return OleDbType.Decimal; + + case "bit": + case "yesno": + case "logical": + case "logical1": + return OleDbType.Boolean; + + case "datetime": + case "date": + case "time": + return OleDbType.Date; + + case "alphanumeric": + case "char": + case "character": + case "character varying": + case "national char": + case "national char varying": + case "national character": + case "national character varying": + case "nchar": + case "string": + case "text": + case "varchar": + return OleDbType.VarWChar; + + case "longchar": + case "longtext": + case "memo": + case "note": + case "ntext": + return OleDbType.LongVarWChar; + + case "binary": + case "varbinary": + case "binary varying": + case "bit varying": + return OleDbType.VarBinary; + + case "longbinary": + case "image": + case "general": + case "oleobject": + return OleDbType.LongVarBinary; + + case "guid": + case "uniqueidentifier": + return OleDbType.Guid; + + default: + // Each release of Jet brings many new aliases to existing types. + // This list may be outdated, please send a report to us. + // + throw new NotSupportedException("Unknown DB type '" + jetType + "'"); + } + } + + public override void AttachParameter(IDbCommand command, IDbDataParameter parameter) + { + // Do some magic to workaround 'Data type mismatch in criteria expression' error + // in JET for some european locales. + // + if (parameter.Value is DateTime) + { + // OleDbType.DBTimeStamp is locale aware, OleDbType.Date is locale neutral. + // + ((OleDbParameter)parameter).OleDbType = OleDbType.Date; + } + else if (parameter.Value is decimal) + { + // OleDbType.Decimal is locale aware, OleDbType.Currency is locale neutral. + // + ((OleDbParameter)parameter).OleDbType = OleDbType.Currency; + } + + base.AttachParameter(command, parameter); + } + + public new const string NameString = DataProvider.ProviderName.Access; + + public override string Name + { + get { return NameString; } + } + + public override int MaxBatchSize + { + get { return 0; } + } + + public override ISqlProvider CreateSqlProvider() + { + return new AccessSqlProvider(); + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.ExceptionToErrorNumber: + if (value is OleDbException) + { + var ex = (OleDbException)value; + if (ex.Errors.Count > 0) + return ex.Errors[0].NativeError; + } + + break; + } + + return SqlProvider.Convert(value, convertType); + } + + #region DataReaderEx + + public override IDataReader GetDataReader(MappingSchema schema, IDataReader dataReader) + { + return dataReader is OleDbDataReader? + new DataReaderEx((OleDbDataReader)dataReader): + base.GetDataReader(schema, dataReader); + } + + class DataReaderEx : DataReaderBase, IDataReader + { + public DataReaderEx(OleDbDataReader rd): base(rd) + { + } + + public new object GetValue(int i) + { + var value = DataReader.GetValue(i); + + if (value is DateTime) + { + var dt = (DateTime)value; + + if (dt.Year == 1899 && dt.Month == 12 && dt.Day == 30) + return new DateTime(1, 1, 1, dt.Hour, dt.Minute, dt.Second, dt.Millisecond); + } + + return value; + } + + public new DateTime GetDateTime(int i) + { + var dt = DataReader.GetDateTime(i); + + if (dt.Year == 1899 && dt.Month == 12 && dt.Day == 30) + return new DateTime(1, 1, 1, dt.Hour, dt.Minute, dt.Second, dt.Millisecond); + + return dt; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/ConvertType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/ConvertType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,129 @@ +using System; + +namespace BLToolkit.Data.DataProvider +{ + public enum ConvertType + { + /// + /// Provided name should be converted to query parameter name. + /// For example: + /// firstName -> @firstName + /// for the following query: + /// SELECT * FROM Person WHERE FirstName = @firstName + /// ^ here + /// + NameToQueryParameter, + + /// + /// Provided name should be converted to command parameter name. + /// For example: + /// firstName -> @firstName + /// for the following query: + /// db.Parameter("@firstName") = "John"; + /// ^ here + /// + NameToCommandParameter, + + [Obsolete("Use NameToCommandParameter or NameToSprocParameter instead.")] + NameToParameter = NameToCommandParameter, + + /// + /// Provided name should be converted to stored procedure parameter name. + /// For example: + /// firstName -> @firstName + /// for the following query: + /// db.Parameter("@firstName") = "John"; + /// ^ here + /// + NameToSprocParameter, + + /// + /// Provided name should be converted to query field name. + /// For example: + /// FirstName -> [FirstName] + /// for the following query: + /// SELECT [FirstName] FROM Person WHERE ID = 1 + /// ^ and ^ + /// + NameToQueryField, + + /// + /// Provided name should be converted to query field alias. + /// For example: + /// ID -> "ID" + /// for the following query: + /// SELECT "ID" as "ID" FROM Person WHERE "ID" = 1 + /// ^ ^ here + /// + NameToQueryFieldAlias, + + /// + /// Provided name should be converted to query database. + /// For example: + /// MyDatabase -> [MyDatabase] + /// for the following query: + /// SELECT * FROM [MyDatabase]..[Person] + /// ^ and ^ + /// + NameToDatabase, + + /// + /// Provided name should be converted to query database. + /// For example: + /// dbo -> [dbo] + /// for the following query: + /// SELECT * FROM [ dbo ].[Person] + /// ^ and ^ + /// + NameToOwner, + + /// + /// Provided name should be converted to query table name. + /// For example: + /// Person -> [Person] + /// for the following query: + /// SELECT * FROM [Person] + /// ^ and ^ + /// + NameToQueryTable, + + /// + /// Provided name should be converted to query table alias. + /// For example: + /// table1 -> [table1] + /// for the following query: + /// SELECT * FROM [Person] [table1] + /// ^ and ^ + /// + NameToQueryTableAlias, + + /// + /// Provided stored procedure parameter name should be converted to name. + /// For example: + /// @firstName -> firstName + /// for the following query: + /// db.Parameter("@firstName") = "John"; + /// ^ '@' has to be removed + /// + SprocParameterToName, + + [Obsolete("Use SprocParameterToName instead.")] + ParameterToName = SprocParameterToName, + + /// + /// Gets error number from a native exception. + /// For example: + /// SqlException -> SqlException.Number, + /// OleDbException -> OleDbException.Errors[0].NativeError + /// + ExceptionToErrorNumber, + + /// + /// Gets error message from a native exception. + /// For example: + /// SqlException -> SqlException.Message, + /// OleDbException -> OleDbException.Errors[0].Message + /// + ExceptionToErrorMessage, + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/DB2DataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/DB2DataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,86 @@ +using System; +using System.Data; +using System.Data.Common; + +using IBM.Data.DB2; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + + public class DB2DataProvider : DataProviderBase + { + public override IDbConnection CreateConnectionObject () { return new DB2Connection (); } + public override DbDataAdapter CreateDataAdapterObject() { return new DB2DataAdapter(); } + public override ISqlProvider CreateSqlProvider () { return new DB2SqlProvider(); } + + public override Type ConnectionType { get { return typeof(DB2Connection); } } + public override string Name { get { return DataProvider.ProviderName.DB2; } } + + public override bool DeriveParameters(IDbCommand command) + { + if (command is DB2Command) + { + DB2CommandBuilder.DeriveParameters((DB2Command)command); + return true; + } + + return false; + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.ExceptionToErrorNumber: + if (value is DB2Exception) + { + var ex = (DB2Exception)value; + + foreach (DB2Error error in ex.Errors) + return error.RowNumber; + + return 0; + } + + break; + + } + + return SqlProvider.Convert(value, convertType); + } + + public override void PrepareCommand(ref CommandType commandType, ref string commandText, ref IDbDataParameter[] commandParameters) + { + base.PrepareCommand(ref commandType, ref commandText, ref commandParameters); + + if (commandParameters != null) foreach (var p in commandParameters) + { + if (p.Value is bool) + p.Value = (bool)p.Value ? 1 : 0; + else if (p.Value is Guid) + { + p.Value = ((Guid)p.Value).ToByteArray(); + p.DbType = DbType.Binary; + p.Size = 16; + } + } + } + + /* + public override int ExecuteArray(IDbCommand command, int iterations) + { + var cmd = (DB2Command)command; + try + { + cmd.ArrayBindCount = iterations; + return cmd.ExecuteNonQuery(); + } + finally + { + cmd.ArrayBindCount = 0; + } + } + */ + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/DataProviderBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/DataProviderBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,513 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Linq; +using System.Linq; + +namespace BLToolkit.Data.DataProvider +{ + using Common; + using Mapping; + using Sql.SqlProvider; + + /// + /// The DataProviderBase is a class that provides specific data provider information + /// for the class. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + public abstract partial class DataProviderBase : IMappingSchemaProvider + { + #region Abstract Properties + + /// + /// Returns an actual type of the connection object used by this instance of the . + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// An instance of the class. + public abstract Type ConnectionType { get; } + + /// + /// Returns the data manager name. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The data manager name. + public abstract string Name { get; } + + private string _uniqueName; + /// + /// Same as , but may be overridden to add two or more providers of same type. + /// + public string UniqueName + { + get { return _uniqueName ?? Name; } + internal set { _uniqueName = value; } + } + + #endregion + + #region Abstract Methods + + /// + /// Creates a new instance of the . + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The object. + public abstract IDbConnection CreateConnectionObject(); + + /// + /// Creates a new connection object with same connection string. + /// + /// A connection object used as prototype. + /// New connection instance. + public virtual IDbConnection CloneConnection(IDbConnection connection) + { + if (connection == null) + throw new ArgumentNullException("connection"); + + var cloneable = connection as ICloneable; + + if (cloneable != null) + return (IDbConnection)cloneable.Clone(); + + var newConnection = CreateConnectionObject(); + + // This is definitelly not enought when PersistSecurityInfo set to false. + // + newConnection.ConnectionString = connection.ConnectionString; + + return newConnection; + } + + /// + /// Creates an instance of the . + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The object. + public abstract DbDataAdapter CreateDataAdapterObject(); + + /// + /// Populates the specified object's Parameters collection with + /// parameter information for the stored procedure specified in the . + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The referencing the stored procedure + /// for which the parameter information is to be derived. + /// The derived parameters will be populated into the Parameters of this command. + /// true - parameters can be derive. + public abstract bool DeriveParameters(IDbCommand command); + + #endregion + + #region Factory methods + + public virtual IDbCommand CreateCommandObject(IDbConnection connection) + { + return connection.CreateCommand(); + } + + public virtual IDbDataParameter CreateParameterObject(IDbCommand command) + { + return command.CreateParameter(); + } + + #endregion + + #region IDbDataParameter methods + + public virtual IDbDataParameter GetParameter( + IDbCommand command, + NameOrIndexParameter nameOrIndex) + { + return (IDbDataParameter)(nameOrIndex.ByName ? + command.Parameters[nameOrIndex.Name] : command.Parameters[nameOrIndex.Index]); + } + + public virtual void AttachParameter( + IDbCommand command, + IDbDataParameter parameter) + { + command.Parameters.Add(parameter); + } + + public virtual void SetUserDefinedType(IDbDataParameter parameter, string typeName) + { + throw new NotSupportedException(Name + " data provider does not support UDT."); + } + + public virtual bool IsValueParameter(IDbDataParameter parameter) + { + return parameter.Direction != ParameterDirection.ReturnValue; + } + + public virtual IDbDataParameter CloneParameter(IDbDataParameter parameter) + { + return (IDbDataParameter)((ICloneable)parameter).Clone(); + } + + public virtual bool InitParameter(IDbDataParameter parameter) + { + return false; + } + + #endregion + + #region Virtual Members + + /// + /// Open an into the given RefCursor object + /// + /// The refcursor to open an to + /// The into the refcursor + public virtual IDataReader GetRefCursorDataReader(object refCursor) + { + throw new NotSupportedException("Operation not supported on this DataProvider"); + } + + public virtual object Convert(object value, ConvertType convertType) + { + return SqlProvider.Convert(value, convertType); + } + + public virtual DataExceptionType ConvertErrorNumberToDataExceptionType(int number) + { + return DataExceptionType.Undefined; + } + + public virtual void InitDbManager(DbManager dbManager) + { + var schema = MappingSchema; + + if (schema != null) + dbManager.MappingSchema = schema; + } + + /// + /// One time initialization from a configuration file. + /// + /// Provider specific attributes. + public virtual void Configure(System.Collections.Specialized.NameValueCollection attributes) + { + } + + public virtual MappingSchema MappingSchema { get; set; } + + public virtual void PrepareCommand(ref CommandType commandType, ref string commandText, ref IDbDataParameter[] commandParameters) + { + /* + if (commandParameters != null) foreach (var p in commandParameters) + { + if (p.Value is System.Data.Linq.Binary) + { + var arr = ((System.Data.Linq.Binary)p.Value).ToArray(); + + p.Value = arr; + p.DbType = DbType.Binary; + p.Size = arr.Length; + } + } + */ + } + + public virtual bool CanReuseCommand(IDbCommand command, CommandType newCommandType) + { + return true; + } + + public virtual int ExecuteArray(IDbCommand command, int iterations) + { + // save parameter values + var parameters = command.Parameters + .OfType() + .Select(param => new + { + Parameter = param, + Value = param.Value as Array + }) + .ToArray(); + + var outParameters = parameters + .Where(p => + p.Parameter.Direction == ParameterDirection.InputOutput || + p.Parameter.Direction == ParameterDirection.Output) + .ToArray(); + + // validate parameter values + foreach (var p in parameters) + { + if (p.Value == null) + { + throw new InvalidOperationException("ExecuteArray requires that all " + + "parameter values are arrays. Parameter name: " + p.Parameter.ParameterName); + } + + if (p.Value.GetLength(0) != iterations) + { + throw new InvalidOperationException("ExecuteArray requires that array sizes are " + + "equal to the number of iterations. Parameter name: " + p.Parameter.ParameterName); + } + } + + try + { + // run iterations + int rowsAffected = 0; + for (int iteration = 0; iteration < iterations; iteration++) + { + // copy input parameter values + foreach (var param in parameters) + { + SetParameterValue(param.Parameter, param.Value.GetValue(iteration)); + } + + rowsAffected += command.ExecuteNonQuery(); + + // return output parameter values + foreach (var param in outParameters) + { + var outputValue = param.Parameter.Value; + param.Value.SetValue(outputValue, iteration); + } + } + + return rowsAffected; + } + finally + { + // restore parameter values + foreach (var param in parameters) + { + param.Parameter.Value = param.Value; + } + } + } + + public virtual string GetSequenceQuery(string sequenceName) + { + return null; + } + + public virtual string NextSequenceQuery(string sequenceName) + { + return null; + } + + public virtual string GetReturningInto(string columnName) + { + return null; + } + + public virtual void SetParameterValue(IDbDataParameter parameter, object value) + { + if (value is System.Data.Linq.Binary) + { + var arr = ((System.Data.Linq.Binary)value).ToArray(); + + parameter.Value = arr; + parameter.DbType = DbType.Binary; + parameter.Size = arr.Length; + } + else + parameter.Value = value; + } + + public abstract ISqlProvider CreateSqlProvider(); + + private ISqlProvider _sqlProvider; + protected ISqlProvider SqlProvider + { + get { return _sqlProvider ?? (_sqlProvider = CreateSqlProvider()); } + } + + public virtual IDataReader GetDataReader(MappingSchema schema, IDataReader dataReader) + { + return dataReader; + } + + public virtual IDataReader GetDataReader(IDbCommand command, CommandBehavior commandBehavior) + { + return command.ExecuteReader(commandBehavior); + } + + public virtual bool ParameterNamesEqual(string paramName1, string paramName2) + { + // default implementation is case-insensitive, because if we make it + // case-sensitive and don't overload it in all existing providers - client code may break + return string.Equals(paramName1, paramName2, StringComparison.OrdinalIgnoreCase); + } + + public virtual DbType GetDbType(Type systemType) + { + if (systemType == typeof(Binary) || systemType == typeof(byte[])) + return DbType.Binary; + + return DbType.Object; + } + + public virtual bool IsMarsEnabled(IDbConnection conn) + { + return false; + } + + public virtual string ProviderName { get { return ConnectionType.Namespace; } } + public virtual int MaxParameters { get { return 100; } } + public virtual int MaxBatchSize { get { return 65536; } } + public virtual string EndOfSql { get { return ";"; } } + + #endregion + + #region DataReaderEx + + protected class DataReaderBase : IDataReader + where T: IDataReader + { + public readonly T DataReader; + + protected DataReaderBase(T rd) + { + DataReader = rd; + } + + #region Implementation of IDisposable + + public void Dispose() + { + DataReader.Dispose(); + } + + #endregion + + #region Implementation of IDataRecord + + public string GetName (int i) { return DataReader.GetName (i); } + public string GetDataTypeName(int i) { return DataReader.GetDataTypeName(i); } + public Type GetFieldType (int i) { return DataReader.GetFieldType (i); } + // GetValue method is virtual since it can be overridden by some data provider + // (For instance, OdbDataProvider uses special methodes for clob data fetching) + public virtual object GetValue (int i) { return DataReader.GetValue (i); } + public int GetValues (object[] values) { return DataReader.GetValues (values); } + public int GetOrdinal (string name) { return DataReader.GetOrdinal (name); } + public bool GetBoolean (int i) { return DataReader.GetBoolean (i); } + public byte GetByte (int i) { return DataReader.GetByte (i); } + public char GetChar (int i) { return DataReader.GetChar (i); } + public Guid GetGuid (int i) { return DataReader.GetGuid (i); } + public short GetInt16 (int i) { return DataReader.GetInt16 (i); } + public int GetInt32 (int i) { return DataReader.GetInt32 (i); } + public long GetInt64 (int i) { return DataReader.GetInt64 (i); } + public float GetFloat (int i) { return DataReader.GetFloat (i); } + public double GetDouble (int i) { return DataReader.GetDouble (i); } + public string GetString (int i) { return DataReader.GetString (i); } + public decimal GetDecimal (int i) { return DataReader.GetDecimal (i); } + public DateTime GetDateTime (int i) { return DataReader.GetDateTime (i); } + public IDataReader GetData (int i) { return DataReader.GetData (i); } + public bool IsDBNull (int i) { return DataReader.IsDBNull (i); } + + public int FieldCount { get { return DataReader.FieldCount; } } + + object IDataRecord.this[int i] { get { return DataReader[i]; } } + object IDataRecord.this[string name] { get { return DataReader[name]; } } + + public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) + { + return DataReader.GetBytes(i, fieldOffset, buffer, bufferoffset, length); + } + + public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) + { + return DataReader.GetChars(i, fieldoffset, buffer, bufferoffset, length); + } + + #endregion + + #region Implementation of IDataReader + + public void Close () { DataReader.Close (); } + public DataTable GetSchemaTable() { return DataReader.GetSchemaTable(); } + public bool NextResult () { return DataReader.NextResult (); } + public bool Read () { return DataReader.Read (); } + public int Depth { get { return DataReader.Depth; } } + public bool IsClosed { get { return DataReader.IsClosed; } } + public int RecordsAffected { get { return DataReader.RecordsAffected; } } + + #endregion + } + + protected abstract class DataReaderEx : DataReaderBase, IDataReaderEx + where T: IDataReader + { + protected DataReaderEx(T rd) : base(rd) + { + } + + #region Implementation of IDataReaderEx + + public abstract DateTimeOffset GetDateTimeOffset(int i); + + #endregion + } + + #endregion + + #region InsertBatch + + public virtual int InsertBatchWithIdentity( + DbManager db, + string insertText, + IEnumerable collection, + MemberMapper[] members, + int maxBatchSize, + DbManager.ParameterProvider getParameters) + { + throw new NotImplementedException("Insert batch with identity is not implemented!"); + } + + public virtual int InsertBatch( + DbManager db, + string insertText, + IEnumerable collection, + MemberMapper[] members, + int maxBatchSize, + DbManager.ParameterProvider getParameters) + { + db.SetCommand(insertText); + return db.ExecuteForEach(collection, members, maxBatchSize, getParameters); + } + + #endregion + + protected int ExecuteSqlList(DbManager db, IEnumerable sqlList) + { + var cnt = 0; + + foreach (string sql in sqlList) + { + cnt += db.SetCommand(sql).ExecuteNonQuery(); + } + + return cnt; + } + + public virtual DbType GetParameterDbType(DbType dbType) + { + return dbType; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/DataProviderInterpreterBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/DataProviderInterpreterBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using System.Data; +using BLToolkit.Mapping; + +namespace BLToolkit.Data.DataProvider +{ + /// + /// BasicSqlProvider equivalent for the non-linq DAL + /// + public abstract class DataProviderInterpreterBase + { + public virtual void SetParameterValue(IDbDataParameter parameter, object value) + { + if (value is System.Data.Linq.Binary) + { + var arr = ((System.Data.Linq.Binary)value).ToArray(); + + parameter.Value = arr; + parameter.DbType = DbType.Binary; + parameter.Size = arr.Length; + } + else + parameter.Value = value; + } + + public virtual List GetInsertBatchSqlList( + string insertText, + IEnumerable collection, + MemberMapper[] members, + int maxBatchSize, + bool withIdentity) + { + return new List(); + } + + public virtual string GetSequenceQuery(string sequenceName) + { + return null; + } + + public virtual string NextSequenceQuery(string sequenceName) + { + return null; + } + + public virtual string GetReturningInto(string columnName) + { + return null; + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/FdpDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/FdpDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,326 @@ +/*** + + * FdpDataProvider +needed FirebirdClient http://sourceforge.net/project/showfiles.php?group_id=9028&package_id=62107 +tested with FirebirdClient 2.1.0 Beta 3 + +Known troubles: +1) Some tests fails due to Fb SQL-syntax specific +2) ResultSet mapping doesn't work - not supported by client +3) UnitTests.CS.DataAccess.OutRefTest tests: Test2 && TestNullable2 doesnt work: + parameters directions should be provided correctly to functions run, that's why + output parameterd would be mapped to Entity e, so asserts should be same a in Test1. + +"Features" +1) Type conversation due to http://www.firebirdsql.org/manual/migration-mssql-data-types.html + BUT! for Binary types BLOB is used! not CHAR! +2) InOut parameters faking: InOut parameters are not suppotred by Fb, but they could be + emulated: each InOut parameter should be defined in RETURNS() section, and allso has a mirror + in parameter section with name [prefix][inOutParameterName], see OutRefTest SP. Faking settings: + FdpDataProvider.InOutInputParameterPrefix = "in_"; + FdpDataProvider.IsInOutParameterEmulation = true; +3) Returned values faking. Each parameter with "magic name" woul be treated as ReturnValue. + see Scalar_ReturnParameter SP. Faking settings: + FdpDataProvider.ReturnParameterName = "RETURN_VALUE"; + FdpDataProvider.IsReturnValueEmulation = true; + + */ + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using System.Data.Common; +using System.Linq; + +using BLToolkit.Data.Sql.SqlProvider; +using BLToolkit.Mapping; +using BLToolkit.Reflection; + +using FirebirdSql.Data.FirebirdClient; + +namespace BLToolkit.Data.DataProvider +{ + public class FdpDataProvider : DataProviderBase + { + public FdpDataProvider() + { + MappingSchema = new FbMappingSchema(); + } + + #region InOut & ReturnValue emulation + public static string InOutInputParameterPrefix = "in_"; + public static string ReturnParameterName = "RETURN_VALUE"; + + public static bool IsReturnValueEmulation = true; + public static bool IsInOutParameterEmulation = true; + + public static bool QuoteIdentifiers + { + get { return FirebirdSqlProvider.QuoteIdentifiers; } + set { FirebirdSqlProvider.QuoteIdentifiers = value; } + } + #endregion + + #region Overloads + public override Type ConnectionType + { + get { return typeof (FbConnection); } + } + + public override string Name + { + get { return DataProvider.ProviderName.Firebird; } + } + + public override int MaxBatchSize + { + get { return 0; } + } + + public override IDbConnection CreateConnectionObject() + { + return new FbConnection(); + } + + public override DbDataAdapter CreateDataAdapterObject() + { + return new FbDataAdapter(); + } + + public override bool DeriveParameters(IDbCommand command) + { + if (command is FbCommand) + { + FbCommandBuilder.DeriveParameters((FbCommand) command); + + if (IsReturnValueEmulation) + foreach (IDbDataParameter par in command.Parameters) + if (IsReturnValue(par)) + par.Direction = ParameterDirection.ReturnValue; + + return true; + } + + return false; + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.ExceptionToErrorNumber: + if (value is FbException) + { + var ex = (FbException) value; + if (ex.Errors.Count > 0) + foreach (FbError error in ex.Errors) + return error.Number; + } + + break; + } + + return SqlProvider.Convert(value, convertType); + } + + public override ISqlProvider CreateSqlProvider() + { + return new FirebirdSqlProvider(); + } + + public override bool IsValueParameter(IDbDataParameter parameter) + { + return parameter.Direction != ParameterDirection.ReturnValue + && parameter.Direction != ParameterDirection.Output; + } + + private string GetInputParameterName(string ioParameterName) + { + return (string) Convert( + InOutInputParameterPrefix + (string) Convert(ioParameterName, ConvertType.SprocParameterToName), + ConvertType.NameToSprocParameter); + } + + private static IDbDataParameter GetParameter(string parameterName, IEnumerable commandParameters) + { + return commandParameters.FirstOrDefault(par => string.Compare(parameterName, par.ParameterName, true) == 0); + } + + private bool IsReturnValue(IDbDataParameter parameter) + { + if (string.Compare(parameter.ParameterName, + (string) Convert(ReturnParameterName, ConvertType.NameToSprocParameter), true) == 0 + ) + return true; + + return false; + } + + public override void PrepareCommand(ref CommandType commandType, ref string commandText, + ref IDbDataParameter[] commandParameters) + { + if (commandParameters != null) + foreach (var par in commandParameters) + { + if (par.Value is bool) + { + var value = (bool) par.Value ? "1" : "0"; + + par.DbType = DbType.AnsiString; + par.Value = value; + par.Size = value.Length; + } + else if (par.Value is Guid) + { + var value = par.Value.ToString(); + + par.DbType = DbType.AnsiStringFixedLength; + par.Value = value; + par.Size = value.Length; + } + + #region "smart" input-output parameter detection + if (commandType == CommandType.StoredProcedure && IsInOutParameterEmulation) + { + var iParameterName = GetInputParameterName(par.ParameterName); + var fakeIOParameter = GetParameter(iParameterName, commandParameters); + + if (fakeIOParameter != null) + { + fakeIOParameter.Value = par.Value; + + // direction should be output, or parameter mistmath for procedure exception + // would be thrown + par.Direction = ParameterDirection.Output; + + // direction should be Input + fakeIOParameter.Direction = ParameterDirection.Input; + } + } + #endregion + } + + base.PrepareCommand(ref commandType, ref commandText, ref commandParameters); + } + + public override bool InitParameter(IDbDataParameter parameter) + { + if (parameter.Value is bool) + { + var value = (bool) parameter.Value ? "1" : "0"; + + parameter.DbType = DbType.AnsiString; + parameter.Value = value; + parameter.Size = value.Length; + } + else if (parameter.Value is Guid) + { + var value = parameter.Value.ToString(); + + parameter.DbType = DbType.AnsiStringFixedLength; + parameter.Value = value; + parameter.Size = value.Length; + } + + return base.InitParameter(parameter); + } + + public override void Configure(NameValueCollection attributes) + { + var inOutInputParameterPrefix = attributes["InOutInputParameterPrefix"]; + if (inOutInputParameterPrefix != null) + InOutInputParameterPrefix = inOutInputParameterPrefix; + + var returnParameterName = attributes["ReturnParameterName"]; + if (returnParameterName != null) + ReturnParameterName = returnParameterName; + + var isReturnValueEmulation = attributes["IsReturnValueEmulation"]; + if (isReturnValueEmulation != null) + IsReturnValueEmulation = Common.Convert.ToBoolean(isReturnValueEmulation); + + var isInOutParameterEmulation = attributes["IsInOutParameterEmulation"]; + if (isInOutParameterEmulation != null) + IsInOutParameterEmulation = Common.Convert.ToBoolean(isInOutParameterEmulation); + + var quoteIdentifiers = attributes["QuoteIdentifiers"]; + if (quoteIdentifiers != null) + QuoteIdentifiers = Common.Convert.ToBoolean(quoteIdentifiers); + + base.Configure(attributes); + } + #endregion + + #region FbDataReaderEx + public override IDataReader GetDataReader(MappingSchema schema, IDataReader dataReader) + { + return + dataReader is FbDataReader + ? new FbDataReaderEx((FbDataReader) dataReader) + : base.GetDataReader(schema, dataReader); + } + + private class FbDataReaderEx : DataReaderBase, IDataReader + { + public FbDataReaderEx(FbDataReader rd) : base(rd) + { + } + + #region IDataReader Members + public new object GetValue(int i) + { + var value = DataReader.GetValue(i); + + if (value is DateTime) + { + var dt = (DateTime) value; + + if (dt.Year == 1970 && dt.Month == 1 && dt.Day == 1) + return new DateTime(1, 1, 1, dt.Hour, dt.Minute, dt.Second, dt.Millisecond); + } + + return value; + } + + public new DateTime GetDateTime(int i) + { + var dt = DataReader.GetDateTime(i); + + if (dt.Year == 1970 && dt.Month == 1 && dt.Day == 1) + return new DateTime(1, 1, 1, dt.Hour, dt.Minute, dt.Second, dt.Millisecond); + + return dt; + } + #endregion + } + #endregion + + #region FbMappingSchema + public class FbMappingSchema : FirebirdMappingSchema + { + protected override object MapInternal(InitContext initContext) + { + var dr = initContext.SourceObject as FbDataReader; + + // Fb's SP returns single row with nulls if selected object doesn't exists + // so for all DBNull's (null) should be returned, instead of object instance + // + if (dr != null) + { + var i = dr.FieldCount; + while (--i >= 0) + if (!dr.IsDBNull(i)) + break; + + // All field are DBNull. + // + if (i < 0) + return null; + } + return base.MapInternal(initContext); + } + } + #endregion + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/FirebirdMappingSchema.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/FirebirdMappingSchema.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,98 @@ +using System; + +namespace BLToolkit.Data.DataProvider +{ + using Mapping; + + public class FirebirdMappingSchema : MappingSchema + { + public byte[] ConvertToByteArray(string value) + { + return System.Text.Encoding.UTF8.GetBytes(value); + } + + public override byte[] ConvertToByteArray(object value) + { + if (value is string) + return ConvertToByteArray((string)value); + + return base.ConvertToByteArray(value); + } + + public bool ConvertToBoolean(string value) + { + if (value.Length == 1) + switch (value[0]) + { + case '1': case 'T' :case 'Y' : case 't': case 'y': return true; + case '0': case 'F' :case 'N' : case 'f': case 'n': return false; + } + + return Common.Convert.ToBoolean(value); + } + + public override bool ConvertToBoolean(object value) + { + if (value is string) + return ConvertToBoolean((string)value); + + return base.ConvertToBoolean(value); + } + + public System.IO.Stream ConvertToStream(string value) + { + return new System.IO.MemoryStream(ConvertToByteArray(value)); + } + + public override System.IO.Stream ConvertToStream(object value) + { + if (value is string) + return ConvertToStream((string)value); + + return base.ConvertToStream(value); + } + +#if !SILVERLIGHT + + public System.Data.SqlTypes.SqlBinary ConvertToSqlBinary(string value) + { + return Common.Convert.ToSqlBinary(ConvertToByteArray(value)); + } + + public override System.Data.SqlTypes.SqlBinary ConvertToSqlBinary(object value) + { + if (value is string) + return ConvertToSqlBinary((string)value); + return base.ConvertToSqlBinary(value); + } + + public System.Data.SqlTypes.SqlBytes ConvertToSqlBytes(string value) + { + return Common.Convert.ToSqlBytes(ConvertToByteArray(value)); + } + + public override System.Data.SqlTypes.SqlBytes ConvertToSqlBytes(object value) + { + if (value is string) + return ConvertToSqlBytes((string)value); + + return base.ConvertToSqlBytes(value); + } + + public override System.Data.SqlTypes.SqlGuid ConvertToSqlGuid(object value) + { + if (value is string) + return new System.Data.SqlTypes.SqlGuid(new Guid((string)value)); + return base.ConvertToSqlGuid(value); + } + +#endif + + public override bool? ConvertToNullableBoolean(object value) + { + if (value is string) + return ConvertToBoolean((string)value); + return base.ConvertToNullableBoolean(value); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/GenericDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/GenericDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,179 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Transactions; +using BLToolkit.Data.DataProvider.Interpreters; +using BLToolkit.Data.Sql.SqlProvider; + +namespace BLToolkit.Data.DataProvider +{ + /// + /// Creates an instance of a db provider for a specified provider name. + /// + public sealed class GenericDataProvider : DataProviderBase + { + private readonly string _providerName; + private readonly DbProviderFactory _factory; + private readonly DataProviderInterpreterBase _dataProviderInterpreter; + + public GenericDataProvider(string providerName) + { + _providerName = providerName; + using (new TransactionScope()) + { + _factory = DbProviderFactories.GetFactory(providerName); + } + + switch (Name) + { + case ProviderFullName.Oracle: + case ProviderFullName.OracleNet: + _dataProviderInterpreter = new OracleDataProviderInterpreter(); + break; + case ProviderFullName.SQLite: + _dataProviderInterpreter = new SqliteDataProviderInterpreter(); + break; + default: + throw new Exception(string.Format("The sql provider {0} isnt supported in the DataProviderInterpreterBase", Name)); + } + } + + #region Overrides of DataProviderBase + + public override Type ConnectionType + { + get + { + var dbConnection = _factory.CreateConnection(); + if (dbConnection != null) + return dbConnection.GetType(); + return null; + } + } + + public override string Name + { + get { return _providerName; } + } + + public override IDbConnection CreateConnectionObject() + { + return _factory.CreateConnection(); + } + + public override DbDataAdapter CreateDataAdapterObject() + { + return _factory.CreateDataAdapter(); + } + + /// + /// Populates the specified IDbCommand object's Parameters collection with + /// parameter information for the stored procedure specified in the IDbCommand. + /// + public override bool DeriveParameters(IDbCommand command) + { + return false; + } + + public override ISqlProvider CreateSqlProvider() + { + switch (Name) + { + case ProviderFullName.OracleNet: + return new OracleSqlProvider(); + case ProviderFullName.SQLite: + return new SQLiteSqlProvider(); + case ProviderFullName.Oracle: + return new OracleSqlProvider(); + default: + throw new Exception(string.Format("The sql provider {0} isnt supported in the GenericDataProvider", Name)); + } + } + + public override void SetParameterValue(IDbDataParameter parameter, object value) + { + _dataProviderInterpreter.SetParameterValue(parameter, value); + } + + public override string GetSequenceQuery(string sequenceName) + { + return _dataProviderInterpreter.GetSequenceQuery(sequenceName); + } + + public override string NextSequenceQuery(string sequenceName) + { + return _dataProviderInterpreter.NextSequenceQuery(sequenceName); + } + + public override string GetReturningInto(string columnName) + { + return _dataProviderInterpreter.GetReturningInto(columnName); + } + + public override object Convert(object value, ConvertType convertType) + { + if (Name == ProviderFullName.Oracle) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter: + var qname = (string) value; + + // + // Avoid "ORA-00972: identifier is too long" error + // Cause error : You tried to reference a table, cluster, view, index, synonym, tablespace, or username with a value that was longer than 30 characters. + // Resolution : Names for tables, clusters, views, indexes, synonyms, tablespaces, and usernames must be 30 characters or less. + // You must shorten the name to no more than 30 characters for these objects. + // + if (qname.Length > 30) + { + qname = qname.Substring(0, 30); + return SqlProvider.Convert(qname, convertType); + } + return SqlProvider.Convert(value, convertType); + } + } + + return base.Convert(value, convertType); + } + + public override int InsertBatchWithIdentity( + DbManager db, + string insertText, + IEnumerable collection, + Mapping.MemberMapper[] members, + int maxBatchSize, + DbManager.ParameterProvider getParameters) + { + if (db.UseQueryText && Name == ProviderFullName.Oracle) + { + List sqlList = _dataProviderInterpreter.GetInsertBatchSqlList(insertText, collection, members, maxBatchSize, true); + return ExecuteSqlList(db, sqlList); + } + return base.InsertBatchWithIdentity(db, insertText, collection, members, maxBatchSize, getParameters); + } + + public override int InsertBatch( + DbManager db, + string insertText, + IEnumerable collection, + Mapping.MemberMapper[] members, + int maxBatchSize, + DbManager.ParameterProvider getParameters) + { + if (Name == ProviderFullName.Oracle) + { + if (db.UseQueryText) + { + List sqlList = _dataProviderInterpreter.GetInsertBatchSqlList(insertText, collection, members, maxBatchSize, false); + return ExecuteSqlList(db, sqlList); + } + throw new NotSupportedException("Set UseQueryText = true on the current generic data provider!"); + } + return base.InsertBatch(db, insertText, collection, members, maxBatchSize, getParameters); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/InformixDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/InformixDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,159 @@ +using System; +using System.Data; +using System.Data.Common; +using System.Globalization; +using System.Threading; + +using IBM.Data.Informix; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + + public class InformixDataProvider : DataProviderBase + { + public override IDbConnection CreateConnectionObject () { return new IfxConnection (); } + public override DbDataAdapter CreateDataAdapterObject() { return new IfxDataAdapter (); } + public override ISqlProvider CreateSqlProvider () { return new InformixSqlProvider(); } + + public override Type ConnectionType { get { return typeof(IfxConnection); } } + public override string Name { get { return DataProvider.ProviderName.Informix; } } + + public override bool DeriveParameters(IDbCommand command) + { + if (command is IfxCommand) + { + IfxCommandBuilder.DeriveParameters((IfxCommand)command); + return true; + } + + return false; + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.ExceptionToErrorNumber: + if (value is IfxException) + { + var ex = (IfxException)value; + + foreach (IfxError error in ex.Errors) + return error.NativeError; + + return 0; + } + + break; + } + + return SqlProvider.Convert(value, convertType); + } + + public override void PrepareCommand(ref CommandType commandType, ref string commandText, ref IDbDataParameter[] commandParameters) + { + base.PrepareCommand(ref commandType, ref commandText, ref commandParameters); + + if (commandParameters != null) foreach (var p in commandParameters) + { + if (p.Value is Guid) + { + var value = p.Value.ToString(); + p.DbType = DbType.AnsiStringFixedLength; + p.Value = value; + p.Size = value.Length; + } + else if (p.Value is bool) + { + p.Value = ((InformixSqlProvider)SqlProvider).ConvertBooleanValue((bool)p.Value); + } + //else if (p.DbType == DbType.Binary) + //{ + // var ip = (IfxParameter)p; + + // ip.IfxType = IfxType.Blob; + //} + } + } + + /* + public override int ExecuteArray(IDbCommand command, int iterations) + { + var cmd = (IfxCommand)command; + try + { + cmd.ArrayBindCount = iterations; + return cmd.ExecuteNonQuery(); + } + finally + { + cmd.ArrayBindCount = 0; + } + } + */ + + #region GetDataReader + + public override IDataReader GetDataReader(Mapping.MappingSchema schema, IDataReader dataReader) + { + return dataReader is IfxDataReader? + new InformixDataReaderEx((IfxDataReader)dataReader): + base.GetDataReader(schema, dataReader); + } + + class InformixDataReaderEx : DataReaderBase, IDataReader + { + public InformixDataReaderEx(IfxDataReader rd): base(rd) + { + } + + public new float GetFloat(int i) + { + var current = Thread.CurrentThread.CurrentCulture; + + if (Thread.CurrentThread.CurrentCulture != CultureInfo.InvariantCulture) + Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; + + var value = DataReader.GetFloat(i); + + if (current != CultureInfo.InvariantCulture) + Thread.CurrentThread.CurrentCulture = current; + + return value; + } + + public new double GetDouble(int i) + { + var current = Thread.CurrentThread.CurrentCulture; + + if (Thread.CurrentThread.CurrentCulture != CultureInfo.InvariantCulture) + Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; + + var value = DataReader.GetDouble(i); + + if (current != CultureInfo.InvariantCulture) + Thread.CurrentThread.CurrentCulture = current; + + return value; + } + + public new decimal GetDecimal(int i) + { + var current = Thread.CurrentThread.CurrentCulture; + + if (Thread.CurrentThread.CurrentCulture != CultureInfo.InvariantCulture) + Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; + + var value = DataReader.GetDecimal (i); + + if (current != CultureInfo.InvariantCulture) + Thread.CurrentThread.CurrentCulture = current; + + return value; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/Interpreters/OracleDataProviderInterpreter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/Interpreters/OracleDataProviderInterpreter.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using BLToolkit.Data.Sql.SqlProvider; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace BLToolkit.Data.DataProvider.Interpreters +{ + public class OracleDataProviderInterpreter : DataProviderInterpreterBase + { + public override void SetParameterValue(IDbDataParameter parameter, object value) + { + if (value is TimeSpan) + { + parameter.Value = ((TimeSpan)value).ToString(); + } + else + base.SetParameterValue(parameter, value); + } + + public override List GetInsertBatchSqlList( + string insertText, + IEnumerable collection, + MemberMapper[] members, + int maxBatchSize, + bool withIdentity) + { + //return GetInsertBatchSqlListWithInsertAll(insertText, collection, members, maxBatchSize); + return GetInsertBatchSqlListUnionAll(insertText, collection, members, maxBatchSize, withIdentity); + } + + private List GetInsertBatchSqlListUnionAll( + string insertText, + IEnumerable collection, + MemberMapper[] members, + int maxBatchSize, + bool withIdentity) + { + var sp = new OracleSqlProvider(); + var n = 0; + var sqlList = new List(); + + var indexValuesWord = insertText.IndexOf(" VALUES (", StringComparison.Ordinal); + var initQuery = insertText.Substring(0, indexValuesWord) + Environment.NewLine; + var valuesQuery = insertText.Substring(indexValuesWord + 9); + var indexEndValuesQuery = valuesQuery.IndexOf(")"); + valuesQuery = valuesQuery.Substring(0, indexEndValuesQuery) + .Replace("\r", "") + .Replace("\n", "") + .Replace("\t", ""); + + // 1 = Number of primary keys generated by sequence + var valuesWihtoutSequence = withIdentity ? valuesQuery.Substring(valuesQuery.IndexOf(",") + 1) : valuesQuery; + + var sb = new StringBuilder(initQuery); + sb.Append(" SELECT "); + sb.AppendFormat(valuesQuery, members.Select(m => m.Name).ToArray()); + sb.AppendLine(" FROM ("); + + initQuery = sb.ToString(); + + sb = new StringBuilder(initQuery); + bool isFirstValues = true; + + foreach (var item in collection) + { + if (!isFirstValues) + sb.AppendLine(" UNION ALL "); + + sb.Append("SELECT "); + + var values = new List(); + foreach (var member in members) + { + var sbItem = new StringBuilder(); + + var value = member.GetValue(item); + + if (value is DateTime?) + value = ((DateTime?)value).Value; + + sp.BuildValue(sbItem, value); + + values.Add(sbItem + " " + member.Name); + } + + sb.AppendFormat(valuesWihtoutSequence, values.ToArray()); + sb.Append(" FROM DUAL"); + + isFirstValues = false; + + n++; + if (n > maxBatchSize) + { + sb.Append(")"); + sqlList.Add(sb.ToString()); + sb = new StringBuilder(initQuery); + isFirstValues = true; + n = 0; + } + } + + if (n > 0) + { + sb.Append(")"); + sqlList.Add(sb.ToString()); + } + return sqlList; + } + + private List GetInsertBatchSqlListWithInsertAll( + string insertText, + IEnumerable collection, + MemberMapper[] members, + int maxBatchSize) + { + var sb = new StringBuilder(); + var sp = new OracleSqlProvider(); + var n = 0; + var sqlList = new List(); + + foreach (var item in collection) + { + if (sb.Length == 0) + sb.AppendLine("INSERT ALL"); + + string strItem = "\t" + insertText + .Replace("INSERT INTO", "INTO") + .Replace("\r", "") + .Replace("\n", "") + .Replace("\t", " ") + .Replace("( ", "("); + + var values = new List(); + foreach (var member in members) + { + var sbItem = new StringBuilder(); + + var keyGenerator = member.MapMemberInfo.KeyGenerator as SequenceKeyGenerator; + if (keyGenerator != null) + { + values.Add(NextSequenceQuery(keyGenerator.Sequence)); + } + else + { + var value = member.GetValue(item); + + if (value is DateTime?) + value = ((DateTime?)value).Value; + + sp.BuildValue(sbItem, value); + + values.Add(sbItem.ToString()); + } + } + + sb.AppendFormat(strItem, values.ToArray()); + sb.AppendLine(); + + n++; + + if (n >= maxBatchSize) + { + sb.AppendLine("SELECT * FROM dual"); + + var sql = sb.ToString(); + sqlList.Add(sql); + + n = 0; + sb.Length = 0; + } + } + + if (n > 0) + { + sb.AppendLine("SELECT * FROM dual"); + + var sql = sb.ToString(); + sqlList.Add(sql); + } + + return sqlList; + } + + public override string GetSequenceQuery(string sequenceName) + { + return string.Format("SELECT {0}.NEXTVAL FROM DUAL", sequenceName); + } + + public override string NextSequenceQuery(string sequenceName) + { + return string.Format("{0}.NEXTVAL", sequenceName); + } + + public override string GetReturningInto(string columnName) + { + return string.Format("returning {0} into :IDENTITY_PARAMETER", columnName); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/Interpreters/SqliteDataProviderInterpreter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/Interpreters/SqliteDataProviderInterpreter.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +using System.Data; + +namespace BLToolkit.Data.DataProvider.Interpreters +{ + public class SqliteDataProviderInterpreter : DataProviderInterpreterBase + { + public override void SetParameterValue(IDbDataParameter parameter, object value) + { + if (parameter.DbType == DbType.DateTime2) + parameter.DbType = DbType.DateTime; + + base.SetParameterValue(parameter, value); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/MonoSqliteDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/MonoSqliteDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,169 @@ +using System; +using System.Data; +using System.Data.Common; +using System.Diagnostics; +using System.Text; +using System.Xml; + +// System.Data.SQLite.dll must be referenced. +// http://sqlite.phxsoftware.com/ +// +using Mono.Data.Sqlite; + +namespace BLToolkit.Data.DataProvider +{ + /// + /// Implements access to the Data Provider for SQLite. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + public sealed class SQLiteDataProvider: DataProviderBase + { + /// + /// Creates the database connection object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The database connection object. + public override IDbConnection CreateConnectionObject() + { + return new SqliteConnection(); + } + + /// + /// Creates the data adapter object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// A data adapter object. + public override DbDataAdapter CreateDataAdapterObject() + { + return new SqliteDataAdapter(); + } + + /// + /// Populates the specified IDbCommand object's Parameters collection with + /// parameter information for the stored procedure specified in the IDbCommand. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The IDbCommand referencing the stored procedure for which the parameter information is to be derived. The derived parameters will be populated into the Parameters of this command. + public override bool DeriveParameters(IDbCommand command) + { + // SQLiteCommandBuilder does not implement DeriveParameters. + // This is not surprising, since SQLite has no support for stored procs. + // + return false; + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter: + case ConvertType.NameToParameter: + return "@" + value; + + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryTable: + { + string name = (string)value; + + if (name.Length > 0 && name[0] == '[') + return value; + + if (name.IndexOf('.') > 0) + value = string.Join("].[", name.Split('.')); + + return "[" + value + "]"; + } + + case ConvertType.ParameterToName: + { + string name = (string)value; + return name.Length > 0 && name[0] == '@'? name.Substring(1): name; + } + + case ConvertType.ExceptionToErrorNumber: + { + if (value is SqliteException) + return ((SqliteException)value).ErrorCode; + break; + } + } + + return value; + } + + public override void AttachParameter(IDbCommand command, IDbDataParameter parameter) + { + if (parameter.Direction == ParameterDirection.Input || parameter.Direction == ParameterDirection.InputOutput) + { + if (parameter.Value is XmlDocument) + { + parameter.Value = Encoding.UTF8.GetBytes(((XmlDocument) parameter.Value).InnerXml); + parameter.DbType = DbType.Binary; + } + } + + base.AttachParameter(command, parameter); + } + + /// + /// Returns connection type. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// An instance of the class. + public override Type ConnectionType + { + get { return typeof(SqliteConnection); } + } + + /// + /// Returns the data provider name. + /// + /// + /// See the method to find an example. + /// + /// AddDataProvider Method + /// Data provider name. + public override string Name + { + get { return "SQLite"; } + } + + public class SQLiteMappingSchema : Mapping.MappingSchema + { + #region Convert + + public override XmlReader ConvertToXmlReader(object value) + { + if (value is byte[]) + value = Encoding.UTF8.GetString((byte[])value); + + return base.ConvertToXmlReader(value); + } + + public override XmlDocument ConvertToXmlDocument(object value) + { + if (value is byte[]) + value = Encoding.UTF8.GetString((byte[])value); + + return base.ConvertToXmlDocument(value); + } + + #endregion + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/MySqlDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/MySqlDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,226 @@ +// MySql Connector/Net +// http://dev.mysql.com/downloads/connector/net/ +// +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; + +using MySql.Data.MySqlClient; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + using Common; + + public class MySqlDataProvider : DataProviderBase + { + #region Static configuration + + public static char ParameterSymbol + { + get { return MySqlSqlProvider.ParameterSymbol; } + set { MySqlSqlProvider.ParameterSymbol = value; } + } + + public static bool TryConvertParameterSymbol + { + get { return MySqlSqlProvider.TryConvertParameterSymbol; } + set { MySqlSqlProvider.TryConvertParameterSymbol = value; } + } + + public static string CommandParameterPrefix + { + get { return MySqlSqlProvider.CommandParameterPrefix; } + set { MySqlSqlProvider.CommandParameterPrefix = value; } + } + + public static string SprocParameterPrefix + { + get { return MySqlSqlProvider.SprocParameterPrefix; } + set { MySqlSqlProvider.SprocParameterPrefix = value; } + } + + public static List ConvertParameterSymbols + { + get { return MySqlSqlProvider.ConvertParameterSymbols; } + set { MySqlSqlProvider.ConvertParameterSymbols = value; } + } + + [Obsolete("Use CommandParameterPrefix or SprocParameterPrefix instead.")] + public static string ParameterPrefix + { + get { return MySqlSqlProvider.SprocParameterPrefix; } + set { SprocParameterPrefix = CommandParameterPrefix = string.IsNullOrEmpty(value) ? string.Empty : value; } + } + + public static void ConfigureOldStyle() + { + ParameterSymbol = '?'; + ConvertParameterSymbols = new List(new[] { '@' }); + TryConvertParameterSymbol = true; + } + + public static void ConfigureNewStyle() + { + ParameterSymbol = '@'; + ConvertParameterSymbols = null; + TryConvertParameterSymbol = false; + } + + static MySqlDataProvider() + { + ConfigureOldStyle(); + } + + #endregion + + public override IDbConnection CreateConnectionObject() + { + return new MySqlConnection(); + } + + public override DbDataAdapter CreateDataAdapterObject() + { + return new MySqlDataAdapter(); + } + + private void ConvertParameterNames(IDbCommand command) + { + foreach (IDataParameter p in command.Parameters) + { + if (p.ParameterName[0] != ParameterSymbol) + p.ParameterName = + Convert( + Convert(p.ParameterName, ConvertType.SprocParameterToName), + command.CommandType == CommandType.StoredProcedure ? ConvertType.NameToSprocParameter : ConvertType.NameToCommandParameter).ToString(); + } + } + + public override bool DeriveParameters(IDbCommand command) + { + if (command is MySqlCommand) + { + MySqlCommandBuilder.DeriveParameters((MySqlCommand)command); + + if (TryConvertParameterSymbol && ConvertParameterSymbols.Count > 0) + ConvertParameterNames(command); + + return true; + } + + return false; + } + + public override IDbDataParameter GetParameter( + IDbCommand command, + NameOrIndexParameter nameOrIndex) + { + if (nameOrIndex.ByName) + { + // if we have a stored procedure, then maybe command paramaters were formatted + // (SprocParameterPrefix added). In this case we need to format given parameter name first + // and only then try to take parameter by formatted parameter name + var parameterName = command.CommandType == CommandType.StoredProcedure + ? Convert(nameOrIndex.Name, ConvertType.NameToSprocParameter).ToString() + : nameOrIndex.Name; + + return (IDbDataParameter)(command.Parameters[parameterName]); + } + return (IDbDataParameter)(command.Parameters[nameOrIndex.Index]); + } + + public override object Convert(object value, ConvertType convertType) + { + if (value == null) + throw new ArgumentNullException("value"); + + switch (convertType) + { + case ConvertType.ExceptionToErrorNumber: + if (value is MySqlException) + return ((MySqlException)value).Number; + break; + + case ConvertType.ExceptionToErrorMessage: + if (value is MySqlException) + return ((MySqlException)value).Message; + break; + } + + return SqlProvider.Convert(value, convertType); + } + + public override DataExceptionType ConvertErrorNumberToDataExceptionType(int number) + { + switch (number) + { + case 1213: return DataExceptionType.Deadlock; + case 1205: return DataExceptionType.Timeout; + case 1216: + case 1217: return DataExceptionType.ForeignKeyViolation; + case 1169: return DataExceptionType.UniqueIndexViolation; + } + + return DataExceptionType.Undefined; + } + + public override Type ConnectionType + { + get { return typeof(MySqlConnection); } + } + + public override string Name + { + get { return DataProvider.ProviderName.MySql; } + } + + public override ISqlProvider CreateSqlProvider() + { + return new MySqlSqlProvider(); + } + + public override void Configure(System.Collections.Specialized.NameValueCollection attributes) + { + var paremeterPrefix = attributes["ParameterPrefix"]; + if (paremeterPrefix != null) + CommandParameterPrefix = SprocParameterPrefix = paremeterPrefix; + + paremeterPrefix = attributes["CommandParameterPrefix"]; + if (paremeterPrefix != null) + CommandParameterPrefix = paremeterPrefix; + + paremeterPrefix = attributes["SprocParameterPrefix"]; + if (paremeterPrefix != null) + SprocParameterPrefix = paremeterPrefix; + + var configName = attributes["ParameterSymbolConfig"]; + if (configName != null) + { + switch (configName) + { + case "OldStyle": + ConfigureOldStyle(); + break; + case "NewStyle": + ConfigureNewStyle(); + break; + } + } + + var parameterSymbol = attributes["ParameterSymbol"]; + if (parameterSymbol != null && parameterSymbol.Length == 1) + ParameterSymbol = parameterSymbol[0]; + + var convertParameterSymbols = attributes["ConvertParameterSymbols"]; + if (convertParameterSymbols != null) + ConvertParameterSymbols = new List(convertParameterSymbols.ToCharArray()); + + var tryConvertParameterSymbol = attributes["TryConvertParameterSymbol"]; + if (tryConvertParameterSymbol != null) + TryConvertParameterSymbol = BLToolkit.Common.Convert.ToBoolean(tryConvertParameterSymbol); + + base.Configure(attributes); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/OdbcDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/OdbcDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,112 @@ +using System; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + + /// + /// Implements access to the Data Provider for ODBC. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + public class OdbcDataProvider : DataProviderBase + { + /// + /// Creates the database connection object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The database connection object. + public override IDbConnection CreateConnectionObject() + { + return new OdbcConnection(); + } + + /// + /// Creates the data adapter object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// A data adapter object. + public override DbDataAdapter CreateDataAdapterObject() + { + return new OdbcDataAdapter(); + } + + /// + /// Populates the specified object's Parameters collection with + /// parameter information for the stored procedure specified in the . + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The referencing the stored procedure for which the parameter + /// information is to be derived. The derived parameters will be populated into + /// the Parameters of this command. + public override bool DeriveParameters(IDbCommand command) + { + OdbcCommandBuilder.DeriveParameters((OdbcCommand)command); + return true; + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.ExceptionToErrorNumber: + if (value is OdbcException) + { + var ex = (OdbcException)value; + if (ex.Errors.Count > 0) + return ex.Errors[0].NativeError; + } + break; + } + + return base.Convert(value, convertType); + } + + public override ISqlProvider CreateSqlProvider() + { + throw new NotSupportedException(); + } + + /// + /// Returns connection type. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// An instance of the class. + public override Type ConnectionType + { + get { return typeof(OdbcConnection); } + } + + public const string NameString = DataProvider.ProviderName.Odbc; + + /// + /// Returns the data provider name. + /// + /// + /// See the method to find an example. + /// + /// AddDataProvider Method + /// Data provider name. + public override string Name + { + get { return NameString; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/OdpDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/OdpDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1708 @@ +// Odp.Net Data Provider. +// http://www.oracle.com/technology/tech/windows/odpnet/index.html +// +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Xml; + +using BLToolkit.Aspects; +using BLToolkit.Common; +using BLToolkit.Mapping; +using BLToolkit.Reflection; + +#if MANAGED +using Oracle.ManagedDataAccess.Client; +using Oracle.ManagedDataAccess.Types; +#else +using Oracle.DataAccess.Client; +using Oracle.DataAccess.Types; +#endif + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + using BLToolkit.Data.Sql; + + /// + /// Implements access to the Data Provider for Oracle. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method +#if !MANAGED + public class OdpDataProvider : DataProviderBase + { + public OdpDataProvider() + { + MappingSchema = new OdpMappingSchema(); + } + + public const string NameString = DataProvider.ProviderName.Oracle; + + private const string DbTypeTableName = "Oracle.DataAccess.Client.OraDb_DbTypeTable"; + + static OdpDataProvider() + { +#else + public class OdpManagedDataProvider : DataProviderBase + { + public OdpManagedDataProvider() + { + MappingSchema = new OdpMappingSchema(); + } + + public const string NameString = DataProvider.ProviderName.OracleManaged; + + private const string DbTypeTableName = "Oracle.ManagedDataAccess.Client.OraDb_DbTypeTable"; + + static OdpManagedDataProvider() + { +#endif + // Fix Oracle.Net bug #1: Array types are not handled. + // + var oraDbDbTypeTableType = typeof(OracleParameter).Assembly.GetType(DbTypeTableName); + + if (null != oraDbDbTypeTableType) + { + var typeTable = (Hashtable)oraDbDbTypeTableType.InvokeMember( + "s_table", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField, + null, null, Type.EmptyTypes); + + if (null != typeTable) + { + typeTable[typeof(DateTime[])] = OracleDbType.TimeStamp; + typeTable[typeof(Int16[])] = OracleDbType.Int16; + typeTable[typeof(Int32[])] = OracleDbType.Int32; + typeTable[typeof(Int64[])] = OracleDbType.Int64; + typeTable[typeof(Single[])] = OracleDbType.Single; + typeTable[typeof(Double[])] = OracleDbType.Double; + typeTable[typeof(Decimal[])] = OracleDbType.Decimal; + typeTable[typeof(TimeSpan[])] = OracleDbType.IntervalDS; + typeTable[typeof(String[])] = OracleDbType.Varchar2; + typeTable[typeof(OracleBFile[])] = OracleDbType.BFile; + typeTable[typeof(OracleBinary[])] = OracleDbType.Raw; + typeTable[typeof(OracleBlob[])] = OracleDbType.Blob; + typeTable[typeof(OracleClob[])] = OracleDbType.Clob; + typeTable[typeof(OracleDate[])] = OracleDbType.Date; + typeTable[typeof(OracleDecimal[])] = OracleDbType.Decimal; + typeTable[typeof(OracleIntervalDS[])] = OracleDbType.IntervalDS; + typeTable[typeof(OracleIntervalYM[])] = OracleDbType.IntervalYM; + typeTable[typeof(OracleRefCursor[])] = OracleDbType.RefCursor; + typeTable[typeof(OracleString[])] = OracleDbType.Varchar2; + typeTable[typeof(OracleTimeStamp[])] = OracleDbType.TimeStamp; + typeTable[typeof(OracleTimeStampLTZ[])]= OracleDbType.TimeStampLTZ; + typeTable[typeof(OracleTimeStampTZ[])] = OracleDbType.TimeStampTZ; +#if !MANAGED + typeTable[typeof(OracleXmlType[])] = OracleDbType.XmlType; +#endif + + typeTable[typeof(Boolean)] = OracleDbType.Byte; + typeTable[typeof(Guid)] = OracleDbType.Raw; + typeTable[typeof(SByte)] = OracleDbType.Decimal; + typeTable[typeof(UInt16)] = OracleDbType.Decimal; + typeTable[typeof(UInt32)] = OracleDbType.Decimal; + typeTable[typeof(UInt64)] = OracleDbType.Decimal; + + typeTable[typeof(Boolean[])] = OracleDbType.Byte; + typeTable[typeof(Guid[])] = OracleDbType.Raw; + typeTable[typeof(SByte[])] = OracleDbType.Decimal; + typeTable[typeof(UInt16[])] = OracleDbType.Decimal; + typeTable[typeof(UInt32[])] = OracleDbType.Decimal; + typeTable[typeof(UInt64[])] = OracleDbType.Decimal; + + typeTable[typeof(Boolean?)] = OracleDbType.Byte; + typeTable[typeof(Guid?)] = OracleDbType.Raw; + typeTable[typeof(SByte?)] = OracleDbType.Decimal; + typeTable[typeof(UInt16?)] = OracleDbType.Decimal; + typeTable[typeof(UInt32?)] = OracleDbType.Decimal; + typeTable[typeof(UInt64?)] = OracleDbType.Decimal; + typeTable[typeof(DateTime?[])] = OracleDbType.TimeStamp; + typeTable[typeof(Int16?[])] = OracleDbType.Int16; + typeTable[typeof(Int32?[])] = OracleDbType.Int32; + typeTable[typeof(Int64?[])] = OracleDbType.Int64; + typeTable[typeof(Single?[])] = OracleDbType.Single; + typeTable[typeof(Double?[])] = OracleDbType.Double; + typeTable[typeof(Decimal?[])] = OracleDbType.Decimal; + typeTable[typeof(TimeSpan?[])] = OracleDbType.IntervalDS; + typeTable[typeof(Boolean?[])] = OracleDbType.Byte; + typeTable[typeof(Guid?[])] = OracleDbType.Raw; + typeTable[typeof(SByte?[])] = OracleDbType.Decimal; + typeTable[typeof(UInt16?[])] = OracleDbType.Decimal; + typeTable[typeof(UInt32?[])] = OracleDbType.Decimal; + typeTable[typeof(UInt64?[])] = OracleDbType.Decimal; + + typeTable[typeof(XmlReader)] = OracleDbType.XmlType; + typeTable[typeof(XmlDocument)] = OracleDbType.XmlType; + typeTable[typeof(MemoryStream)] = OracleDbType.Blob; + typeTable[typeof(XmlReader[])] = OracleDbType.XmlType; + typeTable[typeof(XmlDocument[])] = OracleDbType.XmlType; + typeTable[typeof(MemoryStream[])] = OracleDbType.Blob; + } + } + } + + /// + /// Creates the database connection object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The database connection object. + public override IDbConnection CreateConnectionObject() + { + return new OracleConnection(); + } + + public override IDbCommand CreateCommandObject(IDbConnection connection) + { + var oraConnection = connection as OracleConnection; + + if (null != oraConnection) + { + var oraCommand = oraConnection.CreateCommand(); + + // Fix Oracle.Net bug #2: Empty arrays can not be sent to the server. + // + oraCommand.BindByName = true; + + return oraCommand; + } + + return base.CreateCommandObject(connection); + } + + public override void SetParameterValue(IDbDataParameter parameter, object value) + { + base.SetParameterValue(parameter, value); + + // strings and byte arrays larger than 4000 bytes may be handled improperly + if (parameter is OracleParameterWrap) + { + const int ThresholdSize = 4000; + if (value is string && Encoding.UTF8.GetBytes((string)value).Length > ThresholdSize) + { + ((OracleParameterWrap)parameter).OracleParameter.OracleDbType = OracleDbType.Clob; + } + else if (value is byte[] && ((byte[])value).Length > ThresholdSize) + { + ((OracleParameterWrap)parameter).OracleParameter.OracleDbType = OracleDbType.Blob; + } + } + } + + public override IDbDataParameter CloneParameter(IDbDataParameter parameter) + { + var oraParameter = (parameter is OracleParameterWrap)? + (parameter as OracleParameterWrap).OracleParameter: parameter as OracleParameter; + + if (null != oraParameter) + { + var oraParameterClone = (OracleParameter)oraParameter.Clone(); + + // Fix Oracle.Net bug #3: CollectionType property is not cloned. + // + oraParameterClone.CollectionType = oraParameter.CollectionType; + + // Fix Oracle.Net bug #8423178 + // See http://forums.oracle.com/forums/thread.jspa?threadID=975902&tstart=0 + // + if (oraParameterClone.OracleDbType == OracleDbType.RefCursor) + { + // Set OracleDbType to itself to reset m_bSetDbType and m_bOracleDbTypeExSet + // + oraParameterClone.OracleDbType = OracleDbType.RefCursor; + } + + return OracleParameterWrap.CreateInstance(oraParameterClone); + } + + return base.CloneParameter(parameter); + } + + public override void SetUserDefinedType(IDbDataParameter parameter, string typeName) + { + var oraParameter = (parameter is OracleParameterWrap) ? + (parameter as OracleParameterWrap).OracleParameter : parameter as OracleParameter; + + if (oraParameter == null) + throw new ArgumentException("OracleParameter expected.", "parameter"); + + oraParameter.UdtTypeName = typeName; + } + + /// + /// Creates the data adapter object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// A data adapter object. + public override DbDataAdapter CreateDataAdapterObject() + { + return new OracleDataAdapter(); + } + + /// + /// Populates the specified IDbCommand object's Parameters collection with + /// parameter information for the stored procedure specified in the IDbCommand. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The IDbCommand referencing the stored procedure for which the parameter + /// information is to be derived. The derived parameters will be populated into + /// the Parameters of this command. + public override bool DeriveParameters(IDbCommand command) + { + var oraCommand = command as OracleCommand; + + if (null != oraCommand) + { + try + { + OracleCommandBuilder.DeriveParameters(oraCommand); + } + catch (Exception ex) + { + // Make Oracle less laconic. + // + throw new DataException(string.Format("{0}\nCommandText: {1}", ex.Message, oraCommand.CommandText), ex); + } + + return true; + } + + return false; + } + + /// + /// Open an into the given object + /// + /// an to perform GetDataReader() on + /// The into the returned by GetDataReader() + public override IDataReader GetRefCursorDataReader(object refCursor) + { + var oracleRefCursor = refCursor as OracleRefCursor; + + if (oracleRefCursor == null) + throw new ArgumentException("Argument must be of type 'OracleRefCursor'", "refCursor"); + + return oracleRefCursor.GetDataReader(); + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return ParameterPrefix == null? value: ParameterPrefix + value; + + case ConvertType.SprocParameterToName: + var name = (string)value; + + if (name.Length > 0) + { + if (name[0] == ':') + return name.Substring(1); + + if (ParameterPrefix != null && + name.ToUpper(CultureInfo.InvariantCulture).StartsWith(ParameterPrefix)) + { + return name.Substring(ParameterPrefix.Length); + } + } + + break; + + case ConvertType.ExceptionToErrorNumber: + if (value is OracleException) + return ((OracleException)value).Number; + break; + } + + return SqlProvider.Convert(value, convertType); + } + + public override void PrepareCommand(ref CommandType commandType, ref string commandText, ref IDbDataParameter[] commandParameters) + { + base.PrepareCommand(ref commandType, ref commandText, ref commandParameters); + + if (commandType == CommandType.Text) + { + // Fix Oracle bug #11 '\r' is not a valid character! + // + commandText = commandText.Replace('\r', ' '); + } + } + + public override void AttachParameter(IDbCommand command, IDbDataParameter parameter) + { + var oraParameter = (parameter is OracleParameterWrap)? + (parameter as OracleParameterWrap).OracleParameter: parameter as OracleParameter; + + if (null != oraParameter) + { + if (oraParameter.CollectionType == OracleCollectionType.PLSQLAssociativeArray) + { + if (oraParameter.Direction == ParameterDirection.Input + || oraParameter.Direction == ParameterDirection.InputOutput) + { + var ar = oraParameter.Value as Array; + + if (null != ar && !(ar is byte[] || ar is char[])) + { + oraParameter.Size = ar.Length; + + if (oraParameter.DbType == DbType.String + && oraParameter.Direction == ParameterDirection.InputOutput) + { + var arrayBindSize = new int[oraParameter.Size]; + + for (var i = 0; i < oraParameter.Size; ++i) + { + arrayBindSize[i] = 1024; + } + + oraParameter.ArrayBindSize = arrayBindSize; + } + } + + if (oraParameter.Size == 0) + { + // Skip this parameter. + // Fix Oracle.Net bug #2: Empty arrays can not be sent to the server. + // + return; + } + + if (oraParameter.Value is Stream[]) + { + var streams = (Stream[]) oraParameter.Value; + + for (var i = 0; i < oraParameter.Size; ++i) + { + if (streams[i] is OracleBFile || streams[i] is OracleBlob || streams[i] is OracleClob +#if !MANAGED + || streams[i] is OracleXmlStream +#endif + ) + { + // Known Oracle type. + // + continue; + } + + streams[i] = CopyStream(streams[i], (OracleCommand)command); + } + } + else if (oraParameter.Value is XmlDocument[]) + { + var xmlDocuments = (XmlDocument[]) oraParameter.Value; + var values = new object[oraParameter.Size]; + + switch (oraParameter.OracleDbType) + { + case OracleDbType.XmlType: +#if !MANAGED + for (var i = 0; i < oraParameter.Size; ++i) + { + values[i] = xmlDocuments[i].DocumentElement == null? + (object) DBNull.Value: + new OracleXmlType((OracleConnection)command.Connection, xmlDocuments[i]); + } + + oraParameter.Value = values; + break; +#else + throw new NotSupportedException(); +#endif + // Fix Oracle.Net bug #9: XmlDocument.ToString() returns System.Xml.XmlDocument, + // so m_value.ToString() is not enought. + // + case OracleDbType.Clob: + case OracleDbType.NClob: + case OracleDbType.Varchar2: + case OracleDbType.NVarchar2: + case OracleDbType.Char: + case OracleDbType.NChar: + for (var i = 0; i < oraParameter.Size; ++i) + { + values[i] = xmlDocuments[i].DocumentElement == null? + (object) DBNull.Value: + xmlDocuments[i].InnerXml; + } + + oraParameter.Value = values; + + break; + + // Or convert to bytes if need. + // + case OracleDbType.Blob: + case OracleDbType.BFile: + case OracleDbType.Raw: + case OracleDbType.Long: + case OracleDbType.LongRaw: + for (var i = 0; i < oraParameter.Size; ++i) + { + if (xmlDocuments[i].DocumentElement == null) + values[i] = DBNull.Value; + else + using (var s = new MemoryStream()) + { + xmlDocuments[i].Save(s); + values[i] = s.GetBuffer(); + } + } + + oraParameter.Value = values; + + break; + } + } + } + else if (oraParameter.Direction == ParameterDirection.Output) + { + // Fix Oracle.Net bug #4: ArrayBindSize must be explicitly specified. + // + if (oraParameter.DbType == DbType.String) + { + oraParameter.Size = 1024; + var arrayBindSize = new int[oraParameter.Size]; + for (var i = 0; i < oraParameter.Size; ++i) + { + arrayBindSize[i] = 1024; + } + + oraParameter.ArrayBindSize = arrayBindSize; + } + else + { + oraParameter.Size = 32767; + } + } + } + else if (oraParameter.Value is Stream) + { + var stream = (Stream) oraParameter.Value; + + if (!(stream is OracleBFile) && !(stream is OracleBlob) && + !(stream is OracleClob) +#if !MANAGED + && !(stream is OracleXmlStream) +#endif + ) + { + oraParameter.Value = CopyStream(stream, (OracleCommand)command); + } + } + else if (oraParameter.Value is Byte[]) + { + var bytes = (Byte[]) oraParameter.Value; + + if (bytes.Length > 32000) + { + oraParameter.Value = CopyStream(bytes, (OracleCommand)command); + } + } + else if (oraParameter.Value is XmlDocument) + { + var xmlDocument = (XmlDocument)oraParameter.Value; + if (xmlDocument.DocumentElement == null) + oraParameter.Value = DBNull.Value; + else + { + + switch (oraParameter.OracleDbType) + { + case OracleDbType.XmlType: +#if !MANAGED + oraParameter.Value = new OracleXmlType((OracleConnection)command.Connection, xmlDocument); + break; +#else + throw new NotSupportedException(); +#endif + + // Fix Oracle.Net bug #9: XmlDocument.ToString() returns System.Xml.XmlDocument, + // so m_value.ToString() is not enought. + // + case OracleDbType.Clob: + case OracleDbType.NClob: + case OracleDbType.Varchar2: + case OracleDbType.NVarchar2: + case OracleDbType.Char: + case OracleDbType.NChar: + using (TextWriter w = new StringWriter()) + { + xmlDocument.Save(w); + oraParameter.Value = w.ToString(); + } + break; + + // Or convert to bytes if need. + // + case OracleDbType.Blob: + case OracleDbType.BFile: + case OracleDbType.Raw: + case OracleDbType.Long: + case OracleDbType.LongRaw: + using (var s = new MemoryStream()) + { + xmlDocument.Save(s); + oraParameter.Value = s.GetBuffer(); + } + break; + } + } + } + + parameter = oraParameter; + } + + base.AttachParameter(command, parameter); + } + + private static Stream CopyStream(Stream stream, OracleCommand cmd) + { + return CopyStream(Common.Convert.ToByteArray(stream), cmd); + } + + private static Stream CopyStream(Byte[] bytes, OracleCommand cmd) + { + var ret = new OracleBlob(cmd.Connection); + ret.Write(bytes, 0, bytes.Length); + return ret; + } + + public override bool IsValueParameter(IDbDataParameter parameter) + { + var oraParameter = (parameter is OracleParameterWrap)? + (parameter as OracleParameterWrap).OracleParameter: parameter as OracleParameter; + + if (null != oraParameter) + { + if (oraParameter.OracleDbType == OracleDbType.RefCursor + && oraParameter.Direction == ParameterDirection.Output) + { + // Ignore out ref cursors, while out parameters of other types are o.k. + return false; + } + } + + return base.IsValueParameter(parameter); + } + + public override IDbDataParameter CreateParameterObject(IDbCommand command) + { + var parameter = base.CreateParameterObject(command); + + if (parameter is OracleParameter) + parameter = OracleParameterWrap.CreateInstance(parameter as OracleParameter); + + return parameter; + } + + public override IDbDataParameter GetParameter(IDbCommand command, NameOrIndexParameter nameOrIndex) + { + var parameter = base.GetParameter(command, nameOrIndex); + + if (parameter is OracleParameter) + parameter = OracleParameterWrap.CreateInstance(parameter as OracleParameter); + + return parameter; + } + + /// + /// Returns connection type. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// An instance of the class. + public override Type ConnectionType + { + get { return typeof(OracleConnection); } + } + + /// + /// Returns the data provider name. + /// + /// + /// See the method to find an example. + /// + /// AddDataProvider Method + /// Data provider name. + public override string Name + { + get { return NameString; } + } + + public override int MaxBatchSize + { + get { return 0; } + } + + public override int ExecuteArray(IDbCommand command, int iterations) + { + var cmd = (OracleCommand)command; + var oracleParameters = cmd.Parameters.OfType().ToArray(); + var oldCollectionTypes = oracleParameters.Select(p => p.CollectionType).ToArray(); + + try + { + foreach (var p in oracleParameters) + { + p.CollectionType = OracleCollectionType.None; + } + + cmd.ArrayBindCount = iterations; + return cmd.ExecuteNonQuery(); + } + finally + { + foreach (var p in oracleParameters.Zip(oldCollectionTypes, (p, t) => new { Param = p, CollectionType = t })) + { + p.Param.CollectionType = p.CollectionType; + } + + cmd.ArrayBindCount = 0; + } + } + + public override ISqlProvider CreateSqlProvider() + { + return new OracleSqlProvider(); + } + + public override IDataReader GetDataReader(MappingSchema schema, IDataReader dataReader) + { + return dataReader is OracleDataReader ? + new OracleDataReaderEx((OracleDataReader)dataReader) : + base.GetDataReader(schema, dataReader); + } + + class OracleDataReaderEx: DataReaderEx + { + public OracleDataReaderEx(OracleDataReader rd) + : base(rd) + { + } + + public override DateTimeOffset GetDateTimeOffset(int i) + { + var ts = DataReader.GetOracleTimeStampTZ(i); + return new DateTimeOffset(ts.Value, ts.GetTimeZoneOffset()); + } + } + + private string _parameterPrefix = "P"; + public string ParameterPrefix + { + get { return _parameterPrefix; } + set + { + _parameterPrefix = string.IsNullOrEmpty(value)? null: + value.ToUpper(CultureInfo.InvariantCulture); + } + } + + /// + /// One time initialization from a configuration file. + /// + /// Provider specific attributes. + public override void Configure(System.Collections.Specialized.NameValueCollection attributes) + { + var val = attributes["ParameterPrefix"]; + if (val != null) + ParameterPrefix = val; + + base.Configure(attributes); + } + + #region Inner types + + public class OdpMappingSchema : MappingSchema + { + public override DataReaderMapper CreateDataReaderMapper(IDataReader dataReader) + { + return new OracleDataReaderMapper(this, dataReader); + } + + public override DataReaderMapper CreateDataReaderMapper( + IDataReader dataReader, + NameOrIndexParameter nip) + { + return new OracleScalarDataReaderMapper(this, dataReader, nip); + } + + public override Reflection.Extension.ExtensionList Extensions + { + get { return Map.DefaultSchema.Extensions; } + set { Map.DefaultSchema.Extensions = value; } + } + + #region Convert + + #region Primitive Types + + [CLSCompliant(false)] + public override SByte ConvertToSByte(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? DefaultSByteNullValue: (SByte)oraDecimal.Value; + } + + return base.ConvertToSByte(value); + } + + public override Int16 ConvertToInt16(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? DefaultInt16NullValue: oraDecimal.ToInt16(); + } + + return base.ConvertToInt16(value); + } + + public override Int32 ConvertToInt32(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? DefaultInt32NullValue: oraDecimal.ToInt32(); + } + + return base.ConvertToInt32(value); + } + + public override Int64 ConvertToInt64(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? DefaultInt64NullValue: oraDecimal.ToInt64(); + } + + return base.ConvertToInt64(value); + } + + public override Byte ConvertToByte(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? DefaultByteNullValue: oraDecimal.ToByte(); + } + + return base.ConvertToByte(value); + } + + [CLSCompliant(false)] + public override UInt16 ConvertToUInt16(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? DefaultUInt16NullValue: (UInt16)oraDecimal.Value; + } + + return base.ConvertToUInt16(value); + } + + [CLSCompliant(false)] + public override UInt32 ConvertToUInt32(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? DefaultUInt32NullValue: (UInt32)oraDecimal.Value; + } + + return base.ConvertToUInt32(value); + } + + [CLSCompliant(false)] + public override UInt64 ConvertToUInt64(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? DefaultUInt64NullValue: (UInt64)oraDecimal.Value; + } + + return base.ConvertToUInt64(value); + } + + public override Single ConvertToSingle(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? DefaultSingleNullValue: oraDecimal.ToSingle(); + } + + return base.ConvertToSingle(value); + } + + public override Double ConvertToDouble(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? DefaultDoubleNullValue: oraDecimal.ToDouble(); + } + + return base.ConvertToDouble(value); + } + + public override Boolean ConvertToBoolean(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? DefaultBooleanNullValue: (oraDecimal.Value != 0); + } + + return base.ConvertToBoolean(value); + } + + public override DateTime ConvertToDateTime(object value) + { + if (value is OracleDate) + { + var oraDate = (OracleDate)value; + return oraDate.IsNull? DefaultDateTimeNullValue: oraDate.Value; + } + + return base.ConvertToDateTime(value); + } + + public override Decimal ConvertToDecimal(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? DefaultDecimalNullValue: oraDecimal.Value; + } + + return base.ConvertToDecimal(value); + } + + public override Guid ConvertToGuid(object value) + { + if (value is OracleString) + { + var oraString = (OracleString)value; + return oraString.IsNull? DefaultGuidNullValue: new Guid(oraString.Value); + } + + if (value is OracleBlob) + { + using (var oraBlob = (OracleBlob)value) + return oraBlob.IsNull? DefaultGuidNullValue: new Guid(oraBlob.Value); + } + + return base.ConvertToGuid(value); + } + + public override String ConvertToString(object value) + { + if (value is OracleString) + { + var oraString = (OracleString)value; + return oraString.IsNull? DefaultStringNullValue: oraString.Value; + } +#if !MANAGED + if (value is OracleXmlType) + { + var oraXmlType = (OracleXmlType)value; + return oraXmlType.IsNull ? DefaultStringNullValue : oraXmlType.Value; + } +#endif + if (value is OracleClob) + { + using (var oraClob = (OracleClob)value) + return oraClob.IsNull? DefaultStringNullValue: oraClob.Value; + } + + return base.ConvertToString(value); + } + +#if !MANAGED + public override Stream ConvertToStream(object value) + { + if (value is OracleXmlType) + { + var oraXml = (OracleXmlType)value; + return oraXml.IsNull? DefaultStreamNullValue: oraXml.GetStream(); + } + + return base.ConvertToStream(value); + } + + public override XmlReader ConvertToXmlReader(object value) + { + if (value is OracleXmlType) + { + var oraXml = (OracleXmlType)value; + return oraXml.IsNull? DefaultXmlReaderNullValue: oraXml.GetXmlReader(); + } + + return base.ConvertToXmlReader(value); + } + + public override XmlDocument ConvertToXmlDocument(object value) + { + if (value is OracleXmlType) + { + var oraXml = (OracleXmlType)value; + return oraXml.IsNull? DefaultXmlDocumentNullValue: oraXml.GetXmlDocument(); + } + + return base.ConvertToXmlDocument(value); + } +#endif + + public override Byte[] ConvertToByteArray(object value) + { + if (value is OracleBlob) + { + using (var oraBlob = (OracleBlob)value) + return oraBlob.IsNull? null: oraBlob.Value; + } + + if (value is OracleBinary) + { + var oraBinary = (OracleBinary)value; + return oraBinary.IsNull? null: oraBinary.Value; + } + + if (value is OracleBFile) + { + var oraBFile = (OracleBFile)value; + return oraBFile.IsNull? null: oraBFile.Value; + } + + return base.ConvertToByteArray(value); + } + + public override Char[] ConvertToCharArray(object value) + { + if (value is OracleString) + { + var oraString = (OracleString)value; + return oraString.IsNull? null: oraString.Value.ToCharArray(); + } + + if (value is OracleClob) + { + using (var oraClob = (OracleClob)value) + return oraClob.IsNull? null: oraClob.Value.ToCharArray(); + } + + return base.ConvertToCharArray(value); + } + + #endregion + + #region Nullable Types + + [CLSCompliant(false)] + public override SByte? ConvertToNullableSByte(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? null: (SByte?)oraDecimal.Value; + } + + return base.ConvertToNullableSByte(value); + } + + public override Int16? ConvertToNullableInt16(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? null: (Int16?)oraDecimal.ToInt16(); + } + + return base.ConvertToNullableInt16(value); + } + + public override Int32? ConvertToNullableInt32(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? null: (Int32?)oraDecimal.ToInt32(); + } + + return base.ConvertToNullableInt32(value); + } + + public override Int64? ConvertToNullableInt64(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? null: (Int64?)oraDecimal.ToInt64(); + } + + return base.ConvertToNullableInt64(value); + } + + public override Byte? ConvertToNullableByte(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? null: (Byte?)oraDecimal.ToByte(); + } + + return base.ConvertToNullableByte(value); + } + + [CLSCompliant(false)] + public override UInt16? ConvertToNullableUInt16(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? null: (UInt16?)oraDecimal.Value; + } + + return base.ConvertToNullableUInt16(value); + } + + [CLSCompliant(false)] + public override UInt32? ConvertToNullableUInt32(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? null: (UInt32?)oraDecimal.Value; + } + + return base.ConvertToNullableUInt32(value); + } + + [CLSCompliant(false)] + public override UInt64? ConvertToNullableUInt64(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? null: (UInt64?)oraDecimal.Value; + } + + return base.ConvertToNullableUInt64(value); + } + + public override Single? ConvertToNullableSingle(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? null: (Single?)oraDecimal.ToSingle(); + } + + return base.ConvertToNullableSingle(value); + } + + public override Double? ConvertToNullableDouble(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? null: (Double?)oraDecimal.ToDouble(); + } + + return base.ConvertToNullableDouble(value); + } + + public override Boolean? ConvertToNullableBoolean(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? null: (Boolean?)(oraDecimal.Value != 0); + } + + return base.ConvertToNullableBoolean(value); + } + + public override DateTime? ConvertToNullableDateTime(object value) + { + if (value is OracleDate) + { + var oraDate = (OracleDate)value; + return oraDate.IsNull? null: (DateTime?)oraDate.Value; + } + + return base.ConvertToNullableDateTime(value); + } + + public override Decimal? ConvertToNullableDecimal(object value) + { + if (value is OracleDecimal) + { + var oraDecimal = (OracleDecimal)value; + return oraDecimal.IsNull? null: (Decimal?)oraDecimal.Value; + } + + return base.ConvertToNullableDecimal(value); + } + + public override Guid? ConvertToNullableGuid(object value) + { + if (value is OracleString) + { + var oraString = (OracleString)value; + return oraString.IsNull? null: (Guid?)new Guid(oraString.Value); + } + + if (value is OracleBlob) + { + using (var oraBlob = (OracleBlob)value) + return oraBlob.IsNull? null: (Guid?)new Guid(oraBlob.Value); + } + + return base.ConvertToNullableGuid(value); + } + + #endregion + + #endregion + + public override object MapValueToEnum(object value, Type type) + { + if (value is OracleString) + { + var oracleValue = (OracleString)value; + value = oracleValue.IsNull? null: oracleValue.Value; + } + else if (value is OracleDecimal) + { + var oracleValue = (OracleDecimal)value; + if (oracleValue.IsNull) + value = null; + else + value = oracleValue.Value; + } + + return base.MapValueToEnum(value, type); + } + + public override object MapValueToEnum(object value, MemberAccessor ma) + { + if (value is OracleString) + { + var oracleValue = (OracleString)value; + value = oracleValue.IsNull ? null : oracleValue.Value; + } + else if (value is OracleDecimal) + { + var oracleValue = (OracleDecimal)value; + if (oracleValue.IsNull) + value = null; + else + value = oracleValue.Value; + } + + return base.MapValueToEnum(value, ma); + } + + public override object ConvertChangeType(object value, Type conversionType) + { + // Handle OracleDecimal with IsNull == true case + // + return base.ConvertChangeType(IsNull(value)? null: value, conversionType); + } + + public override bool IsNull(object value) + { + // ODP 10 does not expose this interface to public. + // + // return value is INullable && ((INullable)value).IsNull; + + return + value is OracleDecimal? ((OracleDecimal) value).IsNull: + value is OracleString? ((OracleString) value).IsNull: + value is OracleDate? ((OracleDate) value).IsNull: + value is OracleTimeStamp? ((OracleTimeStamp) value).IsNull: + value is OracleTimeStampTZ? ((OracleTimeStampTZ) value).IsNull: + value is OracleTimeStampLTZ? ((OracleTimeStampLTZ)value).IsNull: +#if !MANAGED + value is OracleXmlType? ((OracleXmlType) value).IsNull: +#endif + value is OracleBlob? ((OracleBlob) value).IsNull: + value is OracleClob? ((OracleClob) value).IsNull: + value is OracleBFile? ((OracleBFile) value).IsNull: + value is OracleBinary? ((OracleBinary) value).IsNull: + value is OracleIntervalDS? ((OracleIntervalDS) value).IsNull: + value is OracleIntervalYM? ((OracleIntervalYM) value).IsNull: + base.IsNull(value); + } + } + + // TODO: implement via IDataReaderEx / DataReaderEx + // + public class OracleDataReaderMapper : DataReaderMapper + { + public OracleDataReaderMapper(MappingSchema mappingSchema, IDataReader dataReader) + : base(mappingSchema, dataReader) + { + _dataReader = dataReader is OracleDataReaderEx? + ((OracleDataReaderEx)dataReader).DataReader: + (OracleDataReader)dataReader; + } + + private readonly OracleDataReader _dataReader; + + public override Type GetFieldType(int index) + { + var fieldType = _dataReader.GetProviderSpecificFieldType(index); + + if (fieldType != typeof(OracleBlob) +#if !MANAGED + && fieldType != typeof(OracleXmlType) +#endif + ) + fieldType = _dataReader.GetFieldType(index); + + return fieldType; + } + + public override object GetValue(object o, int index) + { + var fieldType = _dataReader.GetProviderSpecificFieldType(index); + +#if !MANAGED + if (fieldType == typeof(OracleXmlType)) + { + var xml = _dataReader.GetOracleXmlType(index); + return MappingSchema.ConvertToXmlDocument(xml); + } +#endif + if (fieldType == typeof(OracleBlob)) + { + var blob = _dataReader.GetOracleBlob(index); + return MappingSchema.ConvertToStream(blob); + } + + return _dataReader.IsDBNull(index)? null: + _dataReader.GetValue(index); + } + + public override Boolean GetBoolean(object o, int index) { return MappingSchema.ConvertToBoolean(GetValue(o, index)); } + public override Char GetChar (object o, int index) { return MappingSchema.ConvertToChar (GetValue(o, index)); } + public override Guid GetGuid (object o, int index) { return MappingSchema.ConvertToGuid (GetValue(o, index)); } + + [CLSCompliant(false)] + public override SByte GetSByte (object o, int index) { return (SByte)_dataReader.GetDecimal(index); } + [CLSCompliant(false)] + public override UInt16 GetUInt16 (object o, int index) { return (UInt16)_dataReader.GetDecimal(index); } + [CLSCompliant(false)] + public override UInt32 GetUInt32 (object o, int index) { return (UInt32)_dataReader.GetDecimal(index); } + [CLSCompliant(false)] + public override UInt64 GetUInt64 (object o, int index) { return (UInt64)_dataReader.GetDecimal(index); } + + public override Decimal GetDecimal(object o, int index) { return OracleDecimal.SetPrecision(_dataReader.GetOracleDecimal(index), 28).Value; } + + public override Boolean? GetNullableBoolean(object o, int index) { return MappingSchema.ConvertToNullableBoolean(GetValue(o, index)); } + public override Char? GetNullableChar (object o, int index) { return MappingSchema.ConvertToNullableChar (GetValue(o, index)); } + public override Guid? GetNullableGuid (object o, int index) { return MappingSchema.ConvertToNullableGuid (GetValue(o, index)); } + + [CLSCompliant(false)] + public override SByte? GetNullableSByte (object o, int index) { return _dataReader.IsDBNull(index)? null: (SByte?)_dataReader.GetDecimal(index); } + [CLSCompliant(false)] + public override UInt16? GetNullableUInt16 (object o, int index) { return _dataReader.IsDBNull(index)? null: (UInt16?)_dataReader.GetDecimal(index); } + [CLSCompliant(false)] + public override UInt32? GetNullableUInt32 (object o, int index) { return _dataReader.IsDBNull(index)? null: (UInt32?)_dataReader.GetDecimal(index); } + [CLSCompliant(false)] + public override UInt64? GetNullableUInt64 (object o, int index) { return _dataReader.IsDBNull(index)? null: (UInt64?)_dataReader.GetDecimal(index); } + + public override Decimal? GetNullableDecimal(object o, int index) { return _dataReader.IsDBNull(index)? (decimal?)null: OracleDecimal.SetPrecision(_dataReader.GetOracleDecimal(index), 28).Value; } + } + + public class OracleScalarDataReaderMapper : ScalarDataReaderMapper + { + private readonly OracleDataReader _dataReader; + + public OracleScalarDataReaderMapper( + MappingSchema mappingSchema, + IDataReader dataReader, + NameOrIndexParameter nameOrIndex) + : base(mappingSchema, dataReader, nameOrIndex) + { + _dataReader = dataReader is OracleDataReaderEx? + ((OracleDataReaderEx)dataReader).DataReader: + (OracleDataReader)dataReader; + + _fieldType = _dataReader.GetProviderSpecificFieldType(Index); + + if (_fieldType != typeof(OracleBlob) +#if !MANAGED + && _fieldType != typeof(OracleXmlType) +#endif + ) + _fieldType = _dataReader.GetFieldType(Index); + } + + private readonly Type _fieldType; + + public override Type GetFieldType(int index) + { + return _fieldType; + } + + public override object GetValue(object o, int index) + { +#if !MANAGED + if (_fieldType == typeof(OracleXmlType)) + { + var xml = _dataReader.GetOracleXmlType(Index); + return MappingSchema.ConvertToXmlDocument(xml); + } +#endif + if (_fieldType == typeof(OracleBlob)) + { + var blob = _dataReader.GetOracleBlob(Index); + return MappingSchema.ConvertToStream(blob); + } + + return _dataReader.IsDBNull(index)? null: + _dataReader.GetValue(Index); + } + + public override Boolean GetBoolean(object o, int index) { return MappingSchema.ConvertToBoolean(GetValue(o, Index)); } + public override Char GetChar (object o, int index) { return MappingSchema.ConvertToChar (GetValue(o, Index)); } + public override Guid GetGuid (object o, int index) { return MappingSchema.ConvertToGuid (GetValue(o, Index)); } + + [CLSCompliant(false)] + public override SByte GetSByte (object o, int index) { return (SByte)_dataReader.GetDecimal(Index); } + [CLSCompliant(false)] + public override UInt16 GetUInt16 (object o, int index) { return (UInt16)_dataReader.GetDecimal(Index); } + [CLSCompliant(false)] + public override UInt32 GetUInt32 (object o, int index) { return (UInt32)_dataReader.GetDecimal(Index); } + [CLSCompliant(false)] + public override UInt64 GetUInt64 (object o, int index) { return (UInt64)_dataReader.GetDecimal(Index); } + + public override Decimal GetDecimal(object o, int index) { return OracleDecimal.SetPrecision(_dataReader.GetOracleDecimal(Index), 28).Value; } + + public override Boolean? GetNullableBoolean(object o, int index) { return MappingSchema.ConvertToNullableBoolean(GetValue(o, Index)); } + public override Char? GetNullableChar (object o, int index) { return MappingSchema.ConvertToNullableChar (GetValue(o, Index)); } + public override Guid? GetNullableGuid (object o, int index) { return MappingSchema.ConvertToNullableGuid (GetValue(o, Index)); } + + [CLSCompliant(false)] + public override SByte? GetNullableSByte (object o, int index) { return _dataReader.IsDBNull(index)? null: (SByte?)_dataReader.GetDecimal(Index); } + [CLSCompliant(false)] + public override UInt16? GetNullableUInt16 (object o, int index) { return _dataReader.IsDBNull(index)? null: (UInt16?)_dataReader.GetDecimal(Index); } + [CLSCompliant(false)] + public override UInt32? GetNullableUInt32 (object o, int index) { return _dataReader.IsDBNull(index)? null: (UInt32?)_dataReader.GetDecimal(Index); } + [CLSCompliant(false)] + public override UInt64? GetNullableUInt64 (object o, int index) { return _dataReader.IsDBNull(index)? null: (UInt64?)_dataReader.GetDecimal(Index); } + + public override Decimal? GetNullableDecimal(object o, int index) { return _dataReader.IsDBNull(index)? (decimal?)null: OracleDecimal.SetPrecision(_dataReader.GetOracleDecimal(Index), 28).Value; } + } + + [Mixin(typeof(IDbDataParameter), "_oracleParameter")] + [Mixin(typeof(IDataParameter), "_oracleParameter")] + [Mixin(typeof(IDisposable), "_oracleParameter")] + [Mixin(typeof(ICloneable), "_oracleParameter")] + [CLSCompliant(false)] + public abstract class OracleParameterWrap + { + protected OracleParameter _oracleParameter; + public OracleParameter OracleParameter + { + get { return _oracleParameter; } + } + + public static IDbDataParameter CreateInstance(OracleParameter oraParameter) + { + var wrap = TypeAccessor.CreateInstanceEx(); + + wrap._oracleParameter = oraParameter; + + return (IDbDataParameter)wrap; + } + + public override string ToString() + { + return _oracleParameter.ToString(); + } + + /// + ///Gets or sets the value of the parameter. + /// + /// + ///An that is the value of the parameter. + ///The default value is null. + /// + protected object Value + { +#if CONVERTORACLETYPES + [MixinOverride] + get + { + object value = _oracleParameter.Value; + if (value is OracleBinary) + { + OracleBinary oracleValue = (OracleBinary)value; + return oracleValue.IsNull? null: oracleValue.Value; + } + if (value is OracleDate) + { + OracleDate oracleValue = (OracleDate)value; + if (oracleValue.IsNull) + return null; + return oracleValue.Value; + } + if (value is OracleDecimal) + { + OracleDecimal oracleValue = (OracleDecimal)value; + if (oracleValue.IsNull) + return null; + return oracleValue.Value; + } + if (value is OracleIntervalDS) + { + OracleIntervalDS oracleValue = (OracleIntervalDS)value; + if (oracleValue.IsNull) + return null; + return oracleValue.Value; + } + if (value is OracleIntervalYM) + { + OracleIntervalYM oracleValue = (OracleIntervalYM)value; + if (oracleValue.IsNull) + return null; + return oracleValue.Value; + } + if (value is OracleString) + { + OracleString oracleValue = (OracleString)value; + return oracleValue.IsNull? null: oracleValue.Value; + } + if (value is OracleTimeStamp) + { + OracleTimeStamp oracleValue = (OracleTimeStamp)value; + if (oracleValue.IsNull) + return null; + return oracleValue.Value; + } + if (value is OracleTimeStampLTZ) + { + OracleTimeStampLTZ oracleValue = (OracleTimeStampLTZ)value; + if (oracleValue.IsNull) + return null; + return oracleValue.Value; + } + if (value is OracleTimeStampTZ) + { + OracleTimeStampTZ oracleValue = (OracleTimeStampTZ)value; + if (oracleValue.IsNull) + return null; + return oracleValue.Value; + } + if (value is OracleXmlType) + { + OracleXmlType oracleValue = (OracleXmlType)value; + return oracleValue.IsNull? null: oracleValue.Value; + } + + return value; + } +#endif + [MixinOverride] + set + { + if (null != value) + { + if (value is Guid) + { + // Fix Oracle.Net bug #6: guid type is not handled + // + value = ((Guid)value).ToByteArray(); + } + else if (value is Array && !(value is byte[] || value is char[])) + { + _oracleParameter.CollectionType = OracleCollectionType.PLSQLAssociativeArray; + } + else if (value is IConvertible) + { + var convertible = (IConvertible)value; + var typeCode = convertible.GetTypeCode(); + + switch (typeCode) + { + case TypeCode.Boolean: + // Fix Oracle.Net bug #7: bool type is handled wrong + // + value = convertible.ToByte(null); + break; + + case TypeCode.SByte: + case TypeCode.UInt16: + case TypeCode.UInt32: + case TypeCode.UInt64: + // Fix Oracle.Net bug #8: some integer types are handled wrong + // + value = convertible.ToDecimal(null); + break; + + // Fix Oracle.Net bug #10: zero-length string can not be converted to + // ORAXML type, but null value can be. + // + case TypeCode.String: + if (((string)value).Length == 0) + value = null; + break; + + default: + // Fix Oracle.Net bug #5: Enum type is not handled + // + if (value is Enum) + { + // Convert a Enum value to it's underlying type. + // + value = System.Convert.ChangeType(value, typeCode); + } + break; + } + } + } + + _oracleParameter.Value = value; + } + } + } + + #endregion + + #region InsertBatch + + public override int InsertBatch( + DbManager db, + string insertText, + IEnumerable collection, + MemberMapper[] members, + int maxBatchSize, + DbManager.ParameterProvider getParameters) + { + var sb = new StringBuilder(); + var sp = new OracleSqlProvider(); + var pn = 0; + var n = 0; + var cnt = 0; + var str = "\t" + insertText + .Substring(0, insertText.IndexOf(") VALUES (")) + .Substring(7) + .Replace("\r", "") + .Replace("\n", "") + .Replace("\t", " ") + .Replace("( ", "(") + //.Replace(" ", " ") + + ") VALUES ("; + + var parameters = new List(); + + foreach (var item in collection) + { + if (sb.Length == 0) + sb.AppendLine("INSERT ALL"); + + sb.Append(str); + + foreach (var member in members) + { + var value = member.GetValue(item); + + if (value != null && value.GetType().IsEnum) + value = MappingSchema.MapEnumToValue(value, true); + + if (value is Nullable) + value = ((DateTime?)value).Value; + + if (value is DateTime) + { + var dt = (DateTime)value; + sb.Append(string.Format("to_timestamp('{0:dd.MM.yyyy HH:mm:ss.ffffff}', 'DD.MM.YYYY HH24:MI:SS.FF6')", dt)); + } + else if (value is string && ((string)value).Length >= 2000) + { + var par = db.Parameter("p" + ++pn, value); + parameters.Add(par); + sb.Append(":" + par.ParameterName); + } + else + sp.BuildValue(sb, value); + + sb.Append(", "); + } + + sb.Length -= 2; + sb.AppendLine(")"); + + n++; + + if (n >= maxBatchSize) + { + sb.AppendLine("SELECT * FROM dual"); + + var sql = sb.ToString(); + + if (DbManager.TraceSwitch.TraceInfo) + DbManager.WriteTraceLine("\n" + sql.Replace("\r", ""), DbManager.TraceSwitch.DisplayName); + + cnt += db + .SetCommand(sql, parameters.Count > 0 ? parameters.ToArray() : null) + .ExecuteNonQuery(); + + parameters.Clear(); + pn = 0; + n = 0; + sb.Length = 0; + } + } + + if (n > 0) + { + sb.AppendLine("SELECT * FROM dual"); + + var sql = sb.ToString(); + + if (DbManager.TraceSwitch.TraceInfo) + DbManager.WriteTraceLine("\n" + sql.Replace("\r", ""), DbManager.TraceSwitch.DisplayName); + + cnt += db + .SetCommand(sql, parameters.Count > 0 ? parameters.ToArray() : null) + .ExecuteNonQuery(); + } + + return cnt; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/OleDbDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/OleDbDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,154 @@ +using System; +using System.Data; +using System.Data.Common; +using System.Data.OleDb; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + + /// + /// Implements access to the Data Provider for OLE DB. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + public class OleDbDataProvider : DataProviderBase + { + /// + /// Creates the database connection object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The database connection object. + public override IDbConnection CreateConnectionObject() + { + return new OleDbConnection(); + } + + /// + /// Creates the data adapter object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// A data adapter object. + public override DbDataAdapter CreateDataAdapterObject() + { + return new OleDbDataAdapter(); + } + + /// + /// Populates the specified object's Parameters collection with + /// parameter information for the stored procedure specified in the . + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The referencing the stored procedure for which + /// the parameter information is to be derived. The derived parameters will be + /// populated into the Parameters of this command. + public override bool DeriveParameters(IDbCommand command) + { + OleDbCommandBuilder.DeriveParameters((OleDbCommand)command); + return true; + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter: + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return "@" + value; + + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryFieldAlias: + case ConvertType.NameToQueryTableAlias: + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '[') + return value; + } + + return "[" + value + "]"; + + case ConvertType.NameToDatabase: + case ConvertType.NameToOwner: + case ConvertType.NameToQueryTable: + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '[') + return value; + + if (name.IndexOf('.') > 0) + value = string.Join("].[", name.Split('.')); + } + + return "[" + value + "]"; + + case ConvertType.SprocParameterToName: + if (value != null) + { + var str = value.ToString(); + return str.Length > 0 && str[0] == '@'? str.Substring(1): str; + } + + break; + + case ConvertType.ExceptionToErrorNumber: + if (value is OleDbException) + { + var ex = (OleDbException)value; + if (ex.Errors.Count > 0) + return ex.Errors[0].NativeError; + } + + break; + } + + return value; + } + + public override ISqlProvider CreateSqlProvider() + { + throw new NotSupportedException(); + } + + /// + /// Returns connection type. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// An instance of the class. + public override Type ConnectionType + { + get { return typeof(OleDbConnection); } + } + + public const string NameString = DataProvider.ProviderName.OleDb; + + /// + /// Returns the data provider name. + /// + /// + /// See the method to find an example. + /// + /// AddDataProvider Method + /// Data provider name. + public override string Name + { + get { return NameString; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/OracleDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/OracleDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,147 @@ +using System; +using System.Data; +using System.Data.Common; +using System.Data.OracleClient; +using System.Globalization; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + +#if FW4 + [Obsolete("OracleDataProvider has been deprecated. http://go.microsoft.com/fwlink/?LinkID=144260")] +#pragma warning disable 0618 +#endif + /// + /// Implements access to the Data Provider for Oracle. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + public sealed class OracleDataProvider : DataProviderBase + { + private string _parameterPrefix = "P"; + public string ParameterPrefix + { + get { return _parameterPrefix; } + set + { + _parameterPrefix = string.IsNullOrEmpty(value)? null: + value.ToUpper(CultureInfo.InvariantCulture); + } + } + + /// + /// Creates the database connection object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The database connection object. + public override IDbConnection CreateConnectionObject() + { + return new OracleConnection(); + } + + /// + /// Creates the data adapter object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// A data adapter object. + public override DbDataAdapter CreateDataAdapterObject() + { + return new OracleDataAdapter(); + } + + /// + /// Populates the specified object's Parameters collection with + /// parameter information for the stored procedure specified in the . + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The referencing the stored procedure for which the parameter information is to be derived. The derived parameters will be populated into the Parameters of this command. + public override bool DeriveParameters(IDbCommand command) + { + OracleCommandBuilder.DeriveParameters((OracleCommand)command); + return true; + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return ParameterPrefix == null? value: ParameterPrefix + value; + + case ConvertType.SprocParameterToName: + var name = (string)value; + + if (name.Length > 0) + { + if (name[0] == ':') + return name.Substring(1); + + if (ParameterPrefix != null && + name.ToUpper(CultureInfo.InvariantCulture).StartsWith(ParameterPrefix)) + { + return name.Substring(ParameterPrefix.Length); + } + } + + break; + + case ConvertType.ExceptionToErrorNumber: + if (value is OracleException) + return ((OracleException)value).Code; + break; + } + + return SqlProvider.Convert(value, convertType); + } + + /// + /// Returns connection type. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// An instance of the class. + public override Type ConnectionType + { + get { return typeof(OracleConnection); } + } + + public const string NameString = "Oracle"; + + /// + /// Returns the data provider name. + /// + /// + /// See the method to find an example. + /// + /// AddDataProvider Method + /// Data provider name. + public override string Name + { + get { return NameString; } + } + + public override ISqlProvider CreateSqlProvider() + { + return new OracleSqlProvider(); + } + } + +#if FW4 +#pragma warning restore 0618 +#endif +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/OracleHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/OracleHelper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,250 @@ +using System; +using System.Data; +using System.Diagnostics; +using System.Globalization; +using System.Text.RegularExpressions; + +namespace BLToolkit.Data.DataProvider +{ + public static class OracleHelper + { + #region Text + + /// + /// If value is null or empty, return NULL or the value converted for Oracle SQL query + /// + /// Text + /// Text converted for oracle query + public static string SqlConvertString(string value) + { + if (!string.IsNullOrEmpty(value)) + { + value = value.Replace("'", "''"); + value = value.Replace("&", "' || '&' || '"); + + return "'" + value + "'"; + } + + return string.IsNullOrWhiteSpace(value) ? "NULL" : value; + } + + #endregion + + #region Date & Time + + /// + /// Convert DateTime to TO_DATE('value','YYYYMMDD') + /// + /// Date + /// Date converted for oracle query + public static string SqlConvertDate(DateTime value) + { + return string.Format("TO_DATE('{0}','YYYYMMDD')", value.ToString("yyyyMMdd")); + } + + /// + /// Convert DateTime to TO_DATE('value','YYYYMMDDHH24MISS') + /// + /// DateTime + /// DateTime converted for oracle query + public static string SqlConvertDateTime(DateTime value) + { + return string.Format("TO_DATE('{0}','YYYYMMDDHH24MISS')", value.ToString("yyyyMMddHHmmss")); + } + + /// + /// Convert DateTime to TO_TIMESTAMP('value','YYYYMMDDHH24MISSFF3') + /// + /// DateTime + /// DateTime converted for oracle query + public static string SqlConvertTimeStamp(DateTime value) + { + return string.Format("TO_TIMESTAMP('{0}','YYYYMMDDHH24MISSFF3')", value.ToString("yyyyMMddHHmmssfff")); + } + + /// + /// Convert DateTime to TO_CHAR(TO_DATE('value','YYYYMMDD'))) + /// + /// DateTime + /// DateTime converted for oracle query + public static string SqlConvertDateToChar(DateTime value) + { + return string.Format("TO_CHAR(TO_DATE('{0}','YYYYMMDD'))", value.ToString("yyyyMMdd")); + } + + #endregion + + #region Connection string + + /// + /// Generate the minimum connection string. The connection string looks like + /// Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = server)(PORT = port)))(CONNECT_DATA = (SID = sid)));User Id=username;Password=password; + /// + /// Username + /// Password + /// Server name + /// Database SID + /// Port of the server. Default value is 1521 + /// Default connection string + public static string GetFullConnectionString(string userName, string password, string server, string sid, int port = 1521) + { + return + string.Format( + "Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = {0})(PORT = {1})))(CONNECT_DATA = (SID = {2})));User Id={3};Password={4};", + server, port, sid, userName, password); + } + + /// + /// Generate the minimum connection string. The connection string looks like + /// Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = server)(PORT = port)))(CONNECT_DATA = (SID = sid)));User Id=username;Password=password;Pooling=False; + /// + /// Username + /// Password + /// Server name + /// Database SID + /// Port of the server. Default value is 1521 + /// Default connection string + public static string GetFullConnectionStringWithoutPooling(string userName, string password, string server, string sid, int port = 1521) + { + return + string.Format( + "Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = {0})(PORT = {1})))(CONNECT_DATA = (SID = {2})));User Id={3};Password={4};Pooling=False;", + server, port, sid, userName, password); + } + + /// + /// Generate the minimum connection string. The connection string looks like + /// Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = server)(PORT = port)))(CONNECT_DATA = (SID = sid)));User Id=username;Password=password;Connection Timeout=timeout; + /// + /// Username + /// Password + /// Server name + /// Database SID + /// Port of the server. Default value is 1521 + /// Default connection string + public static string GetFullConnectionString(string userName, string password, string server, string sid, + TimeSpan timeOut, int port = 1521) + { + return + string.Format( + "Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = {0})(PORT = {1})))(CONNECT_DATA = (SID = {2})));User Id={3};Password={4};Connection Timeout={5};", + server, port, sid, userName, password, (int)timeOut.TotalSeconds); + } + + /// + /// Generate the minimum connection string. The connection string looks like + /// Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = server)(PORT = port)))(CONNECT_DATA = (SID = sid)));User Id=username;Password=password;Connection Timeout=timeout;Pooling=False; + /// + /// Username + /// Password + /// Server name + /// Database SID + /// Port of the server. Default value is 1521 + /// Default connection string + public static string GetFullConnectionStringWithoutPooling(string userName, string password, string server, string sid, + TimeSpan timeOut, int port = 1521) + { + return + string.Format( + "Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = {0})(PORT = {1})))(CONNECT_DATA = (SID = {2})));User Id={3};Password={4};Connection Timeout={5};Pooling=False;", + server, port, sid, userName, password, (int)timeOut.TotalSeconds); + } + + /// + /// Generate the minimum connection string. The connection string looks like + /// Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = server)(PORT = port)))(CONNECT_DATA = (SID = sid)));User Id=username;Password=password;Connection Timeout=timeout; + /// + /// Username + /// Password + /// Server name + /// Database SID + /// Port of the server. Default value is 1521 + /// Default connection string + public static string GetFullConnectionString(string userName, string password, string server, string sid, int timeOutInSecond, int port = 1521) + { + return GetFullConnectionString(userName, password, server, sid, TimeSpan.FromSeconds(timeOutInSecond), port); + } + + #endregion + + public static string Interpret(IDbCommand poCommand) + { + if (poCommand.Parameters.Count == 0) + return poCommand.CommandText; + + var oRegex = new Regex(@"(?'[^']+')|(?:[a-zA-Z0-9_]+)"); + MatchCollection oMatchCollection = oRegex.Matches(poCommand.CommandText); + + string strQuery = poCommand.CommandText + " "; + int matchCount = 0; + + for (int i = 0; i < oMatchCollection.Count; i++) + { + if (oMatchCollection[i].Groups["string"].Success) + continue; + + string strParameter = oMatchCollection[i].Groups["Parameters"].Captures[0].Value; + + var param = (IDbDataParameter)poCommand.Parameters[matchCount]; + if (param.Value is DateTime) + { + var dt = (DateTime)param.Value; + + strQuery = strQuery.Replace(strParameter + " ", + dt.Date == dt + ? SqlConvertDate(dt) + " " + : SqlConvertDateTime(dt) + " "); + } + else if (param.Value is string) + strQuery = strQuery.Replace(strParameter, SqlConvertString(param.Value.ToString()) + " "); + else if (param.Value is Int16) + strQuery = strQuery.Replace(strParameter, ((Int16)param.Value).ToString(CultureInfo.InvariantCulture) + " "); + else if (param.Value is Int32) + strQuery = strQuery.Replace(strParameter, ((Int32)param.Value).ToString(CultureInfo.InvariantCulture) + " "); + else if (param.Value is Int64) + strQuery = strQuery.Replace(strParameter, ((Int64)param.Value).ToString(CultureInfo.InvariantCulture) + " "); + else if (param.Value is decimal) + strQuery = strQuery.Replace(strParameter, ((decimal)param.Value).ToString(CultureInfo.InvariantCulture) + " "); + else if (param.Value is float) + strQuery = strQuery.Replace(strParameter, ((float)param.Value).ToString(CultureInfo.InvariantCulture) + " "); + else if (param.Value is double) + strQuery = strQuery.Replace(strParameter, ((double)param.Value).ToString(CultureInfo.InvariantCulture) + " "); + else if (param.Value is TimeSpan) + strQuery = strQuery.Replace(strParameter, "'" + ((TimeSpan)param.Value).ToString() + "' "); + else + throw new NotImplementedException(param.Value.GetType() + " is not implemented yet."); + + matchCount++; + } + + if (matchCount != poCommand.Parameters.Count) + { + // ReSharper disable InvocationIsSkipped + Debug.WriteLine( + "Number of parameters in query is not equals to number of parameters set in the command object " + + poCommand.CommandText); + // ReSharper restore InvocationIsSkipped + var msg = + "Number of parameters in query is not equals to number of parameters set in the command object : " + poCommand.CommandText + "\r\n" + + "Query params :\r\n"; + + foreach (Match match in oMatchCollection) + { + msg += "\t" + match.Value + "\r\n"; + } + + msg += "\nCommand params :\r\n"; + + foreach (IDataParameter param in poCommand.Parameters) + { + msg += "\t" + param.ParameterName + " = " + Convert.ToString(param) + "\r\n"; + } + + throw new Exception(msg); + } + + return strQuery; + } + + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/PostgreSQLDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/PostgreSQLDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,333 @@ +using System; +using System.Data; +using System.Data.Common; + +using Npgsql; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + using BLToolkit.Mapping; + + public class PostgreSQLDataProvider : DataProviderBase + { + #region Configurable + + public enum CaseConvert + { + None, + Lower, + Upper + } + + public static CaseConvert QueryCaseConvert = CaseConvert.None; + + public static bool QuoteIdentifiers + { + get { return PostgreSQLSqlProvider.QuoteIdentifiers; } + set { PostgreSQLSqlProvider.QuoteIdentifiers = value; } + } + + public override void Configure(System.Collections.Specialized.NameValueCollection attributes) + { + var quoteIdentifiers = attributes["QuoteIdentifiers"]; + + if (quoteIdentifiers != null) + QuoteIdentifiers = Common.Convert.ToBoolean(quoteIdentifiers); + + var queryCaseConcert = attributes["QueryCaseConvert"]; + if (queryCaseConcert != null) + { + try + { + QueryCaseConvert = (CaseConvert)Enum.Parse(typeof(CaseConvert), queryCaseConcert, true); + } + catch { } + } + + base.Configure(attributes); + } + + #endregion + + public override IDbConnection CreateConnectionObject() + { + return new NpgsqlConnection(); + } + + public override DbDataAdapter CreateDataAdapterObject() + { + return new NpgsqlDataAdapter(); + } + + public override bool DeriveParameters(IDbCommand command) + { + NpgsqlCommandBuilder.DeriveParameters((NpgsqlCommand)command); + return true; + } + + public override void SetParameterValue(IDbDataParameter parameter, object value) + { + if(value is Enum) + { + var type = Enum.GetUnderlyingType(value.GetType()); + value = (MappingSchema ?? Map.DefaultSchema).ConvertChangeType(value, type); + + } + base.SetParameterValue(parameter, value); + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.ExceptionToErrorNumber: + if (value is NpgsqlException) + { + var ex = (NpgsqlException)value; + + foreach (NpgsqlError error in ex.Errors) + return error.Code; + + return 0; + } + + break; + } + + return SqlProvider.Convert(value, convertType); + } + + public override Type ConnectionType + { + get { return typeof(NpgsqlConnection); } + } + + public override string Name + { + get { return DataProvider.ProviderName.PostgreSQL; } + } + + public override int MaxBatchSize + { + get { return 0; } + } + + public override ISqlProvider CreateSqlProvider() + { + return new PostgreSQLSqlProvider(); + } + + public override void PrepareCommand(ref CommandType commandType, ref string commandText, ref IDbDataParameter[] commandParameters) + { + if (QueryCaseConvert == CaseConvert.Lower) + commandText = commandText.ToLower(); + else if (QueryCaseConvert == CaseConvert.Upper) + commandText = commandText.ToUpper(); + + base.PrepareCommand(ref commandType, ref commandText, ref commandParameters); + } + + public override bool CanReuseCommand(IDbCommand command, CommandType newCommandType) + { + return command.CommandType == newCommandType; + } + + public override IDataReader GetDataReader(MappingSchema schema, IDataReader dataReader) + { + return + dataReader is NpgsqlDataReader + ? new NpgsqlDataReaderEx(schema, (NpgsqlDataReader)dataReader) + : base.GetDataReader(schema, dataReader); + } + + class NpgsqlDataReaderEx : IDataReader + { + private readonly NpgsqlDataReader _reader; + private readonly MappingSchema _schema; + + public NpgsqlDataReaderEx(MappingSchema schema, NpgsqlDataReader reader) + { + _reader = reader; + _schema = schema; + } + + #region IDataReader Members + + public void Close() + { + _reader.Close(); + } + + public int Depth + { + get { return _reader.Depth; } + } + + public DataTable GetSchemaTable() + { + return _reader.GetSchemaTable(); + } + + public bool IsClosed + { + get { return _reader.IsClosed; } + } + + public bool NextResult() + { + return _reader.NextResult(); + } + + public bool Read() + { + return _reader.Read(); + } + + public int RecordsAffected + { + get { return _reader.RecordsAffected; } + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + _reader.Dispose(); + } + + #endregion + + #region IDataRecord Members + + public int FieldCount + { + get { return _reader.FieldCount; } + } + + public bool GetBoolean(int i) + { + return _reader.GetBoolean(i); + } + + public byte GetByte(int i) + { + return _schema.ConvertToByte(_reader.GetValue(i)); + } + + public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) + { + return _reader.GetBytes(i, fieldOffset, buffer, bufferoffset, length); + } + + public char GetChar(int i) + { + return _reader.GetChar(i); + } + + public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) + { + return _reader.GetChars(i, fieldoffset, buffer, bufferoffset, length); + } + + public IDataReader GetData(int i) + { + return _reader.GetData(i); + } + + public string GetDataTypeName(int i) + { + return _reader.GetDataTypeName(i); + } + + public DateTime GetDateTime(int i) + { + return _reader.GetDateTime(i); + } + + public decimal GetDecimal(int i) + { + return _reader.GetDecimal(i); + } + + public double GetDouble(int i) + { + return _reader.GetDouble(i); + } + + public Type GetFieldType(int i) + { + return _reader.GetFieldType(i); + } + + public float GetFloat(int i) + { + return _reader.GetFloat(i); + } + + public Guid GetGuid(int i) + { + return _reader.GetGuid(i); + } + + public short GetInt16(int i) + { + return _reader.GetInt16(i); + } + + public int GetInt32(int i) + { + return _reader.GetInt32(i); + } + + public long GetInt64(int i) + { + return _reader.GetInt64(i); + } + + public string GetName(int i) + { + return _reader.GetName(i); + } + + public int GetOrdinal(string name) + { + return _reader.GetOrdinal(name); + } + + public string GetString(int i) + { + return _reader.GetString(i); + } + + public object GetValue(int i) + { + return _reader.GetValue(i); + } + + public int GetValues(object[] values) + { + return _reader.GetValues(values); + } + + public bool IsDBNull(int i) + { + return _reader.IsDBNull(i); + } + + public object this[string name] + { + get { return _reader[name]; } + } + + public object this[int i] + { + get { return _reader[i]; } + } + + #endregion + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/ProviderName.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/ProviderName.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,41 @@ +namespace BLToolkit.Data.DataProvider +{ + public static class ProviderName + { + public const string Access = "Access"; + public const string DB2 = "DB2"; + public const string Firebird = "Fdp"; + public const string Informix = "Informix"; + public const string MsSql = "Sql"; + public const string MsSql2000 = "MsSql2000"; + public const string MsSql2005 = "MsSql2005"; + public const string MsSql2008 = "MsSql2008"; + public const string MsSql2012 = "MsSql2012"; + public const string MySql = "MySql"; + public const string Odbc = "Odbc"; + public const string OleDb = "OleDb"; + public const string Oracle = "Odp"; + public const string OracleManaged = "OdpManaged"; + public const string PostgreSQL = "PostgreSQL"; + public const string SqlCe = "SqlCe"; + public const string SQLite = "SQLite"; + public const string Sybase = "Sybase"; + } + + public static class ProviderFullName + { + public const string DB2 = "IBM.Data.DB2"; + public const string Firebird = "FirebirdSql.Data.FirebirdClient"; + public const string Informix = "IBM.Data.Informix.Client"; + public const string MsSql = "System.Data.SqlClient"; + public const string MySql = "MySql.Data.MySqlClient"; + public const string Odbc = "System.Data.Odbc"; + public const string OleDb = "System.Data.OleDb"; + public const string OracleNet = "System.Data.OracleClient"; + public const string Oracle = "Oracle.DataAccess.Client"; + public const string PostgreSQL = "Npgsql"; + public const string SqlCe = "System.Data.SqlServerCe"; + public const string SQLite = "System.Data.SQLite"; + public const string Sybase = "Sybase.Data.AseClient"; + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/SQLiteDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/SQLiteDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,215 @@ +using System; +using System.Data; +using System.Data.Common; +using System.Data.SQLite; +using System.Diagnostics; +using System.Text; +using System.Xml; + +using BLToolkit.Data.Sql.SqlProvider; +using BLToolkit.Mapping; +// System.Data.SQLite.dll must be referenced. +// http://sqlite.phxsoftware.com/ +// + +namespace BLToolkit.Data.DataProvider +{ + /// + /// Implements access to the Data Provider for SQLite. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + public sealed class SQLiteDataProvider : DataProviderBase + { + /// + /// Returns connection type. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// An instance of the class. + public override Type ConnectionType + { + get { return typeof (SQLiteConnection); } + } + + /// + /// Returns the data provider name. + /// + /// + /// See the method to find an example. + /// + /// AddDataProvider Method + /// Data provider name. + public override string Name + { + get { return DataProvider.ProviderName.SQLite; } + } + + /// + /// Creates the database connection object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The database connection object. + public override IDbConnection CreateConnectionObject() + { + return new SQLiteConnection(); + } + + /// + /// Creates the data adapter object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// A data adapter object. + public override DbDataAdapter CreateDataAdapterObject() + { + return new SQLiteDataAdapter(); + } + + /// + /// Populates the specified IDbCommand object's Parameters collection with + /// parameter information for the stored procedure specified in the IDbCommand. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The IDbCommand referencing the stored procedure for which the parameter information is to be derived. The derived parameters will be populated into the Parameters of this command. + public override bool DeriveParameters(IDbCommand command) + { + // SQLiteCommandBuilder does not implement DeriveParameters. + // This is not surprising, since SQLite has no support for stored procs. + // + return false; + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.ExceptionToErrorNumber: + { + if (value is SQLiteException) + return ((SQLiteException) value).ErrorCode; + break; + } + } + + return SqlProvider.Convert(value, convertType); + } + + public override DataExceptionType ConvertErrorNumberToDataExceptionType(int number) + { + switch (number) + { + case 19: return DataExceptionType.ConstraintViolation; + } + return DataExceptionType.Undefined; + } + + public override void AttachParameter(IDbCommand command, IDbDataParameter parameter) + { + if (parameter.Direction == ParameterDirection.Input || parameter.Direction == ParameterDirection.InputOutput) + { + if (parameter.Value is XmlDocument) + { + parameter.Value = Encoding.UTF8.GetBytes(((XmlDocument) parameter.Value).InnerXml); + parameter.DbType = DbType.Binary; + } + } + + base.AttachParameter(command, parameter); + } + + public override void SetParameterValue(IDbDataParameter parameter, object value) + { + if (parameter.DbType == DbType.DateTime2) + parameter.DbType = DbType.DateTime; + + base.SetParameterValue(parameter, value); + } + + public override ISqlProvider CreateSqlProvider() + { + return new SQLiteSqlProvider(); + } + + #region Nested type: LoverFunction + /// + /// SQLite built-in text processor is ANSI-only Just override it. + /// + [SQLiteFunction(Name = "lower", Arguments = 1, FuncType = FunctionType.Scalar)] + internal class LoverFunction : SQLiteFunction + { + public override object Invoke(object[] args) + { + Debug.Assert(args != null && args.Length == 1); + var arg = args[0]; + + Debug.Assert(arg is string || arg is DBNull || arg is byte[]); + return + arg is string + ? ((string) arg).ToLower() + : arg is byte[] + ? Encoding.UTF8.GetString((byte[]) arg).ToLower() + : arg; + } + } + #endregion + + #region Nested type: SQLiteMappingSchema + public class SQLiteMappingSchema : MappingSchema + { + #region Convert + public override XmlReader ConvertToXmlReader(object value) + { + if (value is byte[]) + value = Encoding.UTF8.GetString((byte[]) value); + + return base.ConvertToXmlReader(value); + } + + public override XmlDocument ConvertToXmlDocument(object value) + { + if (value is byte[]) + value = Encoding.UTF8.GetString((byte[]) value); + + return base.ConvertToXmlDocument(value); + } + #endregion + } + #endregion + + #region Nested type: UpperFunction + /// + /// SQLite built-in text processor is ANSI-only Just override it. + /// + [SQLiteFunction(Name = "upper", Arguments = 1, FuncType = FunctionType.Scalar)] + internal class UpperFunction : SQLiteFunction + { + public override object Invoke(object[] args) + { + Debug.Assert(args != null && args.Length == 1); + var arg = args[0]; + + Debug.Assert(arg is string || arg is DBNull || arg is byte[]); + return + arg is string + ? ((string) arg).ToUpper() + : arg is byte[] + ? Encoding.UTF8.GetString((byte[]) arg).ToUpper() + : arg; + } + } + #endregion + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/Sql2000DataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/Sql2000DataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using System; +using System.Data; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + + public sealed class Sql2000DataProvider : SqlDataProviderBase + { + public override string Name + { + get { return DataProvider.ProviderName.MsSql2000; } + } + + public override ISqlProvider CreateSqlProvider() + { + return new MsSql2000SqlProvider(); + } + + public override void AttachParameter(IDbCommand command, IDbDataParameter parameter) + { + if (parameter.DbType == DbType.DateTime2) + parameter.DbType = DbType.DateTime; + + base.AttachParameter(command, parameter); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/Sql2005DataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/Sql2005DataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using System; +using System.Data; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + + public sealed class Sql2005DataProvider : SqlDataProviderBase + { + public override string Name + { + get { return DataProvider.ProviderName.MsSql2005; } + } + + public override ISqlProvider CreateSqlProvider() + { + return new MsSql2005SqlProvider(); + } + + public override void AttachParameter(IDbCommand command, IDbDataParameter parameter) + { + if (parameter.DbType == DbType.DateTime2) + parameter.DbType = DbType.DateTime; + + base.AttachParameter(command, parameter); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/Sql2008DataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/Sql2008DataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + + public sealed class Sql2008DataProvider : SqlDataProviderBase + { + static readonly List> _udtTypeNameResolvers = new List>(); + + static Sql2008DataProvider() + { + AddUdtTypeNameResolver(ResolveStandartUdt); + } + + public static void AddUdtTypeNameResolver(Func resolver) + { + _udtTypeNameResolvers.Add(resolver); + } + + static string ResolveStandartUdt(Type type) + { + return type.Namespace == "Microsoft.SqlServer.Types" ? type.Name.Replace("Sql", "") : null; + } + + public override string Name + { + get { return DataProvider.ProviderName.MsSql2008; } + } + + public override ISqlProvider CreateSqlProvider() + { + return new MsSql2008SqlProvider(); + } + + public override void SetParameterValue(IDbDataParameter parameter, object value) + { + base.SetParameterValue(parameter, value); + SetUdtTypeName(parameter, value); + } + + static void SetUdtTypeName(IDbDataParameter parameter, object value) + { + var sqlParameter = parameter as System.Data.SqlClient.SqlParameter; + var valueType = value.GetType(); + + if (sqlParameter != null) + sqlParameter.UdtTypeName = _udtTypeNameResolvers.Select(_=>_(valueType)).FirstOrDefault(_=>!string.IsNullOrEmpty(_)); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/Sql2012DataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/Sql2012DataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + + public sealed class Sql2012DataProvider : SqlDataProviderBase + { + static readonly List> _udtTypeNameResolvers = new List>(); + + static Sql2012DataProvider() + { + AddUdtTypeNameResolver(ResolveStandartUdt); + } + + public static void AddUdtTypeNameResolver(Func resolver) + { + _udtTypeNameResolvers.Add(resolver); + } + + static string ResolveStandartUdt(Type type) + { + return type.Namespace == "Microsoft.SqlServer.Types" ? type.Name.Replace("Sql", "") : null; + } + + public override string Name + { + get { return DataProvider.ProviderName.MsSql2012; } + } + + public override ISqlProvider CreateSqlProvider() + { + return new MsSql2012SqlProvider(); + } + + public override void SetParameterValue(IDbDataParameter parameter, object value) + { + base.SetParameterValue(parameter, value); + SetUdtTypeName(parameter, value); + } + + static void SetUdtTypeName(IDbDataParameter parameter, object value) + { + var sqlParameter = parameter as System.Data.SqlClient.SqlParameter; + var valueType = value.GetType(); + + if (sqlParameter != null) + sqlParameter.UdtTypeName = _udtTypeNameResolvers.Select(_=>_(valueType)).FirstOrDefault(_=>!string.IsNullOrEmpty(_)); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/SqlCeDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/SqlCeDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,120 @@ +using System; +using System.Data; +using System.Data.Common; + +// System.Data.SqlServerCe.dll must be referenced. +// http://www.microsoft.com/sql/editions/compact/default.mspx +// +using System.Data.SqlServerCe; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + + /// + /// Implements access to the Data Provider for Microsoft SQL Server 2005 Everywhere Edition + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + public sealed class SqlCeDataProvider: DataProviderBase + { + /// + /// Creates the database connection object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The database connection object. + public override IDbConnection CreateConnectionObject() + { + return new SqlCeConnection(); + } + + /// + /// Creates the data adapter object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// A data adapter object. + public override DbDataAdapter CreateDataAdapterObject() + { + return new SqlCeDataAdapter(); + } + + /// + /// Populates the specified IDbCommand object's Parameters collection with + /// parameter information for the stored procedure specified in the IDbCommand. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The IDbCommand referencing the stored procedure for which the parameter information is to be derived. The derived parameters will be populated into the Parameters of this command. + public override bool DeriveParameters(IDbCommand command) + { + // SqlCeCommandBuilder does not implement DeriveParameters. + // This is not surprising, since SQL/e has no support for stored procs. + // + return false; + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.ExceptionToErrorNumber: + if (value is SqlCeException) + return ((SqlCeException)value).NativeError; + break; + } + + return SqlProvider.Convert(value, convertType); + } + + /// + /// Returns connection type. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// An instance of the class. + public override Type ConnectionType + { + get { return typeof(SqlCeConnection); } + } + + /// + /// Returns the data provider name. + /// + /// + /// See the method to find an example. + /// + /// AddDataProvider Method + /// Data provider name. + public override string Name + { + get { return DataProvider.ProviderName.SqlCe; } + } + + public override int MaxBatchSize + { + get { return 0; } + } + + public override ISqlProvider CreateSqlProvider() + { + return new SqlCeSqlProvider(); + } + + public override DbType GetParameterDbType(DbType dbType) + { + return dbType == DbType.DateTime2 ? DbType.DateTime : dbType; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/SqlDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/SqlDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +using System; + +namespace BLToolkit.Data.DataProvider +{ + public sealed class SqlDataProvider : SqlDataProviderBase + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/SqlDataProviderBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/SqlDataProviderBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,430 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.SqlClient; +using System.Linq; + +using SqlException = System.Data.SqlClient.SqlException; +using SqlParameter = System.Data.SqlClient.SqlParameter; + +namespace BLToolkit.Data.DataProvider +{ + using Mapping; + using Sql.SqlProvider; + + /// + /// Implements access to the Data Provider for SQL Server. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + public abstract class SqlDataProviderBase : DataProviderBase + { + /// + /// Creates the database connection object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The database connection object. + public override IDbConnection CreateConnectionObject() + { + return new SqlConnection(); + } + + /// + /// Creates the data adapter object. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// A data adapter object. + public override DbDataAdapter CreateDataAdapterObject() + { + return new SqlDataAdapter(); + } + + /// + /// Populates the specified object's Parameters collection with + /// parameter information for the stored procedure specified in the . + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// The referencing the stored procedure for which the parameter + /// information is to be derived. The derived parameters will be populated into the + /// Parameters of this command. + public override bool DeriveParameters(IDbCommand command) + { + SqlCommandBuilder.DeriveParameters((SqlCommand)command); + +#if !MONO + foreach (SqlParameter p in command.Parameters) + { + // We have to clear UDT type names. + // Otherwise it will fail with error + // "Database name is not allowed with a table-valued parameter" + // but this is exactly the way how they are discovered. + // + if (p.SqlDbType == SqlDbType.Structured) + { + var firstDot = p.TypeName.IndexOf('.'); + if (firstDot >= 0) + p.TypeName = p.TypeName.Substring(firstDot + 1); + } + } +#endif + + return true; + } + + public override void PrepareCommand(ref CommandType commandType, ref string commandText, ref IDbDataParameter[] commandParameters) + { + base.PrepareCommand(ref commandType, ref commandText, ref commandParameters); + + if (commandParameters == null) + return; + + foreach (var p in commandParameters) + { + var val = p.Value; + + if (val == null || !val.GetType().IsArray || val is byte[] || val is char[]) + continue; + + var dt = new DataTable(); + + dt.Columns.Add("column_value", val.GetType().GetElementType()); + + dt.BeginLoadData(); + + foreach (object o in (Array)val) + { + var row = dt.NewRow(); + row[0] = o; + dt.Rows.Add(row); + } + + dt.EndLoadData(); + + p.Value = dt; + } + } + + public override void SetUserDefinedType(IDbDataParameter parameter, string typeName) + { +#if !MONO + if (!(parameter is SqlParameter)) + throw new ArgumentException("SqlParameter expected.", "parameter"); + + ((SqlParameter)parameter).TypeName = typeName; +#else + throw new NotSupportedException(); +#endif + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.ExceptionToErrorNumber: + if (value is SqlException) + return ((SqlException)value).Number; + break; + } + + return SqlProvider.Convert(value, convertType); + } + + public override DataExceptionType ConvertErrorNumberToDataExceptionType(int number) + { + switch (number) + { + case 1205: return DataExceptionType.Deadlock; + case -2: return DataExceptionType.Timeout; + case 547: return DataExceptionType.ForeignKeyViolation; + case 2601: return DataExceptionType.UniqueIndexViolation; + case 2627: return DataExceptionType.ConstraintViolation; + } + + return DataExceptionType.Undefined; + } + + /// + /// Returns connection type. + /// + /// + /// See the method to find an example. + /// + /// AddDataManager Method + /// An instance of the class. + public override Type ConnectionType + { + get { return typeof(SqlConnection); } + } + + public const string NameString = DataProvider.ProviderName.MsSql; + + /// + /// Returns the data provider name. + /// + /// + /// See the method to find an example. + /// + /// AddDataProvider Method + /// Data provider name. + public override string Name + { + get { return NameString; } + } + + public override ISqlProvider CreateSqlProvider() + { + return new MsSql2005SqlProvider(); + } + + public override int MaxParameters + { + get { return 2100 - 20; } + } + + public override int MaxBatchSize + { + get { return 65536; } + } + + public override bool IsMarsEnabled(IDbConnection conn) + { + if (conn.ConnectionString != null) + { + return conn.ConnectionString.Split(';') + .Select(s => s.Split('=')) + .Where (s => s.Length == 2 && s[0].Trim().ToLower() == "multipleactiveresultsets") + .Select(s => s[1].Trim().ToLower()) + .Any (s => s == "true" || s == "1" || s == "yes"); + } + + return false; + } + + #region GetDataReader + + public override IDataReader GetDataReader(MappingSchema schema, IDataReader dataReader) + { + return dataReader is SqlDataReader? + new SqlDataReaderEx((SqlDataReader)dataReader): + base.GetDataReader(schema, dataReader); + } + + class SqlDataReaderEx : DataReaderEx + { + public SqlDataReaderEx(SqlDataReader rd): base(rd) + { + } + + public override DateTimeOffset GetDateTimeOffset(int i) + { +#if !MONO + return DataReader.GetDateTimeOffset(i); +#else + throw new NotSupportedException(); +#endif + } + } + + #endregion + + public override int InsertBatch( + DbManager db, + string insertText, + IEnumerable collection, + MemberMapper[] members, + int maxBatchSize, + DbManager.ParameterProvider getParameters) + { + if (db.Transaction != null) + return base.InsertBatch(db, insertText, collection, members, maxBatchSize, getParameters); + + var idx = insertText.IndexOf('\n'); + var tbl = insertText.Substring(0, idx).Substring("INSERT INTO ".Length).TrimEnd('\r'); + var rd = new BulkCopyReader(members, collection); + var bc = new SqlBulkCopy((SqlConnection)db.Connection) + { + BatchSize = maxBatchSize, + DestinationTableName = tbl, + }; + + foreach (var memberMapper in members) + bc.ColumnMappings.Add(new SqlBulkCopyColumnMapping(memberMapper.Ordinal, memberMapper.Name)); + + bc.WriteToServer(rd); + + return rd.Count; + } + + class BulkCopyReader : IDataReader + { + readonly MemberMapper[] _members; + readonly IEnumerable _collection; + readonly IEnumerator _enumerator; + + public int Count; + + public BulkCopyReader(MemberMapper[] members, IEnumerable collection) + { + _members = members; + _collection = collection; + _enumerator = _collection.GetEnumerator(); + } + + #region Implementation of IDisposable + + public void Dispose() + { + } + + #endregion + + #region Implementation of IDataRecord + + public string GetName(int i) + { + return _members[i].Name; + } + + public Type GetFieldType(int i) + { + return _members[i].Type; + } + + public object GetValue(int i) + { + return _members[i].GetValue(_enumerator.Current); + } + + public int FieldCount + { + get { return _members.Length; } + } + + public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) + { + throw new NotImplementedException(); + } + + public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) + { + throw new NotImplementedException(); + } + + public string GetDataTypeName(int i) { throw new NotImplementedException(); } + public int GetValues (object[] values) { throw new NotImplementedException(); } + public int GetOrdinal (string name) { throw new NotImplementedException(); } + public bool GetBoolean (int i) { throw new NotImplementedException(); } + public byte GetByte (int i) { throw new NotImplementedException(); } + public char GetChar (int i) { throw new NotImplementedException(); } + public Guid GetGuid (int i) { throw new NotImplementedException(); } + public short GetInt16 (int i) { throw new NotImplementedException(); } + public int GetInt32 (int i) { throw new NotImplementedException(); } + public long GetInt64 (int i) { throw new NotImplementedException(); } + public float GetFloat (int i) { throw new NotImplementedException(); } + public double GetDouble (int i) { throw new NotImplementedException(); } + public string GetString (int i) { throw new NotImplementedException(); } + public decimal GetDecimal (int i) { throw new NotImplementedException(); } + public DateTime GetDateTime (int i) { throw new NotImplementedException(); } + public IDataReader GetData (int i) { throw new NotImplementedException(); } + public bool IsDBNull (int i) { throw new NotImplementedException(); } + + object IDataRecord.this[int i] + { + get { throw new NotImplementedException(); } + } + + object IDataRecord.this[string name] + { + get { throw new NotImplementedException(); } + } + + #endregion + + #region Implementation of IDataReader + + public void Close() + { + throw new NotImplementedException(); + } + + public DataTable GetSchemaTable() + { + throw new NotImplementedException(); + } + + public bool NextResult() + { + throw new NotImplementedException(); + } + + public bool Read() + { + var b = _enumerator.MoveNext(); + + if (b) + Count++; + + return b; + } + + public int Depth + { + get { throw new NotImplementedException(); } + } + + public bool IsClosed + { + get { throw new NotImplementedException(); } + } + + public int RecordsAffected + { + get { throw new NotImplementedException(); } + } + + #endregion + } + + public override void SetParameterValue(IDbDataParameter parameter, object value) + { + if (value is sbyte) + { + parameter.Value = (byte)(sbyte)value; + } + else if (value is ushort) + { + parameter.Value = (short)(ushort)value; + } + else if (value is uint) + { + parameter.Value = (int)(uint)value; + } + else if (value is ulong) + { + parameter.Value = (long)(ulong)value; + } + else if (value is string) + { + parameter.Value = value; + if (parameter.DbType == DbType.String && ((string)value).Length == 0) parameter.Size = 1; + } + else + { + base.SetParameterValue(parameter, value); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/SybaseAdoDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/SybaseAdoDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,45 @@ +using System; +using System.Data; +using System.Data.OleDb; + +namespace BLToolkit.Data.DataProvider +{ + // Data Provider for DataDirect Sybase ADO Provider 4.2 + // + public sealed class SybaseAdoDataProvider : OleDbDataProvider + { + public override bool DeriveParameters(IDbCommand command) + { + OleDbCommandBuilder.DeriveParameters((OleDbCommand)command); + return true; + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter: + return "?"; + + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return value; + } + + return base.Convert(value, convertType); + } + + public override void AttachParameter(IDbCommand command, IDbDataParameter parameter) + { + if (parameter.Value is string && parameter.DbType == DbType.Guid) + parameter.DbType = DbType.AnsiString; + + base.AttachParameter(command, parameter); + } + + public override string Name + { + get { return "SybaseAdo"; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DataProvider/SybaseDataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/SybaseDataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,221 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text; + +using BLToolkit.Mapping; + +using Sybase.Data.AseClient; + +namespace BLToolkit.Data.DataProvider +{ + using Sql.SqlProvider; + + public class SybaseDataProvider : DataProviderBase + { + public override IDbConnection CreateConnectionObject() + { + return new AseConnection(); + } + + public override DbDataAdapter CreateDataAdapterObject() + { + return new AseDataAdapter(); + } + + public override bool DeriveParameters(IDbCommand command) + { + AseCommandBuilder.DeriveParameters((AseCommand)command); + return true; + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.ExceptionToErrorNumber: + if (value is AseException) + { + var ex = (AseException)value; + + foreach (AseError error in ex.Errors) + if (error.IsError) + return error.MessageNumber; + + foreach (AseError error in ex.Errors) + if (error.MessageNumber != 0) + return error.MessageNumber; + + return 0; + } + + break; + + case ConvertType.ExceptionToErrorMessage: + if (value is AseException) + { + try + { + var ex = (AseException)value; + var sb = new StringBuilder(); + + foreach (AseError error in ex.Errors) + if (error.IsError) + sb.AppendFormat("{0} Ln: {1}{2}", + error.Message.TrimEnd('\n', '\r'), error.LineNum, Environment.NewLine); + + foreach (AseError error in ex.Errors) + if (!error.IsError) + sb.AppendFormat("* {0}{1}", error.Message, Environment.NewLine); + + return sb.Length == 0 ? ex.Message : sb.ToString(); + } + catch + { + } + } + + break; + } + + return SqlProvider.Convert(value, convertType); + } + + public override void AttachParameter(IDbCommand command, IDbDataParameter parameter) + { + if (parameter.Value is string && parameter.DbType == DbType.Guid) + parameter.DbType = DbType.AnsiString; + + base.AttachParameter(command, parameter); + + var p = (AseParameter)parameter; + + if (p.AseDbType == AseDbType.Unsupported && p.Value is DBNull) + parameter.DbType = DbType.AnsiString; + } + + public override Type ConnectionType + { + get { return typeof(AseConnection); } + } + + public override string Name + { + get { return DataProvider.ProviderName.Sybase; } + } + + public override ISqlProvider CreateSqlProvider() + { + return new SybaseSqlProvider(); + } + + public override bool InitParameter(IDbDataParameter parameter) + { + if (parameter.Value is Guid) + { + parameter.Value = parameter.Value.ToString(); + parameter.DbType = DbType.StringFixedLength; + parameter.Size = 36; + + return true; + } + + return false; + } + + public override void PrepareCommand(ref CommandType commandType, ref string commandText, ref IDbDataParameter[] commandParameters) + { + base.PrepareCommand(ref commandType, ref commandText, ref commandParameters); + + List list = null; + + if (commandParameters != null) for (var i = 0; i < commandParameters.Length; i++) + { + var p = commandParameters[i]; + + if (p.Value is Guid) + { + p.Value = p.Value.ToString(); + p.DbType = DbType.StringFixedLength; + p.Size = 36; + } + + if (commandType == CommandType.Text) + { + if (commandText.IndexOf(p.ParameterName) < 0) + { + if (list == null) + { + list = new List(commandParameters.Length); + + for (var j = 0; j < i; j++) + list.Add(commandParameters[j]); + } + } + else + { + if (list != null) + list.Add(p); + } + } + } + + if (list != null) + commandParameters = list.ToArray(); + } + + public override string EndOfSql { get { return ""; } } + + public override DbType GetDbType(Type systemType) + { + if (systemType == typeof(byte[])) + return DbType.Object; + + return base.GetDbType(systemType); + } + + #region DataReaderEx + + public override IDataReader GetDataReader(MappingSchema schema, IDataReader dataReader) + { + return dataReader is AseDataReader? + new DataReaderEx((AseDataReader)dataReader): + base.GetDataReader(schema, dataReader); + } + + class DataReaderEx : DataReaderBase, IDataReader + { + public DataReaderEx(AseDataReader rd): base(rd) + { + } + + public new object GetValue(int i) + { + var value = DataReader.GetValue(i); + + if (value is DateTime) + { + var dt = (DateTime)value; + + if (dt.Year == 1900 && dt.Month == 1 && dt.Day == 1) + return new DateTime(1, 1, 1, dt.Hour, dt.Minute, dt.Second, dt.Millisecond); + } + + return value; + } + + public new DateTime GetDateTime(int i) + { + var dt = DataReader.GetDateTime(i); + + if (dt.Year == 1900 && dt.Month == 1 && dt.Day == 1) + return new DateTime(1, 1, 1, dt.Hour, dt.Minute, dt.Second, dt.Millisecond); + + return dt; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DbConnectionFactory.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DbConnectionFactory.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ +using BLToolkit.Data.DataProvider; + +namespace BLToolkit.Data +{ + public abstract class DbConnectionFactory : IDbConnectionFactory + { + public DataProviderBase Provider; + public string ConnectionString { get; set; } + + #region IDbConnectionFactory Members + + public DbManager CreateDbManager() + { + return CreateDbManager(Provider, ConnectionString); + } + + public virtual DbManager CreateDbManager(DataProviderBase provider, string connectionString) + { + return new DbManager(provider, connectionString); + } + + #endregion + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Data/DbManager.Config.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DbManager.Config.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,782 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Data.SqlClient; +using System.Diagnostics; +using System.Linq; + +namespace BLToolkit.Data +{ + using Configuration; + using DataProvider; + using Properties; + + public partial class DbManager + { + #region Constructors + + /// + /// Initializes a new instance of the class + /// and opens a database connection. + /// + /// + /// + /// This constructor uses a configuration, which has been used first in your application. + /// If there has been no connection used before, an empty string is applied as a default configuration. + /// + /// + /// See the property + /// for an explanation and use of the default configuration. + /// + /// + /// + /// + /// An instance of the database manager class. + [DebuggerStepThrough] + public DbManager() : this(DefaultConfiguration) + { + } + + /// + /// Initializes a new instance of the class + /// and opens a database connection for the provided configuration. + /// + /// + /// See the property + /// for an explanation and use of the configuration string. + /// + /// + /// Configuration string. + /// An instance of the class. + [DebuggerStepThrough] + public DbManager(string configurationString) + : this( + GetDataProvider (configurationString), + GetConnectionString(configurationString)) + { + _configurationString = configurationString; + } + + /// + /// Initializes a new instance of the class + /// and opens a database connection for the provided configuration. + /// + /// + /// See the property + /// for an explanation and use of the configuration string. + /// + /// Configuration string not containing provider name. + /// Provider configuration name. + /// An instance of the class. + [DebuggerStepThrough] + public DbManager(string providerName, string configuration) + : this( + GetDataProvider (providerName + ProviderNameDivider + configuration), + GetConnectionString(providerName + ProviderNameDivider + configuration)) + { + _configurationString = providerName + ProviderNameDivider + configuration; + } + + /// + /// Initializes a new instance of the class for the provided connection. + /// + /// + /// This constructor tries to open the connection if the connection state equals + /// ConnectionState.Closed. + /// In this case the property of the connection + /// must be set before colling the constructor. + /// Otherwise, it neither opens nor closes the connection. + /// + /// + /// Type of the connection could not be recognized. + /// + /// + /// An instance of the class. + /// An instance of the class. + [DebuggerStepThrough] + public DbManager(IDbConnection connection) + : this(GetDataProvider(connection), connection) + { + } + + /// + /// Initializes a new instance of the class for the provided transaction. + /// + /// + /// + [DebuggerStepThrough] + public DbManager(IDbTransaction transaction) + : this(GetDataProvider(transaction.Connection), transaction) + { + } + + /* + /// + /// Initializes a new instance of the class + /// and opens a database connection for the provided configuration and database connection. + /// + /// + /// + /// This constructor opens the connection only if the connection state equals + /// ConnectionState.Closed. + /// Otherwise, it neither opens nor closes the connection. + /// + /// + /// See the property + /// for an explanation and use of the configuration string. + /// + /// + /// + /// An instance of the . + /// The configuration string. + /// An instance of the class. + [DebuggerStepThrough] + public DbManager( + IDbConnection connection, + string configurationString) + { + if (connection == null) + { + Init(configurationString); + + if (configurationString != null) + OpenConnection(configurationString); + } + else + { + Init(connection); + + _configurationString = configurationString; + _connection.ConnectionString = GetConnectionString(configurationString); + + if (_connection.State == ConnectionState.Closed) + OpenConnection(); + } + } + */ + + #endregion + + #region Public Properties + + private string _configurationString; + /// + /// Gets the string used to open a database. + /// + /// + /// A string containing configuration settings. + /// + /// + /// + /// An actual database connection string is read from the appSettings section + /// of application configuration file (App.config, Web.config, or Machine.config) + /// according to the follow rule: + /// + /// + /// <appSettings> + /// <add + /// key = "ConnectionString.configurationString" + /// value = "Server=(local);Database=Northwind;Integrated Security=SSPI" /> + /// </appSettings> + /// + /// + /// If the configuration string is empty, the following rule is applied: + /// + /// + /// <appSettings> + /// <add + /// key = "ConnectionString" + /// value = "Server=(local);Database=Northwind;Integrated Security=SSPI" /> + /// </appSettings> + /// + /// + /// If you don't want to use a configuration file, you can add a database connection string + /// using the method. + /// + /// + /// The configuration string may have a prefix used to define a data provider. The following table + /// contains prefixes for all supported data providers: + /// + /// PrefixProvider + /// SqlData Provider for SQL Server + /// OleDbData Provider for OLE DB + /// OdbcData Provider for ODBC + /// OracleData Provider for Oracle + /// + /// + /// + /// + public string ConfigurationString + { + [DebuggerStepThrough] + get { return _configurationString; } + } + + #endregion + + #region Config Overrides + + protected virtual void InitDataProvider(IDbConnection connection) + { + DataProvider = GetDataProvider(connection); + } + + protected virtual IDbConnection CloneConnection() + { + if (Connection is ICloneable || ConfigurationString == null) + return _dataProvider.CloneConnection(_connection); + + var con = DataProvider.CreateConnectionObject(); + + con.ConnectionString = GetConnectionString(ConfigurationString); + + return con; + } + + protected virtual string GetConnectionHash() + { + return ConfigurationString ?? Connection.ConnectionString.GetHashCode().ToString(); + } + + #endregion + + #region Protected Static Members + + static DbManager() + { + AddDataProvider(new Sql2012DataProvider()); + AddDataProvider(new Sql2008DataProvider()); + AddDataProvider(new Sql2005DataProvider()); + AddDataProvider(new SqlDataProvider()); + AddDataProvider(new Sql2000DataProvider()); + AddDataProvider(new AccessDataProvider()); + AddDataProvider(new OleDbDataProvider()); + AddDataProvider(new OdbcDataProvider()); + + var section = BLToolkitSection.Instance; + + if (section != null) + { + _defaultConfiguration = section.DefaultConfiguration; + + foreach (DataProviderElement provider in section.DataProviders) + { + var dataProviderType = Type.GetType(provider.TypeName, true); + var providerInstance = (DataProviderBase)Activator.CreateInstance(dataProviderType); + + if (!string.IsNullOrEmpty(provider.Name)) + providerInstance.UniqueName = provider.Name; + + providerInstance.Configure(provider.Attributes); + + AddDataProvider(providerInstance); + + if (!provider.Default) + continue; + + if (_defaultDataProviderName != null) + { + throw new ConfigurationErrorsException(string.Format( + Resources.DbManager_MoreThenOneDefaultProvider, _defaultDataProviderName, providerInstance.UniqueName), + provider.ElementInformation.Source, provider.ElementInformation.LineNumber); + } + + _defaultDataProviderName = providerInstance.UniqueName; + } + } + + var dataProviders = ConfigurationManager.AppSettings.Get("BLToolkit.DataProviders"); + + if (dataProviders != null) + { + if (TraceSwitch.TraceWarning) + WriteTraceLine("Using appSettings\\BLToolkit.DataProviders is obsolete. Consider using bltoolkit configuration section instead.", TraceSwitch.DisplayName); + + foreach (var dataProviderTypeName in dataProviders.Split(';')) + AddDataProvider(Type.GetType(dataProviderTypeName, true)); + } + + if (string.IsNullOrEmpty(_defaultConfiguration)) + _defaultConfiguration = ConfigurationManager.AppSettings.Get("BLToolkit.DefaultConfiguration"); + + if (string.IsNullOrEmpty(_defaultDataProviderName)) + _defaultDataProviderName = SqlDataProviderBase.NameString; + } + + volatile static string _firstConfiguration; + private static DataProviderBase _firstProvider; + private static readonly Hashtable _configurationList = Hashtable.Synchronized(new Hashtable()); + private static readonly Hashtable _anyProviderConfigurationList = Hashtable.Synchronized(new Hashtable()); + + private static DataProviderBase GetDataProvider(IDbConnection connection) + { + if (connection == null) throw new ArgumentNullException("connection"); + + var dp = _dataProviderTypeList[connection.GetType()]; + + if (dp == null) + throw new DataException(string.Format( + Resources.DbManager_UnknownConnectionType, connection.GetType().FullName)); + + return dp; + } + + public static DataProviderBase GetDataProvider(string configurationString) + { + if (configurationString == null) throw new ArgumentNullException("configurationString"); + + if (configurationString.StartsWith(AnyProvider)) + return FindFirstSuitableProvider(configurationString); + + if (configurationString == _firstConfiguration) + return _firstProvider; + + var dp = (DataProviderBase)_configurationList[configurationString]; + + if (dp == null) + { + var css = ConfigurationManager.ConnectionStrings[configurationString]; + + if (css != null && !string.IsNullOrEmpty(css.ProviderName)) + { + string provider = null; + + if (css.ProviderName == "System.Data.SqlClient") + { + try + { + using (SqlConnection sqlConnection = new SqlConnection(css.ConnectionString)) + { + sqlConnection.Open(); + + string serverVersion = sqlConnection.ServerVersion; + string[] serverVersionDetails = serverVersion.Split(new string[] {"."}, + StringSplitOptions.None); + + int versionNumber = int.Parse(serverVersionDetails[0]); + + switch (versionNumber) + { + case 8: provider = "MSSQL2000"; break; + case 9: provider = "MSSQL2005"; break; //MSSQL 2005 -> Can the same as 2008 + case 10: provider = "MSSQL2008"; break; + case 11: provider = "MSSQL2012"; break; + default: provider = "MSSQL2008"; break; + } + } + } + catch (Exception) + {} + } + + if (provider == null) + { + // This hack should be redone. + // + provider = css.ProviderName == "System.Data.SqlClient" ? + configurationString.IndexOf("2012") >= 0 ? "MSSQL2012" : + configurationString.IndexOf("2008") >= 0 ? "MSSQL2008" : + configurationString.IndexOf("2000") >= 0 ? "MSSQL2000" : + css.ProviderName : + css.ProviderName; + } + + dp = _dataProviderNameList[provider]; + } + else + { + // configurationString can be: + // '' : default provider, default configuration; + // '.' : default provider, default configuration; + // 'foo.bar' : 'foo' provider, 'bar' configuration; + // 'foo.' : 'foo' provider, default configuration; + // 'foo' : default provider, 'foo' configuration or + // foo provider, default configuration; + // '.foo' : default provider, 'foo' configuration; + // '.foo.bar': default provider, 'foo.bar' configuration; + // + // Default provider is SqlDataProvider + // + var cs = configurationString.ToUpper(); + var key = _defaultDataProviderName; + + if (cs.Length > 0) + { + cs += ProviderNameDivider; + + foreach (var k in _dataProviderNameList.Keys) + { + if (cs.StartsWith(k + ProviderNameDivider)) + { + key = k; + break; + } + } + } + + dp = _dataProviderNameList[key]; + } + + if (dp == null) + throw new DataException(string.Format( + Resources.DbManager_UnknownDataProvider, configurationString)); + + _configurationList[configurationString] = dp; + } + + if (_firstConfiguration == null) + { + lock (_configurationList.SyncRoot) + { + if (_firstConfiguration == null) + { + _firstConfiguration = configurationString; + _firstProvider = dp; + } + } + } + + return dp; + } + + private static bool IsMatchedConfigurationString(string configurationString, string csWithoutProvider) + { + int dividerPos; + + return + !configurationString.StartsWith(AnyProvider) && + (dividerPos = configurationString.IndexOf(ProviderNameDivider)) >= 0 && + 0 == StringComparer.OrdinalIgnoreCase.Compare + (configurationString.Substring(dividerPos + ProviderNameDivider.Length), csWithoutProvider); + } + + private static DataProviderBase FindFirstSuitableProvider(string configurationString) + { + var cs = (string)_anyProviderConfigurationList[configurationString]; + var searchRequired = (cs == null); + + if (searchRequired) + { + var csWithoutProvider = configurationString.Substring(AnyProvider.Length); + + if (configurationString.Length == 0) throw new ArgumentNullException("configurationString"); + + foreach (var str in _connectionStringList.Keys) + { + if (IsMatchedConfigurationString(str, csWithoutProvider)) + { + cs = str; + break; + } + } + + if (cs == null) + { + foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings) + { + if (IsMatchedConfigurationString(css.Name, csWithoutProvider)) + { + cs = css.Name; + break; + } + } + } + + if (cs == null) + { + foreach (var name in ConfigurationManager.AppSettings.AllKeys) + { + if (name.StartsWith("ConnectionString" + ProviderNameDivider)) + { + var str = name.Substring(name.IndexOf(ProviderNameDivider) + ProviderNameDivider.Length); + + if (IsMatchedConfigurationString(str, csWithoutProvider)) + { + cs = str; + break; + } + } + } + } + + if (cs == null) + cs = csWithoutProvider; + } + + var dp = GetDataProvider(cs); + + if (searchRequired) + _anyProviderConfigurationList[configurationString] = cs; + return dp; + } + + private static readonly Dictionary _connectionStringList = new Dictionary(4); + + public static string GetConnectionString(string configurationString) + { + // Use default configuration. + // + if (configurationString == null) + configurationString = DefaultConfiguration; + + if (_anyProviderConfigurationList.Contains(configurationString)) + configurationString = (string)_anyProviderConfigurationList[configurationString]; + + string str; + + // Check cached strings first. + // + if (!_connectionStringList.TryGetValue(configurationString, out str)) + { + lock (_dataProviderListLock) + { + // Connection string is not in the cache. + // + var key = string.Format("ConnectionString{0}{1}", + configurationString.Length == 0? String.Empty: ProviderNameDivider, configurationString); + + var css = ConfigurationManager.ConnectionStrings[configurationString]; + + str = css != null? css.ConnectionString: ConfigurationManager.AppSettings.Get(key); + + if (string.IsNullOrEmpty(str)) + { + throw new DataException(string.Format( + Resources.DbManager_UnknownConfiguration, key)); + } + + // Store the result in cache. + // + _connectionStringList[configurationString] = str; + } + } + + return str; + } + + /* + private void OpenConnection(string configurationString) + { + // If connection is already opened, we close it and open again. + // + if (_connection != null) + { + Dispose(); + GC.ReRegisterForFinalize(this); + } + + // Store the configuration string. + // + _configurationString = configurationString; + + // Create and open the connection object. + // + _connection = _dataProvider.CreateConnectionObject(); + _connection.ConnectionString = GetConnectionString(ConfigurationString); + + OpenConnection(); + } + */ + + #endregion + + #region AddDataProvider + + static readonly Dictionary _dataProviderNameList = new Dictionary(8, StringComparer.OrdinalIgnoreCase); + static readonly Dictionary _dataProviderTypeList = new Dictionary(4); + static readonly object _dataProviderListLock = new object(); + + /// + /// Adds a new data provider. + /// + /// + /// The method can be used to register a new data provider for further use. + /// + /// + /// + /// + /// An instance of the interface. + public static void AddDataProvider(DataProviderBase dataProvider) + { + if (null == dataProvider) + throw new ArgumentNullException("dataProvider"); + + if (string.IsNullOrEmpty(dataProvider.UniqueName)) + throw new ArgumentException(Resources.DbManager_InvalidDataProviderName, "dataProvider"); + + if (string.IsNullOrEmpty(dataProvider.ProviderName)) + throw new ArgumentException(Resources.DbManager_InvalidDataProviderProviderName, "dataProvider"); + + if (dataProvider.ConnectionType == null || !typeof(IDbConnection).IsAssignableFrom(dataProvider.ConnectionType)) + throw new ArgumentException(Resources.DbManager_InvalidDataProviderConnectionType, "dataProvider"); + + lock (_dataProviderListLock) + { + _dataProviderNameList[dataProvider.UniqueName.ToUpper()] = dataProvider; + _dataProviderNameList[dataProvider.ProviderName] = dataProvider; + _dataProviderTypeList[dataProvider.ConnectionType] = dataProvider; + } + } + + /// + /// Adds a new data provider witch a specified name. + /// + /// + /// The method can be used to register a new data provider for further use. + /// + /// + /// + /// + /// The data provider name. + /// An instance of the interface. + public static void AddDataProvider(string providerName, DataProviderBase dataProvider) + { + if (dataProvider == null) + throw new ArgumentNullException("dataProvider"); + + if (string.IsNullOrEmpty(providerName)) + throw new ArgumentException(Resources.DbManager_InvalidDataProviderName, "providerName"); + + dataProvider.UniqueName = providerName; + AddDataProvider(dataProvider); + } + + /// + /// Adds a new data provider. + /// + /// + /// The method can be used to register a new data provider for further use. + /// + /// + /// + /// A data provider type. + public static void AddDataProvider(Type dataProviderType) + { + AddDataProvider((DataProviderBase)Activator.CreateInstance(dataProviderType)); + } + + /// + /// Adds a new data provider witch a specified name. + /// + /// + /// The method can be used to register a new data provider for further use. + /// + /// + /// + /// The data provider name. + /// A data provider type. + public static void AddDataProvider(string providerName, Type dataProviderType) + { + AddDataProvider(providerName, (DataProviderBase)Activator.CreateInstance(dataProviderType)); + } + + #endregion + + #region AddConnectionString + + /// + /// Adds a new connection string or replaces existing one. + /// + /// + /// Use this method when you use only one configuration and + /// you don't want to use a configuration file. + /// + /// + /// A valid database connection string. + public static void AddConnectionString(string connectionString) + { + AddConnectionString(string.Empty, connectionString); + } + + /// + /// Adds a new connection string or replaces existing one. + /// + /// + /// Use this method when you use multiple configurations and + /// you don't want to use a configuration file. + /// + /// + /// The configuration string. + /// A valid database connection string. + public static void AddConnectionString(string configurationString, string connectionString) + { + _connectionStringList[configurationString] = connectionString; + } + + /// + /// Adds a new connection string or replaces existing one. + /// + /// + /// Use this method when you use multiple configurations and + /// you don't want to use a configuration file. + /// + /// + /// The data provider name. + /// The configuration string. + /// A valid database connection string. + public static void AddConnectionString( + string providerName, string configurationString, string connectionString) + { + AddConnectionString(providerName + ProviderNameDivider + configurationString, connectionString); + } + + #endregion + + #region Public Static Properties + + public const string ProviderNameDivider = "."; + public const string AnyProvider = "*" + ProviderNameDivider; + + private static readonly string _defaultDataProviderName; + private static string _defaultConfiguration; + + /// + /// Gets and sets the default configuration string. + /// + /// + /// See the property + /// for an explanation and use of the default configuration. + /// + /// + /// A string containing default configuration settings. + /// + /// + public static string DefaultConfiguration + { + get + { + if (_defaultConfiguration == null) + { + // Grab first registered configuration. + // + var defaultConfiguration = _connectionStringList.Select(de => de.Key).FirstOrDefault(); + + if (defaultConfiguration == null) + { + defaultConfiguration = string.Empty; + + foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings) + { + if (css.ElementInformation.Source != null && + !css.ElementInformation.Source.EndsWith("machine.config", StringComparison.OrdinalIgnoreCase)) + { + defaultConfiguration = css.Name; + break; + } + } + } + + _defaultConfiguration = defaultConfiguration; + } + + return _defaultConfiguration; + } + + set { _defaultConfiguration = value; } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DbManager.Linq.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DbManager.Linq.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,366 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Reflection; +using System.Text; + +using BLToolkit.Aspects; + +namespace BLToolkit.Data +{ + using DataProvider; + using Linq; + using Sql; + using Sql.SqlProvider; + + public partial class DbManager : IDataContext + { + public Table GetTable() + where T : class + { + return new Table(this); + } + + public Table GetTable(bool dispose) + where T : class + { + return new Table(new DataContextInfo(this, dispose)); + } + + public Table GetTable(object instance, [NotNull]MethodInfo methodInfo, [NotNull] params object[] parameters) + where T : class + { + return Linq.Extensions.GetTable(this, instance, methodInfo, parameters); + } + + class PreparedQuery + { + public string[] Commands; + public List SqlParameters; + public IDbDataParameter[] Parameters; + public SqlQuery SqlQuery; + public ISqlProvider SqlProvider; + } + + #region SetQuery + + object IDataContext.SetQuery(IQueryContext queryContext) + { + var query = GetCommand(queryContext); + + GetParameters(queryContext, query); + + if (TraceSwitch.TraceInfo) + WriteTraceLine(((IDataContext)this).GetSqlText(query).Replace("\r", ""), TraceSwitch.DisplayName); + + return query; + } + + PreparedQuery GetCommand(IQueryContext query) + { + if (query.Context != null) + { + return new PreparedQuery + { + Commands = (string[])query.Context, + SqlParameters = query.SqlQuery.Parameters, + SqlQuery = query.SqlQuery + }; + } + + var sql = query.SqlQuery.ProcessParameters(); + + var newSql = ProcessQuery(sql); + + if (sql != newSql) + { + sql = newSql; + sql.IsParameterDependent = true; + } + + var sqlProvider = DataProvider.CreateSqlProvider(); + + var cc = sqlProvider.CommandCount(sql); + var sb = new StringBuilder(); + + var commands = new string[cc]; + + for (var i = 0; i < cc; i++) + { + sb.Length = 0; + + sqlProvider.BuildSql(i, sql, sb, 0, 0, false); + commands[i] = sb.ToString(); + } + + if (!query.SqlQuery.IsParameterDependent) + query.Context = commands; + + return new PreparedQuery + { + Commands = commands, + SqlParameters = sql.Parameters, + SqlQuery = sql, + SqlProvider = sqlProvider + }; + } + + protected virtual SqlQuery ProcessQuery(SqlQuery sqlQuery) + { + return sqlQuery; + } + + void GetParameters(IQueryContext query, PreparedQuery pq) + { + var parameters = query.GetParameters(); + + if (parameters.Length == 0 && pq.SqlParameters.Count == 0) + return; + + var x = DataProvider.Convert("x", ConvertType.NameToQueryParameter).ToString(); + var y = DataProvider.Convert("y", ConvertType.NameToQueryParameter).ToString(); + + var parms = new List(x == y ? pq.SqlParameters.Count : parameters.Length); + + if (x == y) + { + for (var i = 0; i < pq.SqlParameters.Count; i++) + { + var sqlp = pq.SqlParameters[i]; + + if (sqlp.IsQueryParameter) + { + var parm = parameters.Length > i && parameters[i] == sqlp ? parameters[i] : parameters.First(p => p == sqlp); + AddParameter(parms, x, parm); + } + } + } + else + { + foreach (var parm in parameters) + { + if (parm.IsQueryParameter && pq.SqlParameters.Contains(parm)) + { + var name = DataProvider.Convert(parm.Name, ConvertType.NameToQueryParameter).ToString(); + AddParameter(parms, name, parm); + } + } + } + + pq.Parameters = parms.ToArray(); + } + + void AddParameter(ICollection parms, string name, SqlParameter parm) + { + var value = MappingSchema.ConvertParameterValue(parm.Value, parm.SystemType); + + if (value != null) + { + if (parm.DbType == DbType.Object) + parms.Add(Parameter(name, value)); + else if (parm.DbSize == 0) + parms.Add(Parameter(name, value, parm.DbType)); + else + parms.Add(Parameter(name, value, parm.DbType, parm.DbSize)); + } + else + { + var dataType = DataProvider.GetDbType(parm.SystemType); + if (parm.DbType != DbType.Object) + dataType = parm.DbType; + parms.Add(dataType == DbType.Object ? Parameter(name, value) : Parameter(name, null, dataType)); + } + } + + #endregion + + #region ExecuteXXX + + int IDataContext.ExecuteNonQuery(object query) + { + var pq = (PreparedQuery)query; + + SetCommand(pq.Commands[0], pq.Parameters); + + var now = default(DateTime); + + if (TraceSwitch.TraceInfo) + now = DateTime.Now; + + var n = ExecuteNonQuery(); + + if (TraceSwitch.TraceInfo) + WriteTraceLine(string.Format("Execution time: {0}. Records affected: {1}.\r\n", DateTime.Now - now, n), TraceSwitch.DisplayName); + + return n; + } + + object IDataContext.ExecuteScalar(object query) + { + var now = default(DateTime); + + if (TraceSwitch.TraceInfo) + now = DateTime.Now; + + var ret = ExecuteScalarInternal(query); + + if (TraceSwitch.TraceInfo) + WriteTraceLine(string.Format("Execution time: {0}\r\n", DateTime.Now - now), TraceSwitch.DisplayName); + + return ret; + } + + object ExecuteScalarInternal(object query) + { + var pq = (PreparedQuery)query; + + SetCommand(pq.Commands[0], pq.Parameters); + + IDbDataParameter idparam = null; + + if ((pq.SqlProvider ?? DataProvider.CreateSqlProvider()).IsIdentityParameterRequired) + { + var sql = pq.SqlQuery; + + if (sql.IsInsert && sql.Insert.WithIdentity) + { + var pname = DataProvider.Convert("IDENTITY_PARAMETER", ConvertType.NameToQueryParameter).ToString(); + idparam = OutputParameter(pname, DbType.Decimal); + DataProvider.AttachParameter(Command, idparam); + } + } + + if (pq.Commands.Length == 1) + { + if (idparam != null) + { + ExecuteNonQuery(); // так сделано потому, что фаерберд провайдер не возвращает никаких параметров через ExecuteReader + // остальные провайдеры должны поддерживать такой режим + return idparam.Value; + } + + return ExecuteScalar(); + } + + ExecuteNonQuery(); + + return SetCommand(pq.Commands[1]).ExecuteScalar(); + } + + IDataReader IDataContext.ExecuteReader(object query) + { + var pq = (PreparedQuery)query; + + SetCommand(pq.Commands[0], pq.Parameters); + + var now = default(DateTime); + + if (TraceSwitch.TraceInfo) + now = DateTime.Now; + + var ret = ExecuteReader(); + + if (TraceSwitch.TraceInfo) + WriteTraceLine(string.Format("Execution time: {0}\r\n", DateTime.Now - now), TraceSwitch.DisplayName); + + return ret; + } + + void IDataContext.ReleaseQuery(object query) + { + } + + #endregion + + #region GetSqlText + + string IDataContext.GetSqlText(object query) + { + var pq = (PreparedQuery)query; + + var sqlProvider = pq.SqlProvider ?? DataProvider.CreateSqlProvider(); + + var sb = new StringBuilder(); + + sb.Append("-- ").Append(ConfigurationString); + + if (ConfigurationString != DataProvider.Name) + sb.Append(' ').Append(DataProvider.Name); + + if (DataProvider.Name != sqlProvider.Name) + sb.Append(' ').Append(sqlProvider.Name); + + sb.AppendLine(); + + if (pq.Parameters != null && pq.Parameters.Length > 0) + { + foreach (var p in pq.Parameters) + sb + .Append("-- DECLARE ") + .Append(p.ParameterName) + .Append(' ') + .Append(p.Value == null ? p.DbType.ToString() : p.Value.GetType().Name) + .AppendLine(); + + sb.AppendLine(); + + foreach (var p in pq.Parameters) + { + var value = p.Value; + + if (value is string || value is char) + value = "'" + value.ToString().Replace("'", "''") + "'"; + + sb + .Append("-- SET ") + .Append(p.ParameterName) + .Append(" = ") + .Append(value) + .AppendLine(); + } + + sb.AppendLine(); + } + + foreach (var command in pq.Commands) + sb.AppendLine(command); + + while (sb[sb.Length - 1] == '\n' || sb[sb.Length - 1] == '\r') + sb.Length--; + + sb.AppendLine(); + + return sb.ToString(); + } + + #endregion + + #region IDataContext Members + + IDataContext IDataContext.Clone(bool forNestedQuery) + { + if (forNestedQuery && _connection != null && IsMarsEnabled) + return new DbManager(_dataProvider, _connection) { _mappingSchema = _mappingSchema, _transaction = _transaction }; + + return Clone(); + } + + string IDataContext.ContextID + { + get { return DataProvider.Name; } + } + + static Func GetCreateSqlProvider(DataProviderBase dp) + { + return dp.CreateSqlProvider; + } + + Func IDataContext.CreateSqlProvider + { + get { return GetCreateSqlProvider(DataProvider); } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/DbManager.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DbManager.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4485 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Data.Common; +using System.Data.SqlTypes; +using System.Diagnostics; +using System.Text; + +#region ReSharper disable +// ReSharper disable UnusedParameter.Local +#pragma warning disable 1589 +#endregion + +namespace BLToolkit.Data +{ + using Common; + using DataProvider; + using Mapping; + using Properties; + using Reflection; + using Sql; + + /// + /// The DbManager is a primary class of the namespace + /// that can be used to execute commands of different database providers. + /// + /// + /// When the DbManager goes out of scope, it does not close the internal connection object. + /// Therefore, you must explicitly close the connection by calling or + /// . Also, you can use the C# using statement. + /// + /// + [DesignerCategory(@"Code")] + public partial class DbManager: Component + { + #region Init + + public DbManager(DataProviderBase dataProvider, string connectionString) + { + if (dataProvider == null) throw new ArgumentNullException("dataProvider"); + if (connectionString == null) throw new ArgumentNullException("connectionString"); + + _dataProvider = dataProvider; + _connection = dataProvider.CreateConnectionObject(); + + _connection.ConnectionString = connectionString; + + _dataProvider.InitDbManager(this); + } + + public DbManager(DataProviderBase dataProvider, IDbConnection connection) + { + if (dataProvider == null) throw new ArgumentNullException("dataProvider"); + if (connection == null) throw new ArgumentNullException("connection"); + + _dataProvider = dataProvider; + _connection = connection; + + _dataProvider.InitDbManager(this); + } + + public DbManager(DataProviderBase dataProvider, IDbTransaction transaction) + { + if (dataProvider == null) throw new ArgumentNullException("dataProvider"); + if (transaction == null) throw new ArgumentNullException("transaction"); + + _dataProvider = dataProvider; + _connection = transaction.Connection; + _transaction = transaction; + _closeTransaction = false; + + _dataProvider.InitDbManager(this); + } + + DbManager(int n) + { + } + + public virtual DbManager Clone() + { + var clone = + new DbManager(0) + { + _configurationString = _configurationString, + _dataProvider = _dataProvider, + _mappingSchema = _mappingSchema + }; + + if (_connection != null) + clone._connection = CloneConnection(); + + return clone; + } + + public string LastQuery; + + #endregion + + #region Public Properties + + private MappingSchema _mappingSchema = Map.DefaultSchema; + /// + /// Gets the + /// used by this instance of the . + /// + /// + /// A mapping schema. + /// + public MappingSchema MappingSchema + { + [DebuggerStepThrough] + get { return _mappingSchema; } + set { _mappingSchema = value ?? Map.DefaultSchema; } + } + + private DataProviderBase _dataProvider; + /// + /// Gets the + /// used by this instance of the . + /// + /// + /// A data provider. + /// + /// + public DataProviderBase DataProvider + { + [DebuggerStepThrough] + get { return _dataProvider; } + protected set { _dataProvider = value; } + } + + private static TraceSwitch _traceSwitch; + public static TraceSwitch TraceSwitch + { + get { return _traceSwitch ?? (_traceSwitch = new TraceSwitch("DbManager", "DbManager trace switch", +#if DEBUG + "Warning" +#else + "Off" +#endif + )); } + set { _traceSwitch = value; } + } + + public static void TurnTraceSwitchOn() + { + TraceSwitch = new TraceSwitch("DbManager", "DbManager trace switch", "Info"); + } + + public static Action WriteTraceLine = (message, displayName) => Debug.WriteLine(message, displayName); + + private bool _canRaiseEvents = true; + public new bool CanRaiseEvents + { + get { return _canRaiseEvents && base.CanRaiseEvents; } + set { _canRaiseEvents = value; } + } + + /// + /// Use plain text query instead of using command parameters + /// + public bool UseQueryText { get; set; } + + #endregion + + #region Connection + + private bool _closeConnection; + private IDbConnection _connection; + /// + /// Gets or sets the used by this instance of the . + /// + /// + /// The connection to the data source. + /// + /// + /// Then you set a connection object, it has to match the data source type. + /// + /// + /// A connection does not match the data source type. + /// + /// + public IDbConnection Connection + { + [DebuggerStepThrough] + get + { + if (_connection.State == ConnectionState.Closed) + OpenConnection(); + return _connection; + } + + set + { + if (value == null) + throw new ArgumentNullException("value"); + + if (value.GetType() != _dataProvider.ConnectionType) + InitDataProvider(value); + + _connection = value; + _closeConnection = false; + } + } + + [Obsolete] + protected virtual string GetConnectionString(IDbConnection connection) + { + return connection.ConnectionString; + } + + private void OpenConnection() + { + ExecuteOperation(OperationType.OpenConnection, _connection.Open); + _closeConnection = true; + } + + /// + /// Closes the connection to the database. + /// + /// + /// The Close method rolls back any pending transactions + /// and then closes the connection. + /// + /// + /// + public void Close() + { + if (OnClosing != null) + OnClosing(this, EventArgs.Empty); + + if (_selectCommand != null) { _selectCommand.Dispose(); _selectCommand = null; } + if (_insertCommand != null) { _insertCommand.Dispose(); _insertCommand = null; } + if (_updateCommand != null) { _updateCommand.Dispose(); _updateCommand = null; } + if (_deleteCommand != null) { _deleteCommand.Dispose(); _deleteCommand = null; } + + if (_transaction != null && _closeTransaction) + { + ExecuteOperation(OperationType.DisposeTransaction, _transaction.Dispose); + _transaction = null; + } + + if (_connection != null && _closeConnection) + { + ExecuteOperation(OperationType.CloseConnection, _connection.Dispose); + _connection = null; + } + + if (OnClosed != null) + OnClosed(this, EventArgs.Empty); + } + + private bool? _isMarsEnabled; + public bool IsMarsEnabled + { + get + { + if (_isMarsEnabled == null) + _isMarsEnabled = DataProvider.IsMarsEnabled(Connection); + + return _isMarsEnabled.Value; + } + set { _isMarsEnabled = value; } + } + + #endregion + + #region Transactions + + private bool _closeTransaction = true; + private IDbTransaction _transaction; + /// + /// Gets the used by this instance of the . + /// + /// + /// The . The default value is a null reference. + /// + /// + /// You have to call the method to begin a transaction. + /// + /// + /// + public IDbTransaction Transaction + { + [DebuggerStepThrough] + get { return _transaction; } + } + + /// + /// Begins a database transaction. + /// + /// + /// Once the transaction has completed, you must explicitly commit or roll back the transaction + /// by using the > or + /// methods. + /// + /// + /// This instance of the . + /// + public virtual DbManager BeginTransaction() + { + return BeginTransaction(IsolationLevel.ReadCommitted); + } + + /// + /// Begins a database transaction with the specified value. + /// + /// + /// Once the transaction has completed, you must explicitly commit or roll back the transaction + /// by using the or + /// methods. + /// + /// + /// One of the values. + /// This instance of the . + public virtual DbManager BeginTransaction(IsolationLevel il) + { + // If transaction is open, we dispose it, it will rollback all changes. + // + if (_transaction != null) + { + ExecuteOperation(OperationType.DisposeTransaction, _transaction.Dispose); + } + + // Create new transaction object. + // + _transaction = ExecuteOperation( + OperationType.BeginTransaction, + () => Connection.BeginTransaction(il)); + + _closeTransaction = true; + + // If the active command exists. + // + if (_selectCommand != null) _selectCommand.Transaction = _transaction; + if (_insertCommand != null) _insertCommand.Transaction = _transaction; + if (_updateCommand != null) _updateCommand.Transaction = _transaction; + if (_deleteCommand != null) _deleteCommand.Transaction = _transaction; + + return this; + } + + /// + /// Commits the database transaction. + /// + /// This instance of the . + public virtual DbManager CommitTransaction() + { + if (_transaction != null) + { + ExecuteOperation(OperationType.CommitTransaction, _transaction.Commit); + + if (_closeTransaction) + { + ExecuteOperation(OperationType.DisposeTransaction, _transaction.Dispose); + _transaction = null; + } + } + + return this; + } + + /// + /// Rolls back a transaction from a pending state. + /// + /// This instance of the . + public virtual DbManager RollbackTransaction() + { + if (_transaction != null) + { + ExecuteOperation(OperationType.RollbackTransaction, _transaction.Rollback); + + if (_closeTransaction) + { + ExecuteOperation(OperationType.DisposeTransaction, _transaction.Dispose); + _transaction = null; + } + } + + return this; + } + + #endregion + + #region Commands + + private IDbCommand _selectCommand; + /// + /// Gets the used by this instance of the . + /// + /// + /// A used during executing query. + /// + /// + /// The Command can be used to access command parameters. + /// + /// + public IDbCommand Command + { + [DebuggerStepThrough] + get { return SelectCommand; } + } + + /// + /// Gets the select used by this instance of the . + /// + /// + /// A used during executing query. + /// + /// + /// The SelectCommand can be used to access select command parameters. + /// + /// + public IDbCommand SelectCommand + { + [DebuggerStepThrough] + get { return _selectCommand = OnInitCommand(_selectCommand); } + } + + private IDbCommand _insertCommand; + /// + /// Gets the insert used by this instance of the . + /// + /// + /// A used during executing query. + /// + /// + /// The InsertCommand can be used to access insert command parameters. + /// + /// + public IDbCommand InsertCommand + { + [DebuggerStepThrough] + get { return _insertCommand = OnInitCommand(_insertCommand); } + } + + private IDbCommand _updateCommand; + /// + /// Gets the update used by this instance of the . + /// + /// + /// A used during executing query. + /// + /// + /// The UpdateCommand can be used to access update command parameters. + /// + /// + public IDbCommand UpdateCommand + { + [DebuggerStepThrough] + get { return _updateCommand = OnInitCommand(_updateCommand); } + } + + private IDbCommand _deleteCommand; + /// + /// Gets the delete used by this instance of the . + /// + /// + /// A used during executing query. + /// + /// + /// The DeleteCommand can be used to access delete command parameters. + /// + /// + public IDbCommand DeleteCommand + { + [DebuggerStepThrough] + get { return _deleteCommand = OnInitCommand(_deleteCommand); } + } + + /// + /// Initializes a command and raises the event. + /// + protected virtual IDbCommand OnInitCommand(IDbCommand command) + { + if (command == null) + { + // Create a command object. + // + command = _dataProvider.CreateCommandObject(Connection); + + // If an active transaction exists. + // + if (Transaction != null) + { + command.Transaction = Transaction; + } + } + + if (CanRaiseEvents) + { + var handler = (InitCommandEventHandler)Events[_eventInitCommand]; + + if (handler != null) + handler(this, new InitCommandEventArgs(command)); + } + + return command; + } + + /// + /// Helper function. Creates the command object and sets command type and command text. + /// + /// Command action. + /// The + /// (stored procedure, text, etc.) + /// The SQL statement. + /// The command object. + private IDbCommand GetCommand(CommandAction commandAction, CommandType commandType, string sql) + { + var command = GetCommand(commandAction, commandType); + + command.Parameters.Clear(); + command.CommandType = commandType; + command.CommandText = sql; + + return command; + } + + #endregion + + #region Events + + public event EventHandler OnClosing; + public event EventHandler OnClosed; + + private static readonly object _eventBeforeOperation = new object(); + /// + /// Occurs when a server-side operation is about to start. + /// + public event OperationTypeEventHandler BeforeOperation + { + add { Events.AddHandler (_eventBeforeOperation, value); } + remove { Events.RemoveHandler(_eventBeforeOperation, value); } + } + + private static readonly object _eventAfterOperation = new object(); + /// + /// Occurs when a server-side operation is complete. + /// + public event OperationTypeEventHandler AfterOperation + { + add { Events.AddHandler (_eventAfterOperation, value); } + remove { Events.RemoveHandler(_eventAfterOperation, value); } + } + + private static readonly object _eventOperationException = new object(); + /// + /// Occurs when a server-side operation is failed to execute. + /// + public event OperationExceptionEventHandler OperationException + { + add { Events.AddHandler (_eventOperationException, value); } + remove { Events.RemoveHandler(_eventOperationException, value); } + } + + private static readonly object _eventInitCommand = new object(); + /// + /// Occurs when the is initializing. + /// + public event InitCommandEventHandler InitCommand + { + add { Events.AddHandler (_eventInitCommand, value); } + remove { Events.RemoveHandler(_eventInitCommand, value); } + } + + /// + /// Raises the event. + /// + /// The . + protected virtual void OnBeforeOperation(OperationType op) + { + if (CanRaiseEvents) + { + var handler = (OperationTypeEventHandler)Events[_eventBeforeOperation]; + if (handler != null) + handler(this, new OperationTypeEventArgs(op)); + } + } + + /// + /// Raises the event. + /// + /// The . + protected virtual void OnAfterOperation(OperationType op) + { + if (CanRaiseEvents) + { + var handler = (OperationTypeEventHandler)Events[_eventAfterOperation]; + if (handler != null) + handler(this, new OperationTypeEventArgs(op)); + } + } + + /// + /// Raises the event. + /// + /// The . + /// The occurred. + protected virtual void OnOperationException(OperationType op, DataException ex) + { + if (CanRaiseEvents) + { + var handler = (OperationExceptionEventHandler)Events[_eventOperationException]; + if (handler != null) + handler(this, new OperationExceptionEventArgs(op, ex)); + } + + throw ex; + } + + #endregion + + #region Protected Methods + + private IDataReader ExecuteReaderInternal() + { + return ExecuteReader(CommandBehavior.Default); + } + + private IDataReader ExecuteReaderInternal(CommandBehavior commandBehavior) + { + return ExecuteOperation( + OperationType.ExecuteReader, + () => + _dataProvider.GetDataReader(_mappingSchema, SelectCommand.ExecuteReader(commandBehavior))); + } + + private int ExecuteNonQueryInternal() + { + return ExecuteOperation(OperationType.ExecuteNonQuery, SelectCommand.ExecuteNonQuery); + } + + #endregion + + #region Parameters + + private IDbDataParameter[] CreateSpParameters(string spName, object[] parameterValues, bool openNewConnectionToDiscoverParameters) + { + // Pull the parameters for this stored procedure from + // the parameter cache (or discover them & populate the cache) + // + var spParameters = GetSpParameters(spName, true, openNewConnectionToDiscoverParameters); + + // DbParameters are bound by name, plain parameters by order + // + var dbParameters = false; + + if (parameterValues == null || parameterValues.Length == 0 || + parameterValues[0] is IDbDataParameter || parameterValues[0] is IDbDataParameter[]) + { + // The PrepareParameters method may add some additional parameters. + // + parameterValues = PrepareParameters(parameterValues); + + if (parameterValues == null || parameterValues.Length == 0) + return spParameters; + + dbParameters = true; + } + + if (spParameters == null/* || commandParameters.Length == 0*/) + { + spParameters = new IDbDataParameter[parameterValues.Length]; + + if (dbParameters) + parameterValues.CopyTo(spParameters, 0); + else + for (var i = 0; i < parameterValues.Length; i++) + spParameters[i] = Parameter("?", parameterValues[i]); + + return spParameters; + } + + if (dbParameters) + { + // If we receive an array of IDbDataParameter, + // we need to copy parameters to the IDbDataParameter[]. + // + foreach (var spParam in spParameters) + { + var spParamName = spParam.ParameterName; + var found = false; + + foreach (IDbDataParameter paramWithValue in parameterValues) + { + var parameterNamesEqual = _dataProvider.ParameterNamesEqual(spParamName, paramWithValue.ParameterName); + if (!parameterNamesEqual) + { + var convertedParameterName = + _dataProvider.Convert(paramWithValue.ParameterName, ConvertType.NameToSprocParameter).ToString(); + + parameterNamesEqual = _dataProvider.ParameterNamesEqual(spParamName, convertedParameterName); + } + + if (!parameterNamesEqual) continue; + + if (spParam.Direction != paramWithValue.Direction) + { + if (TraceSwitch.TraceWarning) + WriteTraceLine( + string.Format( + "Stored Procedure '{0}'. Parameter '{1}' has different direction '{2}'. Should be '{3}'.", + spName, spParamName, spParam.Direction, paramWithValue.Direction), + TraceSwitch.DisplayName); + + spParam.Direction = paramWithValue.Direction; + } + + if (spParam.Direction != ParameterDirection.Output) + spParam.Value = paramWithValue.Value; + + paramWithValue.ParameterName = spParamName; + found = true; + break; + } + + if (found == false && ( + spParam.Direction == ParameterDirection.Input || + spParam.Direction == ParameterDirection.InputOutput)) + { + if (TraceSwitch.TraceWarning) + WriteTraceLine( + string.Format("Stored Procedure '{0}'. Parameter '{1}' not assigned.", spName, spParamName), + TraceSwitch.DisplayName); + + spParam.SourceColumn = _dataProvider.Convert(spParamName, ConvertType.SprocParameterToName).ToString(); + } + } + } + else + { + // Assign the provided values to the parameters based on parameter order. + // + AssignParameterValues(spName, spParameters, parameterValues); + } + + return spParameters; + } + + /// + /// Creates an one-dimension array of + /// from any combination on IDbDataParameter, IDbDataParameter[] or null references. + /// Null references are stripped, arrays and single parameters are combined + /// into a new array. + /// + /// When two or more parameters has the same name, + /// the first parameter is used, all the rest are ignored. + ///Array of IDbDataParameter, IDbDataParameter[] or null references. + ///An normalized array of without null references. + ///The parameter + /// contains anything except IDbDataParameter, IDbDataParameter[] or null reference. + public virtual IDbDataParameter[] PrepareParameters(object[] parameters) + { + if (parameters == null || parameters.Length == 0) + return null; + + // Little optimization. + // Check if we have only one single ref parameter. + // + object refParam = null; + + foreach (var p in parameters) + if (p != null) + { + if (refParam != null) + { + refParam = null; + break; + } + + refParam = p; + } + + if (refParam is IDbDataParameter[]) + { + return (IDbDataParameter[])refParam; + } + + if (refParam is IDbDataParameter) + { + var oneParameterArray = new IDbDataParameter[1]; + oneParameterArray[0] = (IDbDataParameter)refParam; + return oneParameterArray; + } + + var list = new List(parameters.Length); + var hash = new Dictionary(parameters.Length); + + foreach (var o in parameters) + if (o is IDbDataParameter) + { + var p = (IDbDataParameter) o; + + if (!hash.ContainsKey(p.ParameterName)) + { + list.Add(p); + hash.Add(p.ParameterName, p); + } + } + else if (o is IDbDataParameter[]) + { + foreach (var p in (IDbDataParameter[]) o) + if (!hash.ContainsKey(p.ParameterName)) + { + list.Add(p); + hash.Add(p.ParameterName, p); + } + } + else if (o != null && o != DBNull.Value) + throw new ArgumentException( + Resources.DbManager_NotDbDataParameter, "parameters"); + + return list.ToArray(); + } + + /// + /// This method is used to attach array of to a . + /// + /// The command to which the parameters will be added + /// An array of IDbDataParameters tho be added to command + private void AttachParameters(IDbCommand command, IEnumerable commandParameters) + { + command.Parameters.Clear(); + + foreach (var p in commandParameters) + _dataProvider.AttachParameter(command, p); + } + + private static readonly Dictionary _paramCache = + new Dictionary(); + private static readonly object _paramCacheLock = new object(); + + /// + /// Resolve at run time the appropriate set of parameters for a stored procedure. + /// + /// The name of the stored procedure. + /// Whether or not to include their return value parameter. + /// + /// + protected virtual IDbDataParameter[] DiscoverSpParameters(string spName, bool includeReturnValueParameter, bool openNewConnection) + { + var con = openNewConnection ? CloneConnection() : _connection; + + try + { + if (con.State == ConnectionState.Closed) + { + ExecuteOperation(OperationType.OpenConnection, con.Open); + if (!openNewConnection) + _closeConnection = true; + } + + using (var cmd = con.CreateCommand()) + { + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = spName; + + var res = ExecuteOperation(OperationType.DeriveParameters, () => _dataProvider.DeriveParameters(cmd)); + + if (openNewConnection) + ExecuteOperation(OperationType.CloseConnection, con.Close); + + if (res == false) + return null; + + if (includeReturnValueParameter == false) + { + // All known data providers always treat + // the return value as first parameter. + // + cmd.Parameters.RemoveAt(0); + } + + var discoveredParameters = new IDbDataParameter[cmd.Parameters.Count]; + + for (var i = 0; i < cmd.Parameters.Count; i++) + discoveredParameters[i] = (IDbDataParameter)cmd.Parameters[i]; + + return discoveredParameters; + } + } + finally + { + if (con != null && openNewConnection) + con.Dispose(); + } + } + + /// + /// Copies cached parameter array. + /// + /// The original parameter array. + /// The result array. + private IDbDataParameter[] CloneParameters(IDbDataParameter[] originalParameters) + { + if (originalParameters == null) + return null; + + var clonedParameters = new IDbDataParameter[originalParameters.Length]; + + for (var i = 0; i < originalParameters.Length; i++) + clonedParameters[i] = _dataProvider.CloneParameter(originalParameters[i]); + + return clonedParameters; + } + + /// + /// Retrieves the set of parameters appropriate for the stored procedure. + /// + /// + /// This method will query the database for this information, + /// and then store it in a cache for future requests. + /// + /// The name of the stored procedure. + /// A boolean value indicating + /// whether the return value parameter should be included in the results. + /// + /// An array of the . + public IDbDataParameter[] GetSpParameters(string spName, bool includeReturnValueParameter, bool openNewConnectionToDiscoverParameters) + { + var key = string.Format("{0}:{1}:{2}", GetConnectionHash(), spName, includeReturnValueParameter); + + IDbDataParameter[] cachedParameters; + + // It is thread safe enought to check for a key and get its value without a lock. + // + if (!_paramCache.TryGetValue(key, out cachedParameters)) + { + lock (_paramCacheLock) + { + // There is a possible race condition since the operation may take a time. + // + if (!_paramCache.TryGetValue(key, out cachedParameters)) + { + cachedParameters = DiscoverSpParameters(spName, includeReturnValueParameter, openNewConnectionToDiscoverParameters); + _paramCache.Add(key, cachedParameters); + } + } + } + + return CloneParameters(cachedParameters); + } + + /// + /// This method assigns an array of values to an array of parameters. + /// + /// + /// array of IDbDataParameters to be assigned values + /// array of objects holding the values to be assigned + private void AssignParameterValues(string spName, IDbDataParameter[] commandParameters, object[] parameterValues) + { + if (commandParameters == null || parameterValues == null) + { + // Do nothing if we get no data. + // + return; + } + + var nValues = 0; + + // Iterate through the parameters, assigning the values from + // the corresponding position in the value array. + // + for (var index = 0; index < commandParameters.Length; index++) + { + var parameter = commandParameters[index]; + + if (_dataProvider.IsValueParameter(parameter)) + { + if (nValues >= parameterValues.Length) + throw new ArgumentException(string.Format("Parsing for {0} failed: {1}", spName, GetMissedColumnNames(index, commandParameters))); + + var value = parameterValues[nValues++]; + + _dataProvider.SetParameterValue(parameter, value ?? DBNull.Value); + } + } + + // We must have the same number of values as we pave parameters to put them in. + // + if (nValues != parameterValues.Length) + throw new ArgumentException(string.Format("Parsing for {0} failed: {1}", spName, GetExceedParameters(nValues, parameterValues))); + } + + string GetMissedColumnNames(int startIndex, IDbDataParameter[] commandParameters) + { + var columnNames = new List(); + + for (var index = startIndex; index < commandParameters.Length; index++) + { + var parameter = commandParameters[index]; + + if (_dataProvider.IsValueParameter(parameter)) + { + columnNames.Add(string.Format("{0} {{{1}}}", parameter.ParameterName, parameter.DbType)); + } + } + +#if FW4 + return "Missed columns: " + string.Join(", ", columnNames); +#else + return "Missed columns: " + string.Join(", ", columnNames.ToArray()); +#endif + } + + static string GetExceedParameters(int startIndex, object[] parameterValues) + { + var columnNames = new List(); + + for (var index = startIndex; index < parameterValues.Length; index++) + { + var parameter = parameterValues[index]; + columnNames.Add( + parameter == null + ? "" + : string.Format("{0} {{{1}}}", parameter, parameter.GetType().Name)); + } + +#if FW4 + return "Exceed parameters: " + string.Join(", ", columnNames); +#else + return "Exceed parameters: " + string.Join(", ", columnNames.ToArray()); +#endif + } + + /// + /// Assigns a business object to command parameters. + /// + /// + /// Assigns the to command parameters. + /// + /// + /// + /// The method is used in addition to the method. + /// + /// The to assign. + /// This instance of the . + public DbManager AssignParameterValues(DataRow dataRow) + { + if (dataRow == null) + throw new ArgumentNullException("dataRow"); + + foreach (DataColumn c in dataRow.Table.Columns) + if (c.AutoIncrement == false && c.ReadOnly == false) + { + var o = dataRow[c.ColumnName]; + var name = _dataProvider.Convert(c.ColumnName, GetConvertTypeToParameter()).ToString(); + + Parameter(name).Value = + c.AllowDBNull && _mappingSchema.IsNull(o) ? DBNull.Value : o; + } + + if (_prepared) + InitParameters(CommandAction.Select); + + return this; + } + + /// + /// Assigns a business object to command parameters. + /// + /// + /// The method is used in addition to the method. + /// + /// + /// An object to assign. + /// This instance of the . + public DbManager AssignParameterValues(object obj) + { + if (obj == null) + throw new ArgumentNullException("obj"); + + var om = _mappingSchema.GetObjectMapper(obj.GetType()); + + foreach (MemberMapper mm in om) + { + var name = _dataProvider.Convert(mm.Name, GetConvertTypeToParameter()).ToString(); + + if (Command.Parameters.Contains(name)) + { + var value = mm.GetValue(obj); + + _dataProvider.SetParameterValue( + Parameter(name), + value == null || mm.MapMemberInfo.Nullable && _mappingSchema.IsNull(value)? + DBNull.Value: value); + } + } + + if (_prepared) + InitParameters(CommandAction.Select); + + return this; + } + + private static Array SortArray(Array array, IComparer comparer) + { + if (array == null) + return null; + + var arrayClone = (Array)array.Clone(); + + Array.Sort(arrayClone, comparer); + + return arrayClone; + } + + /// + /// Creates an array of parameters from the object. + /// + /// + /// The method can take an additional parameter list, + /// which can be created by using the same method. + /// + /// + /// The to create parameters. + /// An array of parameters to be added to the result array. + /// An array of parameters. + public IDbDataParameter[] CreateParameters( + DataRow dataRow, params IDbDataParameter[] commandParameters) + { + return CreateParameters(dataRow, null, null, null, commandParameters); + } + + /// + /// Creates an array of parameters from the object. + /// + /// + /// The method can take an additional parameter list, + /// which can be created by using the same method. + /// + /// + /// The to create parameters. + /// Output parameters names. + /// InputOutput parameters names. + /// Parameters names to skip. + /// An array of parameters to be added to the result array. + /// An array of parameters. + public IDbDataParameter[] CreateParameters( + DataRow dataRow, + string[] outputParameters, + string[] inputOutputParameters, + string[] ignoreParameters, + params IDbDataParameter[] commandParameters) + { + if (dataRow == null) + throw new ArgumentNullException("dataRow"); + + var paramList = new ArrayList(); + IComparer comparer = CaseInsensitiveComparer.Default; + + outputParameters = (string[])SortArray(outputParameters, comparer); + inputOutputParameters = (string[])SortArray(inputOutputParameters, comparer); + ignoreParameters = (string[])SortArray(ignoreParameters, comparer); + + foreach (DataColumn c in dataRow.Table.Columns) + { + if (ignoreParameters != null && Array.BinarySearch(ignoreParameters, c.ColumnName, comparer) >= 0) + continue; + + if (c.AutoIncrement || c.ReadOnly) + continue; + + var name = _dataProvider.Convert(c.ColumnName, GetConvertTypeToParameter()).ToString(); + var parameter = + c.AllowDBNull + ? NullParameter(name, dataRow[c.ColumnName]) + : Parameter (name, dataRow[c.ColumnName]); + + if (outputParameters != null && Array.BinarySearch(outputParameters, c.ColumnName, comparer) >= 0) + parameter.Direction = ParameterDirection.Output; + else if (inputOutputParameters != null && Array.BinarySearch(inputOutputParameters, c.ColumnName, comparer) >= 0) + parameter.Direction = ParameterDirection.InputOutput; + + paramList.Add(parameter); + } + + if (commandParameters != null) + paramList.AddRange(commandParameters); + + return (IDbDataParameter[])paramList.ToArray(typeof(IDbDataParameter)); + } + + /// + /// Creates an array of parameters from a business object. + /// + /// + /// The method can take an additional parameter list, + /// which can be created by using the same method. + /// + /// + /// An object. + /// An array of parameters to be added to the result array. + /// An array of parameters. + public IDbDataParameter[] CreateParameters( + object obj, + params IDbDataParameter[] commandParameters) + { + return CreateParameters(obj, null, null, null, commandParameters); + } + + /// + /// Creates an array of parameters from a business object. + /// + /// + /// The method can take an additional parameter list, + /// which can be created by using the same method. + /// + /// + /// An object. + /// Output parameters names. + /// InputOutput parameters names. + /// Parameters names to skip. + /// An array of parameters to be added to the result array. + /// An array of parameters. + public IDbDataParameter[] CreateParameters( + object obj, + string[] outputParameters, + string[] inputOutputParameters, + string[] ignoreParameters, + params IDbDataParameter[] commandParameters) + { + if (obj == null) + throw new ArgumentNullException("obj"); + + var isType = obj is Type; + var type = isType? (Type)obj: obj.GetType(); + var om = _mappingSchema.GetObjectMapper(type); + var paramList = new ArrayList(); + var comparer = CaseInsensitiveComparer.Default; + + outputParameters = (string[])SortArray(outputParameters, comparer); + inputOutputParameters = (string[])SortArray(inputOutputParameters, comparer); + ignoreParameters = (string[])SortArray(ignoreParameters, comparer); + + foreach (MemberMapper mm in om) + { + if (ignoreParameters != null && Array.BinarySearch(ignoreParameters, mm.Name, comparer) >= 0) + continue; + + var value = isType? null: mm.GetValue(obj); + var name = _dataProvider.Convert(mm.Name, GetConvertTypeToParameter()).ToString(); + + var parameter = + value == null ? + NullParameter(name, value, mm.MapMemberInfo.NullValue) : + (mm.DbType != DbType.Object) ? + Parameter(name, value, mm.DbType): + Parameter(name, value); + + if (outputParameters != null && Array.BinarySearch(outputParameters, mm.Name, comparer) >= 0) + parameter.Direction = ParameterDirection.Output; + else if (inputOutputParameters != null && Array.BinarySearch(inputOutputParameters, mm.Name, comparer) >= 0) + parameter.Direction = ParameterDirection.InputOutput; + + paramList.Add(parameter); + } + + if (commandParameters != null) + paramList.AddRange(commandParameters); + + return (IDbDataParameter[])paramList.ToArray(typeof(IDbDataParameter)); + } + + /// + /// Maps all parameters returned from the server to all given objects. + /// + /// Name of a to map return value. + /// An to map from command parameters. + public void MapOutputParameters( + string returnValueMember, + object obj) + { + var dest = _mappingSchema.GetDataDestination(obj); + + foreach (IDbDataParameter parameter in Command.Parameters) + { + var ordinal = -1; + + switch (parameter.Direction) + { + case ParameterDirection.InputOutput: + case ParameterDirection.Output: + ordinal = dest.GetOrdinal( + _dataProvider.Convert(parameter.ParameterName, ConvertType.SprocParameterToName).ToString()); + break; + + case ParameterDirection.ReturnValue: + + if (returnValueMember != null) + { + if (!returnValueMember.StartsWith("@") && dest is ObjectMapper) + { + var om = (ObjectMapper) dest; + var ma = om.TypeAccessor[returnValueMember]; + + if (ma != null) + { + ma.SetValue(obj, _mappingSchema.ConvertChangeType(parameter.Value, ma.Type)); + continue; + } + } + else + returnValueMember = returnValueMember.Substring(1); + + ordinal = dest.GetOrdinal(returnValueMember); + } + + break; + } + + if (ordinal >= 0) + dest.SetValue(obj, ordinal, _mappingSchema.ConvertChangeType(parameter.Value, dest.GetFieldType(ordinal))); + } + } + + /// + /// Maps all parameters returned from the server to an object. + /// + /// An to map from command parameters. + public void MapOutputParameters(object obj) + { + MapOutputParameters(null, obj); + } + + /// + /// Maps all parameters returned from the server to all given objects. + /// + /// Name of the member used to map the + /// return value. Can be null. + /// An array of to map + /// from command parameters. + public void MapOutputParameters(string returnValueMember, params object[] objects) + { + if (objects == null) + return; + + foreach (var obj in objects) + MapOutputParameters(returnValueMember, obj); + } + + /// + /// Maps all parameters returned from the server to an object. + /// + /// An array of to map + /// from command parameters. + public void MapOutputParameters(params object[] objects) + { + MapOutputParameters(null, objects); + } + + /// + /// Adds a parameter to the or returns existing one. + /// + /// + /// Returns an existing parameter. + /// + /// + /// The method can be used to retrieve return and output parameters. + /// + /// + /// The name of the parameter. + /// The object. + public IDbDataParameter Parameter(string parameterName) + { + return _dataProvider.GetParameter(Command, parameterName); + } + + /// + /// Adds an input parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Input type. + /// + /// + /// The name of the parameter. + /// The + /// that is the value of the parameter. + /// The object. + public IDbDataParameter Parameter(string parameterName, object value) + { + return Parameter(ParameterDirection.Input, parameterName, value); + } + + /// + /// Adds an input parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Input type. + /// + /// The name of the parameter. + /// One of the values. + /// The object. + public IDbDataParameter Parameter(string parameterName, DbType dbType) + { + return Parameter(ParameterDirection.Input, parameterName, dbType); + } + + /// + /// Adds an input parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Input type. + /// + /// The name of the parameter. + /// One of the values. + /// Size of the parameter. + /// The object. + public IDbDataParameter Parameter(string parameterName, DbType dbType, int size) + { + return Parameter(ParameterDirection.Input, parameterName, dbType, size); + } + + /// + /// Adds an input parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Input type. + /// If the parameter is null, it's converted to .. + /// + /// + /// The name of the parameter. + /// The + /// that is the value of the parameter. + /// The object. + public IDbDataParameter NullParameter(string parameterName, object value) + { + if (_mappingSchema.IsNull(value)) + @value = DBNull.Value; + + return Parameter(ParameterDirection.Input, parameterName, value); + } + + /// + /// Adds an input parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Input type. + /// + /// The name of the parameter. + /// The + /// that is the value of the parameter. + /// The null equivalent to compare with the value. + /// The object. + public IDbDataParameter NullParameter(string parameterName, object value, object nullValue) + { + if (value == null || value.Equals(nullValue)) + @value = DBNull.Value; + + return Parameter(ParameterDirection.Input, parameterName, value); + } + + /// + /// Adds an input parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Input type. + /// + /// The name of the parameter. + /// The + /// that is the value of the parameter. + /// The object. + public IDbDataParameter InputParameter(string parameterName, object value) + { + return Parameter(ParameterDirection.Input, parameterName, value); + } + + /// + /// Adds an output parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Output type. + /// + /// The name of the parameter. + /// The + /// that is the value of the parameter. + /// The object. + public IDbDataParameter OutputParameter(string parameterName, object value) + { + return Parameter(ParameterDirection.Output, parameterName, value); + } + + /// + /// Adds an output parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Output type. + /// + /// The name of the parameter. + /// One of the values. + /// The object. + public IDbDataParameter OutputParameter(string parameterName, DbType dbType) + { + return Parameter(ParameterDirection.Output, parameterName, dbType); + } + + /// + /// Adds an output parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Output type. + /// + /// The name of the parameter. + /// One of the values. + /// Size of the parameter. + /// The object. + public IDbDataParameter OutputParameter(string parameterName, DbType dbType, int size) + { + return Parameter(ParameterDirection.Output, parameterName, dbType, size); + } + + /// + /// Adds an input-output parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.InputOutput type. + /// + /// The name of the parameter. + /// The + /// that is the value of the parameter. + /// The object. + public IDbDataParameter InputOutputParameter(string parameterName, object value) + { + return Parameter(ParameterDirection.InputOutput,parameterName, value); + } + + /// + /// Adds a return value parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.ReturnValue type. + /// + /// The name of the parameter. + /// The object. + public IDbDataParameter ReturnValue(string parameterName) + { + return Parameter(ParameterDirection.ReturnValue, parameterName, null); + } + + /// + /// Adds a parameter to the . + /// + /// + /// The method creates a parameter with the specified + /// type. + /// + /// One of the values. + /// The name of the parameter. + /// The + /// that is the value of the parameter. + /// The object. + public IDbDataParameter Parameter( + ParameterDirection parameterDirection, + string parameterName, + object value) + { + var parameter = _dataProvider.CreateParameterObject(Command); + + parameter.ParameterName = parameterName; + parameter.Direction = parameterDirection; + + _dataProvider.SetParameterValue(parameter, value ?? DBNull.Value); + + return parameter; + } + + /// + /// Adds a parameter to the . + /// + /// + /// The method creates a parameter with the specified + /// type. + /// + /// One of the values. + /// The name of the parameter. + /// The + /// that is the value of the parameter. + /// One of the values. + /// The object. + public IDbDataParameter Parameter( + ParameterDirection parameterDirection, + string parameterName, + object value, + DbType dbType) + { + var parameter = _dataProvider.CreateParameterObject(Command); + + parameter.ParameterName = parameterName; + parameter.Direction = parameterDirection; + parameter.DbType = _dataProvider.GetParameterDbType(dbType); + + _dataProvider.SetParameterValue(parameter, value ?? DBNull.Value); + + return parameter; + } + + /// + /// Adds an input parameter to the . + /// + /// The name of the parameter. + /// The + /// that is the value of the parameter. + /// One of the values. + /// The object. + public IDbDataParameter Parameter( + string parameterName, + object value, + DbType dbType) + { + return Parameter(ParameterDirection.Input, parameterName, value, dbType); + } + + /// + /// Adds a parameter to the . + /// + /// + /// The method creates a parameter with the specified + /// type. + /// + /// One of the values. + /// The name of the parameter. + /// The + /// that is the value of the parameter. + /// One of the values. + /// Size of the parameter. + /// The object. + public IDbDataParameter Parameter( + ParameterDirection parameterDirection, + string parameterName, + object value, + DbType dbType, + int size) + { + var parameter = _dataProvider.CreateParameterObject(Command); + + parameter.ParameterName = parameterName; + parameter.Direction = parameterDirection; + parameter.DbType = dbType; + parameter.Size = size; + + _dataProvider.SetParameterValue(parameter, value); + + return parameter; + } + + /// + /// Adds a parameter to the . + /// + /// + /// The method creates a parameter with the specified + /// type. + /// + /// One of the values. + /// The name of the parameter. + /// The + /// that is the value of the parameter. + /// User defined type name for a table-valued parameter. + /// The object. + public IDbDataParameter Parameter( + ParameterDirection parameterDirection, + string parameterName, + object value, + string typeName) + { + var parameter = _dataProvider.CreateParameterObject(Command); + + parameter.ParameterName = parameterName; + parameter.Direction = parameterDirection; + _dataProvider.SetUserDefinedType(parameter, typeName); + _dataProvider.SetParameterValue (parameter, value); + + return parameter; + } + + /// + /// Adds an input parameter to the . + /// + /// The name of the parameter. + /// The + /// that is the value of the parameter. + /// One of the values. + /// Size of the parameter. + /// The object. + public IDbDataParameter Parameter( + string parameterName, + object value, + DbType dbType, + int size) + { + return Parameter(ParameterDirection.Input, parameterName, value, dbType, size); + } + + /// + /// Adds a parameter to the . + /// + /// + /// The method creates a parameter with the specified + /// type. + /// + /// One of the values. + /// The name of the parameter. + /// One of the values. + /// The object. + public IDbDataParameter Parameter( + ParameterDirection parameterDirection, + string parameterName, + DbType dbType) + { + var parameter = _dataProvider.CreateParameterObject(Command); + + parameter.ParameterName = parameterName; + parameter.Direction = parameterDirection; + parameter.DbType = dbType; + + return parameter; + } + + /// + /// Adds a parameter to the . + /// + /// + /// The method creates a parameter with the specified + /// type. + /// + /// One of the values. + /// The name of the parameter. + /// One of the values. + /// Size of the parameter. + /// The object. + public IDbDataParameter Parameter( + ParameterDirection parameterDirection, + string parameterName, + DbType dbType, + int size) + { + var parameter = _dataProvider.CreateParameterObject(Command); + + parameter.ParameterName = parameterName; + parameter.Direction = parameterDirection; + parameter.DbType = dbType; + parameter.Size = size; + + return parameter; + } + + /// + /// Creates an input parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Input type + /// and DataRowVersion.Current type. + /// + /// The name of the parameter. + /// One of the values. + /// Size of the parameter. + /// Source column for a parameter in the . + /// The object. + public IDbDataParameter Parameter( + string parameterName, + DbType dbType, + int size, + string sourceColumn) + { + var param = Parameter(ParameterDirection.Input, parameterName, dbType, size); + + param.SourceColumn = sourceColumn; + param.SourceVersion = DataRowVersion.Current; + + return param; + } + + /// + /// Creates an input parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Input type + /// and DataRowVersion.Current type. + /// + /// The name of the parameter. + /// One of the values. + /// Source column for a parameter in the . + /// The object. + public IDbDataParameter Parameter( + string parameterName, + DbType dbType, + string sourceColumn) + { + var param = Parameter(ParameterDirection.Input, parameterName, dbType); + + param.SourceColumn = sourceColumn; + param.SourceVersion = DataRowVersion.Current; + + return param; + } + + /// + /// Creates an input parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Input type + /// and DataRowVersion.Current type. + /// + /// The name of the parameter. + /// One of the values. + /// Size of the parameter. + /// Source column for a parameter in the . + /// Version of data to use for a parameter in the . + /// The object. + public IDbDataParameter Parameter( + string parameterName, + DbType dbType, + int size, + string sourceColumn, + DataRowVersion dataRowVersion) + { + var param = Parameter(ParameterDirection.Input, parameterName, dbType, size); + + param.SourceColumn = sourceColumn; + param.SourceVersion = dataRowVersion; + + return param; + } + + /// + /// Creates an input parameter to the . + /// + /// + /// The method creates a parameter with the + /// ParameterDirection.Input type + /// and DataRowVersion.Current type. + /// + /// The name of the parameter. + /// One of the values. + /// Source column for a parameter in the . + /// Version of data to use for a parameter in the . + /// The object. + public IDbDataParameter Parameter( + string parameterName, + DbType dbType, + string sourceColumn, + DataRowVersion dataRowVersion) + { + var param = Parameter(ParameterDirection.Input, parameterName, dbType); + + param.SourceColumn = sourceColumn; + param.SourceVersion = dataRowVersion; + + return param; + } + + public ConvertType GetConvertTypeToParameter() + { + return Command.CommandType == CommandType.StoredProcedure ? + ConvertType.NameToSprocParameter: + ConvertType.NameToCommandParameter; + } + + #endregion + + #region SetCommand + + /// + /// Specifies the action that command is supposed to perform, i.e. Select, Insert, Update, Delete. + /// It is used in Execute methods of the class to identify command instance + /// to be used. + /// + enum CommandAction + { + Select, + Insert, + Update, + Delete + } + + private bool _executed; + private bool _prepared; + + private IDbDataParameter[] _selectCommandParameters; + private IDbDataParameter[] _insertCommandParameters; + private IDbDataParameter[] _updateCommandParameters; + private IDbDataParameter[] _deleteCommandParameters; + + private void SetCommand(CommandAction commandAction, IDbCommand command) + { + switch (commandAction) + { + case CommandAction.Select: _selectCommand = command; break; + case CommandAction.Insert: _insertCommand = command; break; + case CommandAction.Update: _updateCommand = command; break; + case CommandAction.Delete: _deleteCommand = command; break; + } + } + + private IDbCommand GetCommand(CommandAction commandAction) + { + switch (commandAction) + { + default: + //case CommandAction.Select: + return SelectCommand; + case CommandAction.Insert: return InsertCommand; + case CommandAction.Update: return UpdateCommand; + case CommandAction.Delete: return DeleteCommand; + } + } + + private IDbCommand GetCommand(CommandAction commandAction, CommandType commandType) + { + IDbCommand command; + + switch (commandAction) + { + default : command = _selectCommand; break; + case CommandAction.Insert : command = _insertCommand; break; + case CommandAction.Update : command = _updateCommand; break; + case CommandAction.Delete : command = _deleteCommand; break; + } + + if (command != null && !DataProvider.CanReuseCommand(command, commandType)) + { + command.Dispose(); + + switch (commandAction) + { + default : _selectCommand = null; break; + case CommandAction.Insert : _insertCommand = null; break; + case CommandAction.Update : _updateCommand = null; break; + case CommandAction.Delete : _deleteCommand = null; break; + } + } + + return GetCommand(commandAction); + } + + private void SetCommandParameters(CommandAction commandAction, IDbDataParameter[] commandParameters) + { + switch (commandAction) + { + case CommandAction.Select: _selectCommandParameters = commandParameters; break; + case CommandAction.Insert: _insertCommandParameters = commandParameters; break; + case CommandAction.Update: _updateCommandParameters = commandParameters; break; + case CommandAction.Delete: _deleteCommandParameters = commandParameters; break; + } + } + + private IDbDataParameter[] GetCommandParameters(CommandAction commandAction) + { + switch (commandAction) + { + default: + //case CommandAction.Select: + return _selectCommandParameters; + case CommandAction.Insert: return _insertCommandParameters; + case CommandAction.Update: return _updateCommandParameters; + case CommandAction.Delete: return _deleteCommandParameters; + } + } + + private DbManager SetCommand( + CommandAction commandAction, + CommandType commandType, + string commandText, + params IDbDataParameter[] commandParameters) + { + if (_executed) + { + _executed = false; + _prepared = false; + } + + PrepareCommand(commandAction, commandType, commandText, commandParameters); + + return this; + } + + private DbManager SetSpCommand( + CommandAction commandAction, + string spName, + bool openNewConnectionToDiscoverParameters, + params object[] parameterValues) + { + return SetCommand( + commandAction, + CommandType.StoredProcedure, + spName, + CreateSpParameters(spName, parameterValues, openNewConnectionToDiscoverParameters)); + } + + private DbManager SetSpCommand( + CommandAction commandAction, + string spName, + params object[] parameterValues) + { + return SetCommand( + commandAction, + CommandType.StoredProcedure, + spName, + CreateSpParameters(spName, parameterValues, Configuration.OpenNewConnectionToDiscoverParameters)); + } + + #region Select + + /// + /// Creates a SQL statement. + /// + /// The command text to execute. + /// Current instance. + public DbManager SetCommand( + string commandText) + { + return SetCommand(CommandAction.Select, CommandType.Text, commandText, null); + } + + /// + /// Creates a SQL statement. + /// + /// The (stored procedure, text, etc.) + /// The command text to execute. + /// Current instance. + public DbManager SetCommand( + CommandType commandType, + string commandText) + { + return SetCommand(CommandAction.Select, commandType, commandText, null); + } + + /// + /// Creates a SQL statement. + /// + /// + /// The method can be used to create the INSERT, UPDATE, and DELETE SQL statements. + /// + /// The command text to execute. + /// An array of parameters used to executes the command. + /// Current instance. + public DbManager SetCommand( + string commandText, + params IDbDataParameter[] commandParameters) + { + return SetCommand(CommandAction.Select, CommandType.Text, commandText, commandParameters); + } + + /// + /// Creates a SQL statement. + /// + /// The (stored procedure, text, etc.) + /// The command text to execute. + /// An array of parameters used to executes the command. + /// Current instance. + public DbManager SetCommand( + CommandType commandType, + string commandText, + params IDbDataParameter[] commandParameters) + { + return SetCommand(CommandAction.Select, commandType, commandText, commandParameters); + } + + /// + /// Creates a command to be executed as a stored procedure using the provided parameter values. + /// + /// + /// The method queries the database to discover the parameters for the stored procedure + /// (the first time each stored procedure is called), + /// and assign the values based on parameter order. + /// + /// The name of the stored procedure + /// An array of objects to be assigned as the input values of the stored procedure + /// Current instance. + public DbManager SetSpCommand( + string spName, + params object[] parameterValues) + { + return SetSpCommand(CommandAction.Select, spName, parameterValues); + } + + public DbManager SetSpCommand( + string spName, + bool openNewConnectionToDiscoverParameters, + params object[] parameterValues) + { + return SetSpCommand(CommandAction.Select, spName, openNewConnectionToDiscoverParameters, parameterValues); + } + + public DbManager SetCommand(SqlQuery sql, params IDbDataParameter[] commandParameters) + { + var sb = new StringBuilder(); + + DataProvider.CreateSqlProvider().BuildSql(0, sql, sb, 0, 0, false); + + var command = sb.ToString(); + + if (TraceSwitch.TraceInfo) + { + var info = string.Format("{0} {1}\n{2}", DataProvider.Name, ConfigurationString, command); + + if (commandParameters != null && commandParameters.Length > 0) + foreach (var p in commandParameters) + info += string.Format("\n{0}\t{1}", p.ParameterName, p.Value); + + WriteTraceLine(info, TraceSwitch.DisplayName); + } + + return SetCommand(command, commandParameters); + } + + #endregion + + #region Insert + + /// + /// Creates an Insert SQL statement. + /// + /// + /// The method can be used to create the INSERT, UPDATE, and DELETE SQL statements. + /// + /// The command text to execute. + /// An array of parameters used to executes the command. + /// Current instance. + public DbManager SetInsertCommand( + string commandText, + params IDbDataParameter[] commandParameters) + { + return SetCommand( + CommandAction.Insert, CommandType.Text, commandText, commandParameters); + } + + /// + /// Creates an Insert SQL statement. + /// + /// The (stored procedure, text, etc.) + /// The command text to execute. + /// An array of parameters used to executes the command. + /// Current instance. + public DbManager SetInsertCommand( + CommandType commandType, + string commandText, + params IDbDataParameter[] commandParameters) + { + return SetCommand( + CommandAction.Insert, commandType, commandText, commandParameters); + } + + /// + /// Creates an Insert command to be executed as a stored procedure using the provided parameter values. + /// + /// + /// The method queries the database to discover the parameters for the stored procedure + /// (the first time each stored procedure is called), + /// and assign the values based on parameter order. + /// + /// The name of the stored procedure + /// An array of objects to be assigned as the input values of the stored procedure + /// Current instance. + public DbManager SetInsertSpCommand( + string spName, + params object[] parameterValues) + { + return SetSpCommand(CommandAction.Insert, spName, parameterValues); + } + + #endregion + + #region Update + + /// + /// Creates an Update SQL statement. + /// + /// + /// The method can be used to create the INSERT, UPDATE, and DELETE SQL statements. + /// + /// The command text to execute. + /// An array of parameters used to executes the command. + /// Current instance. + public DbManager SetUpdateCommand( + string commandText, + params IDbDataParameter[] commandParameters) + { + return SetCommand( + CommandAction.Update, CommandType.Text, commandText, commandParameters); + } + + /// + /// Creates an Update SQL statement. + /// + /// The (stored procedure, text, etc.) + /// The command text to execute. + /// An array of parameters used to executes the command. + /// Current instance. + public DbManager SetUpdateCommand( + CommandType commandType, + string commandText, + params IDbDataParameter[] commandParameters) + { + return SetCommand( + CommandAction.Update, commandType, commandText, commandParameters); + } + + /// + /// Creates an Update command to be executed as a stored procedure using the provided parameter values. + /// + /// + /// The method queries the database to discover the parameters for the stored procedure + /// (the first time each stored procedure is called), + /// and assign the values based on parameter order. + /// + /// The name of the stored procedure + /// An array of objects to be assigned as the input values of the stored procedure + /// Current instance. + public DbManager SetUpdateSpCommand( + string spName, + params object[] parameterValues) + { + return SetSpCommand(CommandAction.Update, spName, parameterValues); + } + + #endregion + + #region Delete + + /// + /// Creates a Delete SQL statement. + /// + /// + /// The method can be used to create the INSERT, UPDATE, and DELETE SQL statements. + /// + /// The command text to execute. + /// An array of parameters used to executes the command. + /// Current instance. + public DbManager SetDeleteCommand( + string commandText, + params IDbDataParameter[] commandParameters) + { + return SetCommand( + CommandAction.Delete, CommandType.Text, commandText, commandParameters); + } + + /// + /// Creates a Delete SQL statement. + /// + /// The (stored procedure, text, etc.) + /// The command text to execute. + /// An array of parameters used to executes the command. + /// Current instance. + public DbManager SetDeleteCommand( + CommandType commandType, + string commandText, + params IDbDataParameter[] commandParameters) + { + return SetCommand( + CommandAction.Delete, commandType, commandText, commandParameters); + } + + /// + /// Creates a Delete command to be executed as a stored procedure using the provided parameter values. + /// + /// + /// The method queries the database to discover the parameters for the stored procedure + /// (the first time each stored procedure is called), + /// and assign the values based on parameter order. + /// + /// The name of the stored procedure + /// An array of objects to be assigned as the input values of the stored procedure + /// Current instance. + public DbManager SetDeleteSpCommand( + string spName, + params object[] parameterValues) + { + return SetSpCommand(CommandAction.Delete, spName, parameterValues); + } + + #endregion + + #endregion + + #region Prepare + + private void PrepareCommand( + CommandAction commandAction, + CommandType commandType, + string commandText, + IDbDataParameter[] commandParameters) + { + DataProvider.PrepareCommand(ref commandType, ref commandText, ref commandParameters); + + LastQuery = commandText; + + var command = GetCommand(commandAction, commandType, commandText); + + SetCommand (commandAction, command); + SetCommandParameters(commandAction, commandParameters); + + if (commandParameters != null) + { + AttachParameters(command, commandParameters); + } + } + + /// + /// Prepares a command for execution. + /// + /// Current instance. + public DbManager Prepare() + { + var command = GetCommand(CommandAction.Select); + + if (InitParameters(CommandAction.Select) == false) + ExecuteOperation(OperationType.PrepareCommand, command.Prepare); + + _prepared = true; + + return this; + } + + bool InitParameters(CommandAction commandAction) + { + var prepare = false; + + var commandParameters = GetCommandParameters(commandAction); + + if (commandParameters != null) + { + foreach (var p in commandParameters) + { + if (_dataProvider.InitParameter(p)) + continue; + + // It forces parameter's filed 'MetaType' to be set. + // Same for p.Size = p.Size below. + // + p.DbType = p.DbType; + + if (p.Value is string) + { + var len = ((string)p.Value).Length; + + if (p.Size < len) + { + p.Size = len; + prepare = true; + } + else + p.Size = p.Size; + } + else if (p.Value is DBNull) + { + p.Size = 1; + } + else if (p.Value is byte[]) + { + var len = ((byte[])p.Value).Length; + + if (p.Size < len) + { + p.Size = len; + prepare = true; + } + else + p.Size = p.Size; + } + else if (p.Value is char[]) + { + var len = ((char[])p.Value).Length; + + if (p.Size < len) + { + p.Size = len; + prepare = true; + } + else + p.Size = p.Size; + } + else if (p.Value is decimal) + { + SqlDecimal d = (decimal)p.Value; + + if (p.Precision < d.Precision) + { + p.Precision = d.Precision; + prepare = true; + } + else + p.Precision = p.Precision; + + if (p.Scale < d.Scale) + { + p.Scale = d.Scale; + prepare = true; + } + else + p.Scale = p.Scale; + } + } + + // Re-prepare command to avoid truncation. + // + if (prepare) + { + var command = GetCommand(commandAction); + + AttachParameters(command, commandParameters); + command.Prepare(); + } + } + + return prepare; + } + + #endregion + + #region ExecuteForEach + + /// + /// Executes a SQL statement for a given collection of objects and + /// returns the number of rows affected. + /// + /// + /// The method prepares the object + /// and calls the method for each item of the list. + /// + /// + /// The list of objects used to execute the command. + /// The number of rows affected by the command. + public int ExecuteForEach(ICollection collection) + { + var rowsTotal = 0; + + if (collection != null && collection.Count != 0) + { + var initParameters = true; + + foreach (var o in collection) + { + if (initParameters) + { + initParameters = false; + + var parameters = GetCommandParameters(CommandAction.Select); + + if (parameters == null || parameters.Length == 0) + { + parameters = CreateParameters(o); + + SetCommandParameters(CommandAction.Select, parameters); + AttachParameters(SelectCommand, parameters); + Prepare(); + } + } + + AssignParameterValues(o); + rowsTotal += ExecuteNonQueryInternal(); + MapOutputParameters(o); + } + } + + return rowsTotal; + } + + /// + /// Executes a SQL statement for a given collection of objects and + /// returns the number of rows affected. + /// + /// + /// The method prepares the object + /// and calls the method for each item of the list. + /// + /// + /// The list of objects used to execute the command. + /// The number of rows affected by the command. + public int ExecuteForEach(ICollection collection) + { + var rowsTotal = 0; + + if (collection != null && collection.Count != 0) + { + var initParameters = true; + + foreach (var o in collection) + { + if (initParameters) + { + initParameters = false; + + var parameters = GetCommandParameters(CommandAction.Select); + + if (parameters == null || parameters.Length == 0) + { + parameters = CreateParameters(o); + + SetCommandParameters(CommandAction.Select, parameters); + AttachParameters(SelectCommand, parameters); + Prepare(); + } + } + + AssignParameterValues(o); + rowsTotal += ExecuteNonQueryInternal(); + MapOutputParameters(o); + } + } + + return rowsTotal; + } + + public int ExecuteForEach(int maxBatchSize, IEnumerable collection) + { + var om = _mappingSchema.GetObjectMapper(typeof(T)); + var mms = new List(); + + foreach (MemberMapper mm in om) + { + var name = _dataProvider.Convert(mm.Name, GetConvertTypeToParameter()).ToString(); + + if (Command.Parameters.Contains(name)) + mms.Add(mm); + } + + return + ExecuteForEach( + collection, + mms.ToArray(), + maxBatchSize, + obj => CreateParameters(obj)); + } + + public delegate IDbDataParameter[] ParameterProvider(T obj); + + internal int ExecuteForEach(IEnumerable collection, MemberMapper[] members, int maxBatchSize, ParameterProvider getParameters) + { + if (collection == null) + return 0; + + var maxRows = + Math.Max( + Math.Min( + Math.Max( + members.Length == 0? 1000 : _dataProvider.MaxParameters / members.Length, + members.Length), + maxBatchSize), + 1); + var baseSql = SelectCommand.CommandText; + var paramName = _dataProvider.Convert(".", ConvertType.NameToQueryParameter).ToString(); + var rowsTotal = 0; + var nRows = 0; + var initParameters = true; + var saveCanRaseEvent = _canRaiseEvents; + + _canRaiseEvents = false; + + var sb = new StringBuilder(); + var rowSql = new List(maxRows); + IDbDataParameter[] baseParameters = null; + var parameters = new List(); + var hasValue = new List(); + + var isPrepared = false; + + foreach (var obj in collection) + { + if (initParameters) + { + initParameters = false; + baseParameters = getParameters(obj); + + if (maxRows != 1) + { + var n = 0; + + foreach (var p in baseParameters) + n += p.ParameterName.Length + 3 - "{0}".Length + _dataProvider.EndOfSql.Length; + + maxRows = Math.Max(1, Math.Min(maxRows, _dataProvider.MaxBatchSize / (baseSql.Length + n))); + } + + if (maxRows != 1) + baseSql += _dataProvider.EndOfSql; + } + + if (rowSql.Count < maxRows) + { +// ReSharper disable AccessToModifiedClosure + Converter c1 = p => p.ParameterName + nRows; +// ReSharper restore AccessToModifiedClosure + Converter c2 = p => p.ParameterName; + + sb + .Append("\n") + .AppendFormat( + baseSql, + Array.ConvertAll( + baseParameters, + baseParameters.Length > 0 && baseParameters[0].ParameterName != paramName? c1 : c2)); + + rowSql.Add(sb.Length); + + for (var i = 0; i < members.Length; i++) + { + var value = members[i].GetValue(obj); + var type = members[i].MemberAccessor.Type; + var dbType = members[i].GetDbType(); + + IDbDataParameter p; + + if ((value == null || value == DBNull.Value) && (dbType == DbType.Binary || type == typeof(byte[])) || + type == typeof(System.Data.Linq.Binary)) + { + p = Parameter(baseParameters[i].ParameterName + nRows, DBNull.Value, DbType.Binary); + } + else + { + if (value != null && value.GetType().IsEnum) + value = MappingSchema.MapEnumToValue(value, true); + + p = value != null + ? Parameter(baseParameters[i].ParameterName + nRows, value) + : Parameter(baseParameters[i].ParameterName + nRows, DBNull.Value, members[i].GetDbType()); + } + + parameters.Add(p); + hasValue.Add(value != null); + } + } + else + { + var n = nRows * members.Length; + + for (var i = 0; i < members.Length; i++) + { + var value = members[i].GetValue(obj); + + if (!hasValue[n + i] && value != null) + { + isPrepared = false; + + var type = members[i].MemberAccessor.Type; + var dbType = members[i].GetDbType(); + + if (value.GetType().IsEnum) + value = MappingSchema.MapEnumToValue(value, true); + + IDbDataParameter p; + if (dbType != DbType.Object) + p = Parameter(baseParameters[i].ParameterName + nRows, value ?? DBNull.Value, dbType); + else + p = Parameter(baseParameters[i].ParameterName + nRows, value ?? DBNull.Value/*, dbType*/); + + parameters[n + i] = p; + hasValue [n + i] = true; + } + else + { + if (value != null && value.GetType().IsEnum) + value = MappingSchema.MapEnumToValue(value, true); + + _dataProvider.SetParameterValue( + parameters[n + i], + value ?? DBNull.Value); + //value == null || members[i].MapMemberInfo.Nullable && _mappingSchema.IsNull(value) + // ? DBNull.Value + // : value); + } + + } + } + + nRows++; + + if (nRows >= maxRows) + { + if (!isPrepared) + { + SetCommand(sb.ToString(), parameters.ToArray()); + Prepare(); + isPrepared = true; + } + else + { + InitParameters(CommandAction.Select); + } + + var n = ExecuteNonQueryInternal(); + if (n > 0) + rowsTotal += n; + + nRows = 0; + } + } + + if (nRows > 0) + { + if (rowSql.Count >= maxRows) + { + var nps = nRows * members.Length; + parameters.RemoveRange(nps, parameters.Count - nps); + + sb.Length = rowSql[nRows - 1]; + } + + SetCommand(sb.ToString(), parameters.ToArray()); + Prepare(); + + var n = ExecuteNonQueryInternal(); + if (n > 0) + rowsTotal += n; + } + + _canRaiseEvents = saveCanRaseEvent; + + return rowsTotal; + } + + /// + /// Executes a SQL statement for the and + /// returns the number of rows affected. + /// + /// + /// The method prepares the object + /// and calls the method for each item + /// of the . + /// + /// + /// An instance of the class to execute the command. + /// The number of rows affected by the command. + public int ExecuteForEach(DataTable table) + { + var rowsTotal = 0; + + if (table != null && table.Rows.Count != 0) + { + var parameters = GetCommandParameters(CommandAction.Select); + + if (parameters == null || parameters.Length == 0) + { + parameters = CreateParameters(table.Rows[0]); + + SetCommandParameters(CommandAction.Select, parameters); + AttachParameters(SelectCommand, parameters); + Prepare(); + } + + foreach (DataRow dr in table.Rows) + { + AssignParameterValues(dr); + rowsTotal += ExecuteNonQueryInternal(); + } + } + + return rowsTotal; + } + + /// + /// Executes a SQL statement for the first table of the + /// and returns the number of rows affected. + /// + /// + /// The method prepares the object + /// and calls the method for each item of the first table. + /// + /// + /// An instance of the class to execute the command. + /// The number of rows affected by the command. + public int ExecuteForEach(DataSet dataSet) + { + return ExecuteForEach(dataSet.Tables[0]); + } + + /// + /// Executes a SQL statement for the specified table of the + /// and returns the number of rows affected. + /// + /// + /// The method prepares the object + /// and calls the method for each item of the first table. + /// + /// + /// An instance of the class to execute the command. + /// The table name or index. + /// name/index. + /// The number of rows affected by the command. + public int ExecuteForEach(DataSet dataSet, NameOrIndexParameter nameOrIndex) + { + return nameOrIndex.ByName ? ExecuteForEach(dataSet.Tables[nameOrIndex.Name]) + : ExecuteForEach(dataSet.Tables[nameOrIndex.Index]); + } + + #endregion + + #region ExecuteNonQuery + + /// + /// Executes a SQL statement and returns the number of rows affected. + /// + /// + /// The method can be used to execute the INSERT, UPDATE, and DELETE SQL statements. + /// + /// + /// The number of rows affected by the command. + public int ExecuteNonQuery() + { + if (_prepared) + InitParameters(CommandAction.Select); + + return ExecuteNonQueryInternal(); + } + + /// + /// Executes a SQL statement and returns the number of rows affected. + /// + /// + /// The method can be used to execute the INSERT, UPDATE, and DELETE SQL statements. + /// + /// Name of a to map return value. + /// An to map from command parameters. + /// The number of rows affected by the command. + public int ExecuteNonQuery( + string returnValueMember, + object obj) + { + var rowsAffected = ExecuteNonQuery(); + + MapOutputParameters(returnValueMember, obj); + + return rowsAffected; + } + + /// + /// Executes a SQL statement and returns the number of rows affected. + /// + /// + /// The method can be used to execute the INSERT, UPDATE, and DELETE SQL statements. + /// + /// An to map from command parameters. + /// The number of rows affected by the command. + public int ExecuteNonQuery(object obj) + { + var rowsAffected = ExecuteNonQuery(); + + MapOutputParameters(null, obj); + + return rowsAffected; + } + + /// + /// Executes a SQL statement and returns the number of rows affected. + /// + /// + /// The method can be used to execute the INSERT, UPDATE, and DELETE SQL statements. + /// + /// Name of a to map return value. + /// An array of to map + /// from command parameters. + /// The number of rows affected by the command. + public int ExecuteNonQuery( + string returnValueMember, + params object[] objects) + { + var rowsAffected = ExecuteNonQuery(); + + MapOutputParameters(returnValueMember, objects); + + return rowsAffected; + } + + /// + /// Executes a SQL statement and returns the number of rows affected. + /// + /// + /// The method can be used to execute the INSERT, UPDATE, and DELETE SQL statements. + /// + /// An array of to map + /// from command parameters. + /// The number of rows affected by the command. + public int ExecuteNonQuery(params object[] objects) + { + var rowsAffected = ExecuteNonQuery(); + + MapOutputParameters(null, objects); + + return rowsAffected; + } + + /// + /// Executes several SQL statements at a time using single roundtrip to the server (if supported by data provider). + /// + /// + /// All parameters of the query must be arrays of type corresponding to the type of the parameter. + /// The value of the parameter must be equal to the number of elements of each array. + /// + /// The number of iterations. + /// The number of rows affected by the command. + public int ExecuteArray(int iterations) + { + return ExecuteOperation(OperationType.ExecuteNonQuery, () => DataProvider.ExecuteArray(SelectCommand, iterations)); + } + + #endregion + + #region ExecuteScalar + + /// + /// Executes the query, and returns the first column of the first row + /// in the resultset returned by the query. Extra columns or rows are + /// ignored. + /// + /// The first column of the first row in the resultset. + /// + public object ExecuteScalar() + { + if (_prepared) + InitParameters(CommandAction.Select); + + using (var rd = ExecuteReaderInternal(CommandBehavior.Default)) + return rd.Read() && rd.FieldCount > 0 ? rd.GetValue(0) : null; + } + + /// + /// Executes the query, and returns the value with specified scalar + /// source type. + /// + /// The method used to return the scalar + /// value. + /// + /// + /// ScalarSourceType + /// Return value + /// + /// + /// DataReader + /// The first column of the first row in the resultset. + /// + /// + /// + /// OutputParameter + /// The value of the first output or input/output + /// parameter returned. + /// + /// + /// ReturnValue + /// The value of the "return value" parameter returned. + /// + /// + /// + /// AffectedRows + /// The number of rows affected. + /// + /// + /// + /// + public object ExecuteScalar(ScalarSourceType sourceType) + { + return ExecuteScalar(sourceType, new NameOrIndexParameter()); + } + + /// + /// Executes the query, and returns the value with specified scalar + /// source type. + /// + /// The method used to return the scalar value. + /// The column name/index or output parameter name/index. + /// + /// + /// ScalarSourceType + /// Return value + /// + /// + /// DataReader + /// The column with specified name or at specified index + /// of the first row in the resultset. + /// + /// + /// OutputParameter + /// The value of the output or input/output parameter + /// returned with specified name or at specified index. + /// + /// + /// ReturnValue + /// The value of the "return value" parameter returned. + /// The index parameter is ignored. + /// + /// + /// AffectedRows + /// The number of rows affected. The index parameter is + /// ignored. + /// + /// + /// + public object ExecuteScalar(ScalarSourceType sourceType, NameOrIndexParameter nameOrIndex) + { + if (_prepared) + InitParameters(CommandAction.Select); + + switch (sourceType) + { + case ScalarSourceType.DataReader: + using (var reader = ExecuteReaderInternal()) + if (reader.Read()) + return reader.GetValue(nameOrIndex.ByName ? reader.GetOrdinal(nameOrIndex.Name) : nameOrIndex.Index); + + break; + + case ScalarSourceType.OutputParameter: + ExecuteNonQueryInternal(); + + if (nameOrIndex.ByName) + { + var name = (string)_dataProvider.Convert(nameOrIndex.Name, GetConvertTypeToParameter()); + return Parameter(name).Value; + } + + var index = nameOrIndex.Index; + foreach (IDataParameter p in SelectCommand.Parameters) + { + // Skip the return value parameter. + // + if (p.Direction == ParameterDirection.ReturnValue) + continue; + + if (0 == index) + return p.Value; + + --index; + } + break; + + case ScalarSourceType.ReturnValue: + ExecuteNonQueryInternal(); + + foreach (IDataParameter p in SelectCommand.Parameters) + if (p.Direction == ParameterDirection.ReturnValue) + return p.Value; + + break; + + case ScalarSourceType.AffectedRows: + return ExecuteNonQueryInternal(); + + default: + throw new InvalidEnumArgumentException("sourceType", + (int)sourceType, typeof(ScalarSourceType)); + } + + return null; + } + + /// + /// Executes the query, and returns the first column of the first row + /// in the resultset returned by the query. Extra columns or rows are + /// ignored. + /// + /// + /// The first column of the first row in the resultset. + /// + public T ExecuteScalar() + { + var value = _mappingSchema.ConvertChangeType(ExecuteScalar(), typeof(T)); + return value == null && typeof(T).IsEnum ? default(T) : (T)value; + } + + /// + /// Executes the query, and returns the value with specified scalar + /// source type. + /// + /// The method used to return the scalar + /// value. + /// + /// + /// ScalarSourceType + /// Return value + /// + /// + /// DataReader + /// The first column of the first row in the resultset. + /// + /// + /// + /// OutputParameter + /// The value of the first output or input/output + /// parameter returned. + /// + /// + /// ReturnValue + /// The value of the "return value" parameter returned. + /// + /// + /// + /// AffectedRows + /// The number of rows affected. + /// + /// + /// + /// + public T ExecuteScalar(ScalarSourceType sourceType) + { + return ExecuteScalar(sourceType, new NameOrIndexParameter()); + } + + /// + /// Executes the query, and returns the value with specified scalar + /// source type. + /// + /// The method used to return the scalar value. + /// The column name/index or output parameter name/index. + /// + /// + /// ScalarSourceType + /// Return value + /// + /// + /// DataReader + /// The column with specified name or at specified index + /// of the first row in the resultset. + /// + /// + /// OutputParameter + /// The value of the output or input/output parameter + /// returned with specified name or at specified index. + /// + /// + /// ReturnValue + /// The value of the "return value" parameter returned. + /// The index parameter is ignored. + /// + /// + /// AffectedRows + /// The number of rows affected. The index parameter is + /// ignored. + /// + /// + /// + public T ExecuteScalar(ScalarSourceType sourceType, NameOrIndexParameter nameOrIndex) + { + return (T)_mappingSchema.ConvertChangeType(ExecuteScalar(sourceType, nameOrIndex), typeof(T)); + } + + #endregion + + #region ExecuteScalarList + + /// + /// Executes the query, and returns the array list of values of the + /// specified column of the every row in the resultset returned by the + /// query. Other columns are ignored. + /// + /// The array to fill in. + /// The column name/index or output parameter name/index. + /// The type of the each element. + /// Array list of values of the specified column of the every + /// row in the resultset. + public IList ExecuteScalarList( + IList list, + Type type, + NameOrIndexParameter nameOrIndex) + { + if (list == null) + list = new ArrayList(); + + if (_prepared) + InitParameters(CommandAction.Select); + + using (var dr = ExecuteReaderInternal()) + return _mappingSchema.MapDataReaderToScalarList(dr, nameOrIndex, list, type); + } + + /// + /// Executes the query, and returns the array list of values of first + /// column of the every row in the resultset returned by the query. + /// Other columns are ignored. + /// + /// The array to fill in. + /// The type of the each element. + /// Array list of values of first column of the every row in + /// the resultset. + public IList ExecuteScalarList(IList list, Type type) + { + if (list == null) + list = new ArrayList(); + + return ExecuteScalarList(list, type, 0); + } + + /// + /// Executes the query, and returns the array list of values of the + /// specified column of the every row in the resultset returned by the + /// query. Other columns are ignored. + /// + /// The column name/index. + /// The type of the each element. + /// Array list of values of the specified column of the every + /// row in the resultset. + public ArrayList ExecuteScalarList(Type type, NameOrIndexParameter nameOrIndex) + { + var list = new ArrayList(); + + ExecuteScalarList(list, type, nameOrIndex); + + return list; + } + + /// + /// Executes the query, and returns the array list of values of first + /// column of the every row in the resultset returned by the query. + /// Other columns are ignored. + /// + /// The type of the each element. + /// Array list of values of first column of the every row in + /// the resultset. + public ArrayList ExecuteScalarList(Type type) + { + var list = new ArrayList(); + + ExecuteScalarList(list, type, 0); + + return list; + } + + /// + /// Executes the query, and returns the array list of values of the + /// specified column of the every row in the resultset returned by the + /// query. Other columns are ignored. + /// + /// The array to fill in. + /// The column name/index or output parameter + /// name/index. + /// The type of the each element. + /// Array list of values of the specified column of the every + /// row in the resultset. + public IList ExecuteScalarList( + IList list, + NameOrIndexParameter nameOrIndex) + { + if (list == null) + list = new List(); + + if (_prepared) + InitParameters(CommandAction.Select); + + using (var dr = ExecuteReaderInternal()) + return _mappingSchema.MapDataReaderToScalarList(dr, nameOrIndex, list); + } + + /// + /// Executes the query, and returns the array list of values of first + /// column of the every row in the resultset returned by the query. + /// Other columns are ignored. + /// + /// The array to fill in. + /// The type of the each element. + /// Array list of values of first column of the every row in + /// the resultset. + public IList ExecuteScalarList(IList list) + { + return ExecuteScalarList(list, 0); + } + + /// + /// Executes the query, and returns the array list of values of the + /// specified column of the every row in the resultset returned by the + /// query. Other columns are ignored. + /// + /// The column name/index or output parameter name/index. + /// The type of the each element. + /// Array list of values of the specified column of the every + /// row in the resultset. + public List ExecuteScalarList(NameOrIndexParameter nameOrIndex) + { + var list = new List(); + + ExecuteScalarList(list, nameOrIndex); + + return list; + } + + /// + /// Executes the query, and returns the list of values of first + /// column of the every row in the resultset returned by the query. + /// Other columns are ignored. + /// + /// The type of the each element. + /// Array list of values of first column of the every row in + /// the resultset. + public List ExecuteScalarList() + { + var list = new List(); + + ExecuteScalarList(list, 0); + + return list; + } + + #endregion + + #region ExecuteScalarDictionary + + /// + /// Executes the query, and returns the dictionary. + /// The keys are loaded from a column specified by and + /// values are loaded from a column specified by . + /// Other columns are ignored. + /// + ///The dictionary to add values. + ///The column name/index to load keys. + ///The key type. + ///The column name/index to load values. + ///The value type. + ///The loaded dictionary. + public IDictionary ExecuteScalarDictionary( + IDictionary dic, + NameOrIndexParameter keyField, Type keyFieldType, + NameOrIndexParameter valueField, Type valueFieldType) + { + if (dic == null) + dic = new Hashtable(); + + if (_prepared) + InitParameters(CommandAction.Select); + + //object nullValue = _mappingSchema.GetNullValue(type); + + if (keyField.ByName && keyField.Name.Length > 0 && keyField.Name[0] == '@') + keyField = keyField.Name.Substring(1); + + using (var dr = ExecuteReaderInternal()) + { + if (dr.Read()) + { + var keyIndex = keyField.ByName ? dr.GetOrdinal(keyField.Name) : keyField.Index; + var valueIndex = valueField.ByName ? dr.GetOrdinal(valueField.Name) : valueField.Index; + + do + { + var value = dr[valueIndex]; + var key = dr[keyIndex]; + + if (key == null || key.GetType() != keyFieldType) + key = key is DBNull ? null : _mappingSchema.ConvertChangeType(key, keyFieldType); + + if (value == null || value.GetType() != valueFieldType) + value = value is DBNull ? null : _mappingSchema.ConvertChangeType(value, valueFieldType); + + dic.Add(key, value); + } + while (dr.Read()); + } + } + + return dic; + } + + /// + /// Executes the query, and returns the dictionary. + /// The keys are loaded from a column specified by and + /// values are loaded from a column specified by . + /// Other columns are ignored. + /// + ///The column name/index to load keys. + ///The key type. + ///The column name/index to load values. + ///The value type. + ///The loaded dictionary. + public Hashtable ExecuteScalarDictionary( + NameOrIndexParameter keyField, Type keyFieldType, + NameOrIndexParameter valueField, Type valueFieldType) + { + var table = new Hashtable(); + + ExecuteScalarDictionary(table, keyField, keyFieldType, valueField, valueFieldType); + + return table; + } + + /// + /// Executes the query, and returns the dictionary. + /// The keys are loaded from a column specified by and + /// values are loaded from a column specified by . + /// Other columns are ignored. + /// + ///The key type. + ///The value type. + ///The dictionary to add values. + ///The column name/index to load keys. + ///The column name/index to load values. + ///The loaded dictionary. + public IDictionary ExecuteScalarDictionary( + IDictionary dic, + NameOrIndexParameter keyField, + NameOrIndexParameter valueField) + { + if (dic == null) + dic = new Dictionary(); + + if (_prepared) + InitParameters(CommandAction.Select); + + //object nullValue = _mappingSchema.GetNullValue(type); + + var keyFieldType = typeof(TKey); + var valueFieldType = typeof(T); + + using (var dr = ExecuteReaderInternal()) + if (dr.Read()) + { + var keyIndex = keyField.ByName ? dr.GetOrdinal(keyField.Name) : keyField.Index; + var valueIndex = valueField.ByName ? dr.GetOrdinal(valueField.Name) : valueField.Index; + + do + { + var value = dr[valueIndex]; + var key = dr[keyIndex]; + + if (key == null || key.GetType() != keyFieldType) + key = key is DBNull ? null : _mappingSchema.ConvertChangeType(key, keyFieldType); + + if (value == null || value.GetType() != valueFieldType) + value = value is DBNull ? null : _mappingSchema.ConvertChangeType(value, valueFieldType); + + dic.Add((TKey) key, (T) value); + } while (dr.Read()); + } + + return dic; + } + + /// + /// Executes the query, and returns the dictionary. + /// The keys are loaded from a column specified by and + /// values are loaded from a column specified by . + /// Other columns are ignored. + /// + ///The key type. + ///The value type. + ///The column name/index to load keys. + ///The column name/index to load values. + ///The loaded dictionary. + public Dictionary ExecuteScalarDictionary( + NameOrIndexParameter keyField, + NameOrIndexParameter valueField) + { + var dic = new Dictionary(); + + ExecuteScalarDictionary(dic, keyField, valueField); + + return dic; + } + + #endregion + + #region ExecuteScalarDictionary (Index) + + /// + /// Executes the query, and returns the dictionary. + /// The keys are loaded from columns specified by and + /// values are loaded from a column specified by . + /// Other columns are ignored. + /// + ///The dictionary to add values. + ///The of the key columns. + ///The column name/index to load values. + ///The value type. + ///The loaded dictionary. + public IDictionary ExecuteScalarDictionary( + IDictionary dic, + MapIndex index, + NameOrIndexParameter valueField, + Type valueFieldType) + { + if (dic == null) + dic = new Hashtable(); + + if (_prepared) + InitParameters(CommandAction.Select); + + //object nullValue = _mappingSchema.GetNullValue(type); + + using (var dr = ExecuteReaderInternal()) + if (dr.Read()) + { + var valueIndex = valueField.ByName ? dr.GetOrdinal(valueField.Name) : valueField.Index; + var keyIndex = new int[index.Fields.Length]; + + for (var i = 0; i < keyIndex.Length; i++) + keyIndex[i] = + index.Fields[i].ByName + ? dr.GetOrdinal(index.Fields[i].Name) + : index.Fields[i].Index; + + do + { + var value = dr[valueIndex]; + + if (value == null || value.GetType() != valueFieldType) + value = value is DBNull ? null : _mappingSchema.ConvertChangeType(value, valueFieldType); + + var key = new object[keyIndex.Length]; + + for (var i = 0; i < keyIndex.Length; i++) + key[i] = dr[keyIndex[i]]; + + dic.Add(new CompoundValue(key), value); + } while (dr.Read()); + } + + return dic; + } + + /// + /// Executes the query, and returns the dictionary. + /// The keys are loaded from columns specified by and + /// values are loaded from a column specified by . + /// Other columns are ignored. + /// + ///The of the key columns. + ///The column name/index to load values. + ///The value type. + ///The loaded dictionary. + public Hashtable ExecuteScalarDictionary( + MapIndex index, NameOrIndexParameter valueField, Type valueFieldType) + { + var table = new Hashtable(); + + ExecuteScalarDictionary(table, index, valueField, valueFieldType); + + return table; + } + + /// + /// Executes the query, and returns the dictionary. + /// The keys are loaded from columns specified by and + /// values are loaded from a column specified by . + /// Other columns are ignored. + /// + ///The value type. + ///The dictionary to add values. + ///The of the key columns. + ///The column name/index to load values. + ///The loaded dictionary. + public IDictionary ExecuteScalarDictionary( + IDictionary dic, MapIndex index, NameOrIndexParameter valueField) + { + if (dic == null) + dic = new Dictionary(); + + if (_prepared) + InitParameters(CommandAction.Select); + + //object nullValue = _mappingSchema.GetNullValue(type); + + var valueFieldType = typeof(T); + + using (var dr = ExecuteReaderInternal()) + if (dr.Read()) + { + var valueIndex = valueField.ByName ? dr.GetOrdinal(valueField.Name) : valueField.Index; + var keyIndex = new int[index.Fields.Length]; + + for (var i = 0; i < keyIndex.Length; i++) + keyIndex[i] = index.Fields[i].ByName + ? dr.GetOrdinal(index.Fields[i].Name) + : index.Fields[i].Index; + + do + { + var value = dr[valueIndex]; + + if (value == null || value.GetType() != valueFieldType) + value = value is DBNull ? null : _mappingSchema.ConvertChangeType(value, valueFieldType); + + var key = new object[keyIndex.Length]; + + for (var i = 0; i < keyIndex.Length; i++) + key[i] = dr[keyIndex[i]]; + + dic.Add(new CompoundValue(key), (T) value); + } while (dr.Read()); + } + + return dic; + } + + /// + /// Executes the query, and returns the dictionary. + /// The keys are loaded from columns specified by and + /// values are loaded from a column specified by . + /// Other columns are ignored. + /// + ///The value type. + ///The of the key columns. + ///The column name/index to load values. + ///The loaded dictionary. + public Dictionary ExecuteScalarDictionary( + MapIndex index, NameOrIndexParameter valueField) + { + var dic = new Dictionary(); + + ExecuteScalarDictionary(dic, index, valueField); + + return dic; + } + + #endregion + + #region ExecuteReader + + /// + /// Executes the command and builds an . + /// + /// An instance of the class. + public IDataReader ExecuteReader() + { + if (_prepared) + InitParameters(CommandAction.Select); + + return ExecuteReaderInternal(); + } + + /// + /// Executes the command and builds an . + /// + /// One of the values. + /// An instance of the class. + public IDataReader ExecuteReader(CommandBehavior commandBehavior) + { + if (_prepared) + InitParameters(CommandAction.Select); + + return ExecuteReaderInternal(commandBehavior); + } + + #endregion + + #region ExecuteDataSet + + /// + /// Executes a SQL statement using the provided parameters. + /// + /// + /// See the method + /// to find an example. + /// + /// The . + public DataSet ExecuteDataSet() + { + return ExecuteDataSet(null, 0, 0, "Table"); + } + + /// + /// Executes a SQL statement using the provided parameters. + /// + /// + /// See the method + /// to find an example. + /// + /// The input object. + /// The . + public DataSet ExecuteDataSet( + DataSet dataSet) + { + return ExecuteDataSet(dataSet, 0, 0, "Table"); + } + + /// + /// Executes a SQL statement using the provided parameters. + /// + /// + /// See the method + /// to find an example. + /// + /// The name or index of the populating table. + /// The . + public DataSet ExecuteDataSet( + NameOrIndexParameter table) + { + return ExecuteDataSet(null, 0, 0, table); + } + + /// + /// Executes a SQL statement using the provided parameters. + /// + /// The object to populate. + /// The name or index of the populating table. + /// The . + public DataSet ExecuteDataSet( + DataSet dataSet, + NameOrIndexParameter table) + { + return ExecuteDataSet(dataSet, 0, 0, table); + } + + /// + /// Executes a SQL statement using the provided parameters. + /// + /// The object to populate. + /// The name or index of the populating table. + /// The zero-based record number to start with. + /// The maximum number of records to retrieve. + /// The . + public DataSet ExecuteDataSet( + DataSet dataSet, + int startRecord, + int maxRecords, + NameOrIndexParameter table) + { + if (_prepared) + InitParameters(CommandAction.Select); + + if (dataSet == null) + dataSet = new DataSet(); + + var da = _dataProvider.CreateDataAdapterObject(); + + ((IDbDataAdapter)da).SelectCommand = SelectCommand; + + ExecuteOperation(OperationType.Fill, delegate + { + if (table.ByName) + da.Fill(dataSet, startRecord, maxRecords, table.Name); + else + da.Fill(startRecord, maxRecords, dataSet.Tables[table.Index]); + }); + + return dataSet; + } + + #endregion + + #region ExecuteDataTable + + /// + /// Executes a SQL statement using the provided parameters. + /// + /// The . + public DataTable ExecuteDataTable() + { + return ExecuteDataTable(null); + } + + /// + /// Executes a SQL statement using the provided parameters. + /// + /// The object to populate. + /// The . + public DataTable ExecuteDataTable(DataTable dataTable) + { + if (_prepared) + InitParameters(CommandAction.Select); + + if (dataTable == null) + dataTable = new DataTable(); + + var da = _dataProvider.CreateDataAdapterObject(); + ((IDbDataAdapter)da).SelectCommand = SelectCommand; + + ExecuteOperation(OperationType.Fill, delegate { da.Fill(dataTable); }); + return dataTable; + } + + /// Adds or refreshes rows in a + /// to match those in the data source starting at the specified record + /// and retrieving up to the specified maximum number of records. + /// + /// The zero-based record number to start with. + /// The maximum number of records to retrieve. + /// The objects + /// to fill from the data source. + public void ExecuteDataTables( + int startRecord, + int maxRecords, + params DataTable[] tableList) + { + if (tableList == null || tableList.Length == 0) + return; + + if (_prepared) + InitParameters(CommandAction.Select); + + var da = _dataProvider.CreateDataAdapterObject(); + ((IDbDataAdapter)da).SelectCommand = SelectCommand; + + ExecuteOperation(OperationType.Fill, delegate { da.Fill(startRecord, maxRecords, tableList); }); + } + + /// Adds or refreshes rows in a + /// to match those in the data source starting at the specified record + /// and retrieving up to the specified maximum number of records. + /// + /// The objects + /// to fill from the data source. + public void ExecuteDataTables(params DataTable[] tableList) + { + ExecuteDataTables(0, 0, tableList); + } + + #endregion + + #region ExecuteObject + + /// + /// Executes a SQL statement and maps resultset to an object. + /// + /// An object to populate. + /// The System.Type of the object. + /// Additional parameters passed to object constructor through . + /// A business object. + private object ExecuteObjectInternal(object entity, Type type, object[] parameters) + { + if (_prepared) + InitParameters(CommandAction.Select); + + using (var dr = ExecuteReaderInternal(/*CommandBehavior.SingleRow*/)) // Sybase provider does not support this flag. + return ExecuteOperation(OperationType.Read, () => + { + while (dr.Read()) + return + entity == null + ? _mappingSchema.MapDataReaderToObject(dr, type, parameters) + : _mappingSchema.MapDataReaderToObject(dr, entity, parameters); + + return null; + }); + } + + /// + /// Executes a SQL statement and maps resultset to an object. + /// + /// An object to populate. + /// A business object. + public object ExecuteObject(object entity) + { + if (null == entity) + throw new ArgumentNullException("entity"); + + return ExecuteObjectInternal(entity, entity.GetType(), null); + } + + /// + /// Executes a SQL statement and maps resultset to an object. + /// + /// An object to populate. + /// Additional parameters passed to object constructor through . + /// A business object. + public object ExecuteObject(object entity, params object[] parameters) + { + if (null == entity) + throw new ArgumentNullException("entity"); + + return ExecuteObjectInternal(entity, entity.GetType(), parameters); + } + + /// + /// Executes a SQL statement and maps resultset to an object. + /// + /// Type of an object. + /// A business object. + public object ExecuteObject(Type type) + { + return ExecuteObjectInternal(null, type, null); + } + + /// + /// Executes a SQL statement and maps resultset to an object. + /// + /// Type of an object. + /// Additional parameters passed to object constructor through . + /// A business object. + public object ExecuteObject(Type type, params object[] parameters) + { + return ExecuteObjectInternal(null, type, parameters); + } + + /// + /// Executes a SQL statement and maps resultset to an object. + /// + /// Type of an object. + /// A business object. + public T ExecuteObject() + { + return (T)ExecuteObjectInternal(null, typeof(T), null); + } + + /// + /// Executes a SQL statement and maps resultset to an object. + /// + /// Type of an object. + /// Additional parameters passed to object constructor through . + /// A business object. + public T ExecuteObject(params object[] parameters) + { + return (T)ExecuteObjectInternal(null, typeof(T), parameters); + } + + #endregion + + #region ExecuteList + + private IList ExecuteListInternal(IList list, Type type, params object[] parameters) + { + if (list == null) + list = new ArrayList(); + + if (_prepared) + InitParameters(CommandAction.Select); + + using (var dr = ExecuteReaderInternal()) + //wrap this too, because of PostgreSQL lazy query execution + return ExecuteOperation(OperationType.Fill, () => _mappingSchema.MapDataReaderToList(dr, list, type, parameters)); + } + + private void ExecuteListInternal(IList list, params object[] parameters) + { + if (list == null) + list = new List(); + + if (_prepared) + InitParameters(CommandAction.Select); + + using (var dr = ExecuteReaderInternal()) + ExecuteOperation(OperationType.Fill, () => _mappingSchema.MapDataReaderToList(dr, list, parameters)); + } + + /// + /// Executes the query, and returns an array of business entities using the provided parameters. + /// + /// Type of the business object. + /// An array of business objects. + public ArrayList ExecuteList(Type type) + { + var arrayList = new ArrayList(); + + ExecuteListInternal(arrayList, type, null); + + return arrayList; + } + + /// + /// Executes the query, and returns an array of business entities. + /// + /// Type of an object. + /// Populated list of mapped business objects. + public List ExecuteList() + { + var list = new List(); + + ExecuteListInternal(list, null); + + return list; + } + + /// + /// Executes the query, and returns an array of business entities using the provided parameters. + /// + /// Type of the business object. + /// Additional parameters passed to object constructor through . + /// An array of business objects. + public ArrayList ExecuteList(Type type, params object[] parameters) + { + var arrayList = new ArrayList(); + + ExecuteListInternal(arrayList, type, parameters); + + return arrayList; + } + + /// + /// Executes the query, and returns an array of business entities. + /// + /// Type of an object. + /// Additional parameters passed to object constructor through . + /// Populated list of mapped business objects. + public List ExecuteList(params object[] parameters) + { + var list = new List(); + + ExecuteListInternal(list, parameters); + + return list; + } + + /// + /// Executes the query, and returns an array of business entities. + /// + /// The list of mapped business objects to populate. + /// Type of an object. + /// Populated list of mapped business objects. + public IList ExecuteList(IList list, Type type) + { + return ExecuteListInternal(list, type, null); + } + + /// + /// Executes the query, and returns an array of business entities. + /// + /// Type of an object. + /// The list of mapped business objects to populate. + /// Populated list of mapped business objects. + public IList ExecuteList(IList list) + { + ExecuteListInternal(list, null); + + return list; + } + + /// + /// Executes the query, and returns an array of business entities. + /// + /// The list of mapped business objects to populate. + /// Type of an object. + /// Additional parameters passed to object constructor through . + /// Populated list of mapped business objects. + public IList ExecuteList(IList list, Type type, params object[] parameters) + { + return ExecuteListInternal(list, type, parameters); + } + + /// + /// Executes the query, and returns an array of business entities. + /// + /// Type of an object. + /// The list of mapped business objects to populate. + /// Additional parameters passed to object constructor through . + /// Populated list of mapped business objects. + public IList ExecuteList(IList list, params object[] parameters) + { + ExecuteListInternal(list, parameters); + + return list; + } + + /// + /// Executes the query, and returns an array of business entities. + /// + /// Type of a list. + /// Type of an object. + /// The list of mapped business objects to populate. + /// Additional parameters passed to object constructor through . + /// Populated list of mapped business objects. + public TList ExecuteList(TList list, params object[] parameters) + where TList : IList + { + ExecuteListInternal(list, typeof(T), parameters); + + return list; + } + + /// + /// Executes the query, and returns an array of business entities. + /// + /// Type of a list. + /// Type of an object. + /// Additional parameters passed to object constructor through . + /// Populated list of mapped business objects. + public TList ExecuteList(params object[] parameters) + where TList : IList, new() + { + var list = new TList(); + + ExecuteListInternal(list, typeof(T), parameters); + + return list; + } + + #endregion + + #region ExecuteDictionary + + /// + /// Executes the query, and returns the of business entities + /// using the provided parameters. + /// + /// + /// The field name or index that is used as a key to populate . + /// Business object type. + /// Any additional parameters passed to the constructor with parameter. + /// An instance of the class. + public Hashtable ExecuteDictionary( + NameOrIndexParameter keyField, + Type keyFieldType, + params object[] parameters) + { + var hash = new Hashtable(); + + ExecuteDictionary(hash, keyField, keyFieldType, parameters); + + return hash; + } + + /// + /// Executes the query, and returns the of business entities. + /// + /// + /// A dictionary of mapped business objects to populate. + /// The field name or index that is used as a key to populate . + /// Business object type. + /// Any additional parameters passed to the constructor with parameter. + /// An instance of the . + public IDictionary ExecuteDictionary( + IDictionary dictionary, + NameOrIndexParameter keyField, + Type type, + params object[] parameters) + { + if (dictionary == null) + dictionary = new Hashtable(); + + if (_prepared) + InitParameters(CommandAction.Select); + + using (var dr = ExecuteReaderInternal()) + return _mappingSchema.MapDataReaderToDictionary(dr, dictionary, keyField, type, parameters); + } + + /// + /// Executes the query, and returns a dictionary of business entities. + /// + /// Key's type. + /// Value's type. + /// The field name or index that is used as a key to populate the dictionary. + /// Any additional parameters passed to the constructor with parameter. + /// An instance of the dictionary. + public Dictionary ExecuteDictionary( + NameOrIndexParameter keyField, + params object[] parameters) + { + var dictionary = new Dictionary(); + + ExecuteDictionary(dictionary, keyField, typeof(TValue), parameters); + + return dictionary; + } + + /// + /// Executes the query, and returns the of business entities. + /// + /// A dictionary of mapped business objects to populate. + /// The field name or index that is used as a key to populate . + /// Any additional parameters passed to the constructor with parameter. + /// An instance of the . + public IDictionary ExecuteDictionary( + IDictionary dictionary, + NameOrIndexParameter keyField, + params object[] parameters) + { + return ExecuteDictionary(dictionary, keyField, typeof(TValue), parameters); + } + + /// + /// Executes the query, and returns the of business entities. + /// + /// A dictionary of mapped business objects to populate. + /// The field name or index that is used as a key to populate . + /// Business object type. + /// Any additional parameters passed to the constructor with parameter. + /// An instance of the . + public IDictionary ExecuteDictionary( + IDictionary dictionary, + NameOrIndexParameter keyField, + Type destObjectType, + params object[] parameters) + { + if (dictionary == null) + dictionary = new Dictionary(); + + if (_prepared) + InitParameters(CommandAction.Select); + + using (var dr = ExecuteReaderInternal()) + return _mappingSchema.MapDataReaderToDictionary( + dr, dictionary, keyField, destObjectType, parameters); + } + + #endregion + + #region ExecuteDictionary (Index) + + /// + /// Executes the query, and returns the of business entities + /// using the provided parameters. + /// + /// + /// Dictionary key fields. + /// Business object type. + /// Any additional parameters passed to the constructor with parameter. + /// An instance of the class. + public Hashtable ExecuteDictionary( + MapIndex index, + Type type, + params object[] parameters) + { + var hash = new Hashtable(); + + ExecuteDictionary(hash, index, type, parameters); + + return hash; + } + + /// + /// Executes the query, and returns the of business entities. + /// + /// + /// A dictionary of mapped business objects to populate. + /// Dictionary key fields. + /// Business object type. + /// Any additional parameters passed to the constructor with parameter. + /// An instance of the . + public IDictionary ExecuteDictionary( + IDictionary dictionary, + MapIndex index, + Type type, + params object[] parameters) + { + if (dictionary == null) + dictionary = new Hashtable(); + + if (_prepared) + InitParameters(CommandAction.Select); + + using (var dr = ExecuteReaderInternal()) + return _mappingSchema.MapDataReaderToDictionary(dr, dictionary, index, type, parameters); + } + + /// + /// Executes the query, and returns a dictionary of business entities. + /// + /// Value's type. + /// Dictionary key fields. + /// Any additional parameters passed to the constructor with parameter. + /// An instance of the dictionary. + public Dictionary ExecuteDictionary( + MapIndex index, + params object[] parameters) + { + var dictionary = new Dictionary(); + + ExecuteDictionary(dictionary, index, typeof(TValue), parameters); + + return dictionary; + } + + /// + /// Executes the query, and returns a dictionary of business entities. + /// + /// Value's type. + /// A dictionary of mapped business objects to populate. + /// Dictionary key fields. + /// Any additional parameters passed to the constructor with parameter. + /// An instance of the dictionary. + public IDictionary ExecuteDictionary( + IDictionary dictionary, + MapIndex index, + params object[] parameters) + { + return ExecuteDictionary(dictionary, index, typeof(TValue), parameters); + } + + /// + /// Executes the query, and returns a dictionary of business entities. + /// + /// Value's type. + /// A dictionary of mapped business objects to populate. + /// Dictionary key fields. + /// Business object type. + /// Any additional parameters passed to the constructor with parameter. + /// An instance of the dictionary. + public IDictionary ExecuteDictionary( + IDictionary dictionary, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + if (dictionary == null) + dictionary = new Dictionary(); + + if (_prepared) + InitParameters(CommandAction.Select); + + using (var dr = ExecuteReaderInternal()) + return _mappingSchema.MapDataReaderToDictionary( + dr, dictionary, index, destObjectType, parameters); + } + + #endregion + + #region ExecuteResultSet + + /// + /// Executes the query, and returns multiple results. + /// + /// Array of to populate. + /// The populated . + public MapResultSet[] ExecuteResultSet(params MapResultSet[] resultSets) + { + if (_prepared) + InitParameters(CommandAction.Select); + + using (var dr = ExecuteReaderInternal()) + _mappingSchema.MapDataReaderToResultSet(dr, resultSets); + + return resultSets; + } + + /// + /// Executes the query, and returns multiple results. + /// + /// The type of the master business object. + /// Array of to populate. + /// The populated . + public MapResultSet[] ExecuteResultSet( + Type masterType, params MapNextResult[] nextResults) + { + return ExecuteResultSet(_mappingSchema.ConvertToResultSet(masterType, nextResults)); + } + + /// + /// Executes the query, and returns multiple results. + /// + /// The type of the master business object. + /// Array of to populate. + /// The populated . + public MapResultSet[] ExecuteResultSet(params MapNextResult[] nextResults) + { + return ExecuteResultSet(_mappingSchema.ConvertToResultSet(typeof(T), nextResults)); + } + + #endregion + + #region Update + + private DbDataAdapter CreateDataAdapter() + { + var da = _dataProvider.CreateDataAdapterObject(); + + if (_insertCommand != null) ((IDbDataAdapter)da).InsertCommand = InsertCommand; + if (_updateCommand != null) ((IDbDataAdapter)da).UpdateCommand = UpdateCommand; + if (_deleteCommand != null) ((IDbDataAdapter)da).DeleteCommand = DeleteCommand; + + return da; + } + + /// + /// Calls the corresponding INSERT, UPDATE, or DELETE statements for each inserted, updated, or + /// deleted row in the specified . + /// + /// The used to update the data source. + /// The number of rows successfully updated from the . + public int Update(DataSet dataSet) + { + return Update(dataSet, "Table"); + } + + /// + /// Calls the corresponding INSERT, UPDATE, or DELETE statements for each inserted, updated, or + /// deleted row in the with the specified name. + /// + /// The used to update the data source. + /// The name or index of the source table to use for table mapping. + /// The number of rows successfully updated from the . + public int Update( + DataSet dataSet, + NameOrIndexParameter table) + { + if (dataSet == null) + throw new ArgumentNullException( + "dataSet", Resources.DbManager_CannotUpdateNullDataset); + + var da = CreateDataAdapter(); + + return + ExecuteOperation( + OperationType.Update, + () => + (table.ByName) + ? da.Update(dataSet, table.Name) + : da.Update(dataSet.Tables[table.Index])); + } + + /// + /// Calls the corresponding INSERT, UPDATE, or DELETE statements for + /// each inserted, updated, or deleted row in the specified + /// . + /// + /// The name or index of the source table to + /// use for table mapping. + /// The number of rows successfully updated from the + /// . + public int Update(DataTable dataTable) + { + if (dataTable == null) + throw new ArgumentNullException( + "dataTable", Resources.DbManager_CannotUpdateNullDataTable); + + return + ExecuteOperation( + OperationType.Update, + () => CreateDataAdapter().Update(dataTable)); + } + + #endregion + + #region ExecuteOperation + + private void ExecuteOperation(OperationType operationType, Action operation) + { + try + { + OnBeforeOperation(operationType); + operation(); + OnAfterOperation (operationType); + } + catch (Exception ex) + { + HandleOperationException(operationType, ex); + throw; + } + } + + private T ExecuteOperation(OperationType operationType, Func operation) + { + var res = default(T); + + try + { + OnBeforeOperation(operationType); + res = operation(); + OnAfterOperation (operationType); + } + catch (Exception ex) + { + if (res is IDisposable) + ((IDisposable)res).Dispose(); + + HandleOperationException(operationType, ex); + throw; + } + + return res; + } + + private void HandleOperationException(OperationType op, Exception ex) + { + var dex = new DataException(this, ex); + + if (TraceSwitch.TraceError) + WriteTraceLine(string.Format("Operation '{0}' throws exception '{1}'", op, dex), TraceSwitch.DisplayName); + + OnOperationException(op, dex); + } + + #endregion + + #region IDisposable interface + + /// + /// Releases the unmanaged resources used by the and + /// optionally releases the managed resources. + /// + /// + /// This method is called by the public method + /// and the Finalize method. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + Close(); + + base.Dispose(disposing); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/IDataReaderEx.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/IDataReaderEx.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.Data +{ + public interface IDataReaderEx + { + DateTimeOffset GetDateTimeOffset(int i); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/IDbConnectionFactory.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/IDbConnectionFactory.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ +namespace BLToolkit.Data +{ + public interface IDbConnectionFactory + { + DbManager CreateDbManager(); + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Data/InitCommandEventArgs.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/InitCommandEventArgs.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +using System; +using System.Data; + +namespace BLToolkit.Data +{ + public delegate void InitCommandEventHandler(object sender, InitCommandEventArgs ea); + + public class InitCommandEventArgs : EventArgs + { + private readonly IDbCommand _command; + public IDbCommand Command + { + get { return _command; } + } + + public InitCommandEventArgs(IDbCommand command) + { + _command = command; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/AggregationBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/AggregationBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,168 @@ +using System; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + using Reflection; + + class AggregationBuilder : MethodCallBuilder + { + public static string[] MethodNames = new[] { "Average", "Min", "Max", "Sum" }; + + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable(MethodNames); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + + if (sequence.SqlQuery.Select.IsDistinct || + sequence.SqlQuery.Select.TakeValue != null || + sequence.SqlQuery.Select.SkipValue != null || + !sequence.SqlQuery.GroupBy.IsEmpty) + { + sequence = new SubQueryContext(sequence); + } + + if (!sequence.SqlQuery.OrderBy.IsEmpty) + { + if (sequence.SqlQuery.Select.TakeValue == null && sequence.SqlQuery.Select.SkipValue == null) + sequence.SqlQuery.OrderBy.Items.Clear(); + else + sequence = new SubQueryContext(sequence); + } + + var context = new AggregationContext(buildInfo.Parent, sequence, methodCall); + var sql = sequence.ConvertToSql(null, 0, ConvertFlags.Field).Select(_ => _.Sql).ToArray(); + + if (sql.Length == 1 && sql[0] is SqlQuery) + { + var query = (SqlQuery)sql[0]; + + if (query.Select.Columns.Count == 1) + { + var join = SqlQuery.OuterApply(query); + context.SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); + sql[0] = query.Select.Columns[0]; + } + } + + context.Sql = context.SqlQuery; + context.FieldIndex = context.SqlQuery.Select.Add( + new SqlFunction(methodCall.Type, methodCall.Method.Name, sql)); + + return context; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + class AggregationContext : SequenceContextBase + { + public AggregationContext(IBuildContext parent, IBuildContext sequence, MethodCallExpression methodCall) + : base(parent, sequence, null) + { + _returnType = methodCall.Method.ReturnType; + _methodName = methodCall.Method.Name; + } + + readonly string _methodName; + readonly Type _returnType; + private SqlInfo[] _index; + + public int FieldIndex; + public ISqlExpression Sql; + + static object CheckNullValue(object value, object context) + { + if (value == null || value is DBNull) + throw new InvalidOperationException(string.Format("Function {0} returns non-nullable value, but result is NULL. Use nullable version of the function instead.", context)); + + return value; + } + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + var expr = BuildExpression(FieldIndex); + var mapper = Builder.BuildMapper(expr); + + query.SetElementQuery(mapper.Compile()); + } + + public override Expression BuildExpression(Expression expression, int level) + { + return BuildExpression(ConvertToIndex(expression, level, ConvertFlags.Field)[0].Index); + } + + Expression BuildExpression(int fieldIndex) + { + Expression expr; + + if (_returnType.IsClass || _methodName == "Sum" || TypeHelper.IsNullableType(_returnType)) + { + expr = Builder.BuildSql(_returnType, fieldIndex); + } + else + { + expr = Builder.BuildSql( + _returnType, + fieldIndex, + ReflectionHelper.Expressor.MethodExpressor(o => CheckNullValue(o, o)), + Expression.Constant(_methodName)); + } + + return expr; + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + switch (flags) + { + case ConvertFlags.All : + case ConvertFlags.Key : + case ConvertFlags.Field : return Sequence.ConvertToSql(expression, level + 1, flags); + } + + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + switch (flags) + { + case ConvertFlags.Field : + return _index ?? (_index = new[] + { + new SqlInfo { Query = Parent.SqlQuery, Index = Parent.SqlQuery.Select.Add(Sql), Sql = Sql, } + }); + } + + throw new InvalidOperationException(); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + switch (requestFlag) + { + case RequestFor.Root : return new IsExpressionResult(Lambda != null && expression == Lambda.Parameters[0]); + case RequestFor.Expression : return IsExpressionResult.True; + } + + return IsExpressionResult.False; + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + throw new InvalidOperationException(); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/AllAnyBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/AllAnyBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,161 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class AllAnyBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("All", "Any"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]) { CopyTable = true }); + + if (methodCall.Arguments.Count == 2) + { + var condition = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + + if (methodCall.Method.Name == "All") +#if FW4 || SILVERLIGHT + condition = Expression.Lambda(Expression.Not(condition.Body), condition.Name, condition.Parameters); +#else + condition = Expression.Lambda(Expression.Not(condition.Body), condition.Parameters.ToArray()); +#endif + + sequence = builder.BuildWhere(buildInfo.Parent, sequence, condition, true); + sequence.SetAlias(condition.Parameters[0].Name); + } + + return new AllAnyContext(buildInfo.Parent, methodCall, sequence); + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + if (methodCall.Arguments.Count == 2) + { + var predicate = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + var info = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), predicate.Parameters[0]); + + if (info != null) + { + info.Expression = methodCall.Convert(ex => ConvertMethod(methodCall, 0, info, predicate.Parameters[0], ex)); + info.Parameter = param; + + return info; + } + } + else + { + var info = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), null); + + if (info != null) + { + info.Expression = methodCall.Convert(ex => ConvertMethod(methodCall, 0, info, null, ex)); + info.Parameter = param; + + return info; + } + } + + return null; + } + + class AllAnyContext : SequenceContextBase + { + readonly MethodCallExpression _methodCall; + + public AllAnyContext(IBuildContext parent, MethodCallExpression methodCall, IBuildContext sequence) + : base(parent, sequence, null) + { + _methodCall = methodCall; + } + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + var sql = GetSubQuery(null); + + query.Queries[0].SqlQuery = new SqlQuery(); + query.Queries[0].SqlQuery.Select.Add(sql); + + var expr = Builder.BuildSql(typeof(bool), 0); + var mapper = Builder.BuildMapper(expr); + + query.SetElementQuery(mapper.Compile()); + } + + public override Expression BuildExpression(Expression expression, int level) + { + var idx = ConvertToIndex(expression, level, ConvertFlags.Field); + return Builder.BuildSql(typeof(bool), idx[0].Index); + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + if (expression == null) + { + var sql = GetSubQuery(null); + var query = SqlQuery; + + if (Parent != null) + query = Parent.SqlQuery; + + return new[] { new SqlInfo { Query = query, Sql = sql } }; + } + + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + var sql = ConvertToSql(expression, level, flags); + + if (sql[0].Index < 0) + sql[0].Index = sql[0].Query.Select.Add(sql[0].Sql); + + return sql; + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + if (expression == null) + { + switch (requestFlag) + { + case RequestFor.Expression : + case RequestFor.Field : return IsExpressionResult.False; + } + } + + throw new InvalidOperationException(); + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + throw new InvalidOperationException(); + } + + ISqlExpression _subQuerySql; + + public override ISqlExpression GetSubQuery(IBuildContext context) + { + if (_subQuerySql == null) + { + var cond = new SqlQuery.Condition( + _methodCall.Method.Name == "All", + new SqlQuery.Predicate.FuncLike(SqlFunction.CreateExists(SqlQuery))); + + _subQuerySql = new SqlQuery.SearchCondition(cond); + } + + return _subQuerySql; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/AsUpdatableBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/AsUpdatableBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + + class AsUpdatableBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("AsUpdatable"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/BuildInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/BuildInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,50 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using Data.Sql; + + public class BuildInfo + { + public BuildInfo(IBuildContext parent, Expression expression, SqlQuery sqlQuery) + { + Parent = parent; + Expression = expression; + SqlQuery = sqlQuery; + } + + public BuildInfo(BuildInfo buildInfo, Expression expression) + : this(buildInfo.Parent, expression, buildInfo.SqlQuery) + { + SequenceInfo = buildInfo; + } + + public BuildInfo(BuildInfo buildInfo, Expression expression, SqlQuery sqlQuery) + : this(buildInfo.Parent, expression, sqlQuery) + { + SequenceInfo = buildInfo; + } + + public BuildInfo SequenceInfo { get; set; } + public IBuildContext Parent { get; set; } + public Expression Expression { get; set; } + public SqlQuery SqlQuery { get; set; } + public bool CopyTable { get; set; } + + public bool IsSubQuery { get { return Parent != null; } } + + private bool _isAssociationBuilt; + public bool IsAssociationBuilt + { + get { return _isAssociationBuilt; } + set + { + _isAssociationBuilt = value; + + if (SequenceInfo != null) + SequenceInfo.IsAssociationBuilt = value; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/CastBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/CastBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,59 @@ +using System; +using System.Data; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + + class CastBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("Cast"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + + return new CastContext(sequence, methodCall); + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + class CastContext : PassThroughContext + { + public CastContext(IBuildContext context, MethodCallExpression methodCall) + : base(context) + { + _methodCall = methodCall; + } + + private readonly MethodCallExpression _methodCall; + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + var expr = BuildExpression(null, 0); + var mapper = Builder.BuildMapper(expr); + + query.SetQuery(mapper.Compile()); + } + + public override Expression BuildExpression(Expression expression, int level) + { + var expr = base.BuildExpression(expression, level); + var type = _methodCall.Method.GetGenericArguments()[0]; + + if (expr.Type != type) + expr = Expression.Convert(expr, type); + + return expr; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/ChangeTypeExpression.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/ChangeTypeExpression.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,40 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + class ChangeTypeExpression : Expression + { + public const int ChangeTypeType = 1000; + +#if FW4 || SILVERLIGHT + + public ChangeTypeExpression(Expression expression, Type type) + { + Expression = expression; + _type = type; + } + + readonly Type _type; + + public override Type Type { get { return _type; } } + public override ExpressionType NodeType { get { return (ExpressionType)ChangeTypeType; } } + +#else + + public ChangeTypeExpression(Expression expression, Type type) + : base((ExpressionType)ChangeTypeType, type) + { + Expression = expression; + } + +#endif + + public Expression Expression { get; private set; } + + public override string ToString() + { + return "(" + Type + ")" + Expression; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/ConcatUnionBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/ConcatUnionBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,340 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + using Reflection; + + class ConcatUnionBuilder : MethodCallBuilder + { + #region Builder + + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.Arguments.Count == 2 && methodCall.IsQueryable("Concat", "Union"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence1 = new SubQueryContext(builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]))); + var sequence2 = new SubQueryContext(builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SqlQuery()))); + var union = new SqlQuery.Union(sequence2.SqlQuery, methodCall.Method.Name == "Concat"); + + sequence1.SqlQuery.Unions.Add(union); + + return new UnionContext(sequence1, sequence2, methodCall); + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + #endregion + + #region Context + + sealed class UnionContext : SubQueryContext + { + public UnionContext(SubQueryContext sequence1, SubQueryContext sequence2, MethodCallExpression methodCall) + : base(sequence1) + { + _methodCall = methodCall; + + _isObject = + sequence1.IsExpression(null, 0, RequestFor.Object).Result || + sequence2.IsExpression(null, 0, RequestFor.Object).Result; + + if (_isObject) + { + var type = _methodCall.Method.GetGenericArguments()[0]; + _unionParameter = Expression.Parameter(type, "t"); + } + + Init(sequence1, sequence2); + } + + readonly bool _isObject; + readonly MethodCallExpression _methodCall; + readonly ParameterExpression _unionParameter; + readonly Dictionary _members = new Dictionary(new MemberInfoComparer()); + + class Member + { + public SqlInfo SequenceInfo; + public SqlInfo SqlQueryInfo; + public MemberExpression MemberExpression; + } + + class UnionMember + { + public Member Member; + public SqlInfo Info1; + public SqlInfo Info2; + } + + void Init(SubQueryContext sequence1, SubQueryContext sequence2) + { + var info1 = sequence1.ConvertToIndex(null, 0, ConvertFlags.All).ToList(); + var info2 = sequence2.ConvertToIndex(null, 0, ConvertFlags.All).ToList(); + + if (!_isObject) + return; + + var members = new List(); + + foreach (var info in info1) + { + if (info.Members.Count == 0) + throw new InvalidOperationException(); + + var member = new Member + { + SequenceInfo = info, + MemberExpression = Expression.MakeMemberAccess(_unionParameter, info.Members[0]) + }; + + members.Add(new UnionMember { Member = member, Info1 = info }); + } + + foreach (var info in info2) + { + if (info.Members.Count == 0) + throw new InvalidOperationException(); + + var em = members.FirstOrDefault(m => + m.Member.SequenceInfo != null && + m.Member.SequenceInfo.CompareLastMember(info)); + + if (em == null) + { + var member = new Member { MemberExpression = Expression.MakeMemberAccess(_unionParameter, info.Members[0]) }; + + if (sequence2.IsExpression(member.MemberExpression, 1, RequestFor.Object).Result) + throw new LinqException("Types in {0} are constructed incompatibly.", _methodCall.Method.Name); + + members.Add(new UnionMember { Member = member, Info2 = info }); + } + else + { + em.Info2 = info; + } + } + + sequence1.SqlQuery.Select.Columns.Clear(); + sequence2.SqlQuery.Select.Columns.Clear(); + + for (var i = 0; i < members.Count; i++) + { + var member = members[i]; + + if (member.Info1 == null) + { + member.Info1 = new SqlInfo(member.Info2.Members) + { + Sql = new SqlValue(null), + Query = sequence1.SqlQuery, + }; + + member.Member.SequenceInfo = member.Info1; + } + + if (member.Info2 == null) + { + member.Info2 = new SqlInfo(member.Info1.Members) + { + Sql = new SqlValue(null), + Query = sequence2.SqlQuery, + }; + } + + sequence1.SqlQuery.Select.Columns.Add(new SqlQuery.Column(sequence1.SqlQuery, member.Info1.Sql)); + sequence2.SqlQuery.Select.Columns.Add(new SqlQuery.Column(sequence2.SqlQuery, member.Info2.Sql)); + + member.Member.SequenceInfo.Index = i; + + _members[member.Member.MemberExpression.Member] = member.Member; + } + + foreach (var key in sequence1.ColumnIndexes.Keys.ToList()) + sequence1.ColumnIndexes[key] = sequence1.SqlQuery.Select.Add(key); + + foreach (var key in sequence2.ColumnIndexes.Keys.ToList()) + sequence2.ColumnIndexes[key] = sequence2.SqlQuery.Select.Add(key); + } + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + var expr = BuildExpression(null, 0); + var mapper = Builder.BuildMapper(expr); + + query.SetQuery(mapper.Compile()); + } + + public override Expression BuildExpression(Expression expression, int level) + { + if (_isObject) + { + if (expression == null) + { + var type = _methodCall.Method.GetGenericArguments()[0]; + var nctor = (NewExpression)Expression.Find(e => + { + if (e.NodeType == ExpressionType.New && e.Type == type) + { + var ne = (NewExpression)e; + return ne.Arguments != null && ne.Arguments.Count > 0; + } + + return false; + }); + + Expression expr; + + if (nctor != null) + { + var members = nctor.Members + .Select(m => m is MethodInfo ? TypeHelper.GetPropertyByMethod((MethodInfo)m) : m) + .ToList(); + + expr = Expression.New( + nctor.Constructor, + members + .Select(m => Expression.PropertyOrField(_unionParameter, m.Name)) + .Cast(), + members); + } + else + { + var ta = TypeAccessor.GetAccessor(type); + + expr = Expression.MemberInit( + Expression.New(ta.Type), + _members + .Select(m => Expression.Bind(m.Value.MemberExpression.Member, m.Value.MemberExpression)) + .Cast()); + } + + var ex = Builder.BuildExpression(this, expr); + + return ex; + } + + if (level == 0 || level == 1) + { + var levelExpression = expression.GetLevelExpression(1); + + if (expression == levelExpression && !IsExpression(expression, 1, RequestFor.Object).Result) + { + var idx = ConvertToIndex(expression, level, ConvertFlags.Field); + var n = idx[0].Index; + + if (Parent != null) + n = Parent.ConvertToParentIndex(n, this); + + return Builder.BuildSql(expression.Type, n); + } + } + } + + return base.BuildExpression(expression, level); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor testFlag) + { + if (testFlag == RequestFor.Root && expression == _unionParameter) + return IsExpressionResult.True; + + return base.IsExpression(expression, level, testFlag); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + if (_isObject) + { + return ConvertToSql(expression, level, flags) + .Select(idx => + { + if (idx.Index < 0) + { + if (idx.Index == -2) + { + SqlQuery.Select.Columns.Add(new SqlQuery.Column(SqlQuery, idx.Sql)); + idx.Index = SqlQuery.Select.Columns.Count - 1; + } + else + { + idx.Index = SqlQuery.Select.Add(idx.Sql); + } + } + + return idx; + }) + .ToArray(); + } + + return base.ConvertToIndex(expression, level, flags); + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + if (_isObject) + { + switch (flags) + { + case ConvertFlags.All : + case ConvertFlags.Key : + + if (expression == null) + { + return _members.Values + .Select(m => ConvertToSql(m.MemberExpression, 0, ConvertFlags.Field)[0]) + .ToArray(); + } + + break; + + case ConvertFlags.Field : + + if (expression != null && (level == 0 || level == 1) && expression.NodeType == ExpressionType.MemberAccess) + { + var levelExpression = expression.GetLevelExpression(1); + + if (expression == levelExpression) + { + var ma = (MemberExpression)expression; + var member = _members[ma.Member]; + + if (member.SqlQueryInfo == null) + { + member.SqlQueryInfo = new SqlInfo(member.MemberExpression.Member) + { + Index = -2, + Sql = SubQuery.SqlQuery.Select.Columns[member.SequenceInfo.Index], + Query = SqlQuery, + }; + } + + return new[] { member.SqlQueryInfo }; + } + } + + break; + } + + throw new InvalidOperationException(); + } + + return base.ConvertToSql(expression, level, flags); + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/ContainsBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/ContainsBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,142 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class ContainsBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("Contains") && methodCall.Arguments.Count == 2; + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + return new ContainsContext(buildInfo.Parent, methodCall, sequence); + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + class ContainsContext : SequenceContextBase + { + readonly MethodCallExpression _methodCall; + + public ContainsContext(IBuildContext parent, MethodCallExpression methodCall, IBuildContext sequence) + : base(parent, sequence, null) + { + _methodCall = methodCall; + } + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + var sql = GetSubQuery(null); + + query.Queries[0].SqlQuery = new SqlQuery(); + query.Queries[0].SqlQuery.Select.Add(sql); + + var expr = Builder.BuildSql(typeof(bool), 0); + var mapper = Builder.BuildMapper(expr); + + query.SetElementQuery(mapper.Compile()); + } + + public override Expression BuildExpression(Expression expression, int level) + { + var idx = ConvertToIndex(expression, level, ConvertFlags.Field); + return Builder.BuildSql(typeof(bool), idx[0].Index); + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + if (expression == null) + { + var sql = GetSubQuery(null); + var query = SqlQuery; + + if (Parent != null) + query = Parent.SqlQuery; + + return new[] { new SqlInfo { Query = query, Sql = sql } }; + } + + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + var sql = ConvertToSql(expression, level, flags); + + if (sql[0].Index < 0) + sql[0].Index = sql[0].Query.Select.Add(sql[0].Sql); + + return sql; + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + if (expression == null) + { + switch (requestFlag) + { + case RequestFor.Expression : + case RequestFor.Field : return IsExpressionResult.False; + } + } + + throw new InvalidOperationException(); + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + throw new InvalidOperationException(); + } + + ISqlExpression _subQuerySql; + + public override ISqlExpression GetSubQuery(IBuildContext context) + { + if (_subQuerySql == null) + { + var args = _methodCall.Method.GetGenericArguments(); + var param = Expression.Parameter(args[0], "param"); + var expr = _methodCall.Arguments[1]; + var condition = Expression.Lambda(Expression.Equal(param, expr), param); + + IBuildContext ctx = new ExpressionContext(Parent, Sequence, condition); + + ctx = Builder.GetContext(ctx, expr) ?? ctx; + + Builder.ReplaceParent(ctx, this); + + SqlQuery.Condition cond; + + if (Sequence.SqlQuery != SqlQuery && + (ctx.IsExpression(expr, 0, RequestFor.Field). Result || + ctx.IsExpression(expr, 0, RequestFor.Expression).Result)) + { + Sequence.ConvertToIndex(null, 0, ConvertFlags.All); + var ex = Builder.ConvertToSql(ctx, _methodCall.Arguments[1], false); + cond = new SqlQuery.Condition(false, new SqlQuery.Predicate.InSubQuery(ex, false, SqlQuery)); + } + else + { + var sequence = Builder.BuildWhere(Parent, Sequence, condition, true); + cond = new SqlQuery.Condition(false, new SqlQuery.Predicate.FuncLike(SqlFunction.CreateExists(sequence.SqlQuery))); + } + + _subQuerySql = new SqlQuery.SearchCondition(cond); + } + + return _subQuerySql; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/ConvertFlags.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/ConvertFlags.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +using System; + +namespace BLToolkit.Data.Linq.Builder +{ + public enum ConvertFlags + { + Field, + Key, + All, + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/CountBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/CountBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,162 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class CountBuilder : MethodCallBuilder + { + public static string[] MethodNames = new[] { "Count", "LongCount" }; + + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable(MethodNames); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var returnType = methodCall.Method.ReturnType; + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + + if (sequence.SqlQuery != buildInfo.SqlQuery) + { + if (sequence is JoinBuilder.GroupJoinSubQueryContext) + { + var ctx = new CountContext(buildInfo.Parent, sequence, returnType) + { + SqlQuery = ((JoinBuilder.GroupJoinSubQueryContext)sequence).GetCounter(methodCall) + }; + + ctx.Sql = ctx.SqlQuery; + ctx.FieldIndex = ctx.SqlQuery.Select.Add(SqlFunction.CreateCount(returnType, ctx.SqlQuery), "cnt"); + + return ctx; + } + + if (sequence is GroupByBuilder.GroupByContext) + { + return new CountContext(buildInfo.Parent, sequence, returnType) + { + Sql = SqlFunction.CreateCount(returnType, sequence.SqlQuery), + FieldIndex = -1 + }; + } + } + + if (sequence.SqlQuery.Select.IsDistinct || + sequence.SqlQuery.Select.TakeValue != null || + sequence.SqlQuery.Select.SkipValue != null || + !sequence.SqlQuery.GroupBy.IsEmpty) + { + sequence.ConvertToIndex(null, 0, ConvertFlags.Key); + sequence = new SubQueryContext(sequence); + } + + if (sequence.SqlQuery.OrderBy.Items.Count > 0) + { + if (sequence.SqlQuery.Select.TakeValue == null && sequence.SqlQuery.Select.SkipValue == null) + sequence.SqlQuery.OrderBy.Items.Clear(); + else + sequence = new SubQueryContext(sequence); + } + + var context = new CountContext(buildInfo.Parent, sequence, returnType); + + context.Sql = context.SqlQuery; + context.FieldIndex = context.SqlQuery.Select.Add(SqlFunction.CreateCount(returnType, context.SqlQuery), "cnt"); + + return context; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + internal class CountContext : SequenceContextBase + { + public CountContext(IBuildContext parent, IBuildContext sequence, Type returnType) + : base(parent, sequence, null) + { + _returnType = returnType; + } + + readonly Type _returnType; + private SqlInfo[] _index; + + public int FieldIndex; + public ISqlExpression Sql; + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + var expr = Builder.BuildSql(_returnType, FieldIndex); + var mapper = Builder.BuildMapper(expr); + + query.SetElementQuery(mapper.Compile()); + } + + public override Expression BuildExpression(Expression expression, int level) + { + return Builder.BuildSql(_returnType, ConvertToIndex(expression, level, ConvertFlags.Field)[0].Index); + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + switch (flags) + { + case ConvertFlags.Field : return new[] { new SqlInfo { Query = Parent.SqlQuery, Sql = Sql } }; + } + + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + switch (flags) + { + case ConvertFlags.Field : + return _index ?? (_index = new[] + { + new SqlInfo { Query = Parent.SqlQuery, Index = Parent.SqlQuery.Select.Add(Sql), Sql = Sql, } + }); + } + + throw new InvalidOperationException(); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + switch (requestFlag) + { + case RequestFor.Expression : return IsExpressionResult.True; + } + + return IsExpressionResult.False; + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + return Sequence.GetContext(expression, level, buildInfo); + } + + public override ISqlExpression GetSubQuery(IBuildContext context) + { + var query = context.SqlQuery; + + if (query == SqlQuery) + { + var col = query.Select.Columns[query.Select.Columns.Count - 1]; + + query.Select.Columns.RemoveAt(query.Select.Columns.Count - 1); + + return col.Expression; + } + + return null; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/DefaultIfEmptyBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/DefaultIfEmptyBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,135 @@ +using System; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class DefaultIfEmptyBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("DefaultIfEmpty"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + var defaultValue = methodCall.Arguments.Count == 1 ? null : methodCall.Arguments[1].Unwrap(); + + if (buildInfo.Parent is SelectManyBuilder.SelectManyContext) + { + var groupJoin = ((SelectManyBuilder.SelectManyContext)buildInfo.Parent).Sequence[0] as JoinBuilder.GroupJoinContext; + + if (groupJoin != null) + { + groupJoin.SqlQuery.From.Tables[0].Joins[0].JoinType = SqlQuery.JoinType.Left; + groupJoin.SqlQuery.From.Tables[0].Joins[0].IsWeak = false; + } + } + + return new DefaultIfEmptyContext(buildInfo.Parent, sequence, defaultValue); + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + public class DefaultIfEmptyContext : SequenceContextBase + { + public DefaultIfEmptyContext(IBuildContext parent, IBuildContext sequence, Expression defaultValue) + : base(parent, sequence, null) + { + _defaultValue = defaultValue; + } + + private readonly Expression _defaultValue; + + public override Expression BuildExpression(Expression expression, int level) + { + var expr = Sequence.BuildExpression(expression, level); + + if (expression == null) + { + var q = + from col in SqlQuery.Select.Columns + where !col.CanBeNull() + select SqlQuery.Select.Columns.IndexOf(col); + + var idx = q.DefaultIfEmpty(-1).First(); + + if (idx == -1) + idx = SqlQuery.Select.Add(new SqlValue((int?) 1)); + + var n = ConvertToParentIndex(idx, this); + + var e = Expression.Call( + ExpressionBuilder.DataReaderParam, + ReflectionHelper.DataReader.IsDBNull, + Expression.Constant(n)) as Expression; + + var defaultValue = _defaultValue ?? Expression.Constant(null, expr.Type); + +#if FW4 || SILVERLIGHT + + if (expr.NodeType == ExpressionType.Parameter) + { + var par = (ParameterExpression)expr; + var pidx = Builder.BlockVariables.IndexOf(par); + + if (pidx >= 0) + { + var ex = Builder.BlockExpressions[pidx]; + + if (ex.NodeType == ExpressionType.Assign) + { + var bex = (BinaryExpression)ex; + + if (bex.Left == expr) + { + if (bex.Right.NodeType != ExpressionType.Conditional) + { + Builder.BlockExpressions[pidx] = + Expression.Assign( + bex.Left, + Expression.Condition(e, defaultValue, bex.Right)); + } + } + } + } + } + +#endif + + expr = Expression.Condition(e, defaultValue, expr); + } + + return expr; + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + return Sequence.ConvertToSql(expression, level, flags); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + return Sequence.ConvertToIndex(expression, level, flags); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + return Sequence.IsExpression(expression, level, requestFlag); + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + return Sequence.GetContext(expression, level, buildInfo); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/DeleteBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/DeleteBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,99 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class DeleteBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("Delete"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + + if (methodCall.Arguments.Count == 2) + sequence = builder.BuildWhere(buildInfo.Parent, sequence, (LambdaExpression)methodCall.Arguments[1].Unwrap(), false); + + sequence.SqlQuery.QueryType = QueryType.Delete; + + // Check association. + // + var ctx = sequence as SelectContext; + + if (ctx != null && ctx.IsScalar) + { + var res = ctx.IsExpression(null, 0, RequestFor.Association); + + if (res.Result && res.Context is TableBuilder.AssociatedTableContext) + { + var atc = (TableBuilder.AssociatedTableContext)res.Context; + sequence.SqlQuery.Delete.Table = atc.SqlTable; + } + else + { + res = ctx.IsExpression(null, 0, RequestFor.Table); + + if (res.Result && res.Context is TableBuilder.TableContext) + { + var tc = (TableBuilder.TableContext)res.Context; + + if (sequence.SqlQuery.From.Tables.Count == 0 || sequence.SqlQuery.From.Tables[0].Source != tc.SqlQuery) + sequence.SqlQuery.Delete.Table = tc.SqlTable; + } + } + } + + return new DeleteContext(buildInfo.Parent, sequence); + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + class DeleteContext : SequenceContextBase + { + public DeleteContext(IBuildContext parent, IBuildContext sequence) + : base(parent, sequence, null) + { + } + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + query.SetNonQueryQuery(); + } + + public override Expression BuildExpression(Expression expression, int level) + { + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + throw new InvalidOperationException(); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + throw new InvalidOperationException(); + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + throw new InvalidOperationException(); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/DistinctBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/DistinctBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + + class DistinctBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("Distinct"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + var sql = sequence.SqlQuery; + + if (sql.Select.TakeValue != null || sql.Select.SkipValue != null) + sequence = new SubQueryContext(sequence); + + sequence.SqlQuery.Select.IsDistinct = true; + sequence.ConvertToIndex(null, 0, ConvertFlags.All); + + return sequence; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/ExpressionBuilder.QueryBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/ExpressionBuilder.QueryBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,543 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Reflection; + + partial class ExpressionBuilder + { + #region BuildExpression + + readonly HashSet _skippedExpressions = new HashSet(); + + public Expression BuildExpression(IBuildContext context, Expression expression) + { + var newExpr = expression.Convert2(expr => + { + if (_skippedExpressions.Contains(expr)) + return new ExpressionHelper.ConvertInfo(expr, true); + + if (expr.Find(IsNoneSqlMember) != null) + return new ExpressionHelper.ConvertInfo(expr); + + switch (expr.NodeType) + { + case ExpressionType.MemberAccess: + { + if (IsServerSideOnly(expr) || PreferServerSide(expr)) + return new ExpressionHelper.ConvertInfo(BuildSql(context, expr)); + + var ma = (MemberExpression)expr; + + if (SqlProvider.ConvertMember(ma.Member) != null) + break; + + var ctx = GetContext(context, expr); + + if (ctx != null) + return new ExpressionHelper.ConvertInfo(ctx.BuildExpression(expr, 0)); + + var ex = ma.Expression; + + if (ex != null && ex.NodeType == ExpressionType.Constant) + { + // field = localVariable + // + var c = _expressionAccessors[ex]; + return new ExpressionHelper.ConvertInfo( + Expression.MakeMemberAccess(Expression.Convert(c, ex.Type), ma.Member)); + } + + break; + } + + case ExpressionType.Parameter: + { + if (expr == ParametersParam) + break; + + var ctx = GetContext(context, expr); + + if (ctx != null) + return new ExpressionHelper.ConvertInfo(ctx.BuildExpression(expr, 0)); + + break; + } + + case ExpressionType.Constant: + { + if (ExpressionHelper.IsConstant(expr.Type)) + break; + + if (_expressionAccessors.ContainsKey(expr)) + return new ExpressionHelper.ConvertInfo(Expression.Convert(_expressionAccessors[expr], expr.Type)); + + break; + } + + case ExpressionType.Coalesce: + + if (expr.Type == typeof(string) && MappingSchema.GetDefaultNullValue() != null) + return new ExpressionHelper.ConvertInfo(BuildSql(context, expr)); + + if (CanBeTranslatedToSql(context, ConvertExpression(expr), true)) + return new ExpressionHelper.ConvertInfo(BuildSql(context, expr)); + + break; + + case ExpressionType.Conditional: + + if (CanBeTranslatedToSql(context, ConvertExpression(expr), true)) + return new ExpressionHelper.ConvertInfo(BuildSql(context, expr)); + break; + + case ExpressionType.Call: + { + var ce = (MethodCallExpression)expr; + + if (IsGroupJoinSource(context, ce)) + { + foreach (var arg in ce.Arguments.Skip(1)) + if (!_skippedExpressions.Contains(arg)) + _skippedExpressions.Add(arg); + + break; + } + + if (IsSubQuery(context, ce)) + { + if (TypeHelper.IsSameOrParent(typeof(IEnumerable), expr.Type) && expr.Type != typeof(string) && !expr.Type.IsArray) + return new ExpressionHelper.ConvertInfo(BuildMultipleQuery(context, expr)); + + return new ExpressionHelper.ConvertInfo(GetSubQuery(context, ce).BuildExpression(null, 0)); + } + + if (IsServerSideOnly(expr) || PreferServerSide(expr)) + return new ExpressionHelper.ConvertInfo(BuildSql(context, expr)); + } + + break; + } + + if (EnforceServerSide(context)) + { + switch (expr.NodeType) + { + case ExpressionType.MemberInit : + case ExpressionType.New : + case ExpressionType.Convert : + break; + + default : + if (CanBeCompiled(expr)) + break; + return new ExpressionHelper.ConvertInfo(BuildSql(context, expr)); + } + } + + return new ExpressionHelper.ConvertInfo(expr); + }); + + return newExpr; + } + + static bool EnforceServerSide(IBuildContext context) + { + return context.SqlQuery.Select.IsDistinct; + } + + #endregion + + #region BuildSql + + Expression BuildSql(IBuildContext context, Expression expression) + { + var sqlex = ConvertToSqlExpression(context, expression, true); + var idx = context.SqlQuery.Select.Add(sqlex); + + idx = context.ConvertToParentIndex(idx, context); + + var field = BuildSql(expression.Type, idx); + + return field; + } + + public Expression BuildSql(MemberAccessor ma, int idx, MethodInfo checkNullFunction, Expression context) + { + var expr = Expression.Call(DataReaderParam, ReflectionHelper.DataReader.GetValue, Expression.Constant(idx)); + + if (checkNullFunction != null) + expr = Expression.Call(null, checkNullFunction, expr, context); + + Expression mapper; + + if (TypeHelper.IsEnumOrNullableEnum(ma.Type)) + { + var type = TypeHelper.ToNullable(ma.Type); + mapper = + Expression.Convert( + Expression.Call( + Expression.Constant(MappingSchema), + ReflectionHelper.MapSchema.MapValueToEnumWithMemberAccessor, + expr, + Expression.Constant(ma)), + type); + } + else + { + MethodInfo mi; + + if (!ReflectionHelper.MapSchema.Converters.TryGetValue(ma.Type, out mi)) + { + mapper = + Expression.Convert( + Expression.Call( + Expression.Constant(MappingSchema), + ReflectionHelper.MapSchema.ChangeType, + expr, + Expression.Constant(ma.Type)), + ma.Type); + } + else + { + mapper = Expression.Call(Expression.Constant(MappingSchema), mi, expr); + } + } + + return mapper; + } + + public Expression BuildSql(Type type, int idx, MethodInfo checkNullFunction, Expression context) + { + var expr = Expression.Call(DataReaderParam, ReflectionHelper.DataReader.GetValue, Expression.Constant(idx)); + + if (checkNullFunction != null) + expr = Expression.Call(null, checkNullFunction, expr, context); + + Expression mapper; + + if (type.IsEnum) + { + mapper = + Expression.Convert( + Expression.Call( + Expression.Constant(MappingSchema), + ReflectionHelper.MapSchema.MapValueToEnum, + expr, + Expression.Constant(type)), + type); + } + else + { + MethodInfo mi; + + if (!ReflectionHelper.MapSchema.Converters.TryGetValue(type, out mi)) + { + mapper = + Expression.Convert( + Expression.Call( + Expression.Constant(MappingSchema), + ReflectionHelper.MapSchema.ChangeType, + expr, + Expression.Constant(type)), + type); + } + else + { + mapper = Expression.Call(Expression.Constant(MappingSchema), mi, expr); + } + } + + return mapper; + } + + public Expression BuildSql(Type type, int idx) + { + return BuildSql(type, idx, null, null); + } + + public Expression BuildSql(MemberAccessor ma, int idx) + { + return BuildSql(ma, idx, null, null); + } + + #endregion + + #region IsNonSqlMember + + bool IsNoneSqlMember(Expression expr) + { + switch (expr.NodeType) + { + case ExpressionType.MemberAccess: + { + var me = (MemberExpression)expr; + + var om = ( + from c in Contexts.OfType() + where c.ObjectType == me.Member.DeclaringType + select c.ObjectMapper + ).FirstOrDefault(); + + return om != null && om.Associations.All(a => !TypeHelper.Equals(a.MemberAccessor.MemberInfo, me.Member)) && om[me.Member.Name, true] == null; + } + } + + return false; + } + + #endregion + + #region PreferServerSide + + bool PreferServerSide(Expression expr) + { + switch (expr.NodeType) + { + case ExpressionType.MemberAccess: + { + var pi = (MemberExpression)expr; + var l = SqlProvider.ConvertMember(pi.Member); + + if (l != null) + { + var info = l.Body.Unwrap(); + + if (l.Parameters.Count == 1 && pi.Expression != null) + info = info.Convert(wpi => wpi == l.Parameters[0] ? pi.Expression : wpi); + + return info.Find(PreferServerSide) != null; + } + + var attr = GetFunctionAttribute(pi.Member); + return attr != null && attr.PreferServerSide && !CanBeCompiled(expr); + } + + case ExpressionType.Call: + { + var pi = (MethodCallExpression)expr; + var e = pi; + var l = SqlProvider.ConvertMember(e.Method); + + if (l != null) + return l.Body.Unwrap().Find(PreferServerSide) != null; + + var attr = GetFunctionAttribute(e.Method); + return attr != null && attr.PreferServerSide && !CanBeCompiled(expr); + } + } + + return false; + } + + #endregion + + #region Build Mapper + + public Expression BuildBlock(Expression expression) + { +#if FW4 || SILVERLIGHT + + if (IsBlockDisable || BlockExpressions.Count == 0) + return expression; + + BlockExpressions.Add(expression); + + expression = Expression.Block(BlockVariables, BlockExpressions); + + BlockVariables. Clear(); + BlockExpressions.Clear(); + +#endif + + return expression; + } + + public Expression> BuildMapper(Expression expr) + { + var type = typeof(T); + + if (expr.Type != type) + expr = Expression.Convert(expr, type); + + var mapper = Expression.Lambda>( + BuildBlock(expr), new [] + { + ContextParam, + DataContextParam, + DataReaderParam, + ExpressionParam, + ParametersParam, + }); + + return mapper; + } + + #endregion + + #region BuildMultipleQuery + + interface IMultipleQueryHelper + { + Expression GetSubquery( + ExpressionBuilder builder, + Expression expression, + ParameterExpression paramArray, + IEnumerable parameters); + } + + class MultipleQueryHelper : IMultipleQueryHelper + { + public Expression GetSubquery( + ExpressionBuilder builder, + Expression expression, + ParameterExpression paramArray, + IEnumerable parameters) + { + var lambda = Expression.Lambda>( + expression, + Expression.Parameter(typeof(IDataContext), "ctx"), + paramArray); + var queryReader = CompiledQuery.Compile(lambda); + + return Expression.Call( + null, + ReflectionHelper.Expressor.MethodExpressor(_ => ExecuteSubQuery(null, null, null)), + ContextParam, + Expression.NewArrayInit(typeof(object), parameters), + Expression.Constant(queryReader) + ); + } + + static TRet ExecuteSubQuery( + QueryContext queryContext, + object[] parameters, + Func queryReader) + { + var db = queryContext.GetDataContext(); + + try + { + return queryReader(db.DataContextInfo.DataContext, parameters); + } + finally + { + queryContext.ReleaseDataContext(db); + } + } + } + + public Expression BuildMultipleQuery(IBuildContext context, Expression expression) + { + if (!Common.Configuration.Linq.AllowMultipleQuery) + throw new LinqException("Multiple queries are not allowed. Set the 'BLToolkit.Common.Configuration.Linq.AllowMultipleQuery' flag to 'true' to allow multiple queries."); + + var parameters = new HashSet(); + + expression.Visit(e => + { + if (e.NodeType == ExpressionType.Lambda) + foreach (var p in ((LambdaExpression)e).Parameters) + parameters.Add(p); + }); + + // Convert associations. + // + expression = expression.Convert(e => + { + switch (e.NodeType) + { + case ExpressionType.MemberAccess : + { + var root = e.GetRootObject(); + + if (root != null && + root.NodeType == ExpressionType.Parameter && + !parameters.Contains((ParameterExpression)root)) + { + var res = context.IsExpression(e, 0, RequestFor.Association); + + if (res.Result) + { + var table = (TableBuilder.AssociatedTableContext)res.Context; + + if (table.IsList) + { + var ttype = typeof(Table<>).MakeGenericType(table.ObjectType); + var tbl = Activator.CreateInstance(ttype); + var method = typeof(LinqExtensions) + .GetMethod("Where", BindingFlags.NonPublic | BindingFlags.Static) + .MakeGenericMethod(e.Type, table.ObjectType, ttype); + + var me = (MemberExpression)e; + var op = Expression.Parameter(table.ObjectType, "t"); + + parameters.Add(op); + + Expression ex = null; + + for (var i = 0; i < table.Association.ThisKey.Length; i++) + { + var field1 = table.ParentAssociation.SqlTable.Fields[table.Association.ThisKey [i]]; + var field2 = table. SqlTable.Fields[table.Association.OtherKey[i]]; + + var ee = Expression.Equal( + Expression.MakeMemberAccess(op, field2.MemberMapper.MemberAccessor.MemberInfo), + Expression.MakeMemberAccess(me.Expression, field1.MemberMapper.MemberAccessor.MemberInfo)); + + ex = ex == null ? ee : Expression.AndAlso(ex, ee); + } + + return Expression.Call(null, method, Expression.Constant(tbl), Expression.Lambda(ex, op)); + } + } + } + + break; + } + } + + return e; + }); + + var paramex = Expression.Parameter(typeof(object[]), "ps"); + var parms = new List(); + + // Convert parameters. + // + expression = expression.Convert(e => + { + var root = e.GetRootObject(); + + if (root != null && + root.NodeType == ExpressionType.Parameter && + !parameters.Contains((ParameterExpression)root)) + { + var ex = Expression.Convert(BuildExpression(context, e), typeof(object)); + + parms.Add(ex); + + return Expression.Convert( + Expression.ArrayIndex(paramex, Expression.Constant(parms.Count - 1)), + e.Type); + } + + return e; + }); + + var sqtype = typeof(MultipleQueryHelper<>).MakeGenericType(expression.Type); + var helper = (IMultipleQueryHelper)Activator.CreateInstance(sqtype); + + return helper.GetSubquery(this, expression, paramex, parms); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/ExpressionBuilder.SqlBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/ExpressionBuilder.SqlBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2509 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Common; + using Data.Sql; + using Mapping; + using Reflection; + + partial class ExpressionBuilder + { + #region Build Where + + public IBuildContext BuildWhere(IBuildContext parent, IBuildContext sequence, LambdaExpression condition, bool checkForSubQuery) + { + var makeHaving = false; + var prevParent = sequence.Parent; + + var ctx = new ExpressionContext(parent, sequence, condition); + var expr = ConvertExpression(condition.Body.Unwrap()); + + if (checkForSubQuery && CheckSubQueryForWhere(ctx, expr, out makeHaving)) + { + ReplaceParent(ctx, prevParent); + + sequence = new SubQueryContext(sequence); + prevParent = sequence.Parent; + + ctx = new ExpressionContext(parent, sequence, condition); + } + + BuildSearchCondition( + ctx, + expr, + makeHaving ? + ctx.SqlQuery.Having.SearchCondition.Conditions : + ctx.SqlQuery.Where. SearchCondition.Conditions); + + ReplaceParent(ctx, prevParent); + + return sequence; + } + + bool CheckSubQueryForWhere(IBuildContext context, Expression expression, out bool makeHaving) + { + var makeSubQuery = false; + var isHaving = false; + var isWhere = false; + + expression.Visit(expr => + { + if (_subQueryExpressions != null && _subQueryExpressions.Contains(expr)) + { + makeSubQuery = true; + isWhere = true; + return false; + } + + var stopWalking = false; + + switch (expr.NodeType) + { + case ExpressionType.MemberAccess: + { + var ma = (MemberExpression)expr; + + if (TypeHelper.IsNullableValueMember(ma.Member) || + TypeHelper.IsNullableHasValueMember(ma.Member)) + break; + + if (SqlProvider.ConvertMember(ma.Member) == null) + { + var ctx = GetContext(context, expr); + + if (ctx != null) + { + if (ctx.IsExpression(expr, 0, RequestFor.Expression).Result) + makeSubQuery = true; + stopWalking = true; + } + } + + isWhere = true; + + break; + } + + case ExpressionType.Call: + { + var e = (MethodCallExpression)expr; + + if (e.Method.DeclaringType == typeof(Enumerable) && e.Method.Name != "Contains") + return isHaving = true; + + isWhere = true; + + break; + } + + case ExpressionType.Parameter: + { + var ctx = GetContext(context, expr); + + if (ctx != null) + { + if (ctx.IsExpression(expr, 0, RequestFor.Expression).Result) + makeSubQuery = true; + stopWalking = true; + } + + isWhere = true; + + break; + } + } + + return !stopWalking; + }); + + makeHaving = isHaving && !isWhere; + return makeSubQuery || isHaving && isWhere; + } + + #endregion + + #region BuildTake + + public void BuildTake(IBuildContext context, ISqlExpression expr) + { + var sql = context.SqlQuery; + + sql.Select.Take(expr); + + SqlProvider.SqlQuery = sql; + + if (sql.Select.SkipValue != null && SqlProvider.IsTakeSupported && !SqlProvider.IsSkipSupported) + { + if (context.SqlQuery.Select.SkipValue is SqlParameter && sql.Select.TakeValue is SqlValue) + { + var skip = (SqlParameter)sql.Select.SkipValue; + var parm = (SqlParameter)sql.Select.SkipValue.Clone(new Dictionary(), _ => true); + + parm.SetTakeConverter((int)((SqlValue)sql.Select.TakeValue).Value); + + sql.Select.Take(parm); + + var ep = (from pm in CurrentSqlParameters where pm.SqlParameter == skip select pm).First(); + + ep = new ParameterAccessor + { + Expression = ep.Expression, + Accessor = ep.Accessor, + SqlParameter = parm + }; + + CurrentSqlParameters.Add(ep); + } + else + sql.Select.Take(Convert( + context, + new SqlBinaryExpression(typeof(int), sql.Select.SkipValue, "+", sql.Select.TakeValue, Precedence.Additive))); + } + + if (!SqlProvider.TakeAcceptsParameter) + { + var p = sql.Select.TakeValue as SqlParameter; + + if (p != null) + p.IsQueryParameter = false; + } + } + + #endregion + + #region SubQueryToSql + + public IBuildContext GetSubQuery(IBuildContext context, MethodCallExpression expr) + { + var info = new BuildInfo(context, expr, new SqlQuery { ParentSql = context.SqlQuery }); + var ctx = BuildSequence(info); + + if (ctx.SqlQuery.Select.Columns.Count == 0 && + (ctx.IsExpression(null, 0, RequestFor.Expression).Result || + ctx.IsExpression(null, 0, RequestFor.Field). Result)) + { + ctx.ConvertToIndex(null, 0, ConvertFlags.Field); + } + + return ctx; + } + + internal ISqlExpression SubQueryToSql(IBuildContext context, MethodCallExpression expression) + { + var sequence = GetSubQuery(context, expression); + var subSql = sequence.GetSubQuery(context); + + if (subSql != null) + return subSql; + + var query = context.SqlQuery; + var subQuery = sequence.SqlQuery; + + // This code should be moved to context. + // + if (!query.GroupBy.IsEmpty && !subQuery.Where.IsEmpty) + { + var fromGroupBy = sequence.SqlQuery.Properties + .OfType>() + .Where(p => p.Item1 == "from_group_by" && p.Item2 == context.SqlQuery) + .Any(); + + if (fromGroupBy) + { + if (subQuery.Select.Columns.Count == 1 && + subQuery.Select.Columns[0].Expression.ElementType == QueryElementType.SqlFunction && + subQuery.GroupBy.IsEmpty && !subQuery.Select.HasModifier && !subQuery.HasUnion && + subQuery.Where.SearchCondition.Conditions.Count == 1) + { + var cond = subQuery.Where.SearchCondition.Conditions[0]; + + if (cond.Predicate.ElementType == QueryElementType.ExprExprPredicate && query.GroupBy.Items.Count == 1 || + cond.Predicate.ElementType == QueryElementType.SearchCondition && + query.GroupBy.Items.Count == ((SqlQuery.SearchCondition)cond.Predicate).Conditions.Count) + { + var func = (SqlFunction)subQuery.Select.Columns[0].Expression; + + if (CountBuilder.MethodNames.Contains(func.Name)) + return SqlFunction.CreateCount(func.SystemType, query); + } + } + } + } + + return sequence.SqlQuery; + } + + #endregion + + #region IsSubQuery + + bool IsSubQuery(IBuildContext context, MethodCallExpression call) + { + if (call.IsQueryable()) + { + var info = new BuildInfo(context, call, new SqlQuery { ParentSql = context.SqlQuery }); + + if (!IsSequence(info)) + return false; + + var arg = call.Arguments[0]; + + if (AggregationBuilder.MethodNames.Contains(call.Method.Name)) + while (arg.NodeType == ExpressionType.Call && ((MethodCallExpression) arg).Method.Name == "Select") + arg = ((MethodCallExpression)arg).Arguments[0]; + + var mc = arg as MethodCallExpression; + + while (mc != null) + { + if (!mc.IsQueryable()) + return GetTableFunctionAttribute(mc.Method) != null; + + mc = mc.Arguments[0] as MethodCallExpression; + } + + return arg.NodeType == ExpressionType.Call || IsSubQuerySource(context, arg); + } + + return false; + } + + bool IsSubQuerySource(IBuildContext context, Expression expr) + { + if (expr == null) + return false; + + var ctx = GetContext(context, expr); + + if (ctx != null && ctx.IsExpression(expr, 0, RequestFor.Object).Result) + return true; + + while (expr != null && expr.NodeType == ExpressionType.MemberAccess) + expr = ((MemberExpression)expr).Expression; + + return expr != null && expr.NodeType == ExpressionType.Constant; + } + + bool IsGroupJoinSource(IBuildContext context, MethodCallExpression call) + { + if (!call.IsQueryable() || CountBuilder.MethodNames.Contains(call.Method.Name)) + return false; + + Expression expr = call; + + while (expr.NodeType == ExpressionType.Call) + expr = ((MethodCallExpression)expr).Arguments[0]; + + var ctx = GetContext(context, expr); + + return ctx != null && ctx.IsExpression(expr, 0, RequestFor.GroupJoin).Result; + } + + #endregion + + #region ConvertExpression + + interface IConvertHelper + { + Expression ConvertNull(MemberExpression expression); + } + + class ConvertHelper : IConvertHelper + where T : struct + { + public Expression ConvertNull(MemberExpression expression) + { + return Expression.Call( + null, + ReflectionHelper.Expressor.MethodExpressor(p => Sql.ConvertNullable(p)), + expression.Expression); + } + } + + Expression ConvertExpression(Expression expression) + { + return expression.Convert2(e => + { + if (CanBeConstant(e) || CanBeCompiled(e)) + return new ExpressionHelper.ConvertInfo(e, true); + + switch (e.NodeType) + { + case ExpressionType.New: + { + var ex = ConvertNew((NewExpression)e); + if (ex != null) + return new ExpressionHelper.ConvertInfo(ConvertExpression(ex)); + break; + } + + case ExpressionType.Call: + { + var cm = ConvertMethod((MethodCallExpression)e); + if (cm != null) + return new ExpressionHelper.ConvertInfo(ConvertExpression(cm)); + break; + } + + case ExpressionType.MemberAccess: + { + var ma = (MemberExpression)e; + var l = SqlProvider.ConvertMember(ma.Member); + + if (l != null) + { + var body = l.Body.Unwrap(); + var expr = body.Convert(wpi => wpi.NodeType == ExpressionType.Parameter ? ma.Expression : wpi); + + if (expr.Type != e.Type) + expr = new ChangeTypeExpression(expr, e.Type); + + return new ExpressionHelper.ConvertInfo(ConvertExpression(expr)); + } + + if (TypeHelper.IsNullableValueMember(ma.Member)) + { + var ntype = typeof(ConvertHelper<>).MakeGenericType(ma.Type); + var helper = (IConvertHelper)Activator.CreateInstance(ntype); + var expr = helper.ConvertNull(ma); + + return new ExpressionHelper.ConvertInfo(ConvertExpression(expr)); + } + + if (ma.Member.DeclaringType == typeof(TimeSpan)) + { + switch (ma.Expression.NodeType) + { + case ExpressionType.Subtract : + case ExpressionType.SubtractChecked: + + Sql.DateParts datePart; + + switch (ma.Member.Name) + { + case "TotalMilliseconds" : datePart = Sql.DateParts.Millisecond; break; + case "TotalSeconds" : datePart = Sql.DateParts.Second; break; + case "TotalMinutes" : datePart = Sql.DateParts.Minute; break; + case "TotalHours" : datePart = Sql.DateParts.Hour; break; + case "TotalDays" : datePart = Sql.DateParts.Day; break; + default : return new ExpressionHelper.ConvertInfo(e); + } + + var ex = (BinaryExpression)ma.Expression; + var method = ReflectionHelper.Expressor.MethodExpressor( + _ => Sql.DateDiff(Sql.DateParts.Day, DateTime.MinValue, DateTime.MinValue)); + + var call = + Expression.Convert( + Expression.Call( + null, + method, + Expression.Constant(datePart), + Expression.Convert(ex.Right, typeof(DateTime?)), + Expression.Convert(ex.Left, typeof(DateTime?))), + typeof(double)); + + return new ExpressionHelper.ConvertInfo(ConvertExpression(call)); + } + } + + break; + } + } + + return new ExpressionHelper.ConvertInfo(e); + }); + } + + Expression ConvertMethod(MethodCallExpression pi) + { + var l = SqlProvider.ConvertMember(pi.Method); + return l == null ? null : ConvertMethod(pi, l); + } + + static Expression ConvertMethod(MethodCallExpression pi, LambdaExpression lambda) + { + var ef = lambda.Body.Unwrap(); + var parms = new Dictionary(lambda.Parameters.Count); + var pn = pi.Method.IsStatic ? 0 : -1; + + foreach (var p in lambda.Parameters) + parms.Add(p.Name, pn++); + + var pie = ef.Convert(wpi => + { + if (wpi.NodeType == ExpressionType.Parameter) + { + int n; + if (parms.TryGetValue(((ParameterExpression)wpi).Name, out n)) + return n < 0 ? pi.Object : pi.Arguments[n]; + } + + return wpi; + }); + + if (pi.Method.ReturnType != pie.Type) + pie = new ChangeTypeExpression(pie, pi.Method.ReturnType); + + return pie; + } + + Expression ConvertNew(NewExpression pi) + { + var lambda = SqlProvider.ConvertMember(pi.Constructor); + + if (lambda != null) + { + var ef = lambda.Body.Unwrap(); + var parms = new Dictionary(lambda.Parameters.Count); + var pn = 0; + + foreach (var p in lambda.Parameters) + parms.Add(p.Name, pn++); + + return ef.Convert(wpi => + { + if (wpi.NodeType == ExpressionType.Parameter) + { + var pe = (ParameterExpression)wpi; + var n = parms[pe.Name]; + return pi.Arguments[n]; + } + + return wpi; + }); + } + + return null; + } + + #endregion + + #region BuildExpression + + public SqlInfo[] ConvertExpressions(IBuildContext context, Expression expression, ConvertFlags queryConvertFlag) + { + expression = ConvertExpression(expression); + + switch (expression.NodeType) + { + case ExpressionType.New : + { + var expr = (NewExpression)expression; + +// ReSharper disable ConditionIsAlwaysTrueOrFalse +// ReSharper disable HeuristicUnreachableCode + if (expr.Members == null) + return Array.Empty; +// ReSharper restore HeuristicUnreachableCode +// ReSharper restore ConditionIsAlwaysTrueOrFalse + + return expr.Arguments + .Select((arg,i) => + { + var mi = expr.Members[i]; + if (mi is MethodInfo) + mi = TypeHelper.GetPropertyByMethod((MethodInfo)mi); + + return ConvertExpressions(context, arg, queryConvertFlag).Select(si => si.Clone(mi)); + }) + .SelectMany(si => si) + .ToArray(); + } + + case ExpressionType.MemberInit : + { + var expr = (MemberInitExpression)expression; + var dic = TypeAccessor.GetAccessor(expr.Type) + .Select((m,i) => new { m, i }) + .ToDictionary(_ => _.m.MemberInfo, _ => _.i); + + return expr.Bindings + .Where (b => b is MemberAssignment) + .Cast() + .OrderBy(b => dic[b.Member]) + .Select (a => + { + var mi = a.Member; + if (mi is MethodInfo) + mi = TypeHelper.GetPropertyByMethod((MethodInfo)mi); + + return ConvertExpressions(context, a.Expression, queryConvertFlag).Select(si => si.Clone(mi)); + }) + .SelectMany(si => si) + .ToArray(); + } + } + + var ctx = GetContext(context, expression); + + if (ctx != null && ctx.IsExpression(expression, 0, RequestFor.Object).Result) + return ctx.ConvertToSql(expression, 0, queryConvertFlag); + + return new[] { new SqlInfo { Sql = ConvertToSql(context, expression, false) } }; + } + + public ISqlExpression ConvertToSqlExpression(IBuildContext context, Expression expression, bool convertEnum) + { + var expr = ConvertExpression(expression); + return ConvertToSql(context, expr, false, convertEnum); + } + +#if FW3 + public ISqlExpression ConvertToSql(IBuildContext context, Expression expression, bool unwrap) + { + return ConvertToSql(context, expression, unwrap, true); + } +#endif + + public ISqlExpression ConvertToSql(IBuildContext context, Expression expression, bool unwrap, bool convertEnum +#if !FW3 + = true +#endif + ) + { + if (CanBeConstant(expression)) + return BuildConstant(expression, convertEnum); + + if (CanBeCompiled(expression)) + return BuildParameter(expression).SqlParameter; + + if (unwrap) + expression = expression.Unwrap(); + + switch (expression.NodeType) + { + case ExpressionType.AndAlso : + case ExpressionType.OrElse : + case ExpressionType.Not : + case ExpressionType.Equal : + case ExpressionType.NotEqual : + case ExpressionType.GreaterThan : + case ExpressionType.GreaterThanOrEqual : + case ExpressionType.LessThan : + case ExpressionType.LessThanOrEqual : + { + var condition = new SqlQuery.SearchCondition(); + BuildSearchCondition(context, expression, condition.Conditions); + return condition; + } + + case ExpressionType.And : + case ExpressionType.Or : + { + if (expression.Type == typeof(bool)) + goto case ExpressionType.AndAlso; + goto case ExpressionType.Add; + } + + case ExpressionType.Add : + case ExpressionType.AddChecked : + case ExpressionType.Divide : + case ExpressionType.ExclusiveOr : + case ExpressionType.Modulo : + case ExpressionType.Multiply : + case ExpressionType.MultiplyChecked : + case ExpressionType.Power : + case ExpressionType.Subtract : + case ExpressionType.SubtractChecked : + case ExpressionType.Coalesce : + { + var e = (BinaryExpression)expression; + var l = ConvertToSql(context, e.Left, false); + var r = ConvertToSql(context, e.Right, false); + var t = e.Type; + + switch (expression.NodeType) + { + case ExpressionType.Add : + case ExpressionType.AddChecked : return Convert(context, new SqlBinaryExpression(t, l, "+", r, Precedence.Additive)); + case ExpressionType.And : return Convert(context, new SqlBinaryExpression(t, l, "&", r, Precedence.Bitwise)); + case ExpressionType.Divide : return Convert(context, new SqlBinaryExpression(t, l, "/", r, Precedence.Multiplicative)); + case ExpressionType.ExclusiveOr : return Convert(context, new SqlBinaryExpression(t, l, "^", r, Precedence.Bitwise)); + case ExpressionType.Modulo : return Convert(context, new SqlBinaryExpression(t, l, "%", r, Precedence.Multiplicative)); + case ExpressionType.Multiply: + case ExpressionType.MultiplyChecked : return Convert(context, new SqlBinaryExpression(t, l, "*", r, Precedence.Multiplicative)); + case ExpressionType.Or : return Convert(context, new SqlBinaryExpression(t, l, "|", r, Precedence.Bitwise)); + case ExpressionType.Power : return Convert(context, new SqlFunction(t, "Power", l, r)); + case ExpressionType.Subtract : + case ExpressionType.SubtractChecked : return Convert(context, new SqlBinaryExpression(t, l, "-", r, Precedence.Subtraction)); + case ExpressionType.Coalesce : + { + if (r is SqlFunction) + { + var c = (SqlFunction)r; + + if (c.Name == "Coalesce") + { + var parms = new ISqlExpression[c.Parameters.Length + 1]; + + parms[0] = l; + c.Parameters.CopyTo(parms, 1); + + return Convert(context, new SqlFunction(t, "Coalesce", parms)); + } + } + + return Convert(context, new SqlFunction(t, "Coalesce", l, r)); + } + } + + break; + } + + case ExpressionType.UnaryPlus : + case ExpressionType.Negate : + case ExpressionType.NegateChecked : + { + var e = (UnaryExpression)expression; + var o = ConvertToSql(context, e.Operand, false); + var t = e.Type; + + switch (expression.NodeType) + { + case ExpressionType.UnaryPlus : return o; + case ExpressionType.Negate : + case ExpressionType.NegateChecked : + return Convert(context, new SqlBinaryExpression(t, new SqlValue(-1), "*", o, Precedence.Multiplicative)); + } + + break; + } + + case ExpressionType.Convert : + case ExpressionType.ConvertChecked : + { + var e = (UnaryExpression)expression; + var o = ConvertToSql(context, e.Operand, false); + + if (e.Method == null && e.IsLifted) + return o; + + var t = e.Operand.Type; + var s = SqlDataType.GetDataType(t); + + if (o.SystemType != null && s.Type == typeof(object)) + { + t = o.SystemType; + s = SqlDataType.GetDataType(t); + } + + if (e.Type == t || + t.IsEnum && Enum.GetUnderlyingType(t) == e.Type || + e.Type.IsEnum && Enum.GetUnderlyingType(e.Type) == t) + return o; + + return Convert( + context, + new SqlFunction(e.Type, "$Convert$", SqlDataType.GetDataType(e.Type), s, o)); + } + + case ExpressionType.Conditional : + { + var e = (ConditionalExpression)expression; + var s = ConvertToSql(context, e.Test, false); + var t = ConvertToSql(context, e.IfTrue, false); + var f = ConvertToSql(context, e.IfFalse, false); + + if (f is SqlFunction) + { + var c = (SqlFunction)f; + + if (c.Name == "CASE") + { + var parms = new ISqlExpression[c.Parameters.Length + 2]; + + parms[0] = s; + parms[1] = t; + c.Parameters.CopyTo(parms, 2); + + return Convert(context, new SqlFunction(e.Type, "CASE", parms)); + } + } + + return Convert(context, new SqlFunction(e.Type, "CASE", s, t, f)); + } + + case ExpressionType.MemberAccess : + { + var ma = (MemberExpression)expression; + var attr = GetFunctionAttribute(ma.Member); + + if (attr != null) + return Convert(context, attr.GetExpression(ma.Member)); + + var ctx = GetContext(context, expression); + + if (ctx != null) + { + var sql = ctx.ConvertToSql(expression, 0, ConvertFlags.Field); + + switch (sql.Length) + { + case 0 : break; + case 1 : return sql[0].Sql; + default : throw new InvalidOperationException(); + } + } + + break; + } + + case ExpressionType.Parameter : + { + var ctx = GetContext(context, expression); + + if (ctx != null) + { + var sql = ctx.ConvertToSql(expression, 0, ConvertFlags.Field); + + switch (sql.Length) + { + case 0 : break; + case 1 : return sql[0].Sql; + default : throw new InvalidOperationException(); + } + } + + break; + } + + case ExpressionType.Call : + { + var e = (MethodCallExpression)expression; + + if (e.IsQueryable()) + { + if (IsSubQuery(context, e)) + return SubQueryToSql(context, e); + + if (CountBuilder.MethodNames.Concat(AggregationBuilder.MethodNames).Contains(e.Method.Name)) + { + var ctx = GetContext(context, expression); + + if (ctx != null) + { + var sql = ctx.ConvertToSql(expression, 0, ConvertFlags.Field); + + if (sql.Length != 1) + throw new InvalidOperationException(); + + return sql[0].Sql; + } + + break; + } + + return SubQueryToSql(context, e); + } + + var attr = GetFunctionAttribute(e.Method); + + if (attr != null) + { + var parms = new List(); + + if (e.Object != null) + parms.Add(ConvertToSql(context, e.Object, false)); + + parms.AddRange(e.Arguments.Select(t => ConvertToSql(context, t, false))); + + return Convert(context, attr.GetExpression(e.Method, parms.ToArray())); + } + + break; + } + + case ExpressionType.Invoke : + { + var pi = (InvocationExpression)expression; + var ex = pi.Expression; + + if (ex.NodeType == ExpressionType.Quote) + ex = ((UnaryExpression)ex).Operand; + + if (ex.NodeType == ExpressionType.Lambda) + { + var l = (LambdaExpression)ex; + var dic = new Dictionary(); + + for (var i = 0; i < l.Parameters.Count; i++) + dic.Add(l.Parameters[i], pi.Arguments[i]); + + var pie = l.Body.Convert(wpi => + { + Expression ppi; + return dic.TryGetValue(wpi, out ppi) ? ppi : wpi; + }); + + return ConvertToSql(context, pie, false); + } + + break; + } + + case ExpressionType.TypeIs : + { + var condition = new SqlQuery.SearchCondition(); + BuildSearchCondition(context, expression, condition.Conditions); + return condition; + } + + case (ExpressionType)ChangeTypeExpression.ChangeTypeType : + return ConvertToSql(context, ((ChangeTypeExpression)expression).Expression, false); + } + + if (expression.Type == typeof(bool) && _convertedPredicates.Add(expression)) + { + var predicate = ConvertPredicate(context, expression); + _convertedPredicates.Remove(expression); + if (predicate != null) + return new SqlQuery.SearchCondition(new SqlQuery.Condition(false, predicate)); + } + + throw new LinqException("'{0}' cannot be converted to SQL.", expression); + } + + readonly HashSet _convertedPredicates = new HashSet(); + + #endregion + + #region IsServerSideOnly + + bool IsServerSideOnly(Expression expr) + { + switch (expr.NodeType) + { + case ExpressionType.MemberAccess: + { + var ex = (MemberExpression)expr; + var l = SqlProvider.ConvertMember(ex.Member); + + if (l != null) + return IsServerSideOnly(l.Body.Unwrap()); + + var attr = GetFunctionAttribute(ex.Member); + return attr != null && attr.ServerSideOnly; + } + + case ExpressionType.Call: + { + var e = (MethodCallExpression)expr; + + if (e.Method.DeclaringType == typeof(Enumerable)) + { + if (CountBuilder.MethodNames.Concat(AggregationBuilder.MethodNames).Contains(e.Method.Name)) + return IsQueryMember(e.Arguments[0]); + } + else if (e.Method.DeclaringType == typeof(Queryable)) + { + switch (e.Method.Name) + { + case "Any" : + case "All" : + case "Contains" : return true; + } + } + else + { + var l = SqlProvider.ConvertMember(e.Method); + + if (l != null) + return l.Body.Unwrap().Find(IsServerSideOnly) != null; + + var attr = GetFunctionAttribute(e.Method); + return attr != null && attr.ServerSideOnly; + } + + break; + } + } + + return false; + } + + static bool IsQueryMember(Expression expr) + { + if (expr != null) switch (expr.NodeType) + { + case ExpressionType.Parameter : return true; + case ExpressionType.MemberAccess : return IsQueryMember(((MemberExpression)expr).Expression); + case ExpressionType.Call : + { + var call = (MethodCallExpression)expr; + + if (call.Method.DeclaringType == typeof(Queryable)) + return true; + + if (call.Method.DeclaringType == typeof(Enumerable) && call.Arguments.Count > 0) + return IsQueryMember(call.Arguments[0]); + + return IsQueryMember(call.Object); + } + } + + return false; + } + + #endregion + + #region CanBeConstant + + bool CanBeConstant(Expression expr) + { + return null == expr.Find(ex => + { + if (ex is BinaryExpression || ex is UnaryExpression /*|| ex.NodeType == ExpressionType.Convert*/) + return false; + + switch (ex.NodeType) + { + case ExpressionType.Constant : + { + var c = (ConstantExpression)ex; + + if (c.Value == null || ExpressionHelper.IsConstant(ex.Type)) + return false; + + break; + } + + case ExpressionType.MemberAccess : + { + var ma = (MemberExpression)ex; + + if (ExpressionHelper.IsConstant(ma.Member.DeclaringType) || TypeHelper.IsNullableValueMember(ma.Member)) + return false; + + break; + } + + case ExpressionType.Call : + { + var mc = (MethodCallExpression)ex; + + if (ExpressionHelper.IsConstant(mc.Method.DeclaringType) || mc.Method.DeclaringType == typeof(object)) + return false; + + var attr = GetFunctionAttribute(mc.Method); + + if (attr != null && !attr.ServerSideOnly) + return false; + + break; + } + } + + return true; + }); + } + + #endregion + + #region CanBeCompiled + + bool CanBeCompiled(Expression expr) + { + return null == expr.Find(ex => + { + if (IsServerSideOnly(ex)) + return true; + + switch (ex.NodeType) + { + case ExpressionType.Parameter : + return ex != ParametersParam; + + case ExpressionType.MemberAccess : + { + var attr = GetFunctionAttribute(((MemberExpression)ex).Member); + return attr != null && attr.ServerSideOnly; + } + + case ExpressionType.Call : + { + var attr = GetFunctionAttribute(((MethodCallExpression)ex).Method); + return attr != null && attr.ServerSideOnly; + } + } + + return false; + }); + } + + #endregion + + #region Build Constant + + readonly Dictionary _constants = new Dictionary(); + + SqlValue BuildConstant(Expression expr, bool convertEnum) + { + SqlValue value; + + if (_constants.TryGetValue(expr, out value)) + return value; + + var lambda = Expression.Lambda>(Expression.Convert(expr, typeof(object))); + var v = lambda.Compile()(); + + if (v != null && convertEnum && v.GetType().IsEnum) + { + var attrs = v.GetType().GetCustomAttributes(typeof(SqlEnumAttribute), true); + + v = Map.EnumToValue(v, attrs.Length == 0); + } + + value = new SqlValue(v); + + _constants.Add(expr, value); + + return value; + } + + #endregion + + #region Build Parameter + + readonly Dictionary _parameters = new Dictionary(); + + public readonly HashSet AsParameters = new HashSet(); + + ParameterAccessor BuildParameter(Expression expr) + { + ParameterAccessor p; + + if (_parameters.TryGetValue(expr, out p)) + return p; + + string name = null; + + var newExpr = ReplaceParameter(_expressionAccessors, expr, nm => name = nm); + var mapper = Expression.Lambda>( + Expression.Convert(newExpr, typeof(object)), + new [] { ExpressionParam, ParametersParam }); + + p = new ParameterAccessor + { + Expression = expr, + Accessor = mapper.Compile(), + SqlParameter = new SqlParameter(expr.Type, name, null, MappingSchema) + }; + + _parameters.Add(expr, p); + CurrentSqlParameters.Add(p); + + return p; + } + + Expression ReplaceParameter(IDictionary expressionAccessors, Expression expression, Action setName) + { + return expression.Convert(expr => + { + if (expr.NodeType == ExpressionType.Constant) + { + var c = (ConstantExpression)expr; + + if (!ExpressionHelper.IsConstant(expr.Type) || AsParameters.Contains(c)) + { + Expression val; + + if (expressionAccessors.TryGetValue(expr, out val)) + { + expr = Expression.Convert(val, expr.Type); + + if (expression.NodeType == ExpressionType.MemberAccess) + { + var ma = (MemberExpression)expression; + setName(ma.Member.Name); + } + } + } + } + + return expr; + }); + } + + #endregion + + #region Predicate Converter + + ISqlPredicate ConvertPredicate(IBuildContext context, Expression expression) + { + switch (expression.NodeType) + { + case ExpressionType.Equal : + case ExpressionType.NotEqual : + case ExpressionType.GreaterThan : + case ExpressionType.GreaterThanOrEqual : + case ExpressionType.LessThan : + case ExpressionType.LessThanOrEqual : + { + var e = (BinaryExpression)expression; + return ConvertCompare(context, expression.NodeType, e.Left, e.Right); + } + + case ExpressionType.Call : + { + var e = (MethodCallExpression)expression; + + ISqlPredicate predicate = null; + + if (e.Method.Name == "Equals" && e.Object != null && e.Arguments.Count == 1) + return ConvertCompare(context, ExpressionType.Equal, e.Object, e.Arguments[0]); + + if (e.Method.DeclaringType == typeof(string)) + { + switch (e.Method.Name) + { + case "Contains" : predicate = ConvertLikePredicate(context, e, "%", "%"); break; + case "StartsWith" : predicate = ConvertLikePredicate(context, e, "", "%"); break; + case "EndsWith" : predicate = ConvertLikePredicate(context, e, "%", ""); break; + } + } + else if (e.Method.Name == "Contains") + { + if (e.Method.DeclaringType == typeof(Enumerable) || + TypeHelper.IsSameOrParent(typeof(IList), e.Method.DeclaringType) || + TypeHelper.IsSameOrParent(typeof(ICollection<>), e.Method.DeclaringType)) + { + predicate = ConvertInPredicate(context, e); + } + } + else if (e.Method.Name == "ContainsValue" && TypeHelper.IsSameOrParent(typeof(Dictionary<,>), e.Method.DeclaringType)) + { + var args = TypeHelper.GetGenericArguments(e.Method.DeclaringType, typeof(Dictionary<,>)); + var minf = EnumerableMethods + .First(m => m.Name == "Contains" && m.GetParameters().Length == 2) + .MakeGenericMethod(args[1]); + + var expr = Expression.Call( + minf, + Expression.PropertyOrField(e.Object, "Values"), + e.Arguments[0]); + + predicate = ConvertInPredicate(context, expr); + } + else if (e.Method.Name == "ContainsKey" && TypeHelper.IsSameOrParent(typeof(IDictionary<,>), e.Method.DeclaringType)) + { + var args = TypeHelper.GetGenericArguments(e.Method.DeclaringType, typeof(IDictionary<,>)); + var minf = EnumerableMethods + .First(m => m.Name == "Contains" && m.GetParameters().Length == 2) + .MakeGenericMethod(args[0]); + + var expr = Expression.Call( + minf, + Expression.PropertyOrField(e.Object, "Keys"), + e.Arguments[0]); + + predicate = ConvertInPredicate(context, expr); + } +#if !SILVERLIGHT + else if (e.Method == ReflectionHelper.Functions.String.Like11) predicate = ConvertLikePredicate(context, e); + else if (e.Method == ReflectionHelper.Functions.String.Like12) predicate = ConvertLikePredicate(context, e); +#endif + else if (e.Method == ReflectionHelper.Functions.String.Like21) predicate = ConvertLikePredicate(context, e); + else if (e.Method == ReflectionHelper.Functions.String.Like22) predicate = ConvertLikePredicate(context, e); + + if (predicate != null) + return Convert(context, predicate); + + break; + } + + case ExpressionType.Conditional : + return Convert(context, + new SqlQuery.Predicate.ExprExpr( + ConvertToSql(context, expression, false), + SqlQuery.Predicate.Operator.Equal, + new SqlValue(true))); + + case ExpressionType.MemberAccess : + { + var e = (MemberExpression)expression; + + if (e.Member.Name == "HasValue" && + e.Member.DeclaringType.IsGenericType && + e.Member.DeclaringType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + var expr = ConvertToSql(context, e.Expression, false); + return Convert(context, new SqlQuery.Predicate.IsNull(expr, true)); + } + + break; + } + + case ExpressionType.TypeIs: + { + var e = (TypeBinaryExpression)expression; + var ctx = GetContext(context, e.Expression); + + if (ctx != null && ctx.IsExpression(e.Expression, 0, RequestFor.Table).Result) + return MakeIsPredicate(ctx, e); + + break; + } + } + + var ex = ConvertToSql(context, expression, false); + + if (SqlExpression.NeedsEqual(ex)) + return Convert(context, new SqlQuery.Predicate.ExprExpr(ex, SqlQuery.Predicate.Operator.Equal, new SqlValue(true))); + + return Convert(context, new SqlQuery.Predicate.Expr(ex)); + } + + #region ConvertCompare + + ISqlPredicate ConvertCompare(IBuildContext context, ExpressionType nodeType, Expression left, Expression right) + { + if (left.NodeType == ExpressionType.Convert && left.Type == typeof(int) && right.NodeType == ExpressionType.Constant) + { + var conv = (UnaryExpression)left; + + if (conv.Operand.Type == typeof(char)) + { + left = conv.Operand; + right = Expression.Constant(ConvertTo.From(((ConstantExpression)right).Value)); + } + } + + if (right.NodeType == ExpressionType.Convert && right.Type == typeof(int) && left.NodeType == ExpressionType.Constant) + { + var conv = (UnaryExpression)right; + + if (conv.Operand.Type == typeof(char)) + { + right = conv.Operand; + left = Expression.Constant(ConvertTo.From(((ConstantExpression)left).Value)); + } + } + + #region special case for char? + +// if (left.NodeType == ExpressionType.Convert && left.Type == typeof(int?) && right.NodeType == ExpressionType.Convert) +// { +// var convLeft = left as UnaryExpression; +// var convRight = right as UnaryExpression; +// +// if (convLeft != null && convRight != null && convLeft.Operand.Type == typeof(char?)) +// { +// left = convLeft.Operand; +// right = Expression.Constant(ConvertTo.From(((ConstantExpression)convRight.Operand).Value)); +// } +// } + + #endregion + + switch (nodeType) + { + case ExpressionType.Equal : + case ExpressionType.NotEqual : + + var p = ConvertObjectComparison(nodeType, context, left, context, right); + if (p != null) + return p; + + p = ConvertObjectNullComparison(context, left, right, nodeType == ExpressionType.Equal); + if (p != null) + return p; + + p = ConvertObjectNullComparison(context, right, left, nodeType == ExpressionType.Equal); + if (p != null) + return p; + + if (left.NodeType == ExpressionType.New || right.NodeType == ExpressionType.New) + { + p = ConvertNewObjectComparison(context, nodeType, left, right); + if (p != null) + return p; + } + + break; + } + + SqlQuery.Predicate.Operator op; + + switch (nodeType) + { + case ExpressionType.Equal : op = SqlQuery.Predicate.Operator.Equal; break; + case ExpressionType.NotEqual : op = SqlQuery.Predicate.Operator.NotEqual; break; + case ExpressionType.GreaterThan : op = SqlQuery.Predicate.Operator.Greater; break; + case ExpressionType.GreaterThanOrEqual: op = SqlQuery.Predicate.Operator.GreaterOrEqual; break; + case ExpressionType.LessThan : op = SqlQuery.Predicate.Operator.Less; break; + case ExpressionType.LessThanOrEqual : op = SqlQuery.Predicate.Operator.LessOrEqual; break; + default: throw new InvalidOperationException(); + } + + if (left.NodeType == ExpressionType.Convert || right.NodeType == ExpressionType.Convert + || left.NodeType == ExpressionType.MemberAccess || right.NodeType == ExpressionType.MemberAccess) + { + var p = ConvertEnumConversion(context, left, op, right); + if (p != null) + return p; + } + + var l = ConvertToSql(context, left, false); + var r = ConvertToSql(context, right, true); + + switch (nodeType) + { + case ExpressionType.Equal : + case ExpressionType.NotEqual: + + if (!context.SqlQuery.IsParameterDependent && (l is SqlParameter || r is SqlParameter) && l.CanBeNull() && r.CanBeNull()) + context.SqlQuery.IsParameterDependent = true; + + // | (SqlQuery(Select([]) as q), SqlValue(null)) + // | (SqlValue(null), SqlQuery(Select([]) as q)) => + + SqlQuery q = + l.ElementType == QueryElementType.SqlQuery && + r.ElementType == QueryElementType.SqlValue && + ((SqlValue)r).Value == null && + ((SqlQuery)l).Select.Columns.Count == 0 ? + (SqlQuery)l : + r.ElementType == QueryElementType.SqlQuery && + l.ElementType == QueryElementType.SqlValue && + ((SqlValue)l).Value == null && + ((SqlQuery)r).Select.Columns.Count == 0 ? + (SqlQuery)r : + null; + + if (q != null) + { + q.Select.Columns.Add(new SqlQuery.Column(q, new SqlValue(1))); + } + + break; + } + + if (l is SqlQuery.SearchCondition) + l = Convert(context, new SqlFunction(typeof(bool), "CASE", l, new SqlValue(true), new SqlValue(false))); + + if (r is SqlQuery.SearchCondition) + r = Convert(context, new SqlFunction(typeof(bool), "CASE", r, new SqlValue(true), new SqlValue(false))); + + return Convert(context, new SqlQuery.Predicate.ExprExpr(l, op, r)); + } + + #endregion + + #region ConvertEnumConversion + + ISqlPredicate ConvertEnumConversion(IBuildContext context, Expression left, SqlQuery.Predicate.Operator op, Expression right) + { + Expression value; + Expression operand; + + if (left is MemberExpression) + { + operand = left; + value = right; + } + else if (left.NodeType == ExpressionType.Convert && ((UnaryExpression)left).Operand is MemberExpression) + { + operand = ((UnaryExpression)left).Operand; + value = right; + } + else if (right is MemberExpression) + { + operand = right; + value = left; + } + else if (right.NodeType == ExpressionType.Convert && ((UnaryExpression)right).Operand is MemberExpression) + { + operand = ((UnaryExpression)right).Operand; + value = left; + } + else if (left.NodeType == ExpressionType.Convert) + { + operand = ((UnaryExpression)left).Operand; + value = right; + } + else + { + operand = ((UnaryExpression)right).Operand; + value = left; + } + + var type = operand.Type; + + if (!TypeHelper.IsEnumOrNullableEnum(type)) + return null; + + var dic = new Dictionary(); + + var nullValue = MappingSchema.GetNullValue(type); + + if (nullValue != null) + dic.Add(nullValue, null); + + var mapValues = MappingSchema.GetMapValues(type); + + if (mapValues != null) + foreach (var mv in mapValues) + if (!dic.ContainsKey(mv.OrigValue)) + dic.Add(mv.OrigValue, mv.MapValues[0]); + + switch (value.NodeType) + { + case ExpressionType.Constant: + { + var name = Enum.GetName(type, ((ConstantExpression)value).Value); + +// ReSharper disable ConditionIsAlwaysTrueOrFalse +// ReSharper disable HeuristicUnreachableCode + if (name == null) + return null; +// ReSharper restore HeuristicUnreachableCode +// ReSharper restore ConditionIsAlwaysTrueOrFalse + + var origValue = Enum.Parse(type, name, false); + var mapValue = origValue; + + if (!(operand is MemberExpression)) + { + if (!dic.TryGetValue(origValue, out mapValue)) + return null; + } + + ISqlExpression l, r; + + SqlValue sqlValue; + + if (left.NodeType == ExpressionType.Convert) + { + l = ConvertToSql(context, operand, false); + r = sqlValue = new SqlValue(mapValue); + } + else + { + r = ConvertToSql(context, operand, false); + l = sqlValue = new SqlValue(mapValue); + } + + if (operand is MemberExpression) + { + var me = (MemberExpression)operand; + var memberAccessor = TypeAccessor.GetAccessor(me.Member.DeclaringType)[me.Member.Name]; + sqlValue.SetEnumConverter(memberAccessor, MappingSchema); + } + + + return Convert(context, new SqlQuery.Predicate.ExprExpr(l, op, r)); + } + + case ExpressionType.Convert: + { + value = ((UnaryExpression)value).Operand; + + var l = ConvertToSql(context, operand, false, false); + var r = ConvertToSql(context, value, false, false); + + MemberAccessor memberAccessor = null; + + if (operand is MemberExpression) + { + // is it even possible that operand is not MemberExpression? + // if no, then we can remove this two last uses of SetEnumConverter(type, map) + // and other depending code + // At least currently there is no test coverage for this method and I didn't + // manage to create such test + var me = (MemberExpression)operand; + memberAccessor = TypeAccessor.GetAccessor(me.Member.DeclaringType)[me.Member.Name]; + } + + if (l is SqlValueBase) + { + if (memberAccessor != null) + { + ((SqlValueBase)l).SetEnumConverter(memberAccessor, MappingSchema); + } + else + { + ((SqlValueBase)l).SetEnumConverter(type, MappingSchema); + } + } + + if (r is SqlValueBase) + { + if (memberAccessor != null) + { + ((SqlValueBase)r).SetEnumConverter(memberAccessor, MappingSchema); + } + else + { + ((SqlValueBase)r).SetEnumConverter(type, MappingSchema); + } + } + + return Convert(context, new SqlQuery.Predicate.ExprExpr(l, op, r)); + } + } + + return null; + } + + #endregion + + #region ConvertObjectNullComparison + + ISqlPredicate ConvertObjectNullComparison(IBuildContext context, Expression left, Expression right, bool isEqual) + { + if (right.NodeType == ExpressionType.Constant && ((ConstantExpression)right).Value == null) + { + if (left.NodeType == ExpressionType.MemberAccess || left.NodeType == ExpressionType.Parameter) + { + var ctx = GetContext(context, left); + + if (ctx != null && ctx.IsExpression(left, 0, RequestFor.Object).Result || + left.NodeType == ExpressionType.Parameter && ctx.IsExpression(left, 0, RequestFor.Field).Result) + { + return new SqlQuery.Predicate.Expr(new SqlValue(!isEqual)); + } + } + } + + return null; + } + + #endregion + + #region ConvertObjectComparison + + public ISqlPredicate ConvertObjectComparison( + ExpressionType nodeType, + IBuildContext leftContext, + Expression left, + IBuildContext rightContext, + Expression right) + { + var qsl = GetContext(leftContext, left); + var qsr = GetContext(rightContext, right); + + var sl = qsl != null && qsl.IsExpression(left, 0, RequestFor.Object).Result; + var sr = qsr != null && qsr.IsExpression(right, 0, RequestFor.Object).Result; + + bool isNull; + SqlInfo[] lcols; + + var rmembers = new Dictionary(new MemberInfoComparer()); + + if (sl == false && sr == false) + { + var lmembers = new Dictionary(new MemberInfoComparer()); + + if (!ProcessProjection(lmembers, left) && !ProcessProjection(rmembers, right)) + return null; + + if (lmembers.Count == 0) + { + var r = right; + right = left; + left = r; + + var c = rightContext; + rightContext = leftContext; + leftContext = c; + + var q = qsr; + qsl = q; + + sr = false; + + var lm = lmembers; + lmembers = rmembers; + rmembers = lm; + } + + isNull = right is ConstantExpression && ((ConstantExpression)right).Value == null; + lcols = lmembers.Select(m => new SqlInfo(m.Key) { Sql = ConvertToSql(leftContext, m.Value, false) }).ToArray(); + } + else + { + if (sl == false) + { + var r = right; + right = left; + left = r; + + var c = rightContext; + rightContext = leftContext; + leftContext = c; + + var q = qsr; + qsl = q; + + sr = false; + } + + isNull = right is ConstantExpression && ((ConstantExpression)right).Value == null; + lcols = qsl.ConvertToSql(left, 0, ConvertFlags.Key); + + if (!sr) + ProcessProjection(rmembers, right); + } + + if (lcols.Length == 0) + return null; + + var condition = new SqlQuery.SearchCondition(); + + foreach (var lcol in lcols) + { + if (lcol.Members.Count == 0) + throw new InvalidOperationException(); + + ISqlExpression rcol = null; + + var lmember = lcol.Members[lcol.Members.Count - 1]; + + if (sr) + { + var info = rightContext.ConvertToSql(Expression.MakeMemberAccess(right, lmember), 0, ConvertFlags.Field).Single(); + rcol = info.Sql; + } + else + { + if (rmembers.Count != 0) + { + var info = rightContext.ConvertToSql(rmembers[lmember], 0, ConvertFlags.Field)[0]; + rcol = info.Sql; + } + } + + var rex = + isNull ? + new SqlValue(right.Type, null) : + rcol ?? GetParameter(right, lmember); + + var predicate = Convert(leftContext, new SqlQuery.Predicate.ExprExpr( + lcol.Sql, + nodeType == ExpressionType.Equal ? SqlQuery.Predicate.Operator.Equal : SqlQuery.Predicate.Operator.NotEqual, + rex)); + + condition.Conditions.Add(new SqlQuery.Condition(false, predicate)); + } + + if (nodeType == ExpressionType.NotEqual) + foreach (var c in condition.Conditions) + c.IsOr = true; + + return condition; + } + + ISqlPredicate ConvertNewObjectComparison(IBuildContext context, ExpressionType nodeType, Expression left, Expression right) + { + left = FindExpression(left); + right = FindExpression(right); + + var condition = new SqlQuery.SearchCondition(); + + if (left.NodeType != ExpressionType.New) + { + var temp = left; + left = right; + right = temp; + } + + var newRight = right as NewExpression; + var newExpr = (NewExpression)left; + +// ReSharper disable ConditionIsAlwaysTrueOrFalse +// ReSharper disable HeuristicUnreachableCode + if (newExpr.Members == null) + return null; +// ReSharper restore HeuristicUnreachableCode +// ReSharper restore ConditionIsAlwaysTrueOrFalse + + for (var i = 0; i < newExpr.Arguments.Count; i++) + { + var lex = ConvertToSql(context, newExpr.Arguments[i], false); + var rex = + newRight != null ? + ConvertToSql(context, newRight.Arguments[i], false) : + GetParameter(right, newExpr.Members[i]); + + var predicate = Convert(context, + new SqlQuery.Predicate.ExprExpr( + lex, + nodeType == ExpressionType.Equal ? SqlQuery.Predicate.Operator.Equal : SqlQuery.Predicate.Operator.NotEqual, + rex)); + + condition.Conditions.Add(new SqlQuery.Condition(false, predicate)); + } + + if (nodeType == ExpressionType.NotEqual) + foreach (var c in condition.Conditions) + c.IsOr = true; + + return condition; + } + + ISqlExpression GetParameter(Expression ex, MemberInfo member) + { + if (member is MethodInfo) + member = TypeHelper.GetPropertyByMethod((MethodInfo)member); + + var par = ReplaceParameter(_expressionAccessors, ex, _ => {}); + var expr = Expression.MakeMemberAccess(par.Type == typeof(object) ? Expression.Convert(par, member.DeclaringType) : par, member); + var mapper = Expression.Lambda>( + Expression.Convert(expr, typeof(object)), + new [] { ExpressionParam, ParametersParam }); + + var p = new ParameterAccessor + { + Expression = expr, + Accessor = mapper.Compile(), + SqlParameter = new SqlParameter(expr.Type, member.Name, null, MappingSchema) + }; + + _parameters.Add(expr, p); + CurrentSqlParameters.Add(p); + + return p.SqlParameter; + } + + static Expression FindExpression(Expression expr) + { + var ret = expr.Find(pi => + { + switch (pi.NodeType) + { + case ExpressionType.Convert : + { + var e = (UnaryExpression)expr; + + return + e.Operand.NodeType == ExpressionType.ArrayIndex && + ((BinaryExpression)e.Operand).Left == ParametersParam; + } + + case ExpressionType.MemberAccess : + case ExpressionType.New : + return true; + } + + return false; + }); + + if (ret == null) + throw new InvalidOperationException(); + + return ret; + } + + #endregion + + #region ConvertInPredicate + + private ISqlPredicate ConvertInPredicate(IBuildContext context, MethodCallExpression expression) + { + var e = expression; + var argIndex = e.Object != null ? 0 : 1; + var arr = e.Object ?? e.Arguments[0]; + var arg = e.Arguments[argIndex]; + + ISqlExpression expr = null; + + var ctx = GetContext(context, arg); + + if (ctx is TableBuilder.TableContext && + ctx.SqlQuery != context.SqlQuery && + ctx.IsExpression(arg, 0, RequestFor.Object).Result) + { + expr = ctx.SqlQuery; + } + + if (expr == null) + { + var sql = ConvertExpressions(context, arg, ConvertFlags.Key); + + if (sql.Length == 1 && sql[0].Members.Count == 0) + expr = sql[0].Sql; + else + expr = new SqlExpression( + '\x1' + string.Join(",", sql.Select(s => s.Members[s.Members.Count - 1].Name).ToArray()), + sql.Select(s => s.Sql).ToArray()); + } + + MemberAccessor memberAccessor = null; + + if (arg is MemberExpression) + { + var me = (MemberExpression)arg; + if (TypeHelper.IsEnumOrNullableEnum(me.Type)) + { + memberAccessor = TypeAccessor.GetAccessor(me.Member.DeclaringType)[me.Member.Name]; + } + } + + switch (arr.NodeType) + { + case ExpressionType.NewArrayInit : + { + var newArr = (NewArrayExpression)arr; + + if (newArr.Expressions.Count == 0) + return new SqlQuery.Predicate.Expr(new SqlValue(false)); + + var exprs = new ISqlExpression[newArr.Expressions.Count]; + + for (var i = 0; i < newArr.Expressions.Count; i++) + { + exprs[i] = ConvertToSql(context, newArr.Expressions[i], false, false); + + if (memberAccessor != null && exprs[i] is SqlValue) + { + ((SqlValue)exprs[i]).SetEnumConverter(memberAccessor, MappingSchema); + } + } + + return new SqlQuery.Predicate.InList(expr, false, exprs); + } + + default : + + if (CanBeCompiled(arr)) + { + var p = BuildParameter(arr).SqlParameter; + p.IsQueryParameter = false; + if (memberAccessor != null) + { + p.SetEnumConverter(memberAccessor, MappingSchema); + } + return new SqlQuery.Predicate.InList(expr, false, p); + } + + break; + } + + throw new LinqException("'{0}' cannot be converted to SQL.", expression); + } + + #endregion + + #region LIKE predicate + + ISqlPredicate ConvertLikePredicate(IBuildContext context, MethodCallExpression expression, string start, string end) + { + var e = expression; + var o = ConvertToSql(context, e.Object, false); + var a = ConvertToSql(context, e.Arguments[0], false); + + if (a is SqlValue) + { + var value = ((SqlValue)a).Value; + + if (value == null) + throw new LinqException("NULL cannot be used as a LIKE predicate parameter."); + + return value.ToString().IndexOfAny(new[] { '%', '_' }) < 0? + new SqlQuery.Predicate.Like(o, false, new SqlValue(start + value + end), null): + new SqlQuery.Predicate.Like(o, false, new SqlValue(start + EscapeLikeText(value.ToString()) + end), new SqlValue('~')); + } + + if (a is SqlParameter) + { + var p = (SqlParameter)a; + var ep = (from pm in CurrentSqlParameters where pm.SqlParameter == p select pm).First(); + + ep = new ParameterAccessor + { + Expression = ep.Expression, + Accessor = ep.Accessor, + SqlParameter = new SqlParameter(ep.Expression.Type, p.Name, p.Value, GetLikeEscaper(start, end)) + }; + + CurrentSqlParameters.Add(ep); + + return new SqlQuery.Predicate.Like(o, false, ep.SqlParameter, new SqlValue('~')); + } + + var mi = ReflectionHelper.Expressor.MethodExpressor(_ => _.Replace("", "")); + var ex = + Expression.Call( + Expression.Call( + Expression.Call( + e.Arguments[0], + mi, Expression.Constant("~"), Expression.Constant("~~")), + mi, Expression.Constant("%"), Expression.Constant("~%")), + mi, Expression.Constant("_"), Expression.Constant("~_")); + + var expr = ConvertToSql(context, ConvertExpression(ex), false); + + if (!string.IsNullOrEmpty(start)) + expr = new SqlBinaryExpression(typeof(string), new SqlValue("%"), "+", expr); + + if (!string.IsNullOrEmpty(end)) + expr = new SqlBinaryExpression(typeof(string), expr, "+", new SqlValue("%")); + + return new SqlQuery.Predicate.Like(o, false, expr, new SqlValue('~')); + } + + ISqlPredicate ConvertLikePredicate(IBuildContext context, MethodCallExpression expression) + { + var e = expression; + var a1 = ConvertToSql(context, e.Arguments[0], false); + var a2 = ConvertToSql(context, e.Arguments[1], false); + + ISqlExpression a3 = null; + + if (e.Arguments.Count == 3) + a3 = ConvertToSql(context, e.Arguments[2], false); + + return new SqlQuery.Predicate.Like(a1, false, a2, a3); + } + + static string EscapeLikeText(string text) + { + if (text.IndexOfAny(new[] { '%', '_' }) < 0) + return text; + + var builder = new StringBuilder(text.Length); + + foreach (var ch in text) + { + switch (ch) + { + case '%': + case '_': + case '~': + builder.Append('~'); + break; + } + + builder.Append(ch); + } + + return builder.ToString(); + } + + static Converter GetLikeEscaper(string start, string end) + { + return value => value == null? null: start + EscapeLikeText(value.ToString()) + end; + } + + #endregion + + #region MakeIsPredicate + + internal ISqlPredicate MakeIsPredicate(TableBuilder.TableContext table, Type typeOperand) + { + if (typeOperand == table.ObjectType && !table.InheritanceMapping.Any(m => m.Type == typeOperand)) + return Convert(table, new SqlQuery.Predicate.Expr(new SqlValue(true))); + + return MakeIsPredicate( + table, table.InheritanceMapping, table.InheritanceDiscriminators, typeOperand, + name => table.SqlTable.Fields.Values.First(f => f.Name == name)); + } + + internal ISqlPredicate MakeIsPredicate( + IBuildContext context, + List inheritanceMapping, + List inheritanceDiscriminators, + Type toType, + Func getSql) + { + var mapping = inheritanceMapping + .Select((m,i) => new { m, i }) + .Where ( m => m.m.Type == toType && !m.m.IsDefault) + .ToList(); + + switch (mapping.Count) + { + case 0 : + { + var cond = new SqlQuery.SearchCondition(); + + foreach (var m in inheritanceMapping.Select((m,i) => new { m, i }).Where(m => !m.m.IsDefault)) + { + cond.Conditions.Add( + new SqlQuery.Condition( + false, + Convert(context, + new SqlQuery.Predicate.ExprExpr( + getSql(inheritanceDiscriminators[m.i]), + SqlQuery.Predicate.Operator.NotEqual, + new SqlValue(m.m.Code))))); + } + + return cond; + } + + case 1 : + return Convert(context, + new SqlQuery.Predicate.ExprExpr( + getSql(inheritanceDiscriminators[mapping[0].i]), + SqlQuery.Predicate.Operator.Equal, + new SqlValue(mapping[0].m.Code))); + + default: + { + var cond = new SqlQuery.SearchCondition(); + + foreach (var m in mapping) + { + cond.Conditions.Add( + new SqlQuery.Condition( + false, + Convert(context, + new SqlQuery.Predicate.ExprExpr( + getSql(inheritanceDiscriminators[m.i]), + SqlQuery.Predicate.Operator.Equal, + new SqlValue(m.m.Code))), + true)); + } + + return cond; + } + } + } + + ISqlPredicate MakeIsPredicate(IBuildContext context, TypeBinaryExpression expression) + { + var typeOperand = expression.TypeOperand; + var table = new TableBuilder.TableContext(this, new BuildInfo((IBuildContext)null, Expression.Constant(null), new SqlQuery()), typeOperand); + + if (typeOperand == table.ObjectType && !table.InheritanceMapping.Any(m => m.Type == typeOperand)) + return Convert(table, new SqlQuery.Predicate.Expr(new SqlValue(true))); + + var mapping = table.InheritanceMapping.Select((m,i) => new { m, i }).Where(m => m.m.Type == typeOperand && !m.m.IsDefault).ToList(); + var isEqual = true; + + if (mapping.Count == 0) + { + mapping = table.InheritanceMapping.Select((m,i) => new { m, i }).Where(m => !m.m.IsDefault).ToList(); + isEqual = false; + } + + Expression expr = null; + + foreach (var m in mapping) + { + var field = table.SqlTable.Fields[table.InheritanceDiscriminators[m.i]]; + var ttype = field.MemberMapper.MemberAccessor.TypeAccessor.OriginalType; + var obj = expression.Expression; + + if (obj.Type != ttype) + obj = Expression.Convert(expression.Expression, ttype); + + var left = Expression.PropertyOrField(obj, field.Name); + var code = m.m.Code; + + if (code == null) + code = TypeHelper.GetDefaultValue(left.Type); + else if (left.Type != code.GetType()) + code = MappingSchema.ConvertChangeType(code, left.Type); + + Expression right = Expression.Constant(code, left.Type); + + var e = isEqual ? Expression.Equal(left, right) : Expression.NotEqual(left, right); + + expr = expr != null ? Expression.AndAlso(expr, e) : e; + } + + return ConvertPredicate(context, expr); + } + + #endregion + + #endregion + + #region Search Condition Builder + + void BuildSearchCondition(IBuildContext context, Expression expression, List conditions) + { + switch (expression.NodeType) + { + case ExpressionType.And : + case ExpressionType.AndAlso : + { + var e = (BinaryExpression)expression; + + BuildSearchCondition(context, e.Left, conditions); + BuildSearchCondition(context, e.Right, conditions); + + break; + } + + case ExpressionType.Or : + case ExpressionType.OrElse : + { + var e = (BinaryExpression)expression; + var orCondition = new SqlQuery.SearchCondition(); + + BuildSearchCondition(context, e.Left, orCondition.Conditions); + orCondition.Conditions[orCondition.Conditions.Count - 1].IsOr = true; + BuildSearchCondition(context, e.Right, orCondition.Conditions); + + conditions.Add(new SqlQuery.Condition(false, orCondition)); + + break; + } + + case ExpressionType.Not : + { + var e = expression as UnaryExpression; + var notCondition = new SqlQuery.SearchCondition(); + + BuildSearchCondition(context, e.Operand, notCondition.Conditions); + + if (notCondition.Conditions.Count == 1 && notCondition.Conditions[0].Predicate is SqlQuery.Predicate.NotExpr) + { + var p = notCondition.Conditions[0].Predicate as SqlQuery.Predicate.NotExpr; + p.IsNot = !p.IsNot; + conditions.Add(notCondition.Conditions[0]); + } + else + conditions.Add(new SqlQuery.Condition(true, notCondition)); + + break; + } + + default : + var predicate = ConvertPredicate(context, expression); + + if (predicate is SqlQuery.Predicate.Expr) + { + var expr = ((SqlQuery.Predicate.Expr)predicate).Expr1; + + if (expr.ElementType == QueryElementType.SearchCondition) + { + var sc = (SqlQuery.SearchCondition)expr; + + if (sc.Conditions.Count == 1) + { + conditions.Add(sc.Conditions[0]); + break; + } + } + } + + conditions.Add(new SqlQuery.Condition(false, predicate)); + + break; + } + } + + #endregion + + #region CanBeTranslatedToSql + + bool CanBeTranslatedToSql(IBuildContext context, Expression expr, bool canBeCompiled) + { + List ignoredMembers = null; + + return null == expr.Find(pi => + { + if (ignoredMembers != null) + { + if (pi != ignoredMembers[ignoredMembers.Count - 1]) + throw new InvalidOperationException(); + + if (ignoredMembers.Count == 1) + ignoredMembers = null; + else + ignoredMembers.RemoveAt(ignoredMembers.Count - 1); + + return false; + } + + switch (pi.NodeType) + { + case ExpressionType.MemberAccess : + { + var ma = (MemberExpression)pi; + var attr = GetFunctionAttribute(ma.Member); + + if (attr == null && !TypeHelper.IsNullableValueMember(ma.Member)) + { + if (canBeCompiled) + { + var ctx = GetContext(context, pi); + + if (ctx == null) + return !CanBeCompiled(pi); + + if (ctx.IsExpression(pi, 0, RequestFor.Object).Result) + return !CanBeCompiled(pi); + + ignoredMembers = ma.Expression.GetMembers(); + } + } + + break; + } + + case ExpressionType.Parameter : + { + var ctx = GetContext(context, pi); + + if (ctx == null) + if (canBeCompiled) + return !CanBeCompiled(pi); + + break; + } + + case ExpressionType.Call : + { + var e = (MethodCallExpression)pi; + + if (e.Method.DeclaringType != typeof(Enumerable)) + { + var attr = GetFunctionAttribute(e.Method); + + if (attr == null && canBeCompiled) + return !CanBeCompiled(pi); + } + + break; + } + + case ExpressionType.TypeIs : return canBeCompiled; + case ExpressionType.TypeAs : + case ExpressionType.New : return true; + + case ExpressionType.NotEqual : + case ExpressionType.Equal : + { + var e = (BinaryExpression)pi; + + Expression obj = null; + + if (e.Left.NodeType == ExpressionType.Constant && ((ConstantExpression)e.Left).Value == null) + obj = e.Right; + else if (e.Right.NodeType == ExpressionType.Constant && ((ConstantExpression)e.Right).Value == null) + obj = e.Left; + + if (obj != null) + { + var ctx = GetContext(context, obj); + + if (ctx != null) + { + if (ctx.IsExpression(obj, 0, RequestFor.Table). Result || + ctx.IsExpression(obj, 0, RequestFor.Association).Result) + { + ignoredMembers = obj.GetMembers(); + } + } + } + + break; + } + } + + return false; + }); + } + + #endregion + + #region Helpers + + public IBuildContext GetContext([JetBrains.Annotations.NotNull] IBuildContext current, Expression expression) + { + var root = expression.GetRootObject(); + + for (; current != null; current = current.Parent) + if (current.IsExpression(root, 0, RequestFor.Root).Result) + return current; + + return null; + } + + SqlFunctionAttribute GetFunctionAttribute(ICustomAttributeProvider member) + { + var attrs = member.GetCustomAttributes(typeof(SqlFunctionAttribute), true); + + if (attrs.Length == 0) + return null; + + SqlFunctionAttribute attr = null; + + foreach (SqlFunctionAttribute a in attrs) + { + if (a.SqlProvider == SqlProvider.Name) + { + attr = a; + break; + } + + if (a.SqlProvider == null) + attr = a; + } + + return attr; + } + + internal TableFunctionAttribute GetTableFunctionAttribute(ICustomAttributeProvider member) + { + var attrs = member.GetCustomAttributes(typeof(TableFunctionAttribute), true); + + if (attrs.Length == 0) + return null; + + TableFunctionAttribute attr = null; + + foreach (TableFunctionAttribute a in attrs) + { + if (a.SqlProvider == SqlProvider.Name) + { + attr = a; + break; + } + + if (a.SqlProvider == null) + attr = a; + } + + return attr; + } + + public ISqlExpression Convert(IBuildContext context, ISqlExpression expr) + { + SqlProvider.SqlQuery = context.SqlQuery; + return SqlProvider.ConvertExpression(expr); + } + + public ISqlPredicate Convert(IBuildContext context, ISqlPredicate predicate) + { + SqlProvider.SqlQuery = context.SqlQuery; + return SqlProvider.ConvertPredicate(predicate); + } + + public ISqlExpression ConvertTimeSpanMember(IBuildContext context, MemberExpression expression) + { + if (expression.Member.DeclaringType == typeof(TimeSpan)) + { + switch (expression.Expression.NodeType) + { + case ExpressionType.Subtract : + case ExpressionType.SubtractChecked: + + Sql.DateParts datePart; + + switch (expression.Member.Name) + { + case "TotalMilliseconds" : datePart = Sql.DateParts.Millisecond; break; + case "TotalSeconds" : datePart = Sql.DateParts.Second; break; + case "TotalMinutes" : datePart = Sql.DateParts.Minute; break; + case "TotalHours" : datePart = Sql.DateParts.Hour; break; + case "TotalDays" : datePart = Sql.DateParts.Day; break; + default : return null; + } + + var e = (BinaryExpression)expression.Expression; + + return new SqlFunction( + typeof(int), + "DateDiff", + new SqlValue(datePart), + ConvertToSql(context, e.Right, false), + ConvertToSql(context, e.Left, false)); + } + } + + return null; + } + + internal ISqlExpression ConvertSearchCondition(IBuildContext context, ISqlExpression sqlExpression) + { + if (sqlExpression is SqlQuery.SearchCondition) + { + if (sqlExpression.CanBeNull()) + { + var notExpr = new SqlQuery.SearchCondition + { + Conditions = { new SqlQuery.Condition(true, new SqlQuery.Predicate.Expr(sqlExpression, sqlExpression.Precedence)) } + }; + + return Convert(context, new SqlFunction(sqlExpression.SystemType, "CASE", sqlExpression, new SqlValue(1), notExpr, new SqlValue(0), new SqlValue(null))); + } + + return Convert(context, new SqlFunction(sqlExpression.SystemType, "CASE", sqlExpression, new SqlValue(1), new SqlValue(0))); + } + + return sqlExpression; + } + + public bool ProcessProjection(Dictionary members, Expression expression) + { + switch (expression.NodeType) + { + // new { ... } + // + case ExpressionType.New : + { + var expr = (NewExpression)expression; + +// ReSharper disable ConditionIsAlwaysTrueOrFalse +// ReSharper disable HeuristicUnreachableCode + if (expr.Members == null) + return false; +// ReSharper restore HeuristicUnreachableCode +// ReSharper restore ConditionIsAlwaysTrueOrFalse + + for (var i = 0; i < expr.Members.Count; i++) + { + var member = expr.Members[i]; + + members.Add(member, expr.Arguments[i]); + + if (member is MethodInfo) + members.Add(TypeHelper.GetPropertyByMethod((MethodInfo)member), expr.Arguments[i]); + } + + return true; + } + + // new MyObject { ... } + // + case ExpressionType.MemberInit : + { + var expr = (MemberInitExpression)expression; + var dic = TypeAccessor.GetAccessor(expr.Type) + .Select((m,i) => new { m, i }) + .ToDictionary(_ => _.m.MemberInfo.Name, _ => _.i); + + foreach (var binding in expr.Bindings.Cast().OrderBy(b => dic.ContainsKey(b.Member.Name) ? dic[b.Member.Name] : 1000000)) + { + members.Add(binding.Member, binding.Expression); + + if (binding.Member is MethodInfo) + members.Add(TypeHelper.GetPropertyByMethod((MethodInfo)binding.Member), binding.Expression); + } + + return true; + } + + // .Select(p => everything else) + // + default : + return false; + } + } + + public void ReplaceParent(IBuildContext oldParent, IBuildContext newParent) + { + foreach (var context in Contexts) + if (context != newParent) + if (context.Parent == oldParent) + context.Parent = newParent; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/ExpressionBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/ExpressionBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1331 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Common; + using Data.Sql; + using Data.Sql.SqlProvider; + using Mapping; + using Reflection; + + public partial class ExpressionBuilder + { + #region Sequence + + static readonly object _sync = new object(); + + static List _sequenceBuilders = new List + { + new TableBuilder (), + new SelectBuilder (), + new SelectManyBuilder (), + new WhereBuilder (), + new OrderByBuilder (), + new GroupByBuilder (), + new JoinBuilder (), + new TakeSkipBuilder (), + new DefaultIfEmptyBuilder(), + new DistinctBuilder (), + new FirstSingleBuilder (), + new AggregationBuilder (), + new ScalarSelectBuilder (), + new CountBuilder (), + new PassThroughBuilder (), + new TableAttributeBuilder(), + new InsertBuilder (), + new InsertBuilder.Into (), + new InsertBuilder.Value (), + new InsertOrUpdateBuilder(), + new UpdateBuilder (), + new UpdateBuilder.Set (), + new DeleteBuilder (), + new ContainsBuilder (), + new AllAnyBuilder (), + new ConcatUnionBuilder (), + new IntersectBuilder (), + new CastBuilder (), + new OfTypeBuilder (), + new AsUpdatableBuilder (), + }; + + public static void AddBuilder(ISequenceBuilder builder) + { + _sequenceBuilders.Add(builder); + } + + #endregion + + #region Init + + readonly Query _query; + readonly List _builders = _sequenceBuilders; + private bool _reorder; + readonly Dictionary _expressionAccessors; + private HashSet _subQueryExpressions; + + readonly public List CurrentSqlParameters = new List(); + +#if FW4 || SILVERLIGHT + + readonly public List BlockVariables = new List(); + readonly public List BlockExpressions = new List(); + public bool IsBlockDisable; + +#else + public bool IsBlockDisable = true; +#endif + + readonly HashSet _visitedExpressions; + + public ExpressionBuilder( + Query query, + IDataContextInfo dataContext, + Expression expression, + ParameterExpression[] compiledParameters) + { + _query = query; + _expressionAccessors = expression.GetExpressionAccessors(ExpressionParam); + + CompiledParameters = compiledParameters; + DataContextInfo = dataContext; + OriginalExpression = expression; + + _visitedExpressions = new HashSet(); + Expression = ConvertExpressionTree(expression); + _visitedExpressions = null; + } + + #endregion + + #region Public Members + + public readonly IDataContextInfo DataContextInfo; + public readonly Expression OriginalExpression; + public readonly Expression Expression; + public readonly ParameterExpression[] CompiledParameters; + public readonly List Contexts = new List(); + + private ISqlProvider _sqlProvider; + public ISqlProvider SqlProvider + { + get { return _sqlProvider ?? (_sqlProvider = DataContextInfo.CreateSqlProvider()); } + } + + public static readonly ParameterExpression ContextParam = Expression.Parameter(typeof(QueryContext), "context"); + public static readonly ParameterExpression DataContextParam = Expression.Parameter(typeof(IDataContext), "dctx"); + public static readonly ParameterExpression DataReaderParam = Expression.Parameter(typeof(IDataReader), "rd"); + public static readonly ParameterExpression ParametersParam = Expression.Parameter(typeof(object[]), "ps"); + public static readonly ParameterExpression ExpressionParam = Expression.Parameter(typeof(Expression), "expr"); + + public MappingSchema MappingSchema + { + get { return DataContextInfo.MappingSchema; } + } + + #endregion + + #region Builder SQL + + internal Query Build() + { + var sequence = BuildSequence(new BuildInfo((IBuildContext)null, Expression, new SqlQuery())); + + if (_reorder) + lock (_sync) + { + _reorder = false; + _sequenceBuilders = _sequenceBuilders.OrderByDescending(_ => _.BuildCounter).ToList(); + } + + _query.Init(sequence, CurrentSqlParameters); + + var param = Expression.Parameter(typeof(Query), "info"); + + sequence.BuildQuery((Query)_query, param); + + return (Query)_query; + } + + [JetBrains.Annotations.NotNull] + public IBuildContext BuildSequence(BuildInfo buildInfo) + { + buildInfo.Expression = buildInfo.Expression.Unwrap(); + + var n = _builders[0].BuildCounter; + + foreach (var builder in _builders) + { + if (builder.CanBuild(this, buildInfo)) + { + var sequence = builder.BuildSequence(this, buildInfo); + + lock (builder) + builder.BuildCounter++; + + _reorder = _reorder || n < builder.BuildCounter; + + return sequence; + } + + n = builder.BuildCounter; + } + + throw new LinqException("Sequence '{0}' cannot be converted to SQL.", buildInfo.Expression); + } + + public SequenceConvertInfo ConvertSequence(BuildInfo buildInfo, ParameterExpression param) + { + buildInfo.Expression = buildInfo.Expression.Unwrap(); + + foreach (var builder in _builders) + if (builder.CanBuild(this, buildInfo)) + return builder.Convert(this, buildInfo, param); + + throw new LinqException("Sequence '{0}' cannot be converted to SQL.", buildInfo.Expression); + } + + public bool IsSequence(BuildInfo buildInfo) + { + buildInfo.Expression = buildInfo.Expression.Unwrap(); + + foreach (var builder in _builders) + if (builder.CanBuild(this, buildInfo)) + return builder.IsSequence(this, buildInfo); + + return false; + } + + #endregion + + #region ConvertExpression + + public ParameterExpression SequenceParameter; + + Expression ConvertExpressionTree(Expression expression) + { + var expr = ConvertParameters(expression); + + expr = ExposeExpression (expr); + expr = OptimizeExpression(expr); + + var paramType = expr.Type; + var isQueryable = false; + + if (expression.NodeType == ExpressionType.Call) + { + var call = (MethodCallExpression)expression; + + if (call.IsQueryable() && call.Object == null && call.Arguments.Count > 0 && call.Type.IsGenericType) + { + var type = call.Type.GetGenericTypeDefinition(); + + if (type == typeof(IQueryable<>) || type == typeof(IEnumerable<>)) + { + var arg = call.Type.GetGenericArguments(); + + if (arg.Length == 1) + { + paramType = arg[0]; + isQueryable = true; + } + } + } + } + + SequenceParameter = Expression.Parameter(paramType, "cp"); + + var sequence = ConvertSequence(new BuildInfo((IBuildContext)null, expr, new SqlQuery()), SequenceParameter); + + if (sequence != null) + { + if (sequence.Expression.Type != expr.Type) + { + if (isQueryable) + { + var p = sequence.ExpressionsToReplace.SingleOrDefault(s => s.Path.NodeType == ExpressionType.Parameter); + + return Expression.Call( + ((MethodCallExpression)expr).Method.DeclaringType, + "Select", + new[] { p.Path.Type, paramType }, + sequence.Expression, + Expression.Lambda(p.Expr, (ParameterExpression)p.Path)); + } + + throw new InvalidOperationException(); + } + + return sequence.Expression; + } + + return expr; + } + + #region ConvertParameters + + Expression ConvertParameters(Expression expression) + { + return expression.Convert(expr => + { + switch (expr.NodeType) + { + case ExpressionType.Parameter: + if (CompiledParameters != null) + { + var idx = Array.IndexOf(CompiledParameters, (ParameterExpression)expr); + + if (idx > 0) + return + Expression.Convert( + Expression.ArrayIndex( + ParametersParam, + Expression.Constant(Array.IndexOf(CompiledParameters, (ParameterExpression)expr))), + expr.Type); + } + + break; + } + + return expr; + }); + } + + #endregion + + #region ExposeExpression + + Expression ExposeExpression(Expression expression) + { + return expression.Convert(expr => + { + switch (expr.NodeType) + { + case ExpressionType.MemberAccess: + { + var me = (MemberExpression)expr; + var l = ConvertMethodExpression(me.Member); + + if (l != null) + { + var body = l.Body.Unwrap(); + var ex = body.Convert2(wpi => new ExpressionHelper.ConvertInfo(wpi.NodeType == ExpressionType.Parameter ? me.Expression : wpi)); + + if (ex.Type != expr.Type) + ex = new ChangeTypeExpression(ex, expr.Type); + + return ExposeExpression(ex); + } + + break; + } + + case ExpressionType.Constant : + { + var c = (ConstantExpression)expr; + + // Fix Mono behaviour. + // + //if (c.Value is IExpressionQuery) + // return ((IQueryable)c.Value).Expression; + + if (c.Value is IQueryable && !(c.Value is ITable)) + { + var e = ((IQueryable)c.Value).Expression; + + if (!_visitedExpressions.Contains(e)) + { + _visitedExpressions.Add(e); + return ExposeExpression(e); + } + } + + break; + } + } + + return expr; + }); + } + + #endregion + + #region OptimizeExpression + + private MethodInfo[] _enumerableMethods; + public MethodInfo[] EnumerableMethods + { + get { return _enumerableMethods ?? (_enumerableMethods = typeof(Enumerable).GetMethods()); } + } + + private MethodInfo[] _queryableMethods; + public MethodInfo[] QueryableMethods + { + get { return _queryableMethods ?? (_queryableMethods = typeof(Queryable).GetMethods()); } + } + + readonly Dictionary _optimizedExpressions = new Dictionary(); + + Expression OptimizeExpression(Expression expression) + { + Expression expr; + + if (_optimizedExpressions.TryGetValue(expression, out expr)) + return expr; + + _optimizedExpressions[expression] = expr = expression.Convert(OptimizeExpressionImpl); + + return expr; + } + + Expression OptimizeExpressionImpl(Expression expr) + { + switch (expr.NodeType) + { + case ExpressionType.MemberAccess: + { + var me = (MemberExpression)expr; + + // Replace Count with Count() + // + if (me.Member.Name == "Count") + { + var isList = typeof(ICollection).IsAssignableFrom(me.Member.DeclaringType); + + if (!isList) + isList = me.Member.DeclaringType.GetInterfaces() + .Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IList<>)); + + if (isList) + { + var mi = EnumerableMethods + .First(m => m.Name == "Count" && m.GetParameters().Length == 1) + .MakeGenericMethod(TypeHelper.GetElementType(me.Expression.Type)); + + return Expression.Call(null, mi, me.Expression); + } + } + + if (CompiledParameters == null && TypeHelper.IsSameOrParent(typeof(IQueryable), expr.Type)) + { + var ex = ConvertIQueriable(expr); + + if (ex != expr) + return ConvertExpressionTree(ex); + } + + return ConvertSubquery(expr); + } + + case ExpressionType.Call : + { + var call = (MethodCallExpression)expr; + + if (call.IsQueryable()) + { + switch (call.Method.Name) + { + case "Where" : return ConvertWhere (call); + case "GroupBy" : return ConvertGroupBy (call); + case "SelectMany" : return ConvertSelectMany(call); + case "Select" : return ConvertSelect (call); + case "LongCount" : + case "Count" : + case "Single" : + case "SingleOrDefault" : + case "First" : + case "FirstOrDefault" : return ConvertPredicate (call); + case "Min" : + case "Max" : return ConvertSelector (call, true); + case "Sum" : + case "Average" : return ConvertSelector (call, false); + case "ElementAt" : + case "ElementAtOrDefault" : return ConvertElementAt (call); + } + } + else + { + var l = ConvertMethodExpression(call.Method); + + if (l != null) + return OptimizeExpression(ConvertMethod(call, l)); + + if (CompiledParameters == null && TypeHelper.IsSameOrParent(typeof(IQueryable), expr.Type)) + { + var attr = GetTableFunctionAttribute(call.Method); + + if (attr == null) + { + var ex = ConvertIQueriable(expr); + + if (ex != expr) + return ConvertExpressionTree(ex); + } + } + } + + return ConvertSubquery(expr); + } + } + + return expr; + } + + LambdaExpression ConvertMethodExpression(MemberInfo mi) + { + var attrs = mi.GetCustomAttributes(typeof(MethodExpressionAttribute), true); + + if (attrs.Length == 0) + return null; + + MethodExpressionAttribute attr = null; + + foreach (MethodExpressionAttribute a in attrs) + { + if (a.SqlProvider == SqlProvider.Name) + { + attr = a; + break; + } + + if (a.SqlProvider == null) + attr = a; + } + + if (attr != null) + { + Expression expr; + + if (mi is MethodInfo && ((MethodInfo)mi).IsGenericMethod) + { + var method = (MethodInfo)mi; + var args = method.GetGenericArguments(); + var names = args.Select(t => t.Name).ToArray(); + var name = string.Format(attr.MethodName, names); + + if (name != attr.MethodName) + expr = Expression.Call(mi.DeclaringType, name, Array.Empty); + else + expr = Expression.Call(mi.DeclaringType, name, args); + } + else + { + expr = Expression.Call(mi.DeclaringType, attr.MethodName, Array.Empty); + } + + var call = Expression.Lambda>(Expression.Convert(expr, typeof(LambdaExpression))); + + return call.Compile()(); + } + + return null; + } + + Expression ConvertSubquery(Expression expr) + { + var ex = expr; + + while (ex != null) + { + switch (ex.NodeType) + { + default : return expr; + case ExpressionType.MemberAccess : ex = ((MemberExpression)ex).Expression; break; + case ExpressionType.Call : + { + var call = (MethodCallExpression)ex; + + if (call.Object == null) + { + if (call.IsQueryable()) switch (call.Method.Name) + { + case "Single" : + case "SingleOrDefault" : + case "First" : + case "FirstOrDefault" : + return ConvertSingleOrFirst(expr, call); + } + + return expr; + } + + ex = call.Object; + + break; + } + } + } + + return expr; + } + + Expression ConvertSingleOrFirst(Expression expr, MethodCallExpression call) + { + var param = Expression.Parameter(call.Type, "p"); + var selector = expr.Convert(e => e == call ? param : e); + var method = GetQueriableMethodInfo(call, (m, _) => m.Name == call.Method.Name && m.GetParameters().Length == 1); + var select = call.Method.DeclaringType == typeof(Enumerable) ? + EnumerableMethods + .Where(m => m.Name == "Select" && m.GetParameters().Length == 2) + .First(m => m.GetParameters()[1].ParameterType.GetGenericArguments().Length == 2) : + QueryableMethods + .Where(m => m.Name == "Select" && m.GetParameters().Length == 2) + .First(m => m.GetParameters()[1].ParameterType.GetGenericArguments()[0].GetGenericArguments().Length == 2); + + call = (MethodCallExpression)OptimizeExpression(call); + select = select.MakeGenericMethod(call.Type, expr.Type); + method = method.MakeGenericMethod(expr.Type); + + return Expression.Call(null, method, + Expression.Call(null, select, + call.Arguments[0], + Expression.Lambda(selector, param))); + } + + #endregion + + #region ConvertWhere + + Expression ConvertWhere(MethodCallExpression method) + { + var sequence = OptimizeExpression(method.Arguments[0]); + var predicate = OptimizeExpression(method.Arguments[1]); + var lambda = (LambdaExpression)predicate.Unwrap(); + var lparam = lambda.Parameters[0]; + var lbody = lambda.Body; + + if (lambda.Parameters.Count > 1) + return method; + + var exprs = new List(); + + lbody.Visit(ex => + { + if (ex.NodeType == ExpressionType.Call) + { + var call = (MethodCallExpression)ex; + + if (call.Arguments.Count > 0) + { + var arg = call.Arguments[0]; + + if (call.IsQueryable(AggregationBuilder.MethodNames)) + { + while (arg.NodeType == ExpressionType.Call && ((MethodCallExpression) arg).Method.Name == "Select") + arg = ((MethodCallExpression) arg).Arguments[0]; + + if (arg.NodeType == ExpressionType.Call) + exprs.Add(ex); + } + else if (call.IsQueryable(CountBuilder.MethodNames)) + { + //while (arg.NodeType == ExpressionType.Call && ((MethodCallExpression) arg).Method.Name == "Select") + // arg = ((MethodCallExpression) arg).Arguments[0]; + + if (arg.NodeType == ExpressionType.Call) + exprs.Add(ex); + } + } + } + }); + + Expression expr = null; + + if (exprs.Count > 0) + { + expr = lparam; + + foreach (var ex in exprs) + { + var type = typeof(ExpressionHoder<,>).MakeGenericType(expr.Type, ex.Type); + var fields = type.GetFields(); + + expr = Expression.MemberInit( + Expression.New(type), + Expression.Bind(fields[0], expr), + Expression.Bind(fields[1], ex)); + } + + var dic = new Dictionary(); + var parm = Expression.Parameter(expr.Type, lparam.Name); + + for (var i = 0; i < exprs.Count; i++) + { + Expression ex = parm; + + for (var j = i; j < exprs.Count - 1; j++) + ex = Expression.PropertyOrField(ex, "p"); + + ex = Expression.PropertyOrField(ex, "ex"); + + dic.Add(exprs[i], ex); + + if (_subQueryExpressions == null) + _subQueryExpressions = new HashSet(); + _subQueryExpressions.Add(ex); + } + + var newBody = lbody.Convert(ex => + { + Expression e; + return dic.TryGetValue(ex, out e) ? e : ex; + }); + + var nparm = exprs.Aggregate(parm, (c,t) => Expression.PropertyOrField(c, "p")); + + newBody = newBody.Convert(ex => ex == lparam ? nparm : ex); + + predicate = Expression.Lambda(newBody, parm); + + var methodInfo = GetMethodInfo(method, "Select"); + + methodInfo = methodInfo.MakeGenericMethod(lparam.Type, expr.Type); + sequence = Expression.Call(methodInfo, sequence, Expression.Lambda(expr, lparam)); + } + + if (sequence != method.Arguments[0] || predicate != method.Arguments[1]) + { + var methodInfo = method.Method.GetGenericMethodDefinition(); + var genericType = sequence.Type.GetGenericArguments()[0]; + var newMethod = methodInfo.MakeGenericMethod(genericType); + + method = Expression.Call(newMethod, sequence, predicate); + + if (exprs.Count > 0) + { + var parameter = Expression.Parameter(expr.Type, lparam.Name); + + methodInfo = GetMethodInfo(method, "Select"); + methodInfo = methodInfo.MakeGenericMethod(expr.Type, lparam.Type); + method = Expression.Call(methodInfo, method, + Expression.Lambda( + exprs.Aggregate((Expression)parameter, (current,_) => Expression.PropertyOrField(current, "p")), + parameter)); + } + } + + return method; + } + + #endregion + + #region ConvertGroupBy + + public class GroupSubQuery + { + public TKey Key; + public TElement Element; + } + + interface IGroupByHelper + { + void Set(bool wrapInSubQuery, Expression sourceExpression, LambdaExpression keySelector, LambdaExpression elementSelector, LambdaExpression resultSelector); + + Expression AddElementSelectorQ (); + Expression AddElementSelectorE (); + Expression AddResultQ (); + Expression AddResultE (); + Expression WrapInSubQueryQ (); + Expression WrapInSubQueryE (); + Expression WrapInSubQueryResultQ(); + Expression WrapInSubQueryResultE(); + } + + class GroupByHelper : IGroupByHelper + { + bool _wrapInSubQuery; + Expression _sourceExpression; + LambdaExpression _keySelector; + LambdaExpression _elementSelector; + LambdaExpression _resultSelector; + + public void Set( + bool wrapInSubQuery, + Expression sourceExpression, + LambdaExpression keySelector, + LambdaExpression elementSelector, + LambdaExpression resultSelector) + { + _wrapInSubQuery = wrapInSubQuery; + _sourceExpression = sourceExpression; + _keySelector = keySelector; + _elementSelector = elementSelector; + _resultSelector = resultSelector; + } + + public Expression AddElementSelectorQ() + { + Expression,TKey,TElement,TResult,IQueryable>>> func = (source,key,e,r) => source + .GroupBy(keyParam => key, _ => _) + ; + + var body = func.Body.Unwrap(); + var keyArg = GetLambda(body, 1).Parameters[0]; // .GroupBy(keyParam + + return Convert(func, keyArg, null, null); + } + + public Expression AddElementSelectorE() + { + Expression,TKey,TElement,TResult,IEnumerable>>> func = (source,key,e,r) => source + .GroupBy(keyParam => key, _ => _) + ; + + var body = func.Body.Unwrap(); + var keyArg = GetLambda(body, 1).Parameters[0]; // .GroupBy(keyParam + + return Convert(func, keyArg, null, null); + } + + public Expression AddResultQ() + { + Expression,TKey,TElement,TResult,IQueryable>> func = (source,key,e,r) => source + .GroupBy(keyParam => key, elemParam => e) + .Select (resParam => r) + ; + + var body = func.Body.Unwrap(); + var keyArg = GetLambda(body, 0, 1).Parameters[0]; // .GroupBy(keyParam + var elemArg = GetLambda(body, 0, 2).Parameters[0]; // .GroupBy(..., elemParam + var resArg = GetLambda(body, 1). Parameters[0]; // .Select (resParam + + return Convert(func, keyArg, elemArg, resArg); + } + + public Expression AddResultE() + { + Expression,TKey,TElement,TResult,IEnumerable>> func = (source,key,e,r) => source + .GroupBy(keyParam => key, elemParam => e) + .Select (resParam => r) + ; + + var body = func.Body.Unwrap(); + var keyArg = GetLambda(body, 0, 1).Parameters[0]; // .GroupBy(keyParam + var elemArg = GetLambda(body, 0, 2).Parameters[0]; // .GroupBy(..., elemParam + var resArg = GetLambda(body, 1). Parameters[0]; // .Select (resParam + + return Convert(func, keyArg, elemArg, resArg); + } + + public Expression WrapInSubQueryQ() + { + Expression,TKey,TElement,TResult,IQueryable>>> func = (source,key,e,r) => source + .Select(selectParam => new GroupSubQuery + { + Key = key, + Element = selectParam + }) + .GroupBy(_ => _.Key, elemParam => e) + ; + + var body = func.Body.Unwrap(); + var keyArg = GetLambda(body, 0, 1).Parameters[0]; // .Select (selectParam + var elemArg = GetLambda(body, 2). Parameters[0]; // .GroupBy(..., elemParam + + return Convert(func, keyArg, elemArg, null); + } + + public Expression WrapInSubQueryE() + { + Expression,TKey,TElement,TResult,IEnumerable>>> func = (source,key,e,r) => source + .Select(selectParam => new GroupSubQuery + { + Key = key, + Element = selectParam + }) + .GroupBy(_ => _.Key, elemParam => e) + ; + + var body = func.Body.Unwrap(); + var keyArg = GetLambda(body, 0, 1).Parameters[0]; // .Select (selectParam + var elemArg = GetLambda(body, 2). Parameters[0]; // .GroupBy(..., elemParam + + return Convert(func, keyArg, elemArg, null); + } + + public Expression WrapInSubQueryResultQ() + { + Expression,TKey,TElement,TResult,IQueryable>> func = (source,key,e,r) => source + .Select(selectParam => new GroupSubQuery + { + Key = key, + Element = selectParam + }) + .GroupBy(_ => _.Key, elemParam => e) + .Select (resParam => r) + ; + + var body = func.Body.Unwrap(); + var keyArg = GetLambda(body, 0, 0, 1).Parameters[0]; // .Select (selectParam + var elemArg = GetLambda(body, 0, 2). Parameters[0]; // .GroupBy(..., elemParam + var resArg = GetLambda(body, 1). Parameters[0]; // .Select (resParam + + return Convert(func, keyArg, elemArg, resArg); + } + + public Expression WrapInSubQueryResultE() + { + Expression,TKey,TElement,TResult,IEnumerable>> func = (source,key,e,r) => source + .Select(selectParam => new GroupSubQuery + { + Key = key, + Element = selectParam + }) + .GroupBy(_ => _.Key, elemParam => e) + .Select (resParam => r) + ; + + var body = func.Body.Unwrap(); + var keyArg = GetLambda(body, 0, 0, 1).Parameters[0]; // .Select (selectParam + var elemArg = GetLambda(body, 0, 2). Parameters[0]; // .GroupBy(..., elemParam + var resArg = GetLambda(body, 1). Parameters[0]; // .Select (resParam + + return Convert(func, keyArg, elemArg, resArg); + } + + Expression Convert( + LambdaExpression func, + ParameterExpression keyArg, + ParameterExpression elemArg, + ParameterExpression resArg) + { + var body = func.Body.Unwrap(); + var expr = body.Convert(ex => + { + if (ex == func.Parameters[0]) + return _sourceExpression; + + if (ex == func.Parameters[1]) + return _keySelector.Body.Convert(e => e == _keySelector.Parameters[0] ? keyArg : e); + + if (ex == func.Parameters[2]) + { + Expression obj = elemArg; + + if (_wrapInSubQuery) + obj = Expression.PropertyOrField(elemArg, "Element"); + + if (_elementSelector == null) + return obj; + + return _elementSelector.Body.Convert(e => e == _elementSelector.Parameters[0] ? obj : e); + } + + if (ex == func.Parameters[3]) + return _resultSelector.Body.Convert(e => + { + if (e == _resultSelector.Parameters[0]) + return Expression.PropertyOrField(resArg, "Key"); + + if (e == _resultSelector.Parameters[1]) + return resArg; + + return e; + }); + + return ex; + }); + + return expr; + } + } + + static LambdaExpression GetLambda(Expression expression, params int[] n) + { + foreach (var i in n) + expression = ((MethodCallExpression)expression).Arguments[i].Unwrap(); + return (LambdaExpression)expression; + } + + Expression ConvertGroupBy(MethodCallExpression method) + { + if (method.Arguments[method.Arguments.Count - 1].Unwrap().NodeType != ExpressionType.Lambda) + return method; + + var types = method.Method.GetGenericMethodDefinition().GetGenericArguments() + .Zip(method.Method.GetGenericArguments(), (n, t) => new { n = n.Name, t }) + .ToDictionary(_ => _.n, _ => _.t); + + var sourceExpression = OptimizeExpression(method.Arguments[0].Unwrap()); + var keySelector = (LambdaExpression)OptimizeExpression(method.Arguments[1].Unwrap()); + var elementSelector = types.ContainsKey("TElement") ? (LambdaExpression)OptimizeExpression(method.Arguments[2].Unwrap()) : null; + var resultSelector = types.ContainsKey("TResult") ? + (LambdaExpression)OptimizeExpression(method.Arguments[types.ContainsKey("TElement") ? 3 : 2].Unwrap()) : null; + + var needSubQuery = null != ConvertExpression(keySelector.Body.Unwrap()).Find(IsExpression); + + if (!needSubQuery && resultSelector == null && elementSelector != null) + return method; + + var gtype = typeof(GroupByHelper<,,,>).MakeGenericType( + types["TSource"], + types["TKey"], + types.ContainsKey("TElement") ? types["TElement"] : types["TSource"], + types.ContainsKey("TResult") ? types["TResult"] : types["TSource"]); + + var helper = + //Expression.Lambda>( + // Expression.Convert(Expression.New(gtype), typeof(IGroupByHelper))) + //.Compile()(); + (IGroupByHelper)Activator.CreateInstance(gtype); + + helper.Set(needSubQuery, sourceExpression, keySelector, elementSelector, resultSelector); + + if (method.Method.DeclaringType == typeof(Queryable)) + { + if (!needSubQuery) + return resultSelector == null ? helper.AddElementSelectorQ() : helper.AddResultQ(); + + return resultSelector == null ? helper.WrapInSubQueryQ() : helper.WrapInSubQueryResultQ(); + } + else + { + if (!needSubQuery) + return resultSelector == null ? helper.AddElementSelectorE() : helper.AddResultE(); + + return resultSelector == null ? helper.WrapInSubQueryE() : helper.WrapInSubQueryResultE(); + } + } + + bool IsExpression(Expression ex) + { + switch (ex.NodeType) + { + case ExpressionType.Convert : + case ExpressionType.ConvertChecked : + case ExpressionType.MemberInit : + case ExpressionType.New : + case ExpressionType.NewArrayBounds : + case ExpressionType.NewArrayInit : + case ExpressionType.Parameter : return false; + case ExpressionType.MemberAccess : + { + var ma = (MemberExpression)ex; + var attr = GetFunctionAttribute(ma.Member); + + if (attr != null) + return true; + + return false; + } + } + + return true; + } + + #endregion + + #region ConvertSelectMany + + interface ISelectManyHelper + { + void Set(Expression sourceExpression, LambdaExpression colSelector); + + Expression AddElementSelectorQ(); + Expression AddElementSelectorE(); + } + + class SelectManyHelper : ISelectManyHelper + { + Expression _sourceExpression; + LambdaExpression _colSelector; + + public void Set(Expression sourceExpression, LambdaExpression colSelector) + { + _sourceExpression = sourceExpression; + _colSelector = colSelector; + } + + public Expression AddElementSelectorQ() + { + Expression,IEnumerable,IQueryable>> func = (source,col) => source + .SelectMany(colParam => col, (s,c) => c) + ; + + var body = func.Body.Unwrap(); + var colArg = GetLambda(body, 1).Parameters[0]; // .SelectMany(colParam + + return Convert(func, colArg); + } + + public Expression AddElementSelectorE() + { + Expression,IEnumerable,IEnumerable>> func = (source,col) => source + .SelectMany(colParam => col, (s,c) => c) + ; + + var body = func.Body.Unwrap(); + var colArg = GetLambda(body, 1).Parameters[0]; // .SelectMany(colParam + + return Convert(func, colArg); + } + + Expression Convert(LambdaExpression func, ParameterExpression colArg) + { + var body = func.Body.Unwrap(); + var expr = body.Convert(ex => + { + if (ex == func.Parameters[0]) + return _sourceExpression; + + if (ex == func.Parameters[1]) + return _colSelector.Body.Convert(e => e == _colSelector.Parameters[0] ? colArg : e); + + return ex; + }); + + return expr; + } + } + + Expression ConvertSelectMany(MethodCallExpression method) + { + if (method.Arguments.Count != 2 || ((LambdaExpression)method.Arguments[1].Unwrap()).Parameters.Count != 1) + return method; + + var types = method.Method.GetGenericMethodDefinition().GetGenericArguments() + .Zip(method.Method.GetGenericArguments(), (n, t) => new { n = n.Name, t }) + .ToDictionary(_ => _.n, _ => _.t); + + var sourceExpression = OptimizeExpression(method.Arguments[0].Unwrap()); + var colSelector = (LambdaExpression)OptimizeExpression(method.Arguments[1].Unwrap()); + + var gtype = typeof(SelectManyHelper<,>).MakeGenericType(types["TSource"], types["TResult"]); + var helper = + //Expression.Lambda>( + // Expression.Convert(Expression.New(gtype), typeof(ISelectManyHelper))) + //.Compile()(); + (ISelectManyHelper)Activator.CreateInstance(gtype); + + helper.Set(sourceExpression, colSelector); + + return method.Method.DeclaringType == typeof(Queryable) ? + helper.AddElementSelectorQ() : + helper.AddElementSelectorE(); + } + + #endregion + + #region ConvertPredicate + + Expression ConvertPredicate(MethodCallExpression method) + { + if (method.Arguments.Count != 2) + return method; + + var cm = GetQueriableMethodInfo(method, (m,_) => m.Name == method.Method.Name && m.GetParameters().Length == 1); + var wm = GetMethodInfo(method, "Where"); + + var argType = method.Method.GetGenericArguments()[0]; + + wm = wm.MakeGenericMethod(argType); + cm = cm.MakeGenericMethod(argType); + + return Expression.Call(null, cm, + Expression.Call(null, wm, + OptimizeExpression(method.Arguments[0]), + OptimizeExpression(method.Arguments[1]))); + } + + #endregion + + #region ConvertSelector + + Expression ConvertSelector(MethodCallExpression method, bool isGeneric) + { + if (method.Arguments.Count != 2) + return method; + + isGeneric = isGeneric && method.Method.DeclaringType == typeof(Queryable); + + var types = GetMethodGenericTypes(method); + var sm = GetMethodInfo(method, "Select"); + var cm = GetQueriableMethodInfo(method, (m,isDefault) => + { + if (m.Name == method.Method.Name) + { + var ps = m.GetParameters(); + + if (ps.Length == 1) + { + if (isGeneric) + return true; + + var ts = ps[0].ParameterType.GetGenericArguments(); + return ts[0] == types[1] || isDefault && ts[0].IsGenericParameter; + } + } + + return false; + }); + + var argType = types[0]; + + sm = sm.MakeGenericMethod(argType, types[1]); + + if (cm.IsGenericMethodDefinition) + cm = cm.MakeGenericMethod(types[1]); + + return Expression.Call(null, cm, + OptimizeExpression(Expression.Call(null, sm, + method.Arguments[0], + method.Arguments[1]))); + } + + #endregion + + #region ConvertSelect + + Expression ConvertSelect(MethodCallExpression method) + { + var sequence = OptimizeExpression(method.Arguments[0]); + var lambda1 = (LambdaExpression)method.Arguments[1].Unwrap(); + var lambda = (LambdaExpression)OptimizeExpression(lambda1); + + if (lambda1.Parameters.Count > 1 || + sequence.NodeType != ExpressionType.Call || + ((MethodCallExpression)sequence).Method.Name != method.Method.Name) + { + return method; + } + + var slambda = (LambdaExpression)((MethodCallExpression)sequence).Arguments[1].Unwrap(); + var sbody = slambda.Body.Unwrap(); + + if (slambda.Parameters.Count > 1 || sbody.NodeType != ExpressionType.MemberAccess) + return method; + + var types1 = GetMethodGenericTypes((MethodCallExpression)sequence); + var types2 = GetMethodGenericTypes(method); + + var expr = Expression.Call(null, + GetMethodInfo(method, "Select").MakeGenericMethod(types1[0], types2[1]), + ((MethodCallExpression)sequence).Arguments[0], + Expression.Lambda( + lambda.Body.Convert(ex => ex == lambda.Parameters[0] ? sbody : ex), + slambda.Parameters[0])); + + return expr; + } + + #endregion + + #region ConvertIQueriable + + Expression ConvertIQueriable(Expression expression) + { + if (expression.NodeType == ExpressionType.MemberAccess || expression.NodeType == ExpressionType.Call) + { + var p = Expression.Parameter(typeof(Expression), "exp"); + var exas = expression.GetExpressionAccessors(p); + var expr = ReplaceParameter(exas, expression, _ => {}); + + if (expr.Find(e => e.NodeType == ExpressionType.Parameter && e != p) != null) + return expression; + + var l = Expression.Lambda>(Expression.Convert(expr, typeof(IQueryable)), new [] { p }); + var n = _query.AddQueryableAccessors(expression, l); + + Expression accessor; + + _expressionAccessors.TryGetValue(expression, out accessor); + + var path = + Expression.Call( + Expression.Constant(_query), + ReflectionHelper.Expressor.MethodExpressor(a => a.GetIQueryable(0, null)), + new[] { Expression.Constant(n), accessor ?? Expression.Constant(null, typeof(Expression)) }); + + var qex = _query.GetIQueryable(n, expression); + + if (expression.NodeType == ExpressionType.Call && qex.NodeType == ExpressionType.Call) + { + var m1 = (MethodCallExpression)expression; + var m2 = (MethodCallExpression)qex; + + if (m1.Method == m2.Method) + return expression; + } + + foreach (var a in qex.GetExpressionAccessors(path)) + if (!_expressionAccessors.ContainsKey(a.Key)) + _expressionAccessors.Add(a.Key, a.Value); + + return qex; + } + + throw new InvalidOperationException(); + } + + #endregion + + #region ConvertElementAt + + Expression ConvertElementAt(MethodCallExpression method) + { + var sequence = OptimizeExpression(method.Arguments[0]); + var index = OptimizeExpression(method.Arguments[1]).Unwrap(); + var sourceType = method.Method.GetGenericArguments()[0]; + + MethodInfo skipMethod; + + if (index.NodeType == ExpressionType.Lambda) + { + skipMethod = ReflectionHelper.Expressor.MethodExpressor(o => LinqExtensions.Skip(null, null)); + skipMethod = skipMethod.GetGenericMethodDefinition(); + } + else + { + skipMethod = GetQueriableMethodInfo(method, (mi,_) => mi.Name == "Skip"); + } + + skipMethod = skipMethod.MakeGenericMethod(sourceType); + + var methodName = method.Method.Name == "ElementAt" ? "First" : "FirstOrDefault"; + var firstMethod = GetQueriableMethodInfo(method, (mi,_) => mi.Name == methodName && mi.GetParameters().Length == 1); + + firstMethod = firstMethod.MakeGenericMethod(sourceType); + + return Expression.Call(null, firstMethod, Expression.Call(null, skipMethod, sequence, index)); + } + + #endregion + + #region Helpers + + MethodInfo GetQueriableMethodInfo(MethodCallExpression method, Func predicate) + { + return method.Method.DeclaringType == typeof(Enumerable) ? + EnumerableMethods.FirstOrDefault(m => predicate(m, false)) ?? EnumerableMethods.First(m => predicate(m, true)): + QueryableMethods. FirstOrDefault(m => predicate(m, false)) ?? QueryableMethods. First(m => predicate(m, true)); + } + + MethodInfo GetMethodInfo(MethodCallExpression method, string name) + { + return method.Method.DeclaringType == typeof(Enumerable) ? + EnumerableMethods + .Where(m => m.Name == name && m.GetParameters().Length == 2) + .First(m => m.GetParameters()[1].ParameterType.GetGenericArguments().Length == 2) : + QueryableMethods + .Where(m => m.Name == name && m.GetParameters().Length == 2) + .First(m => m.GetParameters()[1].ParameterType.GetGenericArguments()[0].GetGenericArguments().Length == 2); + } + + static Type[] GetMethodGenericTypes(MethodCallExpression method) + { + return method.Method.DeclaringType == typeof(Enumerable) ? + method.Method.GetParameters()[1].ParameterType.GetGenericArguments() : + method.Method.GetParameters()[1].ParameterType.GetGenericArguments()[0].GetGenericArguments(); + } + + #endregion + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/ExpressionContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/ExpressionContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,108 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + public class ExpressionContext : SequenceContextBase + { + public ExpressionContext(IBuildContext parent, IBuildContext sequence, LambdaExpression lambda) + : base(parent, sequence, lambda) + { + } + + public ExpressionContext(IBuildContext parent, IBuildContext sequence, LambdaExpression lambda, SqlQuery sqlQuery) + : base(parent, sequence, lambda) + { + SqlQuery = sqlQuery; + } + + public override Expression BuildExpression(Expression expression, int level) + { + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + if (level == 0) + { + switch (flags) + { + case ConvertFlags.Field : + case ConvertFlags.Key : + case ConvertFlags.All : + { + var root = expression.GetRootObject(); + + if (root.NodeType == ExpressionType.Parameter) + { + var ctx = Builder.GetContext(this, root); + + if (ctx != null) + { + if (ctx != this) + return ctx.ConvertToSql(expression, 0, flags); + + return root == expression ? + Sequence.ConvertToSql(null, 0, flags) : + Sequence.ConvertToSql(expression, level + 1, flags); + } + } + + break; + } + } + + throw new InvalidOperationException(); + } + + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + throw new InvalidOperationException(); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + switch (requestFlag) + { + case RequestFor.Root : return new IsExpressionResult(Lambda.Parameters.Count > 0 && expression == Lambda.Parameters[0]); + + case RequestFor.Table : + case RequestFor.Association : + case RequestFor.Object : + case RequestFor.GroupJoin : + case RequestFor.Field : + case RequestFor.Expression : + { + var levelExpression = expression.GetLevelExpression(level); + + return levelExpression == expression ? + Sequence.IsExpression(null, 0, requestFlag) : + Sequence.IsExpression(expression, level + 1, requestFlag); + } + } + + return IsExpressionResult.False; + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + if (expression == Lambda.Parameters[0]) + return Sequence.GetContext(null, 0, buildInfo); + + switch (expression.NodeType) + { + case ExpressionType.Constant : + case ExpressionType.New : + case ExpressionType.MemberInit : return null; + } + + return Sequence.GetContext(expression, level + 1, buildInfo); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/ExpressionHoder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/ExpressionHoder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using System; + +#pragma warning disable 649 + +namespace BLToolkit.Data.Linq.Builder +{ + class ExpressionHoder + { + public TP p; + public TE ex; + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/ExpressionTestGenerator.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/ExpressionTestGenerator.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,873 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; + +using BLToolkit.Linq; + +namespace BLToolkit.Data.Linq.Builder +{ + class ExpressionTestGenerator + { + readonly StringBuilder _exprBuilder = new StringBuilder(); + + string _indent = "\t\t\t\t"; + + void PushIndent() { _indent += '\t'; } + void PopIndent () { _indent = _indent.Substring(1); } + + readonly HashSet _visitedExprs = new HashSet(); + + bool BuildExpression(Expression expr) + { + switch (expr.NodeType) + { + case ExpressionType.Add: + case ExpressionType.AddChecked: + case ExpressionType.And: + case ExpressionType.AndAlso: +#if FW4 || SILVERLIGHT + case ExpressionType.Assign: +#endif + case ExpressionType.Coalesce: + case ExpressionType.Divide: + case ExpressionType.Equal: + case ExpressionType.ExclusiveOr: + case ExpressionType.GreaterThan: + case ExpressionType.GreaterThanOrEqual: + case ExpressionType.LeftShift: + case ExpressionType.LessThan: + case ExpressionType.LessThanOrEqual: + case ExpressionType.Modulo: + case ExpressionType.Multiply: + case ExpressionType.MultiplyChecked: + case ExpressionType.NotEqual: + case ExpressionType.Or: + case ExpressionType.OrElse: + case ExpressionType.Power: + case ExpressionType.RightShift: + case ExpressionType.Subtract: + case ExpressionType.SubtractChecked: + { + var e = (BinaryExpression)expr; + + _exprBuilder.Append("("); + + e.Left.Visit(new Func(BuildExpression)); + + switch (expr.NodeType) + { + case ExpressionType.Add : + case ExpressionType.AddChecked : _exprBuilder.Append(" + "); break; + case ExpressionType.And : _exprBuilder.Append(" & "); break; + case ExpressionType.AndAlso : _exprBuilder.Append(" && "); break; +#if FW4 || SILVERLIGHT + case ExpressionType.Assign : _exprBuilder.Append(" = "); break; +#endif + case ExpressionType.Coalesce : _exprBuilder.Append(" ?? "); break; + case ExpressionType.Divide : _exprBuilder.Append(" / "); break; + case ExpressionType.Equal : _exprBuilder.Append(" == "); break; + case ExpressionType.ExclusiveOr : _exprBuilder.Append(" ^ "); break; + case ExpressionType.GreaterThan : _exprBuilder.Append(" > "); break; + case ExpressionType.GreaterThanOrEqual : _exprBuilder.Append(" >= "); break; + case ExpressionType.LeftShift : _exprBuilder.Append(" << "); break; + case ExpressionType.LessThan : _exprBuilder.Append(" < "); break; + case ExpressionType.LessThanOrEqual : _exprBuilder.Append(" <= "); break; + case ExpressionType.Modulo : _exprBuilder.Append(" % "); break; + case ExpressionType.Multiply : + case ExpressionType.MultiplyChecked : _exprBuilder.Append(" * "); break; + case ExpressionType.NotEqual : _exprBuilder.Append(" != "); break; + case ExpressionType.Or : _exprBuilder.Append(" | "); break; + case ExpressionType.OrElse : _exprBuilder.Append(" || "); break; + case ExpressionType.Power : _exprBuilder.Append(" ** "); break; + case ExpressionType.RightShift : _exprBuilder.Append(" >> "); break; + case ExpressionType.Subtract : + case ExpressionType.SubtractChecked : _exprBuilder.Append(" - "); break; + } + + e.Right.Visit(new Func(BuildExpression)); + + _exprBuilder.Append(")"); + + return false; + } + + case ExpressionType.ArrayLength: + { + var e = (UnaryExpression)expr; + + e.Operand.Visit(new Func(BuildExpression)); + _exprBuilder.Append(".Length"); + + return false; + } + + case ExpressionType.Convert: + case ExpressionType.ConvertChecked: + { + var e = (UnaryExpression)expr; + + _exprBuilder.AppendFormat("({0})", GetTypeName(e.Type)); + e.Operand.Visit(new Func(BuildExpression)); + + return false; + } + + case ExpressionType.Negate: + case ExpressionType.NegateChecked: + { + _exprBuilder.Append("-"); + return true; + } + + case ExpressionType.Not: + { + _exprBuilder.Append("!"); + return true; + } + + case ExpressionType.Quote: + return true; + + case ExpressionType.TypeAs: + { + var e = (UnaryExpression)expr; + + _exprBuilder.Append("("); + e.Operand.Visit(new Func(BuildExpression)); + _exprBuilder.AppendFormat(" as {0})", GetTypeName(e.Type)); + + return false; + } + + case ExpressionType.UnaryPlus: + { + _exprBuilder.Append("+"); + return true; + } + + case ExpressionType.ArrayIndex: + { + var e = (BinaryExpression)expr; + + e.Left.Visit(new Func(BuildExpression)); + _exprBuilder.Append("["); + e.Right.Visit(new Func(BuildExpression)); + _exprBuilder.Append("]"); + + return false; + } + + case ExpressionType.MemberAccess : + { + var e = (MemberExpression)expr; + + e.Expression.Visit(new Func(BuildExpression)); + _exprBuilder.AppendFormat(".{0}", e.Member.Name); + + return false; + } + + case ExpressionType.Parameter : + { + var e = (ParameterExpression)expr; + _exprBuilder.Append(e.Name); + return false; + } + + case ExpressionType.Call : + { + var ex = (MethodCallExpression)expr; + var mi = ex.Method; + + var attrs = mi.GetCustomAttributes(typeof(ExtensionAttribute), false); + + if (attrs.Length != 0) + { + ex.Arguments[0].Visit(new Func(BuildExpression)); + PushIndent(); + _exprBuilder.AppendLine().Append(_indent); + } + else if (ex.Object != null) + ex.Object.Visit(new Func(BuildExpression)); + else + _exprBuilder.Append(GetTypeName(mi.DeclaringType)); + + _exprBuilder.Append(".").Append(mi.Name); + + if (mi.IsGenericMethod && mi.GetGenericArguments().Select(GetTypeName).All(t => t != null)) + { + _exprBuilder + .Append("<") + .Append(GetTypeNames(mi.GetGenericArguments(), ",")) + .Append(">"); + } + + _exprBuilder.Append("("); + + PushIndent(); + + var n = attrs.Length != 0 ? 1 : 0; + + for (var i = n; i < ex.Arguments.Count; i++) + { + if (i != n) + _exprBuilder.Append(","); + + _exprBuilder.AppendLine().Append(_indent); + + ex.Arguments[i].Visit(new Func(BuildExpression)); + } + + PopIndent(); + + _exprBuilder.Append(")"); + + if (attrs.Length != 0) + { + PopIndent(); + } + + return false; + } + + case ExpressionType.Constant: + { + var c = (ConstantExpression)expr; + + if (c.Value is IQueryable) + { + var e = ((IQueryable)c.Value).Expression; + + if (_visitedExprs.Add(e)) + { + e.Visit(new Func(BuildExpression)); + return false; + } + } + + _exprBuilder.Append(expr); + + return true; + } + + case ExpressionType.Lambda: + { + var le = (LambdaExpression)expr; + var ps = le.Parameters + .Select(p => (GetTypeName(p.Type) + " " + p.Name).TrimStart()) + .Aggregate("", (p1, p2) => p1 + ", " + p2, p => p.TrimStart(',', ' ')); + + _exprBuilder.Append("(").Append(ps).Append(") => "); + + le.Body.Visit(new Func(BuildExpression)); + return false; + } + + case ExpressionType.Conditional: + { + var e = (ConditionalExpression)expr; + + _exprBuilder.Append("("); + e.Test.Visit(new Func(BuildExpression)); + _exprBuilder.Append(" ? "); + e.IfTrue.Visit(new Func(BuildExpression)); + _exprBuilder.Append(" : "); + e.IfFalse.Visit(new Func(BuildExpression)); + _exprBuilder.Append(")"); + + return false; + } + + case ExpressionType.New: + { + var ne = (NewExpression)expr; + + if (IsAnonymous(ne.Type)) + { + if (ne.Members.Count == 1) + { + _exprBuilder.AppendFormat("new {{ {0} = ", ne.Members[0].Name); + ne.Arguments[0].Visit(new Func(BuildExpression)); + _exprBuilder.Append(" }}"); + } + else + { + _exprBuilder.AppendLine("new").Append(_indent).Append("{"); + + PushIndent(); + + for (var i = 0; i < ne.Members.Count; i++) + { + _exprBuilder.AppendLine().Append(_indent).AppendFormat("{0} = ", ne.Members[i].Name); + ne.Arguments[i].Visit(new Func(BuildExpression)); + + if (i + 1 < ne.Members.Count) + _exprBuilder.Append(","); + } + + PopIndent(); + _exprBuilder.AppendLine().Append(_indent).Append("}"); + } + } + else + { + _exprBuilder.AppendFormat("new {0}(", GetTypeName(ne.Type)); + + for (var i = 0; i < ne.Arguments.Count; i++) + { + ne.Arguments[i].Visit(new Func(BuildExpression)); + if (i + 1 < ne.Arguments.Count) + _exprBuilder.Append(", "); + } + + _exprBuilder.Append(")"); + } + + return false; + } + + case ExpressionType.MemberInit: + { + Func modify = b => + { + switch (b.BindingType) + { + case MemberBindingType.Assignment : + var ma = (MemberAssignment)b; + _exprBuilder.AppendFormat("{0} = ", ma.Member.Name); + ma.Expression.Visit(new Func(BuildExpression)); + break; + default: + _exprBuilder.Append(b.ToString()); + break; + } + + return true; + }; + + var e = (MemberInitExpression)expr; + + e.NewExpression.Visit(new Func(BuildExpression)); + + if (e.Bindings.Count == 1) + { + _exprBuilder.Append(" { "); + modify(e.Bindings[0]); + _exprBuilder.Append(" }"); + } + else + { + _exprBuilder.AppendLine().Append(_indent).Append("{"); + + PushIndent(); + + for (var i = 0; i < e.Bindings.Count; i++) + { + _exprBuilder.AppendLine().Append(_indent); + modify(e.Bindings[i]); + if (i + 1 < e.Bindings.Count) + _exprBuilder.Append(","); + } + + PopIndent(); + _exprBuilder.AppendLine().Append(_indent).Append("}"); + } + + return false; + } + + case ExpressionType.NewArrayInit: + { + var e = (NewArrayExpression)expr; + + _exprBuilder.AppendFormat("new {0}[]", GetTypeName(e.Type.GetElementType())); + + if (e.Expressions.Count == 1) + { + _exprBuilder.Append(" { "); + e.Expressions[0].Visit(new Func(BuildExpression)); + _exprBuilder.Append(" }"); + } + else + { + _exprBuilder.AppendLine().Append(_indent).Append("{"); + + PushIndent(); + + for (var i = 0; i < e.Expressions.Count; i++) + { + _exprBuilder.AppendLine().Append(_indent); + e.Expressions[i].Visit(new Func(BuildExpression)); + if (i + 1 < e.Expressions.Count) + _exprBuilder.Append(","); + } + + PopIndent(); + _exprBuilder.AppendLine().Append(_indent).Append("}"); + } + + return false; + } + + case ExpressionType.TypeIs: + { + var e = (TypeBinaryExpression)expr; + + _exprBuilder.Append("("); + e.Expression.Visit(new Func(BuildExpression)); + _exprBuilder.AppendFormat(" is {0})", e.TypeOperand); + + return false; + } + + case ExpressionType.ListInit: + { + var e = (ListInitExpression)expr; + + e.NewExpression.Visit(new Func(BuildExpression)); + + if (e.Initializers.Count == 1) + { + _exprBuilder.Append(" { "); + e.Initializers[0].Arguments[0].Visit(new Func(BuildExpression)); + _exprBuilder.Append(" }"); + } + else + { + _exprBuilder.AppendLine().Append(_indent).Append("{"); + + PushIndent(); + + for (var i = 0; i < e.Initializers.Count; i++) + { + _exprBuilder.AppendLine().Append(_indent); + e.Initializers[i].Arguments[0].Visit(new Func(BuildExpression)); + if (i + 1 < e.Initializers.Count) + _exprBuilder.Append(","); + } + + PopIndent(); + _exprBuilder.AppendLine().Append(_indent).Append("}"); + } + + return false; + } + + case ExpressionType.Invoke: + { + var e = (InvocationExpression)expr; + + _exprBuilder.Append("Expression.Invoke("); + e.Expression.Visit(new Func(BuildExpression)); + _exprBuilder.Append(", ("); + + for (var i = 0; i < e.Arguments.Count; i++) + { + e.Arguments[i].Visit(new Func(BuildExpression)); + if (i + 1 < e.Arguments.Count) + _exprBuilder.Append(", "); + } + _exprBuilder.Append("))"); + + return false; + } + + default: + _exprBuilder.AppendLine("// Unknown expression.").Append(_indent).Append(expr); + return false; + } + } + + readonly Dictionary _typeNames = new Dictionary + { + { typeof(object), "object" }, + { typeof(bool), "bool" }, + { typeof(int), "int" }, + { typeof(string), "string" }, + }; + + readonly StringBuilder _typeBuilder = new StringBuilder(); + + void BuildType(Type type) + { + if (type.Namespace != null && type.Namespace.StartsWith("System") || + IsAnonymous(type) || + type.Assembly == GetType().Assembly || + type.IsGenericType && type.GetGenericTypeDefinition() != type) + return; + + var name = type.Name;//.Replace('<', '_').Replace('>', '_').Replace('`', '_').Replace("__f__", ""); + + var idx = name.LastIndexOf("`"); + + if (idx > 0) + name = name.Substring(0, idx); + + if (type.IsGenericType) + type = type.GetGenericTypeDefinition(); + + var baseClasses = new[] { type.BaseType } + .Where(t => t != null && t != typeof(object)) + .Concat(type.GetInterfaces()).ToArray(); + + var ctors = type.GetConstructors().Select(c => + { +#if SILVERLIGHT + var attrs = c.GetCustomAttributes(false).ToList(); +#else + var attrs = c.GetCustomAttributesData(); +#endif + var ps = c.GetParameters().Select(p => GetTypeName(p.ParameterType) + " " + p.Name).ToArray(); + return string.Format( + "{0}\n\t\tpublic {1}({2})\n\t\t{{\n\t\t\tthrow new NotImplementedException();\n\t\t}}", + attrs.Count > 0 ? attrs.Select(a => "\n\t\t" + a.ToString()).Aggregate((a1,a2) => a1 + a2) : "", + name, + ps.Length == 0 ? "" : ps.Aggregate((s,t) => s + ", " + t)); + }).ToList(); + + if (ctors.Count == 1 && ctors[0].IndexOf("()") >= 0) + ctors.Clear(); + + var members = type.GetFields().Intersect(_usedMembers.OfType()).Select(f => + { +#if SILVERLIGHT + var attrs = f.GetCustomAttributes(false).ToList(); +#else + var attrs = f.GetCustomAttributesData(); +#endif + return string.Format( + "{0}\n\t\tpublic {1} {2};", + attrs.Count > 0 ? attrs.Select(a => "\n\t\t" + a.ToString()).Aggregate((a1,a2) => a1 + a2) : "", + GetTypeName(f.FieldType), + f.Name); + }) + .Concat( + type.GetProperties().Intersect(_usedMembers.OfType()).Select(p => + { +#if SILVERLIGHT + var attrs = p.GetCustomAttributes(false).ToList(); +#else + var attrs = p.GetCustomAttributesData(); +#endif + return string.Format( + "{0}\n\t\t{3}{1} {2} {{ get; set; }}", + attrs.Count > 0 ? attrs.Select(a => "\n\t\t" + a.ToString()).Aggregate((a1,a2) => a1 + a2) : "", + GetTypeName(p.PropertyType), + p.Name, + type.IsInterface ? "" : "public "); + })) + .Concat( + type.GetMethods().Intersect(_usedMembers.OfType()).Select(m => + { +#if SILVERLIGHT + var attrs = m.GetCustomAttributes(false).ToList(); +#else + var attrs = m.GetCustomAttributesData(); +#endif + var ps = m.GetParameters().Select(p => GetTypeName(p.ParameterType) + " " + p.Name).ToArray(); + return string.Format( + "{0}\n\t\t{5}{4}{1} {2}({3})\n\t\t{{\n\t\t\tthrow new NotImplementedException();\n\t\t}}", + attrs.Count > 0 ? attrs.Select(a => "\n\t\t" + a.ToString()).Aggregate((a1,a2) => a1 + a2) : "", + GetTypeName(m.ReturnType), + m.Name, + ps.Length == 0 ? "" : ps.Aggregate((s,t) => s + ", " + t), + m.IsStatic ? "static " : + m.IsVirtual ? "virtual " : + m.IsAbstract ? "abstract " : + "", + type.IsInterface ? "" : "public "); + })) + .ToArray(); + + { +#if SILVERLIGHT + var attrs = type.GetCustomAttributes(false).ToList(); +#else + var attrs = type.GetCustomAttributesData(); +#endif + + _typeBuilder.AppendFormat( + type.IsGenericType ? +@" +namespace {0} +{{{8} + {6}{7}{1} {2}<{3}>{5} + {{{4}{9} + }} +}} +" +: +@" +namespace {0} +{{{8} + {6}{7}{1} {2}{5} + {{{4}{9} + }} +}} +", + type.Namespace, + type.IsInterface ? "interface" : type.IsClass ? "class" : "struct", + name, + type.IsGenericType ? GetTypeNames(type.GetGenericArguments(), ",") : null, + ctors.Count == 0 ? "" : ctors.Aggregate((s,t) => s + "\n" + t), + baseClasses.Length == 0 ? "" : " : " + GetTypeNames(baseClasses), + type.IsPublic ? "public " : "", + type.IsAbstract && !type.IsInterface ? "abstract " : "", + attrs.Count > 0 ? attrs.Select(a => "\n\t" + a.ToString()).Aggregate((a1,a2) => a1 + a2) : "", + members.Length > 0 ? + (ctors.Count != 0 ? "\n" : "") + members.Aggregate((f1,f2) => f1 + "\n" + f2) : + ""); + } + } + + string GetTypeNames(IEnumerable types, string separator = ", ") + { + return types.Select(GetTypeName).Aggregate("", (t1,t2) => t1 + separator + t2, p => p.TrimStart(separator.ToCharArray())); + } + + bool IsAnonymous(Type type) + { + return type.Name.StartsWith("<>f__AnonymousType"); + } + + string GetTypeName(Type type) + { + if (type == null || type == typeof(object)) + return null; + + if (type.IsGenericParameter) + return type.ToString(); + + string name; + + if (_typeNames.TryGetValue(type, out name)) + return name; + + if (IsAnonymous(type)) + { + _typeNames[type] = null; + return null; + } + + if (type.IsGenericType) + { + var args = type.GetGenericArguments(); + + name = ""; + + if (type.Namespace != "System") + name = type.Namespace + "."; + + name += type.Name; + + var idx = name.LastIndexOf("`"); + + if (idx > 0) + name = name.Substring(0, idx); + + if (type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + name = string.Format("{0}?", GetTypeName(args[0])); + } + else + { + name = string.Format("{0}<{1}>", + name, + args.Select(GetTypeName).Aggregate("", (s,t) => s + "," + t, p => p.TrimStart(','))); + } + + _typeNames[type] = name; + + return name; + } + + if (type.Namespace == "System") + return type.Name; + + return type.ToString(); + } + + readonly HashSet _usedMembers = new HashSet(); + + void VisitMembers(Expression expr) + { + switch (expr.NodeType) + { + case ExpressionType.Call : + { + var ex = (MethodCallExpression)expr; + _usedMembers.Add(ex.Method); + + if (ex.Method.IsGenericMethod) + { + var gmd = ex.Method.GetGenericMethodDefinition(); + + if (gmd != ex.Method) + _usedMembers.Add(gmd); + + var ga = ex.Method.GetGenericArguments(); + + foreach (var type in ga) + _usedMembers.Add(type); + } + + break; + } + + case ExpressionType.MemberAccess : + { + var ex = (MemberExpression)expr; + _usedMembers.Add(ex.Member); + break; + } + + case ExpressionType.MemberInit : + { + var ex = (MemberInitExpression)expr; + + Action> visit = null; visit = bs => + { + foreach (var b in bs) + { + _usedMembers.Add(b.Member); + + switch (b.BindingType) + { + case MemberBindingType.MemberBinding : + visit(((MemberMemberBinding)b).Bindings); + break; + }} + }; + + visit(ex.Bindings); + break; + } + } + } + + readonly HashSet _usedTypes = new HashSet(); + + void AddType(Type type) + { + if (type == null || type == typeof(object) || type.IsGenericParameter || _usedTypes.Contains(type)) + return; + + _usedTypes.Add(type); + + if (type.IsGenericType) + foreach (var arg in type.GetGenericArguments()) + AddType(arg); + + if (type.IsGenericType && type.GetGenericTypeDefinition() != type) + AddType(type.GetGenericTypeDefinition()); + + AddType(type.BaseType); + + foreach (var i in type.GetInterfaces()) + AddType(i); + } + + void VisitTypes(Expression expr) + { + AddType(expr.Type); + + switch (expr.NodeType) + { + case ExpressionType.Call : + { + var ex = (MethodCallExpression)expr; + var mi = ex.Method; + + AddType(mi.DeclaringType); + AddType(mi.ReturnType); + + foreach (var arg in mi.GetGenericArguments()) + AddType(arg); + + break; + } + } + } + + public string GenerateSource(Expression expr) + { + string fileName = null; + StreamWriter sw = null; + + try + { + var dir = Path.Combine(Path.GetTempPath(), "bltookit\\"); + + if (!Directory.Exists(dir)) + Directory.CreateDirectory(dir); + + var number = 0;//DateTime.Now.Ticks; + + fileName = Path.Combine(dir, "ExpressionTest." + number + ".cs"); + + expr.Visit(new Action(VisitMembers)); + expr.Visit(new Action(VisitTypes)); + + foreach (var type in _usedTypes.OrderBy(t => t.Namespace).ThenBy(t => t.Name)) + BuildType(type); + + expr.Visit(new Func(BuildExpression)); + + _exprBuilder.Replace("<>h__TransparentIdentifier", "tp"); + + sw = File.CreateText(fileName); + + sw.WriteLine(@"//--------------------------------------------------------------------------------------------------- +// This code was generated by BLToolkit. +//--------------------------------------------------------------------------------------------------- +using System; +using System.Linq.Expressions; + +using NUnit.Framework; +{0} +namespace Data.Linq.UserTests +{{ + [TestFixture] + public class UserTest : TestBase + {{ + [Test] + public void Test([DataContexts] string context) + {{ + // {1} + using (var db = GetDataContext(context)) + {{ + {2}; + }} + }} + }} +}} +", + _typeBuilder, + expr, + _exprBuilder); + } + catch(Exception ex) + { + if (sw != null) + { + sw.WriteLine(); + sw.WriteLine(ex.GetType()); + sw.WriteLine(ex.Message); + sw.WriteLine(ex.StackTrace); + } + } + finally + { + if (sw != null) + sw.Close(); + } + + return fileName; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/FirstSingleBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/FirstSingleBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,172 @@ +using System; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + using Reflection; + + class FirstSingleBuilder : MethodCallBuilder + { + public static string[] MethodNames = new[] { "First", "FirstOrDefault", "Single", "SingleOrDefault" }; + + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return + methodCall.IsQueryable(MethodNames) && + methodCall.Arguments.Count == 1; + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + var take = 0; + + if (!buildInfo.IsSubQuery || builder.SqlProvider.IsSubQueryTakeSupported) + switch (methodCall.Method.Name) + { + case "First" : + case "FirstOrDefault" : + take = 1; + break; + + case "Single" : + case "SingleOrDefault" : + if (!buildInfo.IsSubQuery) + take = 2; + break; + } + + if (take != 0) + builder.BuildTake(sequence, new SqlValue(take)); + + return new FirstSingleContext(buildInfo.Parent, sequence, methodCall); + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + if (methodCall.Arguments.Count == 2) + { + var predicate = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + var info = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), predicate.Parameters[0]); + + if (info != null) + { + info.Expression = methodCall.Convert(ex => ConvertMethod(methodCall, 0, info, predicate.Parameters[0], ex)); + info.Parameter = param; + + return info; + } + } + else + { + var info = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), null); + + if (info != null) + { + info.Expression = methodCall.Convert(ex => ConvertMethod(methodCall, 0, info, null, ex)); + info.Parameter = param; + + return info; + } + } + + return null; + } + + public class FirstSingleContext : SequenceContextBase + { + public FirstSingleContext(IBuildContext parent, IBuildContext sequence, MethodCallExpression methodCall) + : base(parent, sequence, null) + { + _methodCall = methodCall; + } + + readonly MethodCallExpression _methodCall; + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + Sequence.BuildQuery(query, queryParameter); + + switch (_methodCall.Method.Name) + { + case "First" : query.GetElement = (ctx, db, expr, ps) => query.GetIEnumerable(ctx, db, expr, ps).First(); break; + case "FirstOrDefault" : query.GetElement = (ctx, db, expr, ps) => query.GetIEnumerable(ctx, db, expr, ps).FirstOrDefault(); break; + case "Single" : query.GetElement = (ctx, db, expr, ps) => query.GetIEnumerable(ctx, db, expr, ps).Single(); break; + case "SingleOrDefault" : query.GetElement = (ctx, db, expr, ps) => query.GetIEnumerable(ctx, db, expr, ps).SingleOrDefault(); break; + } + } + + static object SequenceException() + { + return new object[0].First(); + } + + public override Expression BuildExpression(Expression expression, int level) + { + if (expression == null) + { + if (Builder.SqlProvider.IsApplyJoinSupported && Parent.SqlQuery.GroupBy.IsEmpty) + { + var join = SqlQuery.OuterApply(SqlQuery); + + Parent.SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); + + var expr = Sequence.BuildExpression(expression, level); + var idx = SqlQuery.Select.Add(new SqlValue(1)); + + idx = ConvertToParentIndex(idx, this); + + var defaultValue = _methodCall.Method.Name.EndsWith("OrDefault") ? + Expression.Constant(TypeHelper.GetDefaultValue(expr.Type), expr.Type) as Expression : + Expression.Convert( + Expression.Call( + null, + ReflectionHelper.Expressor.MethodExpressor(_ => SequenceException())), + expr.Type); + + expr = Expression.Condition( + Expression.Call( + ExpressionBuilder.DataReaderParam, + ReflectionHelper.DataReader.IsDBNull, + Expression.Constant(idx)), + defaultValue, + expr); + + return expr; + } + + if (Sequence.IsExpression(null, level, RequestFor.Object).Result) + return Builder.BuildMultipleQuery(Parent, _methodCall); + + return Builder.BuildSql(_methodCall.Type, Parent.SqlQuery.Select.Add(SqlQuery)); + } + + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + return Sequence.ConvertToSql(expression, level + 1, flags); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + return Sequence.ConvertToIndex(expression, level, flags); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + return Sequence.IsExpression(expression, level, requestFlag); + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + throw new InvalidOperationException(); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/GroupByBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/GroupByBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,621 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class GroupByBuilder : MethodCallBuilder + { + #region Builder Methods + + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + if (!methodCall.IsQueryable("GroupBy")) + return false; + + var body = ((LambdaExpression)methodCall.Arguments[1].Unwrap()).Body.Unwrap(); + + if (body.NodeType == ExpressionType.MemberInit) + { + var mi = (MemberInitExpression)body; + bool throwExpr; + + if (mi.NewExpression.Arguments.Count > 0 || mi.Bindings.Count == 0) + throwExpr = true; + else + throwExpr = mi.Bindings.Any(b => b.BindingType != MemberBindingType.Assignment); + + if (throwExpr) + throw new NotSupportedException(string.Format("Explicit construction of entity type '{0}' in group by is not allowed.", body.Type)); + } + + return (methodCall.Arguments[methodCall.Arguments.Count - 1].Unwrap().NodeType == ExpressionType.Lambda); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequenceExpr = methodCall.Arguments[0]; + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, sequenceExpr)); + var groupingType = methodCall.Type.GetGenericArguments()[0]; + var keySelector = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + var elementSelector = (LambdaExpression)methodCall.Arguments[2].Unwrap(); + + if (methodCall.Arguments[0].NodeType == ExpressionType.Call) + { + var call = (MethodCallExpression)methodCall.Arguments[0]; + + if (call.Method.Name == "Select") + { + var type = ((LambdaExpression)call.Arguments[1].Unwrap()).Body.Type; + + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ExpressionBuilder.GroupSubQuery<,>)) + { + sequence = new SubQueryContext(sequence); + } + } + } + + var key = new KeyContext(buildInfo.Parent, keySelector, sequence); + var groupSql = builder.ConvertExpressions(key, keySelector.Body.Unwrap(), ConvertFlags.Key); + + if (sequence.SqlQuery.Select.IsDistinct || + sequence.SqlQuery.GroupBy.Items.Count > 0 || + groupSql.Any(_ => !(_.Sql is SqlField || _.Sql is SqlQuery.Column))) + { + sequence = new SubQueryContext(sequence); + key = new KeyContext(buildInfo.Parent, keySelector, sequence); + groupSql = builder.ConvertExpressions(key, keySelector.Body.Unwrap(), ConvertFlags.Key); + } + + //sequence.SqlQuery.GroupBy.Items.Clear(); + + foreach (var sql in groupSql) + sequence.SqlQuery.GroupBy.Expr(sql.Sql); + + new QueryVisitor().Visit(sequence.SqlQuery.From, e => + { + if (e.ElementType == QueryElementType.JoinedTable) + { + var jt = (SqlQuery.JoinedTable)e; + if (jt.JoinType == SqlQuery.JoinType.Inner) + jt.IsWeak = false; + } + }); + + var element = new SelectContext (buildInfo.Parent, elementSelector, sequence/*, key*/); + var groupBy = new GroupByContext(buildInfo.Parent, sequenceExpr, groupingType, sequence, key, element); + + return groupBy; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + #endregion + + #region KeyContext + + internal class KeyContext : SelectContext + { + public KeyContext(IBuildContext parent, LambdaExpression lambda, params IBuildContext[] sequences) + : base(parent, lambda, sequences) + { + } + } + + #endregion + + #region GroupByContext + + internal class GroupByContext : SequenceContextBase + { + public GroupByContext( + IBuildContext parent, + Expression sequenceExpr, + Type groupingType, + IBuildContext sequence, + KeyContext key, + SelectContext element) + : base(parent, sequence, null) + { + _sequenceExpr = sequenceExpr; + _key = key; + _element = element; + _groupingType = groupingType; + + key.Parent = this; + } + + readonly Expression _sequenceExpr; + readonly KeyContext _key; + readonly SelectContext _element; + readonly Type _groupingType; + + internal class Grouping : IGrouping + { + public Grouping( + TKey key, + QueryContext queryContext, + List parameters, + Func> itemReader) + { + Key = key; + + _queryContext = queryContext; + _parameters = parameters; + _itemReader = itemReader; + + if (Common.Configuration.Linq.PreloadGroups) + { + _items = GetItems(); + } + } + + private IList _items; + readonly QueryContext _queryContext; + readonly List _parameters; + readonly Func> _itemReader; + + public TKey Key { get; private set; } + + List GetItems() + { + var db = _queryContext.GetDataContext(); + + try + { + var ps = new object[_parameters.Count]; + + for (var i = 0; i < ps.Length; i++) + ps[i] = _parameters[i].Accessor(_queryContext.Expression, _queryContext.CompiledParameters); + + return _itemReader(db.DataContextInfo.DataContext, Key, ps).ToList(); + } + finally + { + _queryContext.ReleaseDataContext(db); + } + } + + public IEnumerator GetEnumerator() + { + if (_items == null) + _items = GetItems(); + + return _items.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + interface IGroupByHelper + { + Expression GetGrouping(GroupByContext context); + } + + class GroupByHelper : IGroupByHelper + { + public Expression GetGrouping(GroupByContext context) + { + var parameters = context.Builder.CurrentSqlParameters + .Select((p,i) => new { p, i }) + .ToDictionary(_ => _.p.Expression, _ => _.i); + var paramArray = Expression.Parameter(typeof(object[]), "ps"); + + var groupExpression = context._sequenceExpr.Convert(e => + { + int idx; + + if (parameters.TryGetValue(e, out idx)) + { + return + Expression.Convert( + Expression.ArrayIndex(paramArray, Expression.Constant(idx)), + e.Type); + } + + return e; + }); + + var keyParam = Expression.Parameter(typeof(TKey), "key"); + +// ReSharper disable AssignNullToNotNullAttribute + + var expr = Expression.Call( + null, + ReflectionHelper.Expressor.MethodExpressor(_ => Queryable.Where(null, (Expression>)null)), + groupExpression, + Expression.Lambda>( + Expression.Equal(context._key.Lambda.Body, keyParam), + new[] { context._key.Lambda.Parameters[0] })); + + expr = Expression.Call( + null, + ReflectionHelper.Expressor.MethodExpressor(_ => Queryable.Select(null, (Expression>)null)), + expr, + context._element.Lambda); + +// ReSharper restore AssignNullToNotNullAttribute + + var lambda = Expression.Lambda>>( + Expression.Convert(expr, typeof(IQueryable)), + Expression.Parameter(typeof(IDataContext), "ctx"), + keyParam, + paramArray); + + var itemReader = CompiledQuery.Compile(lambda); + var keyExpr = context._key.BuildExpression(null, 0); + var keyReader = Expression.Lambda>( + keyExpr, + new [] + { + ExpressionBuilder.ContextParam, + ExpressionBuilder.DataContextParam, + ExpressionBuilder.DataReaderParam, + ExpressionBuilder.ExpressionParam, + ExpressionBuilder.ParametersParam, + }); + + return Expression.Call( + null, + ReflectionHelper.Expressor.MethodExpressor(_ => GetGrouping(null, null, null, null, null, null, null, null)), + new Expression[] + { + ExpressionBuilder.ContextParam, + ExpressionBuilder.DataContextParam, + ExpressionBuilder.DataReaderParam, + Expression.Constant(context.Builder.CurrentSqlParameters), + ExpressionBuilder.ExpressionParam, + ExpressionBuilder.ParametersParam, + Expression.Constant(keyReader.Compile()), + Expression.Constant(itemReader), + }); + } + + static IGrouping GetGrouping( + QueryContext context, + IDataContext dataContext, + IDataReader dataReader, + List parameterAccessor, + Expression expr, + object[] ps, + Func keyReader, + Func> itemReader) + { + var key = keyReader(context, dataContext, dataReader, expr, ps); + return new Grouping(key, context, parameterAccessor, itemReader); + } + } + + Expression BuildGrouping() + { + var gtype = typeof(GroupByHelper<,,>).MakeGenericType( + _key.Lambda.Body.Type, + _element.Lambda.Body.Type, + _key.Lambda.Parameters[0].Type); + + var isBlockDisable = Builder.IsBlockDisable; + + Builder.IsBlockDisable = true; + + var helper = (IGroupByHelper)Activator.CreateInstance(gtype); + var expr = helper.GetGrouping(this); + + Builder.IsBlockDisable = isBlockDisable; + + return expr; + } + + public override Expression BuildExpression(Expression expression, int level) + { + if (expression == null) + return BuildGrouping(); + + if (level != 0) + { + var levelExpression = expression.GetLevelExpression(level); + + if (levelExpression.NodeType == ExpressionType.MemberAccess) + { + var ma = (MemberExpression)levelExpression; + + if (ma.Member.Name == "Key" && ma.Member.DeclaringType == _groupingType) + { + return levelExpression == expression ? + _key.BuildExpression(null, 0) : + _key.BuildExpression(expression, level + 1); + } + } + } + + throw new InvalidOperationException(); + } + + ISqlExpression ConvertEnumerable(MethodCallExpression call) + { + if (AggregationBuilder.MethodNames.Contains(call.Method.Name)) + { + if (call.Arguments[0].NodeType == ExpressionType.Call) + { + var arg = (MethodCallExpression)call.Arguments[0]; + + if (arg.Method.Name == "Select") + { + if (arg.Arguments[0].NodeType != ExpressionType.Call) + { + var l = (LambdaExpression)arg.Arguments[1].Unwrap(); + var largs = l.Type.GetGenericArguments(); + + if (largs.Length == 2) + { + var p = _element.Parent; + var ctx = new ExpressionContext(Parent, _element, l); + var sql = Builder.ConvertToSql(ctx, l.Body, true); + + Builder.ReplaceParent(ctx, p); + + return new SqlFunction(call.Type, call.Method.Name, sql); + } + } + } + } + } + + if (call.Arguments[0].NodeType == ExpressionType.Call) + { + var ctx = Builder.GetSubQuery(this, call); + + if (Builder.SqlProvider.IsSubQueryColumnSupported) + return ctx.SqlQuery; + + var join = ctx.SqlQuery.CrossApply(); + + SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); + + return ctx.SqlQuery.Select.Columns[0]; + } + + var args = new ISqlExpression[call.Arguments.Count - 1]; + + if (CountBuilder.MethodNames.Contains(call.Method.Name)) + { + if (args.Length > 0) + throw new InvalidOperationException(); + + return SqlFunction.CreateCount(call.Type, SqlQuery); + } + + if (call.Arguments.Count > 1) + { + for (var i = 1; i < call.Arguments.Count; i++) + { + var ex = call.Arguments[i].Unwrap(); + + if (ex is LambdaExpression) + { + var l = (LambdaExpression)ex; + var p = _element.Parent; + var ctx = new ExpressionContext(Parent, _element, l); + + args[i - 1] = Builder.ConvertToSql(ctx, l.Body, true); + + Builder.ReplaceParent(ctx, p); + } + else + { + throw new InvalidOperationException(); + } + } + } + else + { + args = _element.ConvertToSql(null, 0, ConvertFlags.Field).Select(_ => _.Sql).ToArray(); + } + + return new SqlFunction(call.Type, call.Method.Name, args); + } + + PropertyInfo _keyProperty; + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + if (expression == null) + return _key.ConvertToSql(null, 0, flags); + + if (level > 0) + { + switch (expression.NodeType) + { + case ExpressionType.Call : + { + var e = (MethodCallExpression)expression; + + if (e.Method.DeclaringType == typeof(Enumerable)) + { + return new[] { new SqlInfo { Sql = ConvertEnumerable(e) } }; + } + + break; + } + + case ExpressionType.MemberAccess : + { + var levelExpression = expression.GetLevelExpression(level); + + if (levelExpression.NodeType == ExpressionType.MemberAccess) + { + var e = (MemberExpression)levelExpression; + + if (e.Member.Name == "Key") + { + if (_keyProperty == null) + _keyProperty = _groupingType.GetProperty("Key"); + + if (e.Member == _keyProperty) + { + if (levelExpression == expression) + return _key.ConvertToSql(null, 0, flags); + + return _key.ConvertToSql(expression, level + 1, flags); + } + } + + return Sequence.ConvertToSql(expression, level, flags); + } + + break; + } + } + } + + throw new InvalidOperationException(); + } + + readonly Dictionary,SqlInfo[]> _expressionIndex = new Dictionary,SqlInfo[]>(); + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + var key = Tuple.Create(expression, level, flags); + + SqlInfo[] info; + + if (!_expressionIndex.TryGetValue(key, out info)) + { + info = ConvertToSql(expression, level, flags); + + foreach (var item in info) + { + item.Query = SqlQuery; + item.Index = SqlQuery.Select.Add(item.Sql); + } + } + + return info; + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + if (level != 0) + { + var levelExpression = expression.GetLevelExpression(level); + + if (levelExpression.NodeType == ExpressionType.MemberAccess) + { + var ma = (MemberExpression)levelExpression; + + if (ma.Member.Name == "Key" && ma.Member.DeclaringType == _groupingType) + { + return levelExpression == expression ? + _key.IsExpression(null, 0, requestFlag) : + _key.IsExpression(expression, level + 1, requestFlag); + } + } + } + + return IsExpressionResult.False; + } + + public override int ConvertToParentIndex(int index, IBuildContext context) + { + var expr = SqlQuery.Select.Columns[index].Expression; + + if (!SqlQuery.GroupBy.Items.Exists(_ => _ == expr || (expr is SqlQuery.Column && _ == ((SqlQuery.Column)expr).Expression))) + SqlQuery.GroupBy.Items.Add(expr); + + return base.ConvertToParentIndex(index, this); + } + + interface IContextHelper + { + Expression GetContext(Expression sequence, ParameterExpression param, Expression expr1, Expression expr2); + } + + class ContextHelper : IContextHelper + { + public Expression GetContext(Expression sequence, ParameterExpression param, Expression expr1, Expression expr2) + { +// ReSharper disable AssignNullToNotNullAttribute + //ReflectionHelper.Expressor.MethodExpressor(_ => Queryable.Where(null, (Expression>)null)), + var mi = ReflectionHelper.Expressor.MethodExpressor(_ => Enumerable.Where(null, (Func)null)); +// ReSharper restore AssignNullToNotNullAttribute + var arg2 = Expression.Lambda>(Expression.Equal(expr1, expr2), new[] { param }); + + return Expression.Call(null, mi, sequence, arg2); + } + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + if (expression == null && buildInfo != null) + { + if (buildInfo.Parent is SelectManyBuilder.SelectManyContext) + { + var sm = (SelectManyBuilder.SelectManyContext)buildInfo.Parent; + var ctype = typeof(ContextHelper<>).MakeGenericType(_key.Lambda.Parameters[0].Type); + var helper = (IContextHelper)Activator.CreateInstance(ctype); + var expr = helper.GetContext( + Sequence.Expression, + _key.Lambda.Parameters[0], + Expression.PropertyOrField(sm.Lambda.Parameters[0], "Key"), + _key.Lambda.Body); + + return Builder.BuildSequence(new BuildInfo(buildInfo, expr)); + } + + //if (buildInfo.Parent == this) + { + var ctype = typeof(ContextHelper<>).MakeGenericType(_key.Lambda.Parameters[0].Type); + var helper = (IContextHelper)Activator.CreateInstance(ctype); + var expr = helper.GetContext( + _sequenceExpr, + _key.Lambda.Parameters[0], + Expression.PropertyOrField(buildInfo.Expression, "Key"), + _key.Lambda.Body); + + var ctx = Builder.BuildSequence(new BuildInfo(buildInfo, expr)); + + ctx.SqlQuery.Properties.Add(Tuple.Create("from_group_by", SqlQuery)); + + return ctx; + } + + //return this; + } + + if (level != 0) + { + var levelExpression = expression.GetLevelExpression(level); + + if (levelExpression.NodeType == ExpressionType.MemberAccess) + { + var ma = (MemberExpression)levelExpression; + + if (ma.Member.Name == "Key" && ma.Member.DeclaringType == _groupingType) + { + return levelExpression == expression ? + _key.GetContext(null, 0, buildInfo) : + _key.GetContext(expression, level + 1, buildInfo); + } + } + } + + throw new InvalidOperationException(); + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/IBuildContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/IBuildContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +using System; +using System.Linq.Expressions; + +#if DEBUG +#pragma warning disable 3010 +#endif + +namespace BLToolkit.Data.Linq.Builder +{ + using Data.Sql; + + public interface IBuildContext + { +#if DEBUG +// ReSharper disable InconsistentNaming + [CLSCompliant(false)] + string _sqlQueryText { get; } +// ReSharper restore InconsistentNaming +#endif + + ExpressionBuilder Builder { get; } + Expression Expression { get; } + SqlQuery SqlQuery { get; set; } + IBuildContext Parent { get; set; } + + void BuildQuery (Query query, ParameterExpression queryParameter); + Expression BuildExpression (Expression expression, int level); + SqlInfo[] ConvertToSql (Expression expression, int level, ConvertFlags flags); + SqlInfo[] ConvertToIndex (Expression expression, int level, ConvertFlags flags); + IsExpressionResult IsExpression (Expression expression, int level, RequestFor requestFlag); + IBuildContext GetContext (Expression expression, int level, BuildInfo buildInfo); + int ConvertToParentIndex(int index, IBuildContext context); + void SetAlias (string alias); + ISqlExpression GetSubQuery (IBuildContext context); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/ISequenceBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/ISequenceBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,14 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + public interface ISequenceBuilder + { + int BuildCounter { get; set; } + bool CanBuild (ExpressionBuilder builder, BuildInfo buildInfo); + IBuildContext BuildSequence(ExpressionBuilder builder, BuildInfo buildInfo); + SequenceConvertInfo Convert (ExpressionBuilder builder, BuildInfo buildInfo, ParameterExpression param); + bool IsSequence (ExpressionBuilder builder, BuildInfo buildInfo); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/InsertBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/InsertBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,265 @@ +using System; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class InsertBuilder : MethodCallBuilder + { + #region InsertBuilder + + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("Insert", "InsertWithIdentity"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + + var isSubQuery = sequence.SqlQuery.Select.IsDistinct; + + if (isSubQuery) + sequence = new SubQueryContext(sequence); + + switch (methodCall.Arguments.Count) + { + case 1 : + // static int Insert (this IValueInsertable source) + // static int Insert(this ISelectInsertable source) + { + foreach (var item in sequence.SqlQuery.Insert.Items) + sequence.SqlQuery.Select.Expr(item.Expression); + break; + } + + case 2 : // static int Insert(this Table target, Expression> setter) + { + UpdateBuilder.BuildSetter( + builder, + buildInfo, + (LambdaExpression)methodCall.Arguments[1].Unwrap(), + sequence, + sequence.SqlQuery.Insert.Items, + sequence); + + sequence.SqlQuery.Insert.Into = ((TableBuilder.TableContext)sequence).SqlTable; + sequence.SqlQuery.From.Tables.Clear(); + + break; + } + + case 3 : // static int Insert(this IQueryable source, Table target, Expression> setter) + { + var into = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SqlQuery())); + + UpdateBuilder.BuildSetter( + builder, + buildInfo, + (LambdaExpression)methodCall.Arguments[2].Unwrap(), + into, + sequence.SqlQuery.Insert.Items, + sequence); + + sequence.SqlQuery.Select.Columns.Clear(); + + foreach (var item in sequence.SqlQuery.Insert.Items) + sequence.SqlQuery.Select.Columns.Add(new SqlQuery.Column(sequence.SqlQuery, item.Expression)); + + sequence.SqlQuery.Insert.Into = ((TableBuilder.TableContext)into).SqlTable; + + break; + } + } + + var insert = sequence.SqlQuery.Insert; + + var q = insert.Into.Fields.Values.Cast().Except(insert.Items.Select(e => e.Column)) + .OfType() + .Where(f => f.IsIdentity); + + foreach (var field in q) + { + var expr = builder.SqlProvider.GetIdentityExpression(insert.Into, field, false); + + if (expr != null) + { + insert.Items.Insert(0, new SqlQuery.SetExpression(field, expr)); + + if (methodCall.Arguments.Count == 3) + { + sequence.SqlQuery.Select.Columns.Insert(0, new SqlQuery.Column(sequence.SqlQuery, insert.Items[0].Expression)); + } + } + } + + sequence.SqlQuery.QueryType = QueryType.Insert; + sequence.SqlQuery.Insert.WithIdentity = methodCall.Method.Name == "InsertWithIdentity"; + + return new InsertContext(buildInfo.Parent, sequence, sequence.SqlQuery.Insert.WithIdentity); + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + #endregion + + #region InsertContext + + class InsertContext : SequenceContextBase + { + public InsertContext(IBuildContext parent, IBuildContext sequence, bool insertWithIdentity) + : base(parent, sequence, null) + { + _insertWithIdentity = insertWithIdentity; + } + + readonly bool _insertWithIdentity; + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + if (_insertWithIdentity) query.SetScalarQuery(); + else query.SetNonQueryQuery(); + } + + public override Expression BuildExpression(Expression expression, int level) + { + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + throw new InvalidOperationException(); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + throw new InvalidOperationException(); + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + throw new InvalidOperationException(); + } + } + + #endregion + + #region Into + + internal class Into : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("Into"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var source = methodCall.Arguments[0].Unwrap(); + var into = methodCall.Arguments[1].Unwrap(); + + IBuildContext sequence; + + // static IValueInsertable Into(this IDataContext dataContext, Table target) + // + if (source.NodeType == ExpressionType.Constant && ((ConstantExpression)source).Value == null) + { + sequence = builder.BuildSequence(new BuildInfo((IBuildContext)null, into, new SqlQuery())); + + if (sequence.SqlQuery.Select.IsDistinct) + sequence = new SubQueryContext(sequence); + + sequence.SqlQuery.Insert.Into = ((TableBuilder.TableContext)sequence).SqlTable; + sequence.SqlQuery.From.Tables.Clear(); + } + // static ISelectInsertable Into(this IQueryable source, Table target) + // + else + { + sequence = builder.BuildSequence(new BuildInfo(buildInfo, source)); + + if (sequence.SqlQuery.Select.IsDistinct) + sequence = new SubQueryContext(sequence); + + var tbl = builder.BuildSequence(new BuildInfo((IBuildContext)null, into, new SqlQuery())); + sequence.SqlQuery.Insert.Into = ((TableBuilder.TableContext)tbl).SqlTable; + } + + sequence.SqlQuery.Select.Columns.Clear(); + + return sequence; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + } + + #endregion + + #region Value + + internal class Value : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("Value"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + var extract = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + var update = methodCall.Arguments[2].Unwrap(); + + if (sequence.SqlQuery.Insert.Into == null) + { + sequence.SqlQuery.Insert.Into = (SqlTable)sequence.SqlQuery.From.Tables[0].Source; + sequence.SqlQuery.From.Tables.Clear(); + } + + if (update.NodeType == ExpressionType.Lambda) + UpdateBuilder.ParseSet( + builder, + buildInfo, + extract, + (LambdaExpression)update, + sequence, + sequence.SqlQuery.Insert.Into, + sequence.SqlQuery.Insert.Items); + else + UpdateBuilder.ParseSet( + builder, + buildInfo, + extract, + update, + sequence, + sequence.SqlQuery.Insert.Items); + + return sequence; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/InsertOrUpdateBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/InsertOrUpdateBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class InsertOrUpdateBuilder : MethodCallBuilder + { + #region InsertOrUpdateBuilder + + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("InsertOrUpdate"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + + UpdateBuilder.BuildSetter( + builder, + buildInfo, + (LambdaExpression)methodCall.Arguments[1].Unwrap(), + sequence, + sequence.SqlQuery.Insert.Items, + sequence); + + UpdateBuilder.BuildSetter( + builder, + buildInfo, + (LambdaExpression)methodCall.Arguments[2].Unwrap(), + sequence, + sequence.SqlQuery.Update.Items, + sequence); + + sequence.SqlQuery.Insert.Into = ((TableBuilder.TableContext)sequence).SqlTable; + sequence.SqlQuery.Update.Table = ((TableBuilder.TableContext)sequence).SqlTable; + sequence.SqlQuery.From.Tables.Clear(); + sequence.SqlQuery.From.Table(sequence.SqlQuery.Update.Table); + + if (methodCall.Arguments.Count == 3) + { + var table = sequence.SqlQuery.Insert.Into; + var keys = table.GetKeys(false); + + if (keys.Count == 0) + throw new LinqException("InsertOrUpdate method requires the '{0}' table to have a primary key.", table.Name); + + var q = + ( + from k in keys + join i in sequence.SqlQuery.Insert.Items on k equals i.Column + select new { k, i } + ).ToList(); + + var missedKey = keys.Except(q.Select(i => i.k)).FirstOrDefault(); + + if (missedKey != null) + throw new LinqException("InsertOrUpdate method requires the '{0}.{1}' field to be included in the insert setter.", + table.Name, + ((SqlField)missedKey).Name); + + sequence.SqlQuery.Update.Keys.AddRange(q.Select(i => i.i)); + } + else + { + UpdateBuilder.BuildSetter( + builder, + buildInfo, + (LambdaExpression)methodCall.Arguments[3].Unwrap(), + sequence, + sequence.SqlQuery.Update.Keys, + sequence); + } + + sequence.SqlQuery.QueryType = QueryType.InsertOrUpdate; + + return new InsertOrUpdateContext(buildInfo.Parent, sequence); + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + #endregion + + #region UpdateContext + + class InsertOrUpdateContext : SequenceContextBase + { + public InsertOrUpdateContext(IBuildContext parent, IBuildContext sequence) + : base(parent, sequence, null) + { + } + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + if (Builder.SqlProvider.IsInsertOrUpdateSupported) + query.SetNonQueryQuery(); + else + query.MakeAlternativeInsertOrUpdate(SqlQuery); + } + + public override Expression BuildExpression(Expression expression, int level) + { + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + throw new InvalidOperationException(); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + throw new InvalidOperationException(); + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + throw new InvalidOperationException(); + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/IntersectBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/IntersectBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,56 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class IntersectBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.Arguments.Count == 2 && methodCall.IsQueryable("Except", "Intersect"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + var query = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SqlQuery())); + var except = query.SqlQuery; + + sequence = new SubQueryContext(sequence); + + var sql = sequence.SqlQuery; + + except.ParentSql = sql; + + if (methodCall.Method.Name == "Except") + sql.Where.Not.Exists(except); + else + sql.Where.Exists(except); + + var keys1 = sequence.ConvertToSql(null, 0, ConvertFlags.Key); + var keys2 = query. ConvertToSql(null, 0, ConvertFlags.Key); + + if (keys1.Length != keys2.Length) + throw new InvalidOperationException(); + + for (var i = 0; i < keys1.Length; i++) + { + except.Where + .Expr(keys1[i].Sql) + .Equal + .Expr(keys2[i].Sql); + } + + return sequence; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/IsExpressionResult.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/IsExpressionResult.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +using System; + +namespace BLToolkit.Data.Linq.Builder +{ + public struct IsExpressionResult + { + public readonly bool Result; + public readonly IBuildContext Context; + + public IsExpressionResult(bool result) + { + Result = result; + Context = null; + } + + public IsExpressionResult(bool result, IBuildContext context) + { + Result = result; + Context = context; + } + + public static IsExpressionResult True = new IsExpressionResult(true); + public static IsExpressionResult False = new IsExpressionResult(false); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/JoinBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/JoinBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,397 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class JoinBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + if (!methodCall.IsQueryable("Join", "GroupJoin") || methodCall.Arguments.Count != 5) + return false; + + var body = ((LambdaExpression)methodCall.Arguments[2].Unwrap()).Body.Unwrap(); + + if (body.NodeType == ExpressionType .MemberInit) + { + var mi = (MemberInitExpression)body; + bool throwExpr; + + if (mi.NewExpression.Arguments.Count > 0 || mi.Bindings.Count == 0) + throwExpr = true; + else + throwExpr = mi.Bindings.Any(b => b.BindingType != MemberBindingType.Assignment); + + if (throwExpr) + throw new NotSupportedException(string.Format("Explicit construction of entity type '{0}' in join is not allowed.", body.Type)); + } + + return true; + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var isGroup = methodCall.Method.Name == "GroupJoin"; + var outerContext = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0], buildInfo.SqlQuery)); + var innerContext = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SqlQuery())); + var countContext = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SqlQuery())); + + var context = new SubQueryContext(outerContext); + innerContext = isGroup ? new GroupJoinSubQueryContext(innerContext, methodCall) : new SubQueryContext(innerContext); + countContext = new SubQueryContext(countContext); + + var join = isGroup ? innerContext.SqlQuery.WeakLeftJoin() : innerContext.SqlQuery.InnerJoin(); + var sql = context.SqlQuery; + + sql.From.Tables[0].Joins.Add(join.JoinedTable); + + var selector = (LambdaExpression)methodCall.Arguments[4].Unwrap(); + + context.SetAlias(selector.Parameters[0].Name); + innerContext.SetAlias(selector.Parameters[1].Name); + + var outerKeyLambda = ((LambdaExpression)methodCall.Arguments[2].Unwrap()); + var innerKeyLambda = ((LambdaExpression)methodCall.Arguments[3].Unwrap()); + + var outerKeySelector = outerKeyLambda.Body.Unwrap(); + var innerKeySelector = innerKeyLambda.Body.Unwrap(); + + var outerParent = context. Parent; + var innerParent = innerContext.Parent; + var countParent = countContext.Parent; + + var outerKeyContext = new ExpressionContext(buildInfo.Parent, context, outerKeyLambda); + var innerKeyContext = new InnerKeyContext (buildInfo.Parent, innerContext, innerKeyLambda); + var countKeyContext = new ExpressionContext(buildInfo.Parent, countContext, innerKeyLambda); + + // Process counter. + // + var counterSql = ((SubQueryContext)countContext).SqlQuery; + + // Make join and where for the counter. + // + if (outerKeySelector.NodeType == ExpressionType.New) + { + var new1 = (NewExpression)outerKeySelector; + var new2 = (NewExpression)innerKeySelector; + + for (var i = 0; i < new1.Arguments.Count; i++) + { + var arg1 = new1.Arguments[i]; + var arg2 = new2.Arguments[i]; + + BuildJoin(builder, join, outerKeyContext, arg1, innerKeyContext, arg2, countKeyContext, counterSql); + } + } + else if (outerKeySelector.NodeType == ExpressionType.MemberInit) + { + var mi1 = (MemberInitExpression)outerKeySelector; + var mi2 = (MemberInitExpression)innerKeySelector; + + for (var i = 0; i < mi1.Bindings.Count; i++) + { + if (mi1.Bindings[i].Member != mi2.Bindings[i].Member) + throw new LinqException(string.Format("List of member inits does not match for entity type '{0}'.", outerKeySelector.Type)); + + var arg1 = ((MemberAssignment)mi1.Bindings[i]).Expression; + var arg2 = ((MemberAssignment)mi2.Bindings[i]).Expression; + + BuildJoin(builder, join, outerKeyContext, arg1, innerKeyContext, arg2, countKeyContext, counterSql); + } + } + else + { + BuildJoin(builder, join, outerKeyContext, outerKeySelector, innerKeyContext, innerKeySelector, countKeyContext, counterSql); + } + + builder.ReplaceParent(outerKeyContext, outerParent); + builder.ReplaceParent(innerKeyContext, innerParent); + builder.ReplaceParent(countKeyContext, countParent); + + if (isGroup) + { + counterSql.ParentSql = sql; + counterSql.Select.Columns.Clear(); + + var inner = (GroupJoinSubQueryContext)innerContext; + + inner.Join = join.JoinedTable; + inner.CounterSql = counterSql; + return new GroupJoinContext( + buildInfo.Parent, selector, context, inner, methodCall.Arguments[1], outerKeyLambda, innerKeyLambda); + } + + return new JoinContext(buildInfo.Parent, selector, context, innerContext) +#if DEBUG + { + MethodCall = methodCall + } +#endif + ; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + static void BuildJoin( + ExpressionBuilder builder, + SqlQuery.FromClause.Join join, + IBuildContext outerKeyContext, Expression outerKeySelector, + IBuildContext innerKeyContext, Expression innerKeySelector, + IBuildContext countKeyContext, SqlQuery countSql) + { + var predicate = builder.ConvertObjectComparison( + ExpressionType.Equal, + outerKeyContext, outerKeySelector, + innerKeyContext, innerKeySelector); + + if (predicate != null) + join.JoinedTable.Condition.Conditions.Add(new SqlQuery.Condition(false, predicate)); + else + join + .Expr(builder.ConvertToSql(outerKeyContext, outerKeySelector, false)).Equal + .Expr(builder.ConvertToSql(innerKeyContext, innerKeySelector, false)); + + predicate = builder.ConvertObjectComparison( + ExpressionType.Equal, + outerKeyContext, outerKeySelector, + countKeyContext, innerKeySelector); + + if (predicate != null) + countSql.Where.SearchCondition.Conditions.Add(new SqlQuery.Condition(false, predicate)); + else + countSql.Where + .Expr(builder.ConvertToSql(outerKeyContext, outerKeySelector, false)).Equal + .Expr(builder.ConvertToSql(countKeyContext, innerKeySelector, false)); + } + + class InnerKeyContext : ExpressionContext + { + public InnerKeyContext(IBuildContext parent, IBuildContext sequence, LambdaExpression lambda) + : base(parent, sequence, lambda) + { + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + return base + .ConvertToSql(expression, level, flags) + .Select(idx => + { + var n = SqlQuery.Select.Add(idx.Sql); + + return new SqlInfo(idx.Members) + { + Sql = SqlQuery.Select.Columns[n], + Index = n + }; + }) + .ToArray(); + } + } + + internal class JoinContext : SelectContext + { + public JoinContext(IBuildContext parent, LambdaExpression lambda, IBuildContext outerContext, IBuildContext innerContext) + : base(parent, lambda, outerContext, innerContext) + { + } + } + + internal class GroupJoinContext : JoinContext + { + public GroupJoinContext( + IBuildContext parent, + LambdaExpression lambda, + IBuildContext outerContext, + GroupJoinSubQueryContext innerContext, + Expression innerExpression, + LambdaExpression outerKeyLambda, + LambdaExpression innerKeyLambda) + : base(parent, lambda, outerContext, innerContext) + { + _innerExpression = innerExpression; + _outerKeyLambda = outerKeyLambda; + _innerKeyLambda = innerKeyLambda; + + innerContext.GroupJoin = this; + } + + readonly Expression _innerExpression; + readonly LambdaExpression _outerKeyLambda; + readonly LambdaExpression _innerKeyLambda; + private Expression _groupExpression; + + interface IGroupJoinHelper + { + Expression GetGroupJoin(GroupJoinContext context); + } + + class GroupJoinHelper : IGroupJoinHelper + { + public Expression GetGroupJoin(GroupJoinContext context) + { + // Convert outer condition. + // + var outerParam = Expression.Parameter(context._outerKeyLambda.Body.Type, "o"); + var outerKey = context._outerKeyLambda.Body.Convert( + e => e == context._outerKeyLambda.Parameters[0] ? context.Lambda.Parameters[0] : e); + + outerKey = context.Builder.BuildExpression(context, outerKey); + + // Convert inner condition. + // + var parameters = context.Builder.CurrentSqlParameters + .Select((p,i) => new { p, i }) + .ToDictionary(_ => _.p.Expression, _ => _.i); + var paramArray = Expression.Parameter(typeof(object[]), "ps"); + + var innerKey = context._innerKeyLambda.Body.Convert(e => + { + int idx; + + if (parameters.TryGetValue(e, out idx)) + { + return + Expression.Convert( + Expression.ArrayIndex(paramArray, Expression.Constant(idx)), + e.Type); + } + + return e; + }); + + // Item reader. + // +// ReSharper disable AssignNullToNotNullAttribute + + var expr = Expression.Call( + null, + ReflectionHelper.Expressor.MethodExpressor(_ => Queryable.Where(null, (Expression>)null)), + context._innerExpression, + Expression.Lambda>( + Expression.Equal(innerKey, outerParam), + new[] { context._innerKeyLambda.Parameters[0] })); + +// ReSharper restore AssignNullToNotNullAttribute + + var lambda = Expression.Lambda>>( + Expression.Convert(expr, typeof(IQueryable)), + Expression.Parameter(typeof(IDataContext), "ctx"), + outerParam, + paramArray); + + var itemReader = CompiledQuery.Compile(lambda); + + return Expression.Call( + null, + ReflectionHelper.Expressor.MethodExpressor(_ => GetGrouping(null, null, default(TKey), null)), + new[] + { + ExpressionBuilder.ContextParam, + Expression.Constant(context.Builder.CurrentSqlParameters), + outerKey, + Expression.Constant(itemReader), + }); + } + + static IEnumerable GetGrouping( + QueryContext context, + List parameterAccessor, + TKey key, + Func> itemReader) + { + return new GroupByBuilder.GroupByContext.Grouping(key, context, parameterAccessor, itemReader); + } + } + + public override Expression BuildExpression(Expression expression, int level) + { + if (expression == Lambda.Parameters[1]) + { + if (_groupExpression == null) + { + var gtype = typeof(GroupJoinHelper<,>).MakeGenericType( + _innerKeyLambda.Body.Type, + _innerKeyLambda.Parameters[0].Type); + + var helper = (IGroupJoinHelper)Activator.CreateInstance(gtype); + + _groupExpression = helper.GetGroupJoin(this); + } + + return _groupExpression; + } + + return base.BuildExpression(expression, level); + } + } + + internal class GroupJoinSubQueryContext : SubQueryContext + { + //readonly MethodCallExpression _methodCall; + + public SqlQuery.JoinedTable Join; + public SqlQuery CounterSql; + public GroupJoinContext GroupJoin; + + public GroupJoinSubQueryContext(IBuildContext subQuery, MethodCallExpression methodCall) + : base(subQuery) + { + //_methodCall = methodCall; + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + if (expression == null) + return this; + + return base.GetContext(expression, level, buildInfo); + } + + Expression _counterExpression; + SqlInfo[] _counterInfo; + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + if (expression != null && expression == _counterExpression) + return _counterInfo ?? (_counterInfo = new[] + { + new SqlInfo + { + Query = CounterSql.ParentSql, + Index = CounterSql.ParentSql.Select.Add(CounterSql), + Sql = CounterSql + } + }); + + return base.ConvertToIndex(expression, level, flags); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor testFlag) + { + if (testFlag == RequestFor.GroupJoin && expression == null) + return IsExpressionResult.True; + + return base.IsExpression(expression, level, testFlag); + } + + public SqlQuery GetCounter(Expression expr) + { + Join.IsWeak = true; + + _counterExpression = expr; + + return CounterSql; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/MethodCallBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/MethodCallBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,125 @@ +using System; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + + abstract class MethodCallBuilder : ISequenceBuilder + { + public int BuildCounter { get; set; } + + public bool CanBuild(ExpressionBuilder builder, BuildInfo buildInfo) + { + if (buildInfo.Expression.NodeType == ExpressionType.Call) + return CanBuildMethodCall(builder, (MethodCallExpression)buildInfo.Expression, buildInfo); + return false; + } + + public IBuildContext BuildSequence(ExpressionBuilder builder, BuildInfo buildInfo) + { + return BuildMethodCall(builder, (MethodCallExpression)buildInfo.Expression, buildInfo); + } + + public SequenceConvertInfo Convert(ExpressionBuilder builder, BuildInfo buildInfo, ParameterExpression param) + { + return Convert(builder, (MethodCallExpression)buildInfo.Expression, buildInfo, param); + } + + public bool IsSequence(ExpressionBuilder builder, BuildInfo buildInfo) + { + return builder.IsSequence(new BuildInfo(buildInfo, ((MethodCallExpression)buildInfo.Expression).Arguments[0])); + } + + protected abstract bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo); + protected abstract IBuildContext BuildMethodCall (ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo); + protected abstract SequenceConvertInfo Convert (ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param); + + protected static Expression ConvertMethod( + MethodCallExpression methodCall, + int sourceTypeNumber, + SequenceConvertInfo info, + ParameterExpression param, + Expression expression) + { + if (expression == methodCall && param != null && param.Type != info.Parameter.Type) + { + var types = methodCall.Method.GetGenericArguments(); + var mgen = methodCall.Method.GetGenericMethodDefinition(); + + types[sourceTypeNumber] = info.Parameter.Type; + + var args = methodCall.Arguments.ToArray(); + + args[0] = info.Expression; + + for (var i = 1; i < args.Length; i++) + { + var arg = args[i].Unwrap(); + + if (arg.NodeType == ExpressionType.Lambda) + { + var l = (LambdaExpression)arg; + + if (l.Parameters.Any(a => a == param)) + { + args[i] = Expression.Lambda( + l.Body.Convert(ex => ConvertMethod(methodCall, sourceTypeNumber, info, param, ex)), + info.Parameter); + + return Expression.Call(methodCall.Object, mgen.MakeGenericMethod(types), args); + } + } + } + } + + if (expression == methodCall.Arguments[0]) + return info.Expression; + + switch (expression.NodeType) + { + case ExpressionType.Parameter : + + if (info.ExpressionsToReplace != null) + foreach (var item in info.ExpressionsToReplace) + if (expression == item.Path || expression == param && item.Path.NodeType == ExpressionType.Parameter) + return item.Expr; + break; + + case ExpressionType.MemberAccess : + + if (info.ExpressionsToReplace != null) + { + foreach (var item in info.ExpressionsToReplace) + { + var ex1 = expression; + var ex2 = item.Path; + + while (ex1.NodeType == ex2.NodeType) + { + if (ex1.NodeType == ExpressionType.Parameter) + return ex1 == ex2 || info.Parameter == ex2? item.Expr : expression; + + if (ex2.NodeType != ExpressionType.MemberAccess) + break; + + var ma1 = (MemberExpression)ex1; + var ma2 = (MemberExpression)ex2; + + if (ma1.Member != ma2.Member) + break; + + ex1 = ma1.Expression; + ex2 = ma2.Expression; + } + } + } + + break; + } + + return expression; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/OfTypeBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/OfTypeBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,124 @@ +using System; +using System.Data; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + using Reflection; + using Reflection.Extension; + + class OfTypeBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("OfType"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + var table = sequence as TableBuilder.TableContext; + + if (table != null && table.InheritanceMapping.Count > 0) + { + var objectType = methodCall.Type.GetGenericArguments()[0]; + + if (TypeHelper.IsSameOrParent(table.ObjectType, objectType)) + { + var predicate = builder.MakeIsPredicate(table, objectType); + + if (predicate.GetType() != typeof(SqlQuery.Predicate.Expr)) + sequence.SqlQuery.Where.SearchCondition.Conditions.Add(new SqlQuery.Condition(false, predicate)); + } + } + else + { + var toType = methodCall.Type.GetGenericArguments()[0]; + var gargs = TypeHelper.GetGenericArguments(methodCall.Arguments[0].Type, typeof(IQueryable<>)); + var fromType = gargs == null ? typeof(object) : gargs[0]; + + if (toType.IsSubclassOf(fromType)) + { + for (var type = toType.BaseType; type != null && type != typeof(object); type = type.BaseType) + { + var extension = TypeExtension.GetTypeExtension(type, builder.MappingSchema.Extensions); + var mapping = builder.MappingSchema.MetadataProvider.GetInheritanceMapping(type, extension); + + if (mapping.Length > 0) + { + var predicate = MakeIsPredicate(builder, sequence, fromType, toType); + + sequence.SqlQuery.Where.SearchCondition.Conditions.Add(new SqlQuery.Condition(false, predicate)); + + return new OfTypeContext(sequence, methodCall); + } + } + } + } + + return sequence; + } + + ISqlPredicate MakeIsPredicate(ExpressionBuilder builder, IBuildContext context, Type fromType, Type toType) + { + var table = new SqlTable(builder.MappingSchema, fromType); + var mapper = builder.MappingSchema.GetObjectMapper(fromType); + var discriminators = TableBuilder.TableContext.GetInheritanceDiscriminators( + builder, table, fromType, mapper.InheritanceMapping); + + return builder.MakeIsPredicate(context, mapper.InheritanceMapping, discriminators, toType, + name => + { + var field = table.Fields.Values.First(f => f.Name == name); + var member = field.MemberMapper.MemberAccessor.MemberInfo; + var expr = Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member); + var sql = context.ConvertToSql(expr, 1, ConvertFlags.Field)[0].Sql; + + return sql; + }); + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + #region OfTypeContext + + class OfTypeContext : PassThroughContext + { + public OfTypeContext(IBuildContext context, MethodCallExpression methodCall) + : base(context) + { + _methodCall = methodCall; + } + + private readonly MethodCallExpression _methodCall; + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + var expr = BuildExpression(null, 0); + var mapper = Builder.BuildMapper(expr); + + query.SetQuery(mapper.Compile()); + } + + public override Expression BuildExpression(Expression expression, int level) + { + var expr = base.BuildExpression(expression, level); + var type = _methodCall.Method.GetGenericArguments()[0]; + + if (expr.Type != type) + expr = Expression.Convert(expr, type); + + return expr; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/OrderByBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/OrderByBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,68 @@ +using System; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + + class OrderByBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + if (!methodCall.IsQueryable("OrderBy", "OrderByDescending", "ThenBy", "ThenByDescending")) + return false; + + var body = ((LambdaExpression)methodCall.Arguments[1].Unwrap()).Body.Unwrap(); + + if (body.NodeType == ExpressionType.MemberInit) + { + var mi = (MemberInitExpression)body; + bool throwExpr; + + if (mi.NewExpression.Arguments.Count > 0 || mi.Bindings.Count == 0) + throwExpr = true; + else + throwExpr = mi.Bindings.Any(b => b.BindingType != MemberBindingType.Assignment); + + if (throwExpr) + throw new NotSupportedException(string.Format("Explicit construction of entity type '{0}' in order by is not allowed.", body.Type)); + } + + return true; + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + + if (sequence.SqlQuery.Select.TakeValue != null || sequence.SqlQuery.Select.SkipValue != null) + sequence = new SubQueryContext(sequence); + + var lambda = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + var sparent = sequence.Parent; + var order = new ExpressionContext(buildInfo.Parent, sequence, lambda); + var body = lambda.Body.Unwrap(); + var sql = builder.ConvertExpressions(order, body, ConvertFlags.Key); + + builder.ReplaceParent(order, sparent); + + if (!methodCall.Method.Name.StartsWith("Then")) + sequence.SqlQuery.OrderBy.Items.Clear(); + + foreach (var expr in sql) + { + var e = builder.ConvertSearchCondition(sequence, expr.Sql); + sequence.SqlQuery.OrderBy.Expr(e, methodCall.Method.Name.EndsWith("Descending")); + } + + return sequence; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/PassThroughBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/PassThroughBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + + class PassThroughBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("AsQueryable"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/PassThroughContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/PassThroughContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,73 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using Data.Sql; + + public abstract class PassThroughContext : IBuildContext + { + protected PassThroughContext(IBuildContext context) + { + Context = context; + + context.Builder.Contexts.Add(this); + } + + public IBuildContext Context { get; set; } + +#if DEBUG + string IBuildContext._sqlQueryText { get { return Context._sqlQueryText; } } +#endif + + public virtual ExpressionBuilder Builder { get { return Context.Builder; } } + public virtual Expression Expression { get { return Context.Expression; } } + public virtual SqlQuery SqlQuery { get { return Context.SqlQuery; } set { Context.SqlQuery = value; } } + public virtual IBuildContext Parent { get { return Context.Parent; } set { Context.Parent = value; } } + + public virtual void BuildQuery(Query query, ParameterExpression queryParameter) + { + Context.BuildQuery(query, queryParameter); + } + + public virtual Expression BuildExpression(Expression expression, int level) + { + return Context.BuildExpression(expression, level); + } + + public virtual SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + return Context.ConvertToSql(expression, level, flags); + } + + public virtual SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + return Context.ConvertToIndex(expression, level, flags); + } + + public virtual IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + return Context.IsExpression(expression, level, requestFlag); + } + + public virtual IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + return Context.GetContext(expression, level, buildInfo); + } + + public virtual int ConvertToParentIndex(int index, IBuildContext context) + { + return Context.ConvertToParentIndex(index, context); + } + + public virtual void SetAlias(string alias) + { + Context.SetAlias(alias); + } + + public virtual ISqlExpression GetSubQuery(IBuildContext context) + { + return Context.GetSubQuery(context); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/RequestFor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/RequestFor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,52 @@ +using System; + +namespace BLToolkit.Data.Linq.Builder +{ + public enum RequestFor + { + /// + /// Checks the sequence if the expression is a table or an association. + /// + Table, + + /// + /// Checks the sequence if the expression is an association. + /// + Association, + + /// + /// Checks the sequence if the expression is a table, an association, new {}, or new MyClass {}. + /// + Object, + + /// + /// Checks the sequence if the expression is a group join. + /// + GroupJoin, + + /// + /// Checks the sequence if the expression is a field or single value expression. + /// + //Scalar, + + /// + /// Checks the sequence if the expression is a field. + /// + Field, + + /// + /// Checks the sequence if the expression contains an SQL expression. + /// + Expression, + + /// + /// Checks the context if it's a subquery. + /// + SubQuery, + + /// + /// Checks the context if it's a root of the expression. + /// + Root, + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/ScalarSelectBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/ScalarSelectBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,134 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class ScalarSelectBuilder : ISequenceBuilder + { + public int BuildCounter { get; set; } + + public bool CanBuild(ExpressionBuilder builder, BuildInfo buildInfo) + { + return + buildInfo.Expression.NodeType == ExpressionType.Lambda && + ((LambdaExpression)buildInfo.Expression).Parameters.Count == 0; + } + + public IBuildContext BuildSequence(ExpressionBuilder builder, BuildInfo buildInfo) + { + return new ScalarSelectContext(builder) + { + Parent = buildInfo.Parent, + Expression = buildInfo.Expression, + SqlQuery = buildInfo.SqlQuery + }; + } + + public SequenceConvertInfo Convert(ExpressionBuilder builder, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + public bool IsSequence(ExpressionBuilder builder, BuildInfo buildInfo) + { + return true; + } + + class ScalarSelectContext : IBuildContext + { + public ScalarSelectContext(ExpressionBuilder builder) + { + Builder = builder; + + builder.Contexts.Add(this); + } + +#if DEBUG + public string _sqlQueryText { get { return SqlQuery == null ? "" : SqlQuery.SqlText; } } +#endif + + public ExpressionBuilder Builder { get; set; } + public Expression Expression { get; set; } + public SqlQuery SqlQuery { get; set; } + public IBuildContext Parent { get; set; } + + public void BuildQuery(Query query, ParameterExpression queryParameter) + { + var expr = BuildExpression(null, 0); + var mapper = Builder.BuildMapper(expr); + + query.SetQuery(mapper.Compile()); + } + + public Expression BuildExpression(Expression expression, int level) + { + if (expression == null) + expression = ((LambdaExpression)Expression).Body.Unwrap(); + + switch (expression.NodeType) + { + case ExpressionType.New: + case ExpressionType.MemberInit: + { + var expr = Builder.BuildExpression(this, expression); + + if (SqlQuery.Select.Columns.Count == 0) + SqlQuery.Select.Expr(new SqlValue(1)); + + return expr; + } + + default : + { + var expr = Builder.ConvertToSql(this, expression, false); + var idx = SqlQuery.Select.Add(expr); + + return Builder.BuildSql(expression.Type, idx); + } + } + + } + + public SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + throw new NotImplementedException(); + } + + public SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + throw new NotImplementedException(); + } + + public IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + switch (requestFlag) + { + case RequestFor.Expression : return IsExpressionResult.True; + default : return IsExpressionResult.False; + } + } + + public IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + throw new NotImplementedException(); + } + + public int ConvertToParentIndex(int index, IBuildContext context) + { + throw new NotImplementedException(); + } + + public void SetAlias(string alias) + { + } + + public ISqlExpression GetSubQuery(IBuildContext context) + { + return null; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/SelectBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/SelectBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,315 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Reflection; + + class SelectBuilder : MethodCallBuilder + { + #region SelectBuilder + + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + if (methodCall.IsQueryable("Select")) + { + switch (((LambdaExpression)methodCall.Arguments[1].Unwrap()).Parameters.Count) + { + case 1 : + case 2 : return true; + default: break; + } + } + + return false; + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var selector = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + + sequence.SetAlias(selector.Parameters[0].Name); + + var body = selector.Body.Unwrap(); + + switch (body.NodeType) + { + case ExpressionType.Parameter : break; + default : + sequence = CheckSubQueryForSelect(sequence); + break; + } + + var context = selector.Parameters.Count == 1 ? + new SelectContext (buildInfo.Parent, selector, sequence) : + new SelectContext2(buildInfo.Parent, selector, sequence); + +#if DEBUG + context.MethodCall = methodCall; +#endif + + return context; + } + + static IBuildContext CheckSubQueryForSelect(IBuildContext context) + { + return context.SqlQuery.Select.IsDistinct ? new SubQueryContext(context) : context; + } + + #endregion + + #region SelectContext2 + + class SelectContext2 : SelectContext + { + public SelectContext2(IBuildContext parent, LambdaExpression lambda, IBuildContext sequence) + : base(parent, lambda, sequence) + { + } + + static readonly ParameterExpression _counterParam = Expression.Parameter(typeof(int), "counter"); + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + var expr = BuildExpression(null, 0); + + if (expr.Type != typeof(T)) + expr = Expression.Convert(expr, typeof(T)); + + var mapper = Expression.Lambda>( + Builder.BuildBlock(expr), new [] + { + _counterParam, + ExpressionBuilder.ContextParam, + ExpressionBuilder.DataContextParam, + ExpressionBuilder.DataReaderParam, + ExpressionBuilder.ExpressionParam, + ExpressionBuilder.ParametersParam, + }); + + var func = mapper.Compile(); + + Func map = (ctx,db,rd,e,ps,n) => func(n, ctx, db, rd, e, ps); + + query.SetQuery(map); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + switch (requestFlag) + { + case RequestFor.Expression : + case RequestFor.Root : + if (expression == Lambda.Parameters[1]) + return IsExpressionResult.True; + break; + } + + return base.IsExpression(expression, level, requestFlag); + } + + public override Expression BuildExpression(Expression expression, int level) + { + if (expression == Lambda.Parameters[1]) + return _counterParam; + + return base.BuildExpression(expression, level); + } + } + + #endregion + + #region Convert + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression originalMethodCall, BuildInfo buildInfo, ParameterExpression param) + { + var methodCall = originalMethodCall; + var selector = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + var info = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), selector.Parameters[0]); + + if (info != null) + { + methodCall = (MethodCallExpression)methodCall.Convert( + ex => ConvertMethod(methodCall, 0, info, selector.Parameters[0], ex)); + selector = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + } + + if (param != null && param != builder.SequenceParameter) + { + var list = + ( + from path in GetExpressions(selector.Parameters[0], param, 0, selector.Body.Unwrap()) + orderby path.Level descending + select path + ).ToList(); + + if (list.Count > 0) + { + var plist = list.Where(e => e.Expr == selector.Parameters[0]).ToList(); + + if (plist.Count > 1) + list = list.Except(plist.Skip(1)).ToList(); + + var p = plist.FirstOrDefault(); + + if (p == null) + { + var types = methodCall.Method.GetGenericArguments(); + var mgen = methodCall.Method.GetGenericMethodDefinition(); + var btype = typeof(ExpressionHoder<,>).MakeGenericType(types[0], selector.Body.Type); + var fields = btype.GetFields(); + var pold = selector.Parameters[0]; + var psel = Expression.Parameter(types[0], pold.Name); + + methodCall = Expression.Call( + methodCall.Object, + mgen.MakeGenericMethod(types[0], btype), + methodCall.Arguments[0], + Expression.Lambda( + Expression.MemberInit( + Expression.New(btype), + Expression.Bind(fields[0], psel), + Expression.Bind(fields[1], selector.Body.Convert(e => e == pold ? psel : e))), + psel)); + + selector = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + param = Expression.Parameter(selector.Body.Type, param.Name); + + list.Add(new SequenceConvertPath { Path = param, Expr = Expression.MakeMemberAccess(param, fields[1]), Level = 1 }); + + var expr = Expression.MakeMemberAccess(param, fields[0]); + + foreach (var t in list) + t.Expr = t.Expr.Convert(ex => ex == pold ? expr : ex); + + return new SequenceConvertInfo + { + Parameter = param, + Expression = methodCall, + ExpressionsToReplace = list + }; + } + + if (info != null) + { + if (info.ExpressionsToReplace != null) + { + foreach (var path in info.ExpressionsToReplace) + { + path.Path = path.Path.Convert(e => e == info.Parameter ? p.Path : e); + path.Expr = path.Expr.Convert(e => e == info.Parameter ? p.Path : e); + path.Level += p.Level; + + list.Add(path); + } + + list = list.OrderByDescending(path => path.Level).ToList(); + } + } + + if (list.Count > 1) + { + return new SequenceConvertInfo + { + Parameter = param, + Expression = methodCall, + ExpressionsToReplace = list + .Where (e => e != p) + .Select(ei => + { + ei.Expr = ei.Expr.Convert(e => e == p.Expr ? p.Path : e); + return ei; + }) + .ToList() + }; + } + } + } + + if (methodCall != originalMethodCall) + return new SequenceConvertInfo + { + Parameter = param, + Expression = methodCall, + }; + + return null; + } + + static IEnumerable GetExpressions(ParameterExpression param, Expression path, int level, Expression expression) + { + switch (expression.NodeType) + { + // new { ... } + // + case ExpressionType.New : + { + var expr = (NewExpression)expression; + + if (expr.Members != null) for (var i = 0; i < expr.Members.Count; i++) + { + var q = GetExpressions(param, Expression.MakeMemberAccess(path, expr.Members[i]), level + 1, expr.Arguments[i]); + foreach (var e in q) + yield return e; + } + + break; + } + + // new MyObject { ... } + // + case ExpressionType.MemberInit : + { + var expr = (MemberInitExpression)expression; + var dic = TypeAccessor.GetAccessor(expr.Type) + .Select((m,i) => new { m, i }) + .ToDictionary(_ => _.m.MemberInfo.Name, _ => _.i); + + foreach (var binding in expr.Bindings.Cast().OrderBy(b => dic[b.Member.Name])) + { + var q = GetExpressions(param, Expression.MakeMemberAccess(path, binding.Member), level + 1, binding.Expression); + foreach (var e in q) + yield return e; + } + + break; + } + + // parameter + // + case ExpressionType.Parameter : + if (expression == param) + yield return new SequenceConvertPath { Path = path, Expr = expression, Level = level }; + break; + + case ExpressionType.TypeAs : + yield return new SequenceConvertPath { Path = path, Expr = expression, Level = level }; + break; + + // Queriable method. + // + case ExpressionType.Call : + { + var call = (MethodCallExpression)expression; + + if (call.IsQueryable()) + if (TypeHelper.IsSameOrParent(typeof(IEnumerable), call.Type) || + TypeHelper.IsSameOrParent(typeof(IQueryable), call.Type) || + FirstSingleBuilder.MethodNames.Contains(call.Method.Name)) + yield return new SequenceConvertPath { Path = path, Expr = expression, Level = level }; + + break; + } + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/SelectContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/SelectContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1081 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + using Reflection; + + // This class implements double functionality (scalar and member type selects) + // and could be implemented as two different classes. + // But the class means to have a lot of inheritors, and functionality of the inheritors + // will be doubled as well. So lets double it once here. + // + public class SelectContext : IBuildContext + { + #region Init + +#if DEBUG + [CLSCompliant(false)] + public string _sqlQueryText { get { return SqlQuery == null ? "" : SqlQuery.SqlText; } } + + public MethodCallExpression MethodCall; +#endif + + public IBuildContext[] Sequence { get; set; } + public LambdaExpression Lambda { get; set; } + public Expression Body { get; set; } + public ExpressionBuilder Builder { get; private set; } + public SqlQuery SqlQuery { get; set; } + public IBuildContext Parent { get; set; } + public bool IsScalar { get; private set; } + + Expression IBuildContext.Expression { get { return Lambda; } } + + public readonly Dictionary Members = new Dictionary(new MemberInfoComparer()); + + public SelectContext(IBuildContext parent, LambdaExpression lambda, params IBuildContext[] sequences) + { + Parent = parent; + Sequence = sequences; + Builder = sequences[0].Builder; + Lambda = lambda; + Body = lambda.Body; + SqlQuery = sequences[0].SqlQuery; + + foreach (var context in Sequence) + context.Parent = this; + + IsScalar = !Builder.ProcessProjection(Members, Body); + + Builder.Contexts.Add(this); + } + + #endregion + + #region BuildQuery + + public virtual void BuildQuery(Query query, ParameterExpression queryParameter) + { + var expr = BuildExpression(null, 0); + var mapper = Builder.BuildMapper(expr); + + query.SetQuery(mapper.Compile()); + } + + #endregion + + #region BuildExpression + + public virtual Expression BuildExpression(Expression expression, int level) + { + { + var key = Tuple.Create(expression, level, ConvertFlags.Field); + + SqlInfo[] info; + + if (_expressionIndex.TryGetValue(key, out info)) + { + var idx = Parent == null ? info[0].Index : Parent.ConvertToParentIndex(info[0].Index, this); + return Builder.BuildSql((expression ?? Body).Type, idx); + } + } + + if (expression == null) + return Builder.BuildExpression(this, Body); + + var levelExpression = expression.GetLevelExpression(level); + + if (IsScalar) + { + if (Body.NodeType != ExpressionType.Parameter && level == 0) + if (levelExpression == expression) + if (IsSubQuery() && IsExpression(null, 0, RequestFor.Expression).Result) + { + var info = ConvertToIndex(expression, level, ConvertFlags.Field).Single(); + var idx = Parent == null ? info.Index : Parent.ConvertToParentIndex(info.Index, this); + + return Builder.BuildSql(expression.Type, idx); + } + + return ProcessScalar( + expression, + level, + (ctx, ex, l) => ctx.BuildExpression(ex, l), + () => GetSequence(expression, level).BuildExpression(null, 0)); + } + else + { + if (level == 0) + { + var sequence = GetSequence(expression, level); + + return levelExpression == expression ? + sequence.BuildExpression(null, 0) : + sequence.BuildExpression(expression, level + 1); + } + + switch (levelExpression.NodeType) + { + case ExpressionType.MemberAccess : + { + var memberExpression = GetMemberExpression( + ((MemberExpression)levelExpression).Member, + levelExpression == expression, + levelExpression.Type); + + if (levelExpression == expression) + { + if (IsSubQuery()) + { + switch (memberExpression.NodeType) + { + case ExpressionType.New : + case ExpressionType.MemberInit : + { + return memberExpression.Convert(e => + { + if (e != memberExpression) + { + switch (e.NodeType) + { + case ExpressionType.MemberAccess : + var sequence = GetSequence(memberExpression, 0); + + if (sequence != null && + !sequence.IsExpression(e, 0, RequestFor.Object).Result && + !sequence.IsExpression(e, 0, RequestFor.Field). Result) + { + var info = ConvertToIndex(e, 0, ConvertFlags.Field).Single(); + var idx = Parent == null ? info.Index : Parent.ConvertToParentIndex(info.Index, this); + + return Builder.BuildSql(e.Type, idx); + } + + return Builder.BuildExpression(this, e); + } + } + + return e; + }); + } + } + + var me = memberExpression.NodeType == ExpressionType.Parameter ? null : memberExpression; + + if (!IsExpression(me, 0, RequestFor.Object).Result && + !IsExpression(me, 0, RequestFor.Field). Result) + { + var info = ConvertToIndex(expression, level, ConvertFlags.Field).Single(); + var idx = Parent == null ? info.Index : Parent.ConvertToParentIndex(info.Index, this); + + return Builder.BuildSql(expression.Type, idx); + } + } + + return Builder.BuildExpression(this, memberExpression); + } + + { + var sequence = GetSequence(expression, level); + + switch (memberExpression.NodeType) + { + case ExpressionType.Parameter : + { + var parameter = Lambda.Parameters[Sequence.Length == 0 ? 0 : Array.IndexOf(Sequence, sequence)]; + + if (memberExpression == parameter) + return sequence.BuildExpression(expression, level + 1); + + break; + + } + + case ExpressionType.New : + case ExpressionType.MemberInit : + { + var mmExpresion = GetMemberExpression(memberExpression, expression, level + 1); + return Builder.BuildExpression(this, mmExpresion); + } + } + + var expr = expression.Convert(ex => ex == levelExpression ? memberExpression : ex); + + return sequence.BuildExpression(expr, 1); + } + } + + case ExpressionType.Parameter : + break; + } + } + + throw new InvalidOperationException(); + } + + #endregion + + #region ConvertToSql + + readonly Dictionary _sql = new Dictionary(new MemberInfoComparer()); + + public virtual SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + if (expression != null && level > 0 && expression.NodeType == ExpressionType.Call) + { + var e = (MethodCallExpression)expression; + + if (e.Method.DeclaringType == typeof(Enumerable)) + { + return new[] { new SqlInfo { Sql = Builder.SubQueryToSql(this, e) } }; + } + } + + if (IsScalar) + { + if (expression == null) + return Builder.ConvertExpressions(this, Body, flags); + + switch (flags) + { + case ConvertFlags.Field : + case ConvertFlags.Key : + case ConvertFlags.All : + { + if (Body.NodeType != ExpressionType.Parameter && level == 0) + { + var levelExpression = expression.GetLevelExpression(level); + + if (levelExpression != expression) + if (flags != ConvertFlags.Field && IsExpression(expression, level, RequestFor.Field).Result) + flags = ConvertFlags.Field; + } + + return ProcessScalar( + expression, + level, + (ctx, ex, l) => ctx.ConvertToSql(ex, l, flags), + () => new[] { new SqlInfo { Sql = Builder.ConvertToSql(this, expression, false) } }); + } + } + } + else + { + if (expression == null) + { + if (flags != ConvertFlags.Field) + { + var q = + from m in Members + where !(m.Key is MethodInfo) + select ConvertMember(m.Key, m.Value, flags) into mm + from m in mm + select m; + + return q.ToArray(); + } + + throw new InvalidOperationException(); + } + + switch (flags) + { + case ConvertFlags.All : + case ConvertFlags.Key : + case ConvertFlags.Field : + { + var levelExpression = expression.GetLevelExpression(level); + + switch (levelExpression.NodeType) + { + case ExpressionType.MemberAccess : + { + if (level != 0 && levelExpression == expression) + { + var member = ((MemberExpression)levelExpression).Member; + + SqlInfo[] sql; + + if (!_sql.TryGetValue(member, out sql)) + { + var memberExpression = GetMemberExpression( + member, levelExpression == expression, levelExpression.Type); + + sql = ConvertExpressions(memberExpression, flags) + .Select(si => si.Clone(member)).ToArray(); + + _sql.Add(member, sql); + } + + return sql; + } + + return ProcessMemberAccess( + expression, (MemberExpression)levelExpression, level, + (n,ctx,ex,l,mex) => + { + switch (n) + { + case 0 : + var buildExpression = GetExpression(expression, levelExpression, mex); + return ConvertExpressions(buildExpression, flags); + default: + return ctx.ConvertToSql(ex, l, flags); + } + }); + } + + case ExpressionType.Parameter: + if (levelExpression != expression) + return GetSequence(expression, level).ConvertToSql(expression, level + 1, flags); + + if (level == 0) + return GetSequence(expression, level).ConvertToSql(null, 0, flags); + + break; + + default: + if (level == 0) + return Builder.ConvertExpressions(this, expression, flags); + break; + } + + break; + } + } + } + + throw new InvalidOperationException(); + } + + SqlInfo[] ConvertMember(MemberInfo member, Expression expression, ConvertFlags flags) + { + return ConvertExpressions(expression, flags) + .Select(si => si.Clone(member)) + .ToArray(); + } + + SqlInfo[] ConvertExpressions(Expression expression, ConvertFlags flags) + { + return Builder.ConvertExpressions(this, expression, flags) + .Select(CheckExpression) + .ToArray(); + } + + SqlInfo CheckExpression(SqlInfo expression) + { + if (expression.Sql is SqlQuery.SearchCondition) + { + expression.Sql = Builder.Convert(this, new SqlFunction(typeof(bool), "CASE", expression.Sql, new SqlValue(true), new SqlValue(false))); + } + + return expression; + } + + #endregion + + #region ConvertToIndex + + readonly Dictionary,SqlInfo[]> _expressionIndex = new Dictionary,SqlInfo[]>(); + + public virtual SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + var key = Tuple.Create(expression, level, flags); + + SqlInfo[] info; + + if (!_expressionIndex.TryGetValue(key, out info)) + { + info = ConvertToIndexInternal(expression, level, flags); + + var newInfo = info + .Select(i => + { + if (i.Query == SqlQuery) + return i; + + return new SqlInfo(i.Members) + { + Query = SqlQuery, + Index = SqlQuery.Select.Add(i.Query.Select.Columns[i.Index]) + }; + }) + .ToArray(); + + _expressionIndex.Add(key, newInfo); + + return newInfo; + } + + return info; + } + + readonly Dictionary,SqlInfo[]> _memberIndex = new Dictionary,SqlInfo[]>(); + + SqlInfo[] ConvertToIndexInternal(Expression expression, int level, ConvertFlags flags) + { + if (IsScalar) + { + if (Body.NodeType == ExpressionType.Parameter) + for (var i = 0; i < Sequence.Length; i++) + if (Body == Lambda.Parameters[i]) + return Sequence[i].ConvertToIndex(expression, level, flags); + + if (expression == null) + { + var key = Tuple.Create((MemberInfo)null, flags); + + SqlInfo[] idx; + + if (!_memberIndex.TryGetValue(key, out idx)) + { + idx = ConvertToSql(null, 0, flags); + + foreach (var info in idx) + SetInfo(info); + + _memberIndex.Add(key, idx); + } + + return idx; + } + + switch (flags) + { + case ConvertFlags.Field : + case ConvertFlags.All : + return ProcessScalar( + expression, + level, + (ctx, ex, l) => ctx.ConvertToIndex(ex, l, flags), + () => GetSequence(expression, level).ConvertToIndex(expression, level + 1, flags)); + } + } + else + { + if (expression == null) + { + switch (flags) + { + case ConvertFlags.Field : throw new InvalidOperationException(); + case ConvertFlags.Key : + case ConvertFlags.All : + { + var p = Expression.Parameter(Body.Type, "p"); + var q = + from m in Members.Keys + where !(m is MethodInfo) + select new + { + Sql = ConvertToIndex(Expression.MakeMemberAccess(p, m), 1, flags), + Member = m + } into mm + from m in mm.Sql.Select(s => s.Clone(mm.Member)) + select m; + + return q.ToArray(); + } + } + } + + switch (flags) + { + case ConvertFlags.All : + case ConvertFlags.Key : + case ConvertFlags.Field : + { + if (level == 0) + { + var idx = Builder.ConvertExpressions(this, expression, flags); + + foreach (var info in idx) + SetInfo(info); + + return idx; + } + + var levelExpression = expression.GetLevelExpression(level); + + switch (levelExpression.NodeType) + { + case ExpressionType.MemberAccess : + { + if (levelExpression == expression) + { + var member = Tuple.Create(((MemberExpression)levelExpression).Member, flags); + + SqlInfo[] idx; + + if (!_memberIndex.TryGetValue(member, out idx)) + { + idx = ConvertToSql(expression, level, flags); + + if (flags == ConvertFlags.Field && idx.Length != 1) + throw new InvalidOperationException(); + + foreach (var info in idx) + SetInfo(info); + + _memberIndex.Add(member, idx); + } + + return idx; + } + + return ProcessMemberAccess( + expression, + (MemberExpression)levelExpression, + level, + (n, ctx, ex, l, _) => n == 0 ? + GetSequence(expression, level).ConvertToIndex(expression, level + 1, flags) : + ctx.ConvertToIndex(ex, l, flags)); + } + + case ExpressionType.Parameter: + + if (levelExpression != expression) + return GetSequence(expression, level).ConvertToIndex(expression, level + 1, flags); + break; + } + + break; + } + } + } + + throw new InvalidOperationException(); + } + + void SetInfo(SqlInfo info) + { + info.Query = SqlQuery; + + if (info.Sql == SqlQuery) + info.Index = SqlQuery.Select.Columns.Count - 1; + else + info.Index = SqlQuery.Select.Add(info.Sql); + } + + #endregion + + #region IsExpression + + public virtual IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + switch (requestFlag) + { + case RequestFor.SubQuery : return IsExpressionResult.False; + case RequestFor.Root : + return new IsExpressionResult(Sequence.Length == 1 ? + expression == Lambda.Parameters[0] : + Lambda.Parameters.Any(p => p == expression)); + } + + if (IsScalar) + { + if (expression == null) + return IsExpression(Body, 0, requestFlag); + + switch (requestFlag) + { + default : return IsExpressionResult.False; + case RequestFor.Table : + case RequestFor.Association : + case RequestFor.Field : + case RequestFor.Expression : + case RequestFor.Object : + case RequestFor.GroupJoin : + return ProcessScalar( + expression, + level, + (ctx, ex, l) => ctx.IsExpression(ex, l, requestFlag), + () => new IsExpressionResult(requestFlag == RequestFor.Expression)); + } + } + else + { + switch (requestFlag) + { + default : return IsExpressionResult.False; + case RequestFor.Table : + case RequestFor.Association : + case RequestFor.Field : + case RequestFor.Expression : + case RequestFor.Object : + case RequestFor.GroupJoin : + { + if (expression == null) + { + if (requestFlag == RequestFor.Expression) + return new IsExpressionResult(Members.Values.Any(member => IsExpression(member, 0, requestFlag).Result)); + + return new IsExpressionResult(requestFlag == RequestFor.Object); + } + + var levelExpression = expression.GetLevelExpression(level); + + switch (levelExpression.NodeType) + { + case ExpressionType.MemberAccess : + { + var member = ((MemberExpression)levelExpression).Member; + + Expression memberExpression; + + if (!Members.TryGetValue(member, out memberExpression)) + { + var nm = Members.Keys.FirstOrDefault(m => m.Name == member.Name); + + if (nm != null && member.DeclaringType.IsInterface) + { + if (TypeHelper.IsSameOrParent(member.DeclaringType, nm.DeclaringType)) + memberExpression = Members[nm]; + else + { + var mdt = TypeHelper.GetDefiningTypes(member.DeclaringType, member); + var ndt = TypeHelper.GetDefiningTypes(Body.Type, nm); + + if (mdt.Intersect(ndt).Any()) + memberExpression = Members[nm]; + } + } + + if (memberExpression == null) + return new IsExpressionResult(requestFlag == RequestFor.Expression); + //throw new InvalidOperationException( + // string.Format("Invalid member '{0}.{1}'", member.DeclaringType, member.Name)); + } + + if (levelExpression == expression) + { + switch (memberExpression.NodeType) + { + case ExpressionType.New : + case ExpressionType.MemberInit : + return new IsExpressionResult(requestFlag == RequestFor.Object); + } + } + + return ProcessMemberAccess( + expression, + (MemberExpression)levelExpression, + level, + (n,ctx,ex,l,_) => n == 0 ? + new IsExpressionResult(requestFlag == RequestFor.Expression) : + ctx.IsExpression(ex, l, requestFlag)); + } + + case ExpressionType.Parameter : + { + var sequence = GetSequence(expression, level); + var parameter = Lambda.Parameters[Sequence.Length == 0 ? 0 : Array.IndexOf(Sequence, sequence)]; + + if (levelExpression == expression) + { + if (levelExpression == parameter) + return sequence.IsExpression(null, 0, requestFlag); + } + else if (level == 0) + return sequence.IsExpression(expression, 1, requestFlag); + + break; + } + + case ExpressionType.New : + case ExpressionType.MemberInit : return new IsExpressionResult(requestFlag == RequestFor.Object); + default : return new IsExpressionResult(requestFlag == RequestFor.Expression); + } + + break; + } + } + } + + throw new InvalidOperationException(); + } + + #endregion + + #region GetContext + + public virtual IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + if (expression == null) + return this; + + if (IsScalar) + { + return ProcessScalar( + expression, + level, + (ctx, ex, l) => ctx.GetContext(ex, l, buildInfo), + () => { throw new InvalidOperationException(); }); + } + else + { + var levelExpression = expression.GetLevelExpression(level); + + switch (levelExpression.NodeType) + { + case ExpressionType.MemberAccess : + { + if (levelExpression == expression && Sequence.Length == 1 && !(Sequence[0] is GroupByBuilder.GroupByContext)) + { + var memberExpression = GetMemberExpression( + ((MemberExpression)levelExpression).Member, + levelExpression == expression, + levelExpression.Type); + + //var sequence = GetSequence(memberExpression, 0); + //return sequence.GetContext(memberExpression, 1, new BuildInfo(buildInfo, memberExpression)); + + var ctx = GetContext(memberExpression, 0, new BuildInfo(this, memberExpression, buildInfo.SqlQuery)); + + if (ctx != null) + { + return ctx; + } + } + + var context = ProcessMemberAccess( + expression, + (MemberExpression)levelExpression, + level, + (n,ctx,ex,l,_) => n == 0 ? + null : + ctx.GetContext(ex, l, buildInfo)); + + if (context == null) + throw new InvalidOperationException(); + + return context; + } + + case ExpressionType.Parameter : + { + var sequence = GetSequence(expression, level); + var parameter = Lambda.Parameters[Sequence.Length == 0 ? 0 : Array.IndexOf(Sequence, sequence)]; + + if (levelExpression == expression) + { + if (levelExpression == parameter) + return sequence.GetContext(null, 0, buildInfo); + } + else if (level == 0) + return sequence.GetContext(expression, 1, buildInfo); + + break; + } + } + + if (level == 0) + { + var sequence = GetSequence(expression, level); + return sequence.GetContext(expression, level + 1, buildInfo); + } + } + + throw new InvalidOperationException(); + } + + #endregion + + #region ConvertToParentIndex + + public virtual int ConvertToParentIndex(int index, IBuildContext context) + { + if (context.SqlQuery != SqlQuery) + index = SqlQuery.Select.Add(context.SqlQuery.Select.Columns[index]); + + return Parent == null ? index : Parent.ConvertToParentIndex(index, this); + } + + #endregion + + #region SetAlias + + public virtual void SetAlias(string alias) + { + } + + #endregion + + #region GetSubQuery + + public ISqlExpression GetSubQuery(IBuildContext context) + { + return null; + } + + #endregion + + #region Helpers + + T ProcessScalar(Expression expression, int level, Func action, Func defaultAction) + { + if (level == 0) + { + if (Body.NodeType == ExpressionType.Parameter) + { + var sequence = GetSequence(Body, 0); + + return expression == Body ? + action(sequence, null, 0) : + action(sequence, expression, 1); + } + + var levelExpression = expression.GetLevelExpression(level); + + if (levelExpression != expression) + { + var ctx = GetSequence(expression, level); + return ctx == null ? defaultAction() : action(ctx, expression, Sequence.Contains(ctx) ? level + 1 : 0); + } + + if (expression.NodeType == ExpressionType.Parameter) + { + var sequence = GetSequence(expression, level); + var parameter = Lambda.Parameters[Sequence.Length == 0 ? 0 : Array.IndexOf(Sequence, sequence)]; + + if (levelExpression == parameter) + return action(sequence, null, 0); + } + + switch (Body.NodeType) + { + case ExpressionType.MemberAccess : return action(GetSequence(expression, level), null, 0); + default : return defaultAction(); + } + } + else + { + var root = Body.GetRootObject(); + + if (root.NodeType == ExpressionType.Parameter) + { + var levelExpression = expression.GetLevelExpression(level - 1); + var newExpression = GetExpression(expression, levelExpression, Body); + + return action(this, newExpression, 0); + } + } + + throw new InvalidOperationException(); + } + + T ProcessMemberAccess(Expression expression, MemberExpression levelExpression, int level, + Func action) + { + var memberExpression = Members[levelExpression.Member]; + var newExpression = GetExpression(expression, levelExpression, memberExpression); + var sequence = GetSequence (expression, level); + var nextLevel = 1; + + if (sequence != null) + { + var idx = Sequence.Length == 0 ? 0 : Array.IndexOf(Sequence, sequence); + + if (idx >= 0) + { + var parameter = Lambda.Parameters[idx]; + + if (levelExpression == expression) + { + if (memberExpression == parameter) + return action(1, sequence, null, 0, memberExpression); + +// if (!(sequence is GroupByBuilder.GroupByContext) && memberExpression.GetRootObject() == parameter) +// return action(3, this, newExpression, 0, memberExpression); + } + } + else + { + nextLevel = 0; + } + } + + switch (memberExpression.NodeType) + { + case ExpressionType.MemberAccess : + case ExpressionType.Parameter : + if (sequence != null) + return action(2, sequence, newExpression, nextLevel, memberExpression); + throw new InvalidOperationException(); + + case ExpressionType.New : + case ExpressionType.MemberInit : + { + var mmExpresion = GetMemberExpression(memberExpression, expression, level + 1); + return action(3, this, mmExpresion, 0, memberExpression); + } + } + + return action(0, this, null, 0, memberExpression); + } + + protected bool IsSubQuery() + { + for (var p = Parent; p != null; p = p.Parent) + if (p.IsExpression(null, 0, RequestFor.SubQuery).Result) + return true; + return false; + } + + IBuildContext GetSequence(Expression expression, int level) + { + if (Sequence.Length == 1 && Sequence[0].Parent == null) + return Sequence[0]; + + Expression root = null; + + if (IsScalar) + { + root = expression.GetRootObject(); + } + else + { + var levelExpression = expression.GetLevelExpression(level); + + switch (levelExpression.NodeType) + { + case ExpressionType.MemberAccess : + { + var memberExpression = Members[((MemberExpression)levelExpression).Member]; + + root = memberExpression.GetRootObject(); + + if (root.NodeType != ExpressionType.Parameter) + return null; + + break; + } + + case ExpressionType.Parameter : + { + root = expression.GetRootObject(); + break; + } + } + } + + if (root != null) + for (var i = 0; i < Lambda.Parameters.Count; i++) + if (root == Lambda.Parameters[i]) + return Sequence[i]; + + foreach (var context in Sequence) + { + if (context.Parent != null) + { + var ctx = Builder.GetContext(context, root); + if (ctx != null) + return ctx; + } + } + + return null; + } + + static Expression GetExpression(Expression expression, Expression levelExpression, Expression memberExpression) + { + return levelExpression != expression ? + expression.Convert(ex => ex == levelExpression ? memberExpression : ex) : + memberExpression; + } + + static Expression GetMemberExpression(Expression newExpression, Expression expression, int level) + { + var levelExpresion = expression.GetLevelExpression(level); + + switch (newExpression.NodeType) + { + case ExpressionType.New : + case ExpressionType.MemberInit : break; + default : + var le = expression.GetLevelExpression(level - 1); + return GetExpression(expression, le, newExpression); + } + + if (levelExpresion.NodeType != ExpressionType.MemberAccess) + throw new LinqException("Invalid expression {0}", levelExpresion); + + var me = (MemberExpression)levelExpresion; + + switch (newExpression.NodeType) + { + case ExpressionType.New: + { + var expr = (NewExpression)newExpression; + +// ReSharper disable ConditionIsAlwaysTrueOrFalse +// ReSharper disable HeuristicUnreachableCode + if (expr.Members == null) + throw new LinqException("Invalid expression {0}", expression); +// ReSharper restore HeuristicUnreachableCode +// ReSharper restore ConditionIsAlwaysTrueOrFalse + + for (var i = 0; i < expr.Members.Count; i++) + if (me.Member == expr.Members[i]) + return levelExpresion == expression ? + expr.Arguments[i].Unwrap() : + GetMemberExpression(expr.Arguments[i].Unwrap(), expression, level + 1); + + throw new LinqException("Invalid expression {0}", expression); + } + + case ExpressionType.MemberInit: + { + var expr = (MemberInitExpression)newExpression; + + foreach (var binding in expr.Bindings.Cast()) + { + if (me.Member == binding.Member) + return levelExpresion == expression ? + binding.Expression.Unwrap() : + GetMemberExpression(binding.Expression.Unwrap(), expression, level + 1); + } + + throw new LinqException("Invalid expression {0}", expression); + } + } + + return expression; + } + + Expression GetMemberExpression(MemberInfo member, bool add, Type type) + { + Expression memberExpression; + + if (!Members.TryGetValue(member, out memberExpression)) + { + foreach (var m in Members) + { + if (m.Key.Name == member.Name) + { + if (TypeHelper.Equals(m.Key, member, IsScalar ? null : Body.Type)) + return m.Value; + } + } + + if (add && TypeHelper.IsSameOrParent(member.DeclaringType, Body.Type)) + { + memberExpression = Expression.Constant( + TypeHelper.GetDefaultValue(type), type); + + Members.Add(member, memberExpression); + } + else + throw new InvalidOperationException(); + } + + return memberExpression; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/SelectManyBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/SelectManyBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,246 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class SelectManyBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return + methodCall.IsQueryable("SelectMany") && + methodCall.Arguments.Count == 3 && + ((LambdaExpression)methodCall.Arguments[1].Unwrap()).Parameters.Count == 1; + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + var collectionSelector = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + var resultSelector = (LambdaExpression)methodCall.Arguments[2].Unwrap(); + + if (!sequence.SqlQuery.GroupBy.IsEmpty) + { + sequence = new SubQueryContext(sequence); + } + + var context = new SelectManyContext(buildInfo.Parent, collectionSelector, sequence); + var expr = collectionSelector.Body.Unwrap(); + + var collectionInfo = new BuildInfo(context, expr, new SqlQuery()); + var collection = builder.BuildSequence(collectionInfo); + var leftJoin = collection is DefaultIfEmptyBuilder.DefaultIfEmptyContext; + var sql = collection.SqlQuery; + + var sequenceTables = new HashSet(sequence.SqlQuery.From.Tables[0].GetTables()); + var newQuery = null != new QueryVisitor().Find(sql, e => e == collectionInfo.SqlQuery); + var crossApply = null != new QueryVisitor().Find(sql, e => + e.ElementType == QueryElementType.TableSource && sequenceTables.Contains((ISqlTableSource)e) || + e.ElementType == QueryElementType.SqlField && sequenceTables.Contains(((SqlField)e).Table) || + e.ElementType == QueryElementType.Column && sequenceTables.Contains(((SqlQuery.Column)e).Parent)); + + if (collection is JoinBuilder.GroupJoinSubQueryContext) + { + var groupJoin = ((JoinBuilder.GroupJoinSubQueryContext)collection).GroupJoin; + + groupJoin.SqlQuery.From.Tables[0].Joins[0].JoinType = SqlQuery.JoinType.Inner; + groupJoin.SqlQuery.From.Tables[0].Joins[0].IsWeak = false; + } + + if (!newQuery) + { + context.Collection = new SubQueryContext(collection, sequence.SqlQuery, false); + return new SelectContext(buildInfo.Parent, resultSelector, sequence, context); + } + + if (!crossApply) + { + if (!leftJoin) + { + context.Collection = new SubQueryContext(collection, sequence.SqlQuery, true); + return new SelectContext(buildInfo.Parent, resultSelector, sequence, context); + } + else + { + var join = SqlQuery.OuterApply(sql); + sequence.SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); + context.Collection = new SubQueryContext(collection, sequence.SqlQuery, false); + + return new SelectContext(buildInfo.Parent, resultSelector, sequence, context); + } + } + + if (collection is TableBuilder.TableContext) + { + var table = (TableBuilder.TableContext)collection; + var join = table.SqlTable.TableArguments != null && table.SqlTable.TableArguments.Length > 0 ? + (leftJoin ? SqlQuery.OuterApply(sql) : SqlQuery.CrossApply(sql)) : + (leftJoin ? SqlQuery.LeftJoin (sql) : SqlQuery.InnerJoin (sql)); + + join.JoinedTable.Condition.Conditions.AddRange(sql.Where.SearchCondition.Conditions); + join.JoinedTable.CanConvertApply = false; + + sql.Where.SearchCondition.Conditions.Clear(); + + var collectionParent = collection.Parent as TableBuilder.TableContext; + + // Association. + // + if (collectionParent != null && collectionInfo.IsAssociationBuilt) + { + var ts = (SqlQuery.TableSource)new QueryVisitor().Find(sequence.SqlQuery.From, e => + { + if (e.ElementType == QueryElementType.TableSource) + { + var t = (SqlQuery.TableSource)e; + return t.Source == collectionParent.SqlTable; + } + + return false; + }); + + ts.Joins.Add(join.JoinedTable); + } + else + { + sequence.SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); + } + + context.Collection = new SubQueryContext(collection, sequence.SqlQuery, false); + return new SelectContext(buildInfo.Parent, resultSelector, sequence, context); + } + else + { + var join = leftJoin ? SqlQuery.OuterApply(sql) : SqlQuery.CrossApply(sql); + sequence.SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); + + context.Collection = new SubQueryContext(collection, sequence.SqlQuery, false); + return new SelectContext(buildInfo.Parent, resultSelector, sequence, context); + } + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + public class SelectManyContext : SelectContext + { + public SelectManyContext(IBuildContext parent, LambdaExpression lambda, IBuildContext sequence) + : base(parent, lambda, sequence) + { + } + + private IBuildContext _collection; + public IBuildContext Collection + { + get { return _collection; } + set + { + _collection = value; + _collection.Parent = this; + } + } + + public override Expression BuildExpression(Expression expression, int level) + { + if (expression == null) + return Collection.BuildExpression(expression, level); + + var root = expression.GetRootObject(); + + if (root == Lambda.Parameters[0]) + return base.BuildExpression(expression, level); + + return Collection.BuildExpression(expression, level); + } + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + if (Collection == null) + base.BuildQuery(query, queryParameter); + + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + if (Collection != null) + { + if (expression == null) + return Collection.ConvertToIndex(expression, level, flags); + + var root = expression.GetRootObject(); + + if (root != Lambda.Parameters[0]) + return Collection.ConvertToIndex(expression, level, flags); + } + + return base.ConvertToIndex(expression, level, flags); + } + + /* + public override int ConvertToParentIndex(int index, IBuildContext context) + { + if (Collection == null) + return base.ConvertToParentIndex(index, context); + + throw new NotImplementedException(); + } + */ + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + if (Collection != null) + { + if (expression == null) + return Collection.ConvertToSql(expression, level, flags); + + var root = expression.GetRootObject(); + + if (root != Lambda.Parameters[0]) + return Collection.ConvertToSql(expression, level, flags); + } + + return base.ConvertToSql(expression, level, flags); + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + if (Collection != null) + { + if (expression == null) + return Collection.GetContext(expression, level, buildInfo); + + var root = expression.GetRootObject(); + + if (root != Lambda.Parameters[0]) + return Collection.GetContext(expression, level, buildInfo); + } + + return base.GetContext(expression, level, buildInfo); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + if (Collection != null) + { + if (expression == null) + return Collection.IsExpression(expression, level, requestFlag); + + var root = expression.GetRootObject(); + + if (root != Lambda.Parameters[0]) + return Collection.IsExpression(expression, level, requestFlag); + } + + return base.IsExpression(expression, level, requestFlag); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/SequenceContextBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/SequenceContextBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,73 @@ +using System; +using System.Data; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using Data.Sql; + + public abstract class SequenceContextBase : IBuildContext + { + protected SequenceContextBase(IBuildContext parent, IBuildContext sequence, LambdaExpression lambda) + { + Parent = parent; + Sequence = sequence; + Builder = sequence.Builder; + Lambda = lambda; + SqlQuery = sequence.SqlQuery; + + Sequence.Parent = this; + + Builder.Contexts.Add(this); + } + +#if DEBUG + [CLSCompliant(false)] + public string _sqlQueryText { get { return SqlQuery == null ? "" : SqlQuery.SqlText; } } +#endif + + public IBuildContext Parent { get; set; } + public IBuildContext Sequence { get; set; } + public ExpressionBuilder Builder { get; set; } + public LambdaExpression Lambda { get; set; } + public SqlQuery SqlQuery { get; set; } + + Expression IBuildContext.Expression { get { return Lambda; } } + + public virtual void BuildQuery(Query query, ParameterExpression queryParameter) + { + var expr = BuildExpression(null, 0); + var mapper = Builder.BuildMapper(expr); + + query.SetQuery(mapper.Compile()); + } + + public abstract Expression BuildExpression(Expression expression, int level); + public abstract SqlInfo[] ConvertToSql (Expression expression, int level, ConvertFlags flags); + public abstract SqlInfo[] ConvertToIndex (Expression expression, int level, ConvertFlags flags); + public abstract IsExpressionResult IsExpression (Expression expression, int level, RequestFor requestFlag); + public abstract IBuildContext GetContext (Expression expression, int level, BuildInfo buildInfo); + + public virtual int ConvertToParentIndex(int index, IBuildContext context) + { + return Parent == null ? index : Parent.ConvertToParentIndex(index, context); + } + + public virtual void SetAlias(string alias) + { + } + + public virtual ISqlExpression GetSubQuery(IBuildContext context) + { + return null; + } + + protected bool IsSubQuery() + { + for (var p = Parent; p != null; p = p.Parent) + if (p.IsExpression(null, 0, RequestFor.SubQuery).Result) + return true; + return false; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/SequenceConvertInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/SequenceConvertInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + public class SequenceConvertInfo + { + public ParameterExpression Parameter; + public Expression Expression; + public List ExpressionsToReplace; + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/SequenceConvertPath.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/SequenceConvertPath.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +using System; +using System.Diagnostics; +using System.Linq.Expressions; + +using JetBrains.Annotations; + +namespace BLToolkit.Data.Linq.Builder +{ + [DebuggerDisplay("Path = {Path}, Expr = {Expr}, Level = {Level}")] + public class SequenceConvertPath + { + [NotNull] public Expression Path; + [NotNull] public Expression Expr; + public int Level; + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/SqlInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/SqlInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using BLToolkit.Reflection; + +namespace BLToolkit.Data.Linq.Builder +{ + using Data.Sql; + + public class SqlInfo + { + public ISqlExpression Sql; + public SqlQuery Query; + public int Index = -1; + public List Members = new List(); + + public SqlInfo() + { + } + + public SqlInfo(MemberInfo mi) + { + Members.Add(mi); + } + + public SqlInfo(IEnumerable mi) + { + Members.AddRange(mi); + } + + public SqlInfo Clone() + { + return new SqlInfo(Members) { Sql = Sql, Query = Query, Index = Index }; + } + + public SqlInfo Clone(MemberInfo mi) + { + var info = Clone(); + if (Members.Count == 0 || Members[0] != mi) + info.Members.Insert(0, mi); + else + { + + } + return info; + } + + public bool CompareMembers(SqlInfo info) + { + return Members.Count == info.Members.Count && !Members.Where((t, i) => !TypeHelper.Equals(t, info.Members[i])).Any(); + } + + public bool CompareLastMember(SqlInfo info) + { + return + Members.Count > 0 && info.Members.Count > 0 && + TypeHelper.Equals(Members[Members.Count - 1], info.Members[info.Members.Count - 1]); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/SubQueryContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/SubQueryContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class SubQueryContext : PassThroughContext + { + public readonly IBuildContext SubQuery; + + public SubQueryContext(IBuildContext subQuery, SqlQuery sqlQuery, bool addToSql) + : base(subQuery) + { + if (sqlQuery == subQuery.SqlQuery) + throw new ArgumentException("Wrong subQuery argument.", "subQuery"); + + SubQuery = subQuery; + SubQuery.Parent = this; + + SqlQuery = sqlQuery; + + if (addToSql) + sqlQuery.From.Table(SubQuery.SqlQuery); + } + + public SubQueryContext(IBuildContext subQuery, bool addToSql) + : this(subQuery, new SqlQuery { ParentSql = subQuery.SqlQuery.ParentSql }, addToSql) + { + } + + public SubQueryContext(IBuildContext subQuery) + : this(subQuery, true) + { + } + + public override SqlQuery SqlQuery { get; set; } + public override IBuildContext Parent { get; set; } + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + if (Expression.NodeType == ExpressionType.Lambda) + { + var le = (LambdaExpression)Expression; + + if (le.Parameters.Count == 1 && null != Expression.Find( + e => e.NodeType == ExpressionType.Call && ((MethodCallExpression)e).IsQueryable())) + { + if (le.Body.NodeType == ExpressionType.New) + { + var ne = (NewExpression)le.Body; + var p = Expression.Parameter(ne.Type, "p"); + + var seq = new SelectContext( + Parent, + Expression.Lambda( + Expression.New( + ne.Constructor, + ne.Members.Select(m => Expression.MakeMemberAccess(p, m)).ToArray(), + ne.Members), + p), + this); + + seq.BuildQuery(query, queryParameter); + + return; + } + + if (le.Body.NodeType == ExpressionType.MemberInit) + { + var mi = (MemberInitExpression)le.Body; + + if (mi.NewExpression.Arguments.Count == 0 && mi.Bindings.All(b => b is MemberAssignment)) + { + var p = Expression.Parameter(mi.Type, "p"); + + var seq = new SelectContext( + Parent, + Expression.Lambda( + Expression.MemberInit( + mi.NewExpression, + mi.Bindings + .OfType() + .Select(ma => Expression.Bind(ma.Member, Expression.MakeMemberAccess(p, ma.Member))) + .ToArray()), + p), + this); + + seq.BuildQuery(query, queryParameter); + + return; + } + } + } + } + + base.BuildQuery(query, queryParameter); + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + return SubQuery + .ConvertToIndex(expression, level, flags) + .Select(idx => new SqlInfo(idx.Members) { Sql = SubQuery.SqlQuery.Select.Columns[idx.Index] }) + .ToArray(); + } + + // JoinContext has similar logic. Consider to review it. + // + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + return ConvertToSql(expression, level, flags) + .Select(idx => + { + idx.Query = SqlQuery; + idx.Index = GetIndex((SqlQuery.Column)idx.Sql); + + return idx; + }) + .ToArray(); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor testFlag) + { + switch (testFlag) + { + case RequestFor.SubQuery : return IsExpressionResult.True; + } + + return base.IsExpression(expression, level, testFlag); + } + + internal protected readonly Dictionary ColumnIndexes = new Dictionary(); + + protected virtual int GetIndex(SqlQuery.Column column) + { + int idx; + + if (!ColumnIndexes.TryGetValue(column, out idx)) + { + idx = SqlQuery.Select.Add(column); + ColumnIndexes.Add(column, idx); + } + + return idx; + } + + public override int ConvertToParentIndex(int index, IBuildContext context) + { + var idx = GetIndex(context.SqlQuery.Select.Columns[index]); + return Parent == null ? idx : Parent.ConvertToParentIndex(idx, this); + } + + public override void SetAlias(string alias) + { + if (alias.Contains('<')) + return; + + if (SqlQuery.From.Tables[0].Alias == null) + SqlQuery.From.Tables[0].Alias = alias; + } + + public override ISqlExpression GetSubQuery(IBuildContext context) + { + return null; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/TableAttributeBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/TableAttributeBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,38 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + + class TableAttributeBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("TableName", "DatabaseName", "OwnerName"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + + var table = (TableBuilder.TableContext)sequence; + var value = (string)((ConstantExpression)methodCall.Arguments[1]).Value; + + switch (methodCall.Method.Name) + { + case "TableName" : table.SqlTable.PhysicalName = value; break; + case "DatabaseName" : table.SqlTable.Database = value; break; + case "OwnerName" : table.SqlTable.Owner = value; break; + } + + return sequence; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/TableBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/TableBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1278 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + using Mapping; + using Reflection; + using Reflection.Extension; + + class TableBuilder : ISequenceBuilder + { + #region TableBuilder + + int ISequenceBuilder.BuildCounter { get; set; } + + static T Find(ExpressionBuilder builder, BuildInfo buildInfo, Func action) + { + var expression = buildInfo.Expression; + + switch (expression.NodeType) + { + case ExpressionType.Constant: + { + var c = (ConstantExpression)expression; + if (c.Value is IQueryable) + return action(1, null); + + break; + } + + case ExpressionType.Call: + { + var mc = (MethodCallExpression)expression; + + if (mc.Method.Name == "GetTable") + if (expression.Type.IsGenericType && expression.Type.GetGenericTypeDefinition() == typeof(Table<>)) + return action(2, null); + + var attr = builder.GetTableFunctionAttribute(mc.Method); + + if (attr != null) + return action(5, null); + + break; + } + + case ExpressionType.MemberAccess: + + if (expression.Type.IsGenericType && expression.Type.GetGenericTypeDefinition() == typeof(Table<>)) + return action(3, null); + + // Looking for association. + // + if (buildInfo.IsSubQuery && buildInfo.SqlQuery.From.Tables.Count == 0) + { + var ctx = builder.GetContext(buildInfo.Parent, expression); + if (ctx != null) + return action(4, ctx); + } + + break; + + case ExpressionType.Parameter: + { + if (buildInfo.IsSubQuery && buildInfo.SqlQuery.From.Tables.Count == 0) + { + var ctx = builder.GetContext(buildInfo.Parent, expression); + if (ctx != null) + return action(4, ctx); + } + + break; + } + } + + return action(0, null); + } + + public bool CanBuild(ExpressionBuilder builder, BuildInfo buildInfo) + { + return Find(builder, buildInfo, (n,_) => n > 0); + } + + public IBuildContext BuildSequence(ExpressionBuilder builder, BuildInfo buildInfo) + { + return Find(builder, buildInfo, (n,ctx) => + { + switch (n) + { + case 0 : return null; + case 1 : return new TableContext(builder, buildInfo, ((IQueryable)((ConstantExpression)buildInfo.Expression).Value).ElementType); + case 2 : + case 3 : return new TableContext(builder, buildInfo, buildInfo.Expression.Type.GetGenericArguments()[0]); + case 4 : return ctx.GetContext(buildInfo.Expression, 0, buildInfo); + case 5 : return new TableContext(builder, buildInfo); + } + + throw new InvalidOperationException(); + }); + } + + public SequenceConvertInfo Convert(ExpressionBuilder builder, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + public bool IsSequence(ExpressionBuilder builder, BuildInfo buildInfo) + { + return true; + } + + #endregion + + #region TableContext + + public class TableContext : IBuildContext + { + #region Properties + +#if DEBUG + public string _sqlQueryText { get { return SqlQuery == null ? "" : SqlQuery.SqlText; } } +#endif + + public ExpressionBuilder Builder { get; private set; } + public Expression Expression { get; private set; } + public SqlQuery SqlQuery { get; set; } + + public virtual IBuildContext Parent { get; set; } + + public Type OriginalType; + public Type ObjectType; + public ObjectMapper ObjectMapper; + public SqlTable SqlTable; + + #endregion + + #region Init + + public TableContext(ExpressionBuilder builder, BuildInfo buildInfo, Type originalType) + { + Builder = builder; + Parent = buildInfo.Parent; + Expression = buildInfo.Expression; + SqlQuery = buildInfo.SqlQuery; + + OriginalType = originalType; + ObjectType = GetObjectType(); + SqlTable = new SqlTable(builder.MappingSchema, ObjectType); + ObjectMapper = Builder.MappingSchema.GetObjectMapper(ObjectType); + + SqlQuery.From.Table(SqlTable); + + Init(); + } + + protected TableContext(ExpressionBuilder builder, SqlQuery sqlQuery) + { + Builder = builder; + SqlQuery = sqlQuery; + } + + public TableContext(ExpressionBuilder builder, BuildInfo buildInfo) + { + Builder = builder; + Parent = buildInfo.Parent; + Expression = buildInfo.Expression; + SqlQuery = buildInfo.SqlQuery; + + var mc = (MethodCallExpression)Expression; + var attr = builder.GetTableFunctionAttribute(mc.Method); + + if (!mc.Method.ReturnType.IsGenericType || mc.Method.ReturnType.GetGenericTypeDefinition() != typeof(Table<>)) + throw new LinqException("Table function has to return Table."); + + OriginalType = mc.Method.ReturnType.GetGenericArguments()[0]; + ObjectType = GetObjectType(); + SqlTable = new SqlTable(builder.MappingSchema, ObjectType); + ObjectMapper = Builder.MappingSchema.GetObjectMapper(ObjectType); + + SqlQuery.From.Table(SqlTable); + + var args = mc.Arguments.Select(a => builder.ConvertToSql(this, a, false)); + + attr.SetTable(SqlTable, mc.Method, mc.Arguments, args); + + Init(); + } + + protected Type GetObjectType() + { + for (var type = OriginalType.BaseType; type != null && type != typeof(object); type = type.BaseType) + { + var extension = TypeExtension.GetTypeExtension(type, Builder.MappingSchema.Extensions); + var mapping = Builder.MappingSchema.MetadataProvider.GetInheritanceMapping(type, extension); + + if (mapping.Length > 0) + return type; + } + + return OriginalType; + } + + public List InheritanceMapping; + public List InheritanceDiscriminators; + + protected void Init() + { + Builder.Contexts.Add(this); + + InheritanceMapping = ObjectMapper.InheritanceMapping; + + if (InheritanceMapping.Count > 0) + InheritanceDiscriminators = GetInheritanceDiscriminators(Builder, SqlTable, ObjectType, InheritanceMapping); + + // Original table is a parent. + // + if (ObjectType != OriginalType) + { + var predicate = Builder.MakeIsPredicate(this, OriginalType); + + if (predicate.GetType() != typeof(SqlQuery.Predicate.Expr)) + SqlQuery.Where.SearchCondition.Conditions.Add(new SqlQuery.Condition(false, predicate)); + } + } + + internal static List GetInheritanceDiscriminators( + ExpressionBuilder builder, + SqlTable sqlTable, + Type objectType, + List inheritanceMapping) + { + var inheritanceDiscriminators = new List(inheritanceMapping.Count); + + foreach (var mapping in inheritanceMapping) + { + string discriminator = null; + + foreach (MemberMapper mm in builder.MappingSchema.GetObjectMapper(mapping.Type)) + { + if (mm.MapMemberInfo.SqlIgnore == false && !sqlTable.Fields.Any(f => f.Value.Name == mm.MemberName)) + { + var field = new SqlField(mm.Type, mm.MemberName, mm.Name, mm.MapMemberInfo.Nullable, int.MinValue, null, mm); + sqlTable.Fields.Add(field); + } + + if (mm.MapMemberInfo.IsInheritanceDiscriminator) + discriminator = mm.MapMemberInfo.MemberName; + } + + inheritanceDiscriminators.Add(discriminator); + } + + var dname = inheritanceDiscriminators.FirstOrDefault(s => s != null); + + if (dname == null) + throw new LinqException("Inheritance Discriminator is not defined for the '{0}' hierarchy.", objectType); + + for (var i = 0; i < inheritanceDiscriminators.Count; i++) + if (inheritanceDiscriminators[i] == null) + inheritanceDiscriminators[i] = dname; + + return inheritanceDiscriminators; + } + + #endregion + + #region BuildQuery + + class MappingData + { + public MappingSchema MappingSchema; + public ObjectMapper ObjectMapper; + public int[] Index; + public IValueMapper[] ValueMappers; + } + + static object MapDataReaderToObject1(IDataReader dataReader, MappingData data) + { + var source = data.MappingSchema.CreateDataReaderMapper(dataReader); + var destObject = data.ObjectMapper.CreateInstance(); + + if (data.ValueMappers == null) + { + var mappers = new IValueMapper[data.Index.Length]; + + for (var i = 0; i < data.Index.Length; i++) + { + var n = data.Index[i]; + + if (n < 0) + continue; + + if (!data.ObjectMapper.SupportsTypedValues(i)) + { + mappers[i] = data.MappingSchema.DefaultValueMapper; + continue; + } + + var sourceType = source. GetFieldType(n) ?? typeof(object); + var destType = data.ObjectMapper.GetFieldType(i) ?? typeof(object); + + IValueMapper t; + + if (sourceType == destType) + { + lock (data.MappingSchema.SameTypeMappers) + if (!data.MappingSchema.SameTypeMappers.TryGetValue(sourceType, out t)) + data.MappingSchema.SameTypeMappers.Add(sourceType, t = data.MappingSchema.GetValueMapper(sourceType, destType)); + } + else + { + var key = new KeyValuePair(sourceType, destType); + + lock (data.MappingSchema.DifferentTypeMappers) + if (!data.MappingSchema.DifferentTypeMappers.TryGetValue(key, out t)) + data.MappingSchema.DifferentTypeMappers.Add(key, t = data.MappingSchema.GetValueMapper(sourceType, destType)); + } + + mappers[i] = t; + } + + data.ValueMappers = mappers; + } + + var dest = data.ObjectMapper; + var idx = data.Index; + var ms = data.ValueMappers; + + for (var i = 0; i < idx.Length; i++) + { + var n = idx[i]; + + if (n >= 0) + ms[i].Map(source, dataReader, n, dest, destObject, i); + } + + return destObject; + } + + static object MapDataReaderToObject2(IDataReader dataReader, MappingData data) + { + var source = data.MappingSchema.CreateDataReaderMapper(dataReader); + + var initContext = new InitContext + { + MappingSchema = data.MappingSchema, + DataSource = source, + SourceObject = dataReader, + ObjectMapper = data.ObjectMapper + }; + + var destObject = data.ObjectMapper.CreateInstance(initContext); + + if (initContext.StopMapping) + return destObject; + + var smDest = destObject as ISupportMapping; + + if (smDest != null) + { + smDest.BeginMapping(initContext); + + if (initContext.StopMapping) + return destObject; + } + + if (data.ValueMappers == null) + { + var mappers = new IValueMapper[data.Index.Length]; + + for (var i = 0; i < data.Index.Length; i++) + { + var n = data.Index[i]; + + if (n < 0) + continue; + + if (!data.ObjectMapper.SupportsTypedValues(i)) + { + mappers[i] = data.MappingSchema.DefaultValueMapper; + continue; + } + + var sourceType = source. GetFieldType(n) ?? typeof(object); + var destType = data.ObjectMapper.GetFieldType(i) ?? typeof(object); + + IValueMapper t; + + if (sourceType == destType) + { + lock (data.MappingSchema.SameTypeMappers) + if (!data.MappingSchema.SameTypeMappers.TryGetValue(sourceType, out t)) + data.MappingSchema.SameTypeMappers.Add(sourceType, t = data.MappingSchema.GetValueMapper(sourceType, destType)); + } + else + { + var key = new KeyValuePair(sourceType, destType); + + lock (data.MappingSchema.DifferentTypeMappers) + if (!data.MappingSchema.DifferentTypeMappers.TryGetValue(key, out t)) + data.MappingSchema.DifferentTypeMappers.Add(key, t = data.MappingSchema.GetValueMapper(sourceType, destType)); + } + + mappers[i] = t; + } + + data.ValueMappers = mappers; + } + + var dest = data.ObjectMapper; + var idx = data.Index; + var ms = data.ValueMappers; + + for (var i = 0; i < idx.Length; i++) + { + var n = idx[i]; + + if (n >= 0) + ms[i].Map(source, dataReader, n, dest, destObject, i); + } + + if (smDest != null) + smDest.EndMapping(initContext); + + return destObject; + } + + static object DefaultInheritanceMappingException(object value, Type type) + { + throw new LinqException("Inheritance mapping is not defined for discriminator value '{0}' in the '{1}' hierarchy.", value, type); + } + + static readonly MethodInfo _mapperMethod1 = ReflectionHelper.Expressor.MethodExpressor(_ => MapDataReaderToObject1(null, null)); + static readonly MethodInfo _mapperMethod2 = ReflectionHelper.Expressor.MethodExpressor(_ => MapDataReaderToObject2(null, null)); + +#if FW4 || SILVERLIGHT + ParameterExpression _variable; + static int _varIndex; +#endif + + Expression BuildTableExpression(bool buildBlock, Type objectType, int[] index) + { +#if FW4 || SILVERLIGHT + if (buildBlock && _variable != null) + return _variable; +#endif + + var data = new MappingData + { + MappingSchema = Builder.MappingSchema, + ObjectMapper = Builder.MappingSchema.GetObjectMapper(objectType), + Index = index + }; + + Expression expr; + + if (Builder.DataContextInfo.DataContext == null || + TypeHelper.IsSameOrParent(typeof(ISupportMapping), objectType) || + TypeHelper.GetFirstAttribute(objectType, typeof(ObjectFactoryAttribute)) != null) + { + expr = Expression.Convert( + Expression.Call(null, _mapperMethod2, + ExpressionBuilder.DataReaderParam, + Expression.Constant(data)), + objectType); + } + else + { + expr = Expression.Convert( + Expression.Call(null, _mapperMethod1, + ExpressionBuilder.DataReaderParam, + Expression.Constant(data)), + objectType); + } + + expr = ProcessExpression(expr); + +#if FW4 || SILVERLIGHT + + if (!buildBlock) + return expr; + + Builder.BlockVariables. Add(_variable = Expression.Variable(expr.Type, expr.Type.Name + _varIndex++)); + Builder.BlockExpressions.Add(Expression.Assign(_variable, expr)); + + return _variable; + +#else + return expr; +#endif + } + + protected virtual Expression ProcessExpression(Expression expression) + { + return expression; + } + + int[] BuildIndex(int[] index, Type objectType) + { + var names = new Dictionary(); + var n = 0; + + foreach (MemberMapper mm in Builder.MappingSchema.GetObjectMapper(objectType)) + if (mm.MapMemberInfo.SqlIgnore == false) + names.Add(mm.MemberName, n++); + + var q = + from r in SqlTable.Fields.Values.Select((f,i) => new { f, i }) + where names.ContainsKey(r.f.Name) + orderby names[r.f.Name] + select index[r.i]; + + return q.ToArray(); + } + + Expression BuildQuery(Type tableType) + { + SqlInfo[] info; + + if (ObjectType == tableType) + { + info = ConvertToIndex(null, 0, ConvertFlags.All); + } + else + { + info = ConvertToSql(null, 0, ConvertFlags.All); + + var table = new SqlTable(Builder.MappingSchema, tableType); + var q = + from fld1 in table.Fields.Values.Select((f,i) => new { f, i }) + join fld2 in info on fld1.f.Name equals ((SqlField)fld2.Sql).Name + orderby fld1.i + select GetIndex(fld2); + + info = q.ToArray(); + } + + var index = info.Select(idx => ConvertToParentIndex(idx.Index, null)).ToArray(); + + if (ObjectType != tableType || InheritanceMapping.Count == 0) + return BuildTableExpression(!Builder.IsBlockDisable, tableType, index); + + Expression expr; + + var defaultMapping = InheritanceMapping.SingleOrDefault(m => m.IsDefault); + + if (defaultMapping != null) + { + expr = Expression.Convert( + BuildTableExpression(false, defaultMapping.Type, BuildIndex(index, defaultMapping.Type)), + ObjectType); + } + else + { + var exceptionMethod = ReflectionHelper.Expressor.MethodExpressor(_ => DefaultInheritanceMappingException(null, null)); + var dindex = + ( + from f in SqlTable.Fields.Values + where f.Name == InheritanceDiscriminators[0] + select ConvertToParentIndex(_indexes[f].Index, null) + ).First(); + + expr = Expression.Convert( + Expression.Call(null, exceptionMethod, + Expression.Call( + ExpressionBuilder.DataReaderParam, + ReflectionHelper.DataReader.GetValue, + Expression.Constant(dindex)), + Expression.Constant(ObjectType)), + ObjectType); + } + + foreach (var mapping in InheritanceMapping.Select((m,i) => new { m, i }).Where(m => m.m != defaultMapping)) + { + var dindex = + ( + from f in SqlTable.Fields.Values + where f.Name == InheritanceDiscriminators[mapping.i] + select ConvertToParentIndex(_indexes[f].Index, null) + ).First(); + + Expression testExpr; + + if (mapping.m.Code == null) + { + testExpr = Expression.Call( + ExpressionBuilder.DataReaderParam, + ReflectionHelper.DataReader.IsDBNull, + Expression.Constant(dindex)); + } + else + { + var codeType = mapping.m.Code.GetType(); + + testExpr = Expression.Equal( + Expression.Constant(mapping.m.Code), + Builder.BuildSql(codeType, dindex)); + } + + expr = Expression.Condition( + testExpr, + Expression.Convert(BuildTableExpression(false, mapping.m.Type, BuildIndex(index, mapping.m.Type)), ObjectType), + expr); + } + + return expr; + } + + public void BuildQuery(Query query, ParameterExpression queryParameter) + { + var expr = BuildQuery(typeof(T)); + var mapper = Builder.BuildMapper(expr); + + query.SetQuery(mapper.Compile()); + } + + #endregion + + #region BuildExpression + + public Expression BuildExpression(Expression expression, int level) + { + // Build table. + // + var table = FindTable(expression, level, false); + + if (table == null) + { + if (expression is MemberExpression) + { + var memberExpression = (MemberExpression)expression; + + if (ObjectMapper != null && + ObjectMapper.TypeAccessor.OriginalType == memberExpression.Member.DeclaringType) + { + throw new LinqException("Member '{0}.{1}' is not a table column.", + memberExpression.Member.Name, memberExpression.Member.Name); + } + } + + throw new InvalidOperationException(); + } + + if (table.Field == null) + return table.Table.BuildQuery(table.Table.OriginalType); + + // Build field. + // + var info = ConvertToIndex(expression, level, ConvertFlags.Field).Single(); + var idx = ConvertToParentIndex(info.Index, null); + + if (expression is MemberExpression) + { + var me = (MemberExpression)expression; + var memberAccessor = TypeAccessor.GetAccessor(me.Member.DeclaringType)[me.Member.Name]; + return Builder.BuildSql(memberAccessor, idx); + } + else + { + return Builder.BuildSql(expression.Type, idx); + } + } + + #endregion + + #region ConvertToSql + + public SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + switch (flags) + { + case ConvertFlags.All : + { + var table = FindTable(expression, level, false); + + if (table.Field == null) + return table.Table.SqlTable.Fields.Values + .Select(_ => new SqlInfo(_.MemberMapper.MemberAccessor.MemberInfo) { Sql = _ }) + .ToArray(); + + break; + } + + case ConvertFlags.Key : + { + var table = FindTable(expression, level, false); + + if (table.Field == null) + { + var q = + from f in table.Table.SqlTable.Fields.Values + where f.IsPrimaryKey + orderby f.PrimaryKeyOrder + select new SqlInfo(f.MemberMapper.MemberAccessor.MemberInfo) { Sql = f }; + + var key = q.ToArray(); + + return key.Length != 0 ? key : ConvertToSql(expression, level, ConvertFlags.All); + } + + break; + } + + case ConvertFlags.Field : + { + var table = FindTable(expression, level, true); + + if (table.Field != null) + return new[] + { + new SqlInfo(table.Field.MemberMapper.MemberAccessor.MemberInfo) { Sql = table.Field } + }; + + break; + } + } + + throw new InvalidOperationException(); + } + + #endregion + + #region ConvertToIndex + + readonly Dictionary _indexes = new Dictionary(); + + protected SqlInfo GetIndex(SqlInfo expr) + { + SqlInfo n; + + if (_indexes.TryGetValue(expr.Sql, out n)) + return n; + + if (expr.Sql is SqlField) + { + var field = (SqlField)expr.Sql; + expr.Index = SqlQuery.Select.Add(field, field.Alias); + } + else + { + expr.Index = SqlQuery.Select.Add(expr.Sql); + } + + expr.Query = SqlQuery; + + _indexes.Add(expr.Sql, expr); + + return expr; + } + + public SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + switch (flags) + { + case ConvertFlags.Field : + case ConvertFlags.Key : + case ConvertFlags.All : + + var info = ConvertToSql(expression, level, flags); + + for (var i = 0; i < info.Length; i++) + info[i] = GetIndex(info[i]); + + return info; + } + + throw new InvalidOperationException(); + } + + #endregion + + #region IsExpression + + public IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFor) + { + switch (requestFor) + { + case RequestFor.Field : + { + var table = FindTable(expression, level, false); + return new IsExpressionResult(table != null && table.Field != null); + } + + case RequestFor.Table : + case RequestFor.Object : + { + var table = FindTable(expression, level, false); + var isTable = + table != null && + table.Field == null && + (expression == null || expression.GetLevelExpression(table.Level) == expression); + + return new IsExpressionResult(isTable, isTable ? table.Table : null); + } + + case RequestFor.Expression : + { + if (expression == null) + return IsExpressionResult.False; + + var levelExpression = expression.GetLevelExpression(level); + + switch (levelExpression.NodeType) + { + case ExpressionType.MemberAccess : + case ExpressionType.Parameter : + case ExpressionType.Call : + + var table = FindTable(expression, level, false); + return new IsExpressionResult(table == null); + } + + return IsExpressionResult.True; + } + + case RequestFor.Association : + { + if (ObjectMapper.Associations.Count > 0) + { + var table = FindTable(expression, level, false); + var isat = + table != null && + table.Table is AssociatedTableContext && + table.Field == null && + (expression == null || expression.GetLevelExpression(table.Level) == expression); + + return new IsExpressionResult(isat, isat ? table.Table : null); + } + + return IsExpressionResult.False; + } + } + + return IsExpressionResult.False; + } + + #endregion + + #region GetContext + + interface IAssociationHelper + { + Expression GetExpression(Expression parent, AssociatedTableContext association); + } + + class AssociationHelper : IAssociationHelper + where T : class + { + public Expression GetExpression(Expression parent, AssociatedTableContext association) + { + Expression expr = null; + var param = Expression.Parameter(typeof(T), "c"); + + foreach (var cond in (association).ParentAssociationJoin.Condition.Conditions) + { + var p = (SqlQuery.Predicate.ExprExpr)cond.Predicate; + var e1 = Expression.MakeMemberAccess(parent, ((SqlField)p.Expr1).MemberMapper.MemberAccessor.MemberInfo); + var e2 = Expression.MakeMemberAccess(param, ((SqlField)p.Expr2).MemberMapper.MemberAccessor.MemberInfo) as Expression; + + while (e1.Type != e2.Type) + { + if (TypeHelper.IsNullableType(e1.Type)) + { + e1 = Expression.PropertyOrField(e1, "Value"); + continue; + } + + if (TypeHelper.IsNullableType(e2.Type)) + { + e2 = Expression.PropertyOrField(e2, "Value"); + continue; + } + + e2 = Expression.Convert(e2, e1.Type); + } + + var ex = Expression.Equal(e1, e2); + + expr = expr == null ? ex : Expression.AndAlso(expr, ex); + } + + var predicate = Expression.Lambda>(expr, param); + + return association.Builder.DataContextInfo.DataContext.GetTable().Where(predicate).Expression; + } + } + + public IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + if (expression == null) + { + if (buildInfo != null && buildInfo.IsSubQuery) + { + var table = new TableContext( + Builder, + new BuildInfo(Parent is SelectManyBuilder.SelectManyContext ? this : Parent, Expression, buildInfo.SqlQuery), + SqlTable.ObjectType); + + return table; + } + + return this; + } + + if (ObjectMapper.Associations.Count > 0) + { + var levelExpression = expression.GetLevelExpression(level); + + if (buildInfo != null && buildInfo.IsSubQuery) + { + if (levelExpression == expression && expression.NodeType == ExpressionType.MemberAccess) + { + var tableLevel = GetAssociation(expression, level); + var association = (AssociatedTableContext)tableLevel.Table; + + if (association.IsList) + { + var ma = (MemberExpression)buildInfo.Expression; + var atype = typeof(AssociationHelper<>).MakeGenericType(association.ObjectType); + var helper = (IAssociationHelper)Activator.CreateInstance(atype); + var expr = helper.GetExpression(ma.Expression, association); + + buildInfo.IsAssociationBuilt = true; + + if (tableLevel.IsNew || buildInfo.CopyTable) + association.ParentAssociationJoin.IsWeak = true; + + return Builder.BuildSequence(new BuildInfo(buildInfo, expr)); + } + } + else + { + var association = GetAssociation(levelExpression, level); + var paj = ((AssociatedTableContext)association.Table).ParentAssociationJoin; + + paj.IsWeak = paj.IsWeak && buildInfo.CopyTable; + + return association.Table.GetContext(expression, level + 1, buildInfo); + } + } + } + + throw new InvalidOperationException(); + } + + #endregion + + #region ConvertToParentIndex + + public int ConvertToParentIndex(int index, IBuildContext context) + { + return Parent == null ? index : Parent.ConvertToParentIndex(index, this); + } + + #endregion + + #region SetAlias + + public void SetAlias(string alias) + { + if (alias.Contains('<')) + return; + + if (SqlTable.Alias == null) + SqlTable.Alias = alias; + } + + #endregion + + #region GetSubQuery + + public ISqlExpression GetSubQuery(IBuildContext context) + { + return null; + } + + #endregion + + #region Helpers + + SqlField GetField(Expression expression, int level, bool throwException) + { + if (expression.NodeType == ExpressionType.MemberAccess) + { + var memberExpression = (MemberExpression)expression; + var levelExpression = expression.GetLevelExpression(level); + + if (levelExpression.NodeType == ExpressionType.MemberAccess) + { + if (levelExpression != expression) + { + var levelMember = (MemberExpression)levelExpression; + + if (TypeHelper.IsNullableValueMember(memberExpression.Member) && memberExpression.Expression == levelExpression) + memberExpression = levelMember; + else + { + var sameType = + levelMember.Member.ReflectedType == SqlTable.ObjectType || + levelMember.Member.DeclaringType == SqlTable.ObjectType; + + if (!sameType) + { + var mi = SqlTable.ObjectType.GetMember(levelMember.Member.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + sameType = mi.Any(_ => _.DeclaringType == levelMember.Member.DeclaringType); + } + + if (sameType || InheritanceMapping.Count > 0) + { + foreach (var field in SqlTable.Fields.Values) + { + if (field.MemberMapper is MemberMapper.ComplexMapper) + { + var name = levelMember.Member.Name; + + for (var ex = (MemberExpression)expression; ex != levelMember; ex = (MemberExpression)ex.Expression) + name += "." + ex.Member.Name; + + if (field.MemberMapper.MemberName == name) + return field; + } + } + } + } + } + + if (levelExpression == memberExpression) + { + foreach (var field in SqlTable.Fields.Values) + { + if (TypeHelper.Equals(field.MemberMapper.MapMemberInfo.MemberAccessor.MemberInfo, memberExpression.Member, SqlTable.ObjectType)) + { + if (field.MemberMapper is MemberMapper.ComplexMapper && + field.MemberMapper.MemberName.IndexOf('.') > 0) + { + var name = memberExpression.Member.Name; + var me = memberExpression; + + if (!(me.Expression is MemberExpression)) + return null; + + while (me.Expression is MemberExpression) + { + me = (MemberExpression)me.Expression; + name = me.Member.Name + '.' + name; + } + + return SqlTable.Fields.Values.FirstOrDefault(f => f.MemberMapper.MemberName == name); + } + + return field; + } + + if (InheritanceMapping.Count > 0 && field.Name == memberExpression.Member.Name) + foreach (var mapping in InheritanceMapping) + foreach (MemberMapper mm in Builder.MappingSchema.GetObjectMapper(mapping.Type)) + if (TypeHelper.Equals(mm.MapMemberInfo.MemberAccessor.MemberInfo, memberExpression.Member)) + return field; + } + + if (throwException && + ObjectMapper != null && + ObjectMapper.TypeAccessor.OriginalType == memberExpression.Member.DeclaringType) + { + throw new LinqException("Member '{0}.{1}' is not a table column.", + memberExpression.Member.DeclaringType.Name, memberExpression.Member.Name); + } + } + } + } + + return null; + } + + [JetBrains.Annotations.NotNull] + readonly Dictionary _associations = + new Dictionary(new MemberInfoComparer()); + + class TableLevel + { + public TableContext Table; + public SqlField Field; + public int Level; + public bool IsNew; + } + + TableLevel FindTable(Expression expression, int level, bool throwException) + { + if (expression == null) + return new TableLevel { Table = this }; + + var levelExpression = expression.GetLevelExpression(level); + + switch (levelExpression.NodeType) + { + case ExpressionType.MemberAccess : + case ExpressionType.Parameter : + { + var field = GetField(expression, level, throwException); + + if (field != null || (level == 0 && levelExpression == expression)) + return new TableLevel { Table = this, Field = field, Level = level }; + + return GetAssociation(expression, level); + } + } + + return null; + } + + TableLevel GetAssociation(Expression expression, int level) + { + var objectMapper = ObjectMapper; + var levelExpression = expression.GetLevelExpression(level); + var inheritance = + ( + from m in InheritanceMapping + let om = Builder.MappingSchema.GetObjectMapper(m.Type) + where om.Associations.Count > 0 + select om + ).ToList(); + + if (objectMapper.Associations.Count > 0 || inheritance.Count > 0) + { + if (levelExpression.NodeType == ExpressionType.MemberAccess) + { + var memberExpression = (MemberExpression)levelExpression; + var isNew = false; + + AssociatedTableContext tableAssociation; + + if (!_associations.TryGetValue(memberExpression.Member, out tableAssociation)) + { + var q = + from a in objectMapper.Associations.Concat(inheritance.SelectMany(om => om.Associations)) + where TypeHelper.Equals(a.MemberAccessor.MemberInfo, memberExpression.Member) + select new AssociatedTableContext(Builder, this, a) { Parent = Parent }; + + tableAssociation = q.FirstOrDefault(); + + isNew = true; + + _associations.Add(memberExpression.Member, tableAssociation); + } + + if (tableAssociation != null) + { + if (levelExpression == expression) + return new TableLevel { Table = tableAssociation, Level = level, IsNew = isNew }; + + var al = tableAssociation.GetAssociation(expression, level + 1); + + if (al != null) + return al; + + var field = tableAssociation.GetField(expression, level + 1, false); + + return new TableLevel { Table = tableAssociation, Field = field, Level = field == null ? level : level + 1, IsNew = isNew }; + } + } + } + + return null; + } + + #endregion + } + + #endregion + + #region AssociatedTableContext + + public class AssociatedTableContext : TableContext + { + public readonly TableContext ParentAssociation; + public readonly SqlQuery.JoinedTable ParentAssociationJoin; + public readonly Association Association; + public readonly bool IsList; + + public override IBuildContext Parent + { + get { return ParentAssociation.Parent; } + set { } + } + + public AssociatedTableContext(ExpressionBuilder builder, TableContext parent, Association association) + : base(builder, parent.SqlQuery) + { + var type = TypeHelper.GetMemberType(association.MemberAccessor.MemberInfo); + var left = association.CanBeNull; + + if (TypeHelper.IsSameOrParent(typeof(IEnumerable), type)) + { + var etypes = TypeHelper.GetGenericArguments(type, typeof(IEnumerable)); + type = etypes != null && etypes.Length > 0 ? etypes[0] : TypeHelper.GetListItemType(type); + IsList = true; + } + + OriginalType = type; + ObjectType = GetObjectType(); + ObjectMapper = Builder.MappingSchema.GetObjectMapper(ObjectType); + SqlTable = new SqlTable(builder.MappingSchema, ObjectType); + + var psrc = parent.SqlQuery.From[parent.SqlTable]; + var join = left ? SqlTable.WeakLeftJoin() : IsList ? SqlTable.InnerJoin() : SqlTable.WeakInnerJoin(); + + Association = association; + ParentAssociation = parent; + ParentAssociationJoin = join.JoinedTable; + + psrc.Joins.Add(join.JoinedTable); + + for (var i = 0; i < association.ThisKey.Length; i++) + { + SqlField field1; + SqlField field2; + + if (!parent.SqlTable.Fields.TryGetValue(association.ThisKey[i], out field1)) + throw new LinqException("Association key '{0}' not found for type '{1}.", association.ThisKey[i], parent.ObjectType); + + if (!SqlTable.Fields.TryGetValue(association.OtherKey[i], out field2)) + throw new LinqException("Association key '{0}' not found for type '{1}.", association.OtherKey[i], ObjectType); + + join.Field(field1).Equal.Field(field2); + } + + Init(); + } + + protected override Expression ProcessExpression(Expression expression) + { + var isLeft = false; + + for ( + var association = this; + isLeft == false && association != null; + association = association.ParentAssociation as AssociatedTableContext) + { + isLeft = + association.ParentAssociationJoin.JoinType == SqlQuery.JoinType.Left || + association.ParentAssociationJoin.JoinType == SqlQuery.JoinType.OuterApply; + } + + if (isLeft) + { + Expression cond = null; + + var keys = ConvertToIndex(null, 0, ConvertFlags.Key); + + foreach (var key in keys) + { + var index2 = ConvertToParentIndex(key.Index, null); + + Expression e = Expression.Call( + ExpressionBuilder.DataReaderParam, + ReflectionHelper.DataReader.IsDBNull, + Expression.Constant(index2)); + + cond = cond == null ? e : Expression.AndAlso(cond, e); + } + + expression = Expression.Condition(cond, Expression.Constant(null, expression.Type), expression); + } + + return expression; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/TakeSkipBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/TakeSkipBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + + class TakeSkipBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("Skip", "Take"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + + var arg = methodCall.Arguments[1].Unwrap(); + + if (arg.NodeType == ExpressionType.Lambda) + arg = ((LambdaExpression)arg).Body.Unwrap(); + + var expr = builder.ConvertToSql(sequence, arg, false); + + if (methodCall.Method.Name == "Take") + { + BuildTake(builder, sequence, expr); + } + else + { + BuildSkip(builder, sequence, sequence.SqlQuery.Select.SkipValue, expr); + } + + return sequence; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + var info = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), null); + + if (info != null) + { + info.Expression = + Expression.Call( + methodCall.Method.DeclaringType, + methodCall.Method.Name, + new[] { info.Expression.Type.GetGenericArguments()[0] }, + info.Expression, methodCall.Arguments[1]); + info.Parameter = param; + + return info; + } + + return null; + } + + static void BuildTake(ExpressionBuilder builder, IBuildContext sequence, ISqlExpression expr) + { + var sql = sequence.SqlQuery; + + builder.SqlProvider.SqlQuery = sql; + + sql.Select.Take(expr); + + if (sql.Select.SkipValue != null && builder.SqlProvider.IsTakeSupported && !builder.SqlProvider.IsSkipSupported) + { + if (sql.Select.SkipValue is SqlParameter && sql.Select.TakeValue is SqlValue) + { + var skip = (SqlParameter)sql.Select.SkipValue; + var parm = (SqlParameter)sql.Select.SkipValue.Clone(new Dictionary(), _ => true); + + parm.SetTakeConverter((int)((SqlValue)sql.Select.TakeValue).Value); + + sql.Select.Take(parm); + + var ep = (from pm in builder.CurrentSqlParameters where pm.SqlParameter == skip select pm).First(); + + ep = new ParameterAccessor + { + Expression = ep.Expression, + Accessor = ep.Accessor, + SqlParameter = parm + }; + + builder.CurrentSqlParameters.Add(ep); + } + else + sql.Select.Take(builder.Convert( + sequence, + new SqlBinaryExpression(typeof(int), sql.Select.SkipValue, "+", sql.Select.TakeValue, Precedence.Additive))); + } + + if (!builder.SqlProvider.TakeAcceptsParameter) + { + var p = sql.Select.TakeValue as SqlParameter; + + if (p != null) + p.IsQueryParameter = false; + } + } + + static void BuildSkip(ExpressionBuilder builder, IBuildContext sequence, ISqlExpression prevSkipValue, ISqlExpression expr) + { + var sql = sequence.SqlQuery; + + builder.SqlProvider.SqlQuery = sql; + + sql.Select.Skip(expr); + + builder.SqlProvider.SqlQuery = sql; + + if (sql.Select.TakeValue != null) + { + if (builder.SqlProvider.IsSkipSupported || !builder.SqlProvider.IsTakeSupported) + sql.Select.Take(builder.Convert( + sequence, + new SqlBinaryExpression(typeof(int), sql.Select.TakeValue, "-", sql.Select.SkipValue, Precedence.Additive))); + + if (prevSkipValue != null) + sql.Select.Skip(builder.Convert( + sequence, + new SqlBinaryExpression(typeof(int), prevSkipValue, "+", sql.Select.SkipValue, Precedence.Additive))); + } + + if (!builder.SqlProvider.TakeAcceptsParameter) + { + var p = sql.Select.SkipValue as SqlParameter; + + if (p != null) + p.IsQueryParameter = false; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/UpdateBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/UpdateBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,443 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + using Data.Sql; + using Reflection; + + class UpdateBuilder : MethodCallBuilder + { + #region Update + + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("Update"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + + switch (methodCall.Arguments.Count) + { + case 1 : // int Update(this IUpdateable source) + CheckAssociation(sequence); + break; + + case 2 : // int Update(this IQueryable source, Expression> setter) + { + CheckAssociation(sequence); + + BuildSetter( + builder, + buildInfo, + (LambdaExpression)methodCall.Arguments[1].Unwrap(), + sequence, + sequence.SqlQuery.Update.Items, + sequence); + break; + } + + case 3 : + { + var expr = methodCall.Arguments[1].Unwrap(); + + if (expr is LambdaExpression) + { + // int Update(this IQueryable source, Expression> predicate, Expression> setter) + // + sequence = builder.BuildWhere(buildInfo.Parent, sequence, (LambdaExpression)methodCall.Arguments[1].Unwrap(), false); + + CheckAssociation(sequence); + + BuildSetter( + builder, + buildInfo, + (LambdaExpression)methodCall.Arguments[2].Unwrap(), + sequence, + sequence.SqlQuery.Update.Items, + sequence); + } + else + { + // static int Update(this IQueryable source, Table target, Expression> setter) + // + var into = builder.BuildSequence(new BuildInfo(buildInfo, expr, new SqlQuery())); + + sequence.ConvertToIndex(null, 0, ConvertFlags.All); + sequence.SqlQuery.ResolveWeakJoins(new List()); + sequence.SqlQuery.Select.Columns.Clear(); + + BuildSetter( + builder, + buildInfo, + (LambdaExpression)methodCall.Arguments[2].Unwrap(), + into, + sequence.SqlQuery.Update.Items, + sequence); + + var sql = sequence.SqlQuery; + + sql.Select.Columns.Clear(); + + foreach (var item in sql.Update.Items) + sql.Select.Columns.Add(new SqlQuery.Column(sql, item.Expression)); + + sql.Update.Table = ((TableBuilder.TableContext)into).SqlTable; + } + + break; + } + } + + sequence.SqlQuery.QueryType = QueryType.Update; + + return new UpdateContext(buildInfo.Parent, sequence); + } + + static void CheckAssociation(IBuildContext sequence) + { + var ctx = sequence as SelectContext; + + if (ctx != null && ctx.IsScalar) + { + var res = ctx.IsExpression(null, 0, RequestFor.Association); + + if (res.Result && res.Context is TableBuilder.AssociatedTableContext) + { + var atc = (TableBuilder.AssociatedTableContext)res.Context; + sequence.SqlQuery.Update.Table = atc.SqlTable; + } + else + { + res = ctx.IsExpression(null, 0, RequestFor.Table); + + if (res.Result && res.Context is TableBuilder.TableContext) + { + var tc = (TableBuilder.TableContext)res.Context; + + if (sequence.SqlQuery.From.Tables.Count == 0 || sequence.SqlQuery.From.Tables[0].Source != tc.SqlQuery) + sequence.SqlQuery.Update.Table = tc.SqlTable; + } + } + } + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + + #endregion + + #region Helpers + + internal static void BuildSetter( + ExpressionBuilder builder, + BuildInfo buildInfo, + LambdaExpression setter, + IBuildContext into, + List items, + IBuildContext sequence) + { + var path = Expression.Parameter(setter.Body.Type, "p"); + var ctx = new ExpressionContext(buildInfo.Parent, sequence, setter); + + if (setter.Body.NodeType == ExpressionType.MemberInit) + { + var ex = (MemberInitExpression)setter.Body; + var p = sequence.Parent; + + BuildSetter(builder, into, items, ctx, ex, path); + + builder.ReplaceParent(ctx, p); + } + else + { + var sqlInfo = ctx.ConvertToSql(setter.Body, 0, ConvertFlags.All); + + foreach (var info in sqlInfo) + { + if (info.Members.Count == 0) + throw new LinqException("Object initializer expected for insert statement."); + + if (info.Members.Count != 1) + throw new InvalidOperationException(); + + var member = info.Members[0]; + var pe = Expression.MakeMemberAccess(path, member); + var column = into.ConvertToSql(pe, 1, ConvertFlags.Field); + var expr = info.Sql; + + if (expr is SqlParameter) + { + var type = member.MemberType == MemberTypes.Field ? + ((FieldInfo) member).FieldType : + ((PropertyInfo)member).PropertyType; + + if (TypeHelper.IsEnumOrNullableEnum(type)) + { + var memberAccessor = TypeAccessor.GetAccessor(member.DeclaringType)[member.Name]; + ((SqlParameter)expr).SetEnumConverter(memberAccessor, builder.MappingSchema); + } + } + + items.Add(new SqlQuery.SetExpression(column[0].Sql, expr)); + } + } + } + + static void BuildSetter( + ExpressionBuilder builder, + IBuildContext into, + List items, + IBuildContext ctx, + MemberInitExpression expression, + Expression path) + { + foreach (var binding in expression.Bindings) + { + var member = binding.Member; + + if (member is MethodInfo) + member = TypeHelper.GetPropertyByMethod((MethodInfo)member); + + if (binding is MemberAssignment) + { + var ma = binding as MemberAssignment; + var pe = Expression.MakeMemberAccess(path, member); + + if (ma.Expression is MemberInitExpression && !into.IsExpression(pe, 1, RequestFor.Field).Result) + { + BuildSetter( + builder, + into, + items, + ctx, + (MemberInitExpression)ma.Expression, Expression.MakeMemberAccess(path, member)); + } + else + { + var column = into.ConvertToSql(pe, 1, ConvertFlags.Field); + var expr = builder.ConvertToSqlExpression(ctx, ma.Expression, false); + + if (expr is SqlValueBase && TypeHelper.IsEnumOrNullableEnum(ma.Expression.Type)) + { + var memberAccessor = TypeAccessor.GetAccessor(ma.Member.DeclaringType)[ma.Member.Name]; + ((SqlValueBase)expr).SetEnumConverter(memberAccessor, builder.MappingSchema); + } + + items.Add(new SqlQuery.SetExpression(column[0].Sql, expr)); + } + } + else + throw new InvalidOperationException(); + } + } + + internal static void ParseSet( + ExpressionBuilder builder, + BuildInfo buildInfo, + LambdaExpression extract, + LambdaExpression update, + IBuildContext select, + SqlTable table, + List items) + { + var ext = extract.Body; + + while (ext.NodeType == ExpressionType.Convert || ext.NodeType == ExpressionType.ConvertChecked) + ext = ((UnaryExpression)ext).Operand; + + if (ext.NodeType != ExpressionType.MemberAccess || ext.GetRootObject() != extract.Parameters[0]) + throw new LinqException("Member expression expected for the 'Set' statement."); + + var body = (MemberExpression)ext; + var member = body.Member; + + if (member is MethodInfo) + member = TypeHelper.GetPropertyByMethod((MethodInfo)member); + + var members = body.GetMembers(); + var name = members + .Skip(1) + .Select(ex => + { + var me = ex as MemberExpression; + + if (me == null) + return null; + + var m = me.Member; + + if (m is MethodInfo) + m = TypeHelper.GetPropertyByMethod((MethodInfo)m); + + return m; + }) + .Where(m => m != null && !TypeHelper.IsNullableValueMember(m)) + .Select(m => m.Name) + .Aggregate((s1,s2) => s1 + "." + s2); + + if (table != null && !table.Fields.ContainsKey(name)) + throw new LinqException("Member '{0}.{1}' is not a table column.", member.DeclaringType.Name, name); + + var column = table != null ? + table.Fields[name] : + select.ConvertToSql( + body, 1, ConvertFlags.Field)[0].Sql; + //Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field)[0].Sql; + var sp = select.Parent; + var ctx = new ExpressionContext(buildInfo.Parent, select, update); + var expr = builder.ConvertToSqlExpression(ctx, update.Body, false); + + builder.ReplaceParent(ctx, sp); + + if (expr is SqlValueBase && TypeHelper.IsEnumOrNullableEnum(update.Body.Type)) + { + var memberAccessor = TypeAccessor.GetAccessor(body.Member.DeclaringType)[body.Member.Name]; + ((SqlValueBase)expr).SetEnumConverter(memberAccessor, builder.MappingSchema); + } + + items.Add(new SqlQuery.SetExpression(column, expr)); + } + + internal static void ParseSet( + ExpressionBuilder builder, + BuildInfo buildInfo, + LambdaExpression extract, + Expression update, + IBuildContext select, + List items) + { + var ext = extract.Body; + + if (!ExpressionHelper.IsConstant(update.Type) && !builder.AsParameters.Contains(update)) + builder.AsParameters.Add(update); + + while (ext.NodeType == ExpressionType.Convert || ext.NodeType == ExpressionType.ConvertChecked) + ext = ((UnaryExpression)ext).Operand; + + if (ext.NodeType != ExpressionType.MemberAccess || ext.GetRootObject() != extract.Parameters[0]) + throw new LinqException("Member expression expected for the 'Set' statement."); + + var body = (MemberExpression)ext; + var member = body.Member; + + if (member is MethodInfo) + member = TypeHelper.GetPropertyByMethod((MethodInfo)member); + + var column = select.ConvertToSql( + body, 1, ConvertFlags.Field); + //Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field); + + if (column.Length == 0) + throw new LinqException("Member '{0}.{1}' is not a table column.", member.DeclaringType.Name, member.Name); + + var expr = builder.ConvertToSql(select, update, false, false); + + if (expr is SqlValueBase && TypeHelper.IsEnumOrNullableEnum(update.Type)) + { + var memberAccessor = TypeAccessor.GetAccessor(body.Member.DeclaringType)[body.Member.Name]; + ((SqlValueBase)expr).SetEnumConverter(memberAccessor, builder.MappingSchema); + } + + items.Add(new SqlQuery.SetExpression(column[0].Sql, expr)); + } + + #endregion + + #region UpdateContext + + class UpdateContext : SequenceContextBase + { + public UpdateContext(IBuildContext parent, IBuildContext sequence) + : base(parent, sequence, null) + { + } + + public override void BuildQuery(Query query, ParameterExpression queryParameter) + { + query.SetNonQueryQuery(); + } + + public override Expression BuildExpression(Expression expression, int level) + { + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) + { + throw new InvalidOperationException(); + } + + public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) + { + throw new InvalidOperationException(); + } + + public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) + { + throw new InvalidOperationException(); + } + + public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) + { + throw new InvalidOperationException(); + } + } + + #endregion + + #region Set + + internal class Set : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("Set"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + var extract = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + var update = methodCall.Arguments[2].Unwrap(); + + if (update.NodeType == ExpressionType.Lambda) + ParseSet( + builder, + buildInfo, + extract, + (LambdaExpression)update, + sequence, + sequence.SqlQuery.Update.Table, + sequence.SqlQuery.Update.Items); + else + ParseSet( + builder, + buildInfo, + extract, + update, + sequence, + sequence.SqlQuery.Update.Items); + + return sequence; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + return null; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Builder/WhereBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Builder/WhereBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,57 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq.Builder +{ + using BLToolkit.Linq; + + class WhereBuilder : MethodCallBuilder + { + protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + return methodCall.IsQueryable("Where"); + } + + protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) + { + var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); + var condition = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + var result = builder.BuildWhere(buildInfo.Parent, sequence, condition, true); + + result.SetAlias(condition.Parameters[0].Name); + + return result; + } + + protected override SequenceConvertInfo Convert( + ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) + { + var predicate = (LambdaExpression)methodCall.Arguments[1].Unwrap(); + var info = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), predicate.Parameters[0]); + + if (info != null) + { + info.Expression = methodCall.Convert(ex => ConvertMethod(methodCall, 0, info, predicate.Parameters[0], ex)); + + if (param != null) + { + if (param.Type != info.Parameter.Type) + param = Expression.Parameter(info.Parameter.Type, param.Name); + + if (info.ExpressionsToReplace != null) + foreach (var path in info.ExpressionsToReplace) + { + path.Path = path.Path.Convert(e => e == info.Parameter ? param : e); + path.Expr = path.Expr.Convert(e => e == info.Parameter ? param : e); + } + } + + info.Parameter = param; + + return info; + } + + return null; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/CompiledQuery.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/CompiledQuery.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,336 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq +{ + using BLToolkit.Linq; + using Reflection; + + /// + /// Provides for compilation and caching of queries for reuse. + /// + public class CompiledQuery + { + protected CompiledQuery(LambdaExpression query) + { + _query = query; + } + + readonly object _sync = new object(); + readonly LambdaExpression _query; + volatile Func _compiledQuery; + + TResult ExecuteQuery(params object[] args) + { + if (_compiledQuery == null) + lock (_sync) + if (_compiledQuery == null) + _compiledQuery = CompileQuery(_query); + + return (TResult)_compiledQuery(args); + } + + private interface ITableHelper + { + Expression CallTable(LambdaExpression query, Expression expr, ParameterExpression ps, bool isQueriable); + } + + internal class TableHelper : ITableHelper + { + public Expression CallTable(LambdaExpression query, Expression expr, ParameterExpression ps, bool isQueriable) + { + var table = new CompiledTable(query, expr); + + return Expression.Call( + Expression.Constant(table), + isQueriable ? + ReflectionHelper.Expressor>.MethodExpressor(t => t.Create (null)) : + ReflectionHelper.Expressor>.MethodExpressor(t => t.Execute(null)), + ps); + } + } + + static Func CompileQuery(LambdaExpression query) + { + var ps = Expression.Parameter(typeof(object[]), "ps"); + + var info = query.Body.Convert(pi => + { + switch (pi.NodeType) + { + case ExpressionType.Parameter : + { + var idx = query.Parameters.IndexOf((ParameterExpression)pi); + + if (idx >= 0) + return Expression.Convert(Expression.ArrayIndex(ps, Expression.Constant(idx)), pi.Type); + + break; + } + + case ExpressionType.Call : + { + var expr = (MethodCallExpression)pi; + + if (expr.IsQueryable()) + { + var qtype = TypeHelper.GetGenericType( + TypeHelper.IsSameOrParent(typeof(IQueryable), expr.Type) ? + typeof(IQueryable<>) : + typeof(IEnumerable<>), + expr.Type); + + var helper = (ITableHelper)Activator.CreateInstance( + typeof(TableHelper<>).MakeGenericType(qtype == null ? expr.Type : qtype.GetGenericArguments()[0])); + + return helper.CallTable(query, expr, ps, qtype != null); + } + + if (expr.Method.Name == "GetTable" && expr.Method.DeclaringType == typeof(Extensions)) + goto case ExpressionType.MemberAccess; + } + + break; + + case ExpressionType.MemberAccess : + if (pi.Type.IsGenericType && pi.Type.GetGenericTypeDefinition() == typeof(Table<>)) + { + var helper = (ITableHelper)Activator + .CreateInstance(typeof(TableHelper<>) + .MakeGenericType(pi.Type.GetGenericArguments()[0])); + return helper.CallTable(query, pi, ps, true); + } + + break; + } + + return pi; + }); + + return Expression.Lambda>(Expression.Convert(info, typeof(object)), ps).Compile(); + } + + #region Invoke + + public TResult Invoke(TDC dataContext) + { + return ExecuteQuery(dataContext); + } + + public TResult Invoke(TDC dataContext, T1 arg1) + { + return ExecuteQuery(dataContext, arg1); + } + + public TResult Invoke(TDC dataContext, T1 arg1, T2 arg2) + { + return ExecuteQuery(dataContext, arg1, arg2); + } + + public TResult Invoke(TDC dataContext, T1 arg1, T2 arg2, T3 arg3) + { + return ExecuteQuery(dataContext, arg1, arg2, arg3); + } + + public TResult Invoke(TDC dataContext, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + return ExecuteQuery(dataContext, arg1, arg2, arg3, arg4); + } + + public TResult Invoke(TDC dataContext, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + return ExecuteQuery(dataContext, arg1, arg2, arg3, arg4, arg5); + } + + #endregion + + #region Compile + + /// + /// Compiles the query. + /// + /// + /// A generic delegate that represents the compiled query. + /// + /// + /// The query expression to be compiled. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Returned type of the delegate returned by the method. + /// + public static Func Compile( + [JetBrains.Annotations.NotNull] Expression> query) + where TDC : IDataContext + { + if (query == null) throw new ArgumentNullException("query"); + return new CompiledQuery(query).Invoke; + } + + /// + /// Compiles the query. + /// + /// + /// A generic delegate that represents the compiled query. + /// + /// + /// The query expression to be compiled. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Returned type of the delegate returned by the method. + /// + public static Func Compile( + [JetBrains.Annotations.NotNull] Expression> query) + where TDC : IDataContext + { + if (query == null) throw new ArgumentNullException("query"); + return new CompiledQuery(query).Invoke; + } + + /// + /// Compiles the query. + /// + /// + /// A generic delegate that represents the compiled query. + /// + /// + /// The query expression to be compiled. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Returned type of the delegate returned by the method. + /// + public static Func Compile( + [JetBrains.Annotations.NotNull] Expression> query) + where TDC : IDataContext + { + if (query == null) throw new ArgumentNullException("query"); + return new CompiledQuery(query).Invoke; + } + + /// + /// Compiles the query. + /// + /// + /// A generic delegate that represents the compiled query. + /// + /// + /// The query expression to be compiled. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Returned type of the delegate returned by the method. + /// + public static Func Compile( + [JetBrains.Annotations.NotNull] Expression> query) + where TDC : IDataContext + { + if (query == null) throw new ArgumentNullException("query"); + return new CompiledQuery(query).Invoke; + } + + /// + /// Compiles the query. + /// + /// + /// A generic delegate that represents the compiled query. + /// + /// + /// The query expression to be compiled. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Returned type of the delegate returned by the method. + /// + public static Func Compile( + [JetBrains.Annotations.NotNull] Expression> query) + where TDC : IDataContext + { + if (query == null) throw new ArgumentNullException("query"); + return new CompiledQuery(query).Invoke; + } + + /// + /// Compiles the query. + /// + /// + /// A generic delegate that represents the compiled query. + /// + /// + /// The query expression to be compiled. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Returned type of the delegate returned by the method. + /// + public static Func Compile( + [JetBrains.Annotations.NotNull] Expression> query) + where TDC : IDataContext + { + if (query == null) throw new ArgumentNullException("query"); + return new CompiledQuery(query).Invoke; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/CompiledTableT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/CompiledTableT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq +{ + using Mapping; + using Builder; + + class CompiledTable + { + public CompiledTable(LambdaExpression lambda, Expression expression) + { + _lambda = lambda; + _expression = expression; + } + + readonly LambdaExpression _lambda; + readonly Expression _expression; + readonly object _sync = new object(); + + string _lastContextID; + MappingSchema _lastMappingSchema; + Query _lastQuery; + + readonly Dictionary> _infos = new Dictionary>(); + + Query GetInfo(IDataContext dataContext) + { + var dataContextInfo = DataContextInfo.Create(dataContext); + + string lastContextID; + MappingSchema lastMappingSchema; + Query query; + + lock (_sync) + { + lastContextID = _lastContextID; + lastMappingSchema = _lastMappingSchema; + query = _lastQuery; + } + + var contextID = dataContextInfo.ContextID; + var mappingSchema = dataContextInfo.MappingSchema; + + if (lastContextID != contextID || lastMappingSchema != mappingSchema) + query = null; + + if (query == null) + { + var key = new { contextID, mappingSchema }; + + lock (_sync) + _infos.TryGetValue(key, out query); + + if (query == null) + { + lock (_sync) + { + _infos.TryGetValue(key, out query); + + if (query == null) + { + query = new ExpressionBuilder(new Query(), dataContextInfo, _expression, _lambda.Parameters.ToArray()) + .Build(); + + _infos.Add(key, query); + + _lastContextID = contextID; + _lastMappingSchema = mappingSchema; + _lastQuery = query; + } + } + } + } + + return query; + } + + public IQueryable Create(object[] parameters) + { + var db = (IDataContext)parameters[0]; + return new Table(db, _expression) { Info = GetInfo(db), Parameters = parameters }; + } + + public T Execute(object[] parameters) + { + var db = (IDataContext)parameters[0]; + var ctx = DataContextInfo.Create(db); + var query = GetInfo(db); + + return (T)query.GetElement(null, ctx, _expression, parameters); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/DataContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/DataContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,173 @@ +using System; +using System.Data; +using System.Text; + +namespace BLToolkit.Data.Linq +{ + using Data.Sql.SqlProvider; + using DataProvider; + using Mapping; + + public class DataContext : IDataContext + { + public DataContext() : this(DbManager.DefaultConfiguration) + { + } + + public DataContext(string configurationString) + { + ConfigurationString = configurationString; + DataProvider = DbManager.GetDataProvider(configurationString); + ContextID = DataProvider.Name; + + MappingSchema = DataProvider.MappingSchema ?? Map.DefaultSchema; + } + + public string ConfigurationString { get; private set; } + public DataProviderBase DataProvider { get; private set; } + public string ContextID { get; set; } + public MappingSchema MappingSchema { get; set; } + public string LastQuery { get; set; } + + private bool _keepConnectionAlive; + public bool KeepConnectionAlive + { + get { return _keepConnectionAlive; } + set + { + _keepConnectionAlive = value; + + if (value == false) + ReleaseQuery(); + } + } + + private bool? _isMarsEnabled; + public bool IsMarsEnabled + { + get + { + if (_isMarsEnabled == null) + { + if (_dbManager == null) + return false; + _isMarsEnabled = _dbManager.IsMarsEnabled; + } + + return _isMarsEnabled.Value; + } + set { _isMarsEnabled = value; } + } + + internal int LockDbManagerCounter; + + string _connectionString; + DbManager _dbManager; + + internal DbManager GetDBManager() + { + if (_dbManager == null) + { + if (_connectionString == null) + _connectionString = DbManager.GetConnectionString(ConfigurationString); + + _dbManager = new DbManager(DataProvider, _connectionString) { MappingSchema = MappingSchema }; + } + + return _dbManager; + } + + internal void ReleaseQuery() + { + LastQuery = _dbManager.LastQuery; + + if (_dbManager != null && LockDbManagerCounter == 0 && KeepConnectionAlive == false) + { + _dbManager.Dispose(); + _dbManager = null; + } + } + + Func IDataContext.CreateSqlProvider + { + get { return DataProvider.CreateSqlProvider; } + } + + object IDataContext.SetQuery(IQueryContext queryContext) + { + var ctx = GetDBManager() as IDataContext; + return ctx.SetQuery(queryContext); + } + + int IDataContext.ExecuteNonQuery(object query) + { + var ctx = GetDBManager() as IDataContext; + return ctx.ExecuteNonQuery(query); + } + + object IDataContext.ExecuteScalar(object query) + { + var ctx = GetDBManager() as IDataContext; + return ctx.ExecuteScalar(query); + } + + IDataReader IDataContext.ExecuteReader(object query) + { + var ctx = GetDBManager() as IDataContext; + return ctx.ExecuteReader(query); + } + + void IDataContext.ReleaseQuery(object query) + { + ReleaseQuery(); + } + + string IDataContext.GetSqlText(object query) + { + if (_dbManager != null) + return ((IDataContext)_dbManager).GetSqlText(query); + + var ctx = GetDBManager() as IDataContext; + var str = ctx.GetSqlText(query); + + ReleaseQuery(); + + return str; + } + + DataContext(int n) {} + + IDataContext IDataContext.Clone(bool forNestedQuery) + { + var dc = new DataContext(0) + { + ConfigurationString = ConfigurationString, + KeepConnectionAlive = KeepConnectionAlive, + DataProvider = DataProvider, + ContextID = ContextID, + MappingSchema = MappingSchema, + }; + + if (forNestedQuery && _dbManager != null && _dbManager.IsMarsEnabled) + dc._dbManager = _dbManager.Transaction != null ? + new DbManager(DataProvider, _dbManager.Transaction) { MappingSchema = MappingSchema } : + new DbManager(DataProvider, _dbManager.Connection) { MappingSchema = MappingSchema }; + + return dc; + } + + public event EventHandler OnClosing; + + void IDisposable.Dispose() + { + if (_dbManager != null) + { + if (OnClosing != null) + OnClosing(this, EventArgs.Empty); + + _dbManager.Dispose(); + _dbManager = null; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/DataContextInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/DataContextInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + using Data.Sql.SqlProvider; + using Mapping; + + public class DataContextInfo : IDataContextInfo + { + public DataContextInfo(IDataContext dataContext) + { + DataContext = dataContext; + DisposeContext = false; + } + + public DataContextInfo(IDataContext dataContext, bool disposeContext) + { + DataContext = dataContext; + DisposeContext = disposeContext; + } + + public IDataContext DataContext { get; private set; } + public bool DisposeContext { get; private set; } + public string ContextID { get { return DataContext.ContextID; } } + public MappingSchema MappingSchema { get { return DataContext.MappingSchema; } } + + public ISqlProvider CreateSqlProvider() + { + return DataContext.CreateSqlProvider(); + } + + public IDataContextInfo Clone(bool forNestedQuery) + { + return new DataContextInfo(DataContext.Clone(forNestedQuery)); + } + + public static IDataContextInfo Create(IDataContext dataContext) + { +#if SILVERLIGHT + if (dataContext == null) throw new ArgumentNullException("dataContext"); + return new DataContextInfo(dataContext); +#else + return dataContext == null ? (IDataContextInfo)new DefaultDataContextInfo() : new DataContextInfo(dataContext); +#endif + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/DataContextTransaction.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/DataContextTransaction.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,95 @@ +using System; +using System.Data; + +using JetBrains.Annotations; + +namespace BLToolkit.Data.Linq +{ + public class DataContextTransaction : IDisposable + { + public DataContextTransaction([NotNull] DataContext dataContext) + { + if (dataContext == null) throw new ArgumentNullException("dataContext"); + + DataContext = dataContext; + } + + public DataContext DataContext { get; set; } + + int _transactionCounter; + + public void BeginTransaction() + { + var db = DataContext.GetDBManager(); + + db.BeginTransaction(); + + if (_transactionCounter == 0) + DataContext.LockDbManagerCounter++; + + _transactionCounter++; + } + + public void BeginTransaction(IsolationLevel level) + { + var db = DataContext.GetDBManager(); + + db.BeginTransaction(level); + + if (_transactionCounter == 0) + DataContext.LockDbManagerCounter++; + + _transactionCounter++; + } + + public void CommitTransaction() + { + if (_transactionCounter > 0) + { + var db = DataContext.GetDBManager(); + + db.CommitTransaction(); + + _transactionCounter--; + + if (_transactionCounter == 0) + { + DataContext.LockDbManagerCounter--; + DataContext.ReleaseQuery(); + } + } + } + + public void RollbackTransaction() + { + if (_transactionCounter > 0) + { + var db = DataContext.GetDBManager(); + + db.RollbackTransaction(); + + _transactionCounter--; + + if (_transactionCounter == 0) + { + DataContext.LockDbManagerCounter--; + DataContext.ReleaseQuery(); + } + } + } + + public void Dispose() + { + if (_transactionCounter > 0) + { + var db = DataContext.GetDBManager(); + + db.RollbackTransaction(); + + _transactionCounter = 0; + + DataContext.LockDbManagerCounter--; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/DefaultDataContextInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/DefaultDataContextInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + using Data.Sql.SqlProvider; + using DataProvider; + using Mapping; + + class DefaultDataContextInfo : IDataContextInfo + { + private IDataContext _dataContext; + public IDataContext DataContext { get { return _dataContext ?? (_dataContext = new DbManager()); } } + + public MappingSchema MappingSchema { get { return Map.DefaultSchema; } } + public bool DisposeContext { get { return true; } } + public string ContextID { get { return _dataProvider.Name; } } + + public ISqlProvider CreateSqlProvider() + { + return _dataProvider.CreateSqlProvider(); + } + + public IDataContextInfo Clone(bool forNestedQuery) + { + return new DataContextInfo(DataContext.Clone(forNestedQuery)); + } + + static readonly DataProviderBase _dataProvider = DbManager.GetDataProvider(DbManager.DefaultConfiguration); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/ExpressionQuery.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/ExpressionQuery.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,159 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +using JetBrains.Annotations; + +namespace BLToolkit.Data.Linq +{ + using Reflection; + + public abstract class ExpressionQuery : IOrderedQueryable, IQueryProvider + { + #region Init + + protected void Init(IDataContextInfo dataContextInfo, Expression expression) + { +#if SILVERLIGHT + if (dataContextInfo == null) throw new ArgumentNullException("dataContextInfo"); + + DataContextInfo = dataContextInfo; +#else + DataContextInfo = dataContextInfo ?? new DefaultDataContextInfo(); +#endif + Expression = expression ?? Expression.Constant(this); + } + + [NotNull] public Expression Expression { get; set; } + [NotNull] public IDataContextInfo DataContextInfo { get; set; } + + internal Query Info; + internal object[] Parameters; + + #endregion + + #region Public Members + + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + private string _sqlTextHolder; + +// ReSharper disable InconsistentNaming + [UsedImplicitly] + private string _sqlText { get { return SqlText; }} +// ReSharper restore InconsistentNaming + + public string SqlText + { + get + { + if (_sqlTextHolder == null) + { + var info = GetQuery(Expression, true); + _sqlTextHolder = info.GetSqlText(DataContextInfo.DataContext, Expression, Parameters, 0); + } + + return _sqlTextHolder; + } + } + + #endregion + + #region Execute + + IEnumerable Execute(IDataContextInfo dataContextInfo, Expression expression) + { + return GetQuery(expression, true).GetIEnumerable(null, dataContextInfo, expression, Parameters); + } + + Query GetQuery(Expression expression, bool cache) + { + if (cache && Info != null) + return Info; + + var info = Query.GetQuery(DataContextInfo, expression); + + if (cache) + Info = info; + + return info; + } + + #endregion + + #region IQueryable Members + + Type IQueryable.ElementType + { + get { return typeof(T); } + } + + Expression IQueryable.Expression + { + get { return Expression; } + } + + IQueryProvider IQueryable.Provider + { + get { return this; } + } + + #endregion + + #region IQueryProvider Members + + IQueryable IQueryProvider.CreateQuery(Expression expression) + { + if (expression == null) + throw new ArgumentNullException("expression"); + + return new ExpressionQueryImpl(DataContextInfo, expression); + } + + IQueryable IQueryProvider.CreateQuery(Expression expression) + { + if (expression == null) + throw new ArgumentNullException("expression"); + + var elementType = TypeHelper.GetElementType(expression.Type) ?? expression.Type; + + try + { + return (IQueryable)Activator.CreateInstance(typeof(ExpressionQueryImpl<>).MakeGenericType(elementType), new object[] { DataContextInfo, expression }); + } + catch (TargetInvocationException ex) + { + throw ex.InnerException; + } + } + + TResult IQueryProvider.Execute(Expression expression) + { + return (TResult)GetQuery(expression, false).GetElement(null, DataContextInfo, expression, Parameters); + } + + object IQueryProvider.Execute(Expression expression) + { + return GetQuery(expression, false).GetElement(null, DataContextInfo, expression, Parameters); + } + + #endregion + + #region IEnumerable Members + + IEnumerator IEnumerable.GetEnumerator() + { + return Execute(DataContextInfo, Expression).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return Execute(DataContextInfo, Expression).GetEnumerator(); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/ExpressionQueryImpl.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/ExpressionQueryImpl.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,27 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq +{ + class ExpressionQueryImpl : ExpressionQuery, IExpressionQuery + { + public ExpressionQueryImpl(IDataContextInfo dataContext, Expression expression) + { + Init(dataContext, expression); + } + + //public new string SqlText + //{ + // get { return base.SqlText; } + //} + +//#if OVERRIDETOSTRING + + public override string ToString() + { + return base.SqlText; + } + +//#endif + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Expressions.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Expressions.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1238 @@ +using System; +using System.Collections.Generic; +using System.Data.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +#region ReSharper disables +// ReSharper disable RedundantTypeArgumentsOfMethod +// ReSharper disable RedundantCast +// ReSharper disable PossibleInvalidOperationException +// ReSharper disable CSharpWarnings::CS0693 +// ReSharper disable RedundantToStringCall +#endregion + +namespace BLToolkit.Data.Linq +{ + using B = Boolean; + using C = Char; + using S = String; + using I = Int32; + using O = Object; + using D = DateTime; + using T = TimeSpan; + using F = Double; + using M = Decimal; + + public static class Expressions + { + #region MapMember + + public static void MapMember(MemberInfo memberInfo, LambdaExpression expression) + { + MapMember("", memberInfo, expression); + } + + public static void MapMember(string providerName, MemberInfo memberInfo, LambdaExpression expression) + { + Dictionary dic; + + if (!_members.TryGetValue(providerName, out dic)) + _members.Add(providerName, dic = new Dictionary()); + + dic[memberInfo] = expression; + } + + public static void MapMember(Expression> memberInfo, LambdaExpression expression) + { + MapMember("", M(memberInfo), expression); + } + + public static void MapMember(string providerName, Expression> memberInfo, LambdaExpression expression) + { + MapMember(providerName, M(memberInfo), expression); + } + + public static void MapMember(Expression> memberInfo, LambdaExpression expression) + { + MapMember("", M(memberInfo), expression); + } + + public static void MapMember(string providerName, Expression> memberInfo, LambdaExpression expression) + { + MapMember(providerName, M(memberInfo), expression); + } + + public static void MapMember (string providerName, Expression> memberInfo, Expression> expression) { MapMember(providerName, ReflectionHelper.MemeberInfo(memberInfo), expression); } + public static void MapMember ( Expression> memberInfo, Expression> expression) { MapMember("", ReflectionHelper.MemeberInfo(memberInfo), expression); } + public static void MapMember (string providerName, Expression> memberInfo, Expression> expression) { MapMember(providerName, ReflectionHelper.MemeberInfo(memberInfo), expression); } + public static void MapMember ( Expression> memberInfo, Expression> expression) { MapMember("", ReflectionHelper.MemeberInfo(memberInfo), expression); } + public static void MapMember (string providerName, Expression> memberInfo, Expression> expression) { MapMember(providerName, ReflectionHelper.MemeberInfo(memberInfo), expression); } + public static void MapMember ( Expression> memberInfo, Expression> expression) { MapMember("", ReflectionHelper.MemeberInfo(memberInfo), expression); } + public static void MapMember (string providerName, Expression> memberInfo, Expression> expression) { MapMember(providerName, ReflectionHelper.MemeberInfo(memberInfo), expression); } + public static void MapMember ( Expression> memberInfo, Expression> expression) { MapMember("", ReflectionHelper.MemeberInfo(memberInfo), expression); } + public static void MapMember (string providerName, Expression> memberInfo, Expression> expression) { MapMember(providerName, ReflectionHelper.MemeberInfo(memberInfo), expression); } + public static void MapMember ( Expression> memberInfo, Expression> expression) { MapMember("", ReflectionHelper.MemeberInfo(memberInfo), expression); } + public static void MapMember(string providerName, Expression> memberInfo, Expression> expression) { MapMember(providerName, ReflectionHelper.MemeberInfo(memberInfo), expression); } + public static void MapMember( Expression> memberInfo, Expression> expression) { MapMember("", ReflectionHelper.MemeberInfo(memberInfo), expression); } + + #endregion + + #region Public Members + + public static LambdaExpression ConvertMember(string providerName, MemberInfo mi) + { + Dictionary dic; + LambdaExpression expr; + + if (Members.TryGetValue(providerName, out dic)) + if (dic.TryGetValue(mi, out expr)) + return expr; + + if (!Members[""].TryGetValue(mi, out expr)) + { + if (mi is MethodInfo && mi.Name == "CompareString" && mi.DeclaringType.FullName == "Microsoft.VisualBasic.CompilerServices.Operators") + { + lock (_members) + { + if (!Members[""].TryGetValue(mi, out expr)) + { + expr = L((s1,s2,b) => b ? string.CompareOrdinal(s1.ToUpper(), s2.ToUpper()) : string.CompareOrdinal(s1, s2)); + + _members[""].Add(mi, expr); + } + } + } + } + + return expr; + } + + #endregion + + #region Function Mapping + + #region Helpers + + static MemberInfo M(Expression> func) + { + return ReflectionHelper.MemeberInfo(func); + } + + static MemberInfo M(Expression> func) + { + return ReflectionHelper.MemeberInfo(func); + } + + static LambdaExpression L (Expression> func) { return func; } + static LambdaExpression L (Expression> func) { return func; } + static LambdaExpression L (Expression> func) { return func; } + static LambdaExpression L (Expression> func) { return func; } + static LambdaExpression L (Expression> func) { return func; } + static LambdaExpression L (Expression> func) { return func; } + static LambdaExpression L (Expression> func) { return func; } + + #endregion + + static public Dictionary> Members { get { return _members; } } + static readonly Dictionary> _members = new Dictionary> + { + { "", new Dictionary { + + #region String + + { M(() => "".Length ), L ( obj => Sql.Length(obj).Value) }, + { M(() => "".Substring (0) ), L ((obj,p0) => Sql.Substring(obj, p0 + 1, obj.Length - p0)) }, + { M(() => "".Substring (0,0) ), L ((obj,p0,p1) => Sql.Substring(obj, p0 + 1, p1)) }, + { M(() => "".ContainsExactly("") ), L ((obj,p0) => p0.Length == 0 ? 0 : (Sql.ContainsExactly(p0, obj) .Value) - 1) }, + { M(() => "".IndexOf ("") ), L ((obj,p0) => p0.Length == 0 ? 0 : (Sql.CharIndex(p0, obj) .Value) - 1) }, + { M(() => "".IndexOf ("",0) ), L ((obj,p0,p1) => p0.Length == 0 && obj.Length > p1 ? p1 : (Sql.CharIndex(p0, obj, p1 + 1).Value) - 1) }, + { M(() => "".IndexOf ("",0,0) ), L((obj,p0,p1,p2) => p0.Length == 0 && obj.Length > p1 ? p1 : (Sql.CharIndex(p0, Sql.Left(obj, p2), p1) .Value) - 1) }, + { M(() => "".IndexOf (' ') ), L ((obj,p0) => (Sql.CharIndex(p0, obj) .Value) - 1) }, + { M(() => "".IndexOf (' ',0) ), L ((obj,p0,p1) => (Sql.CharIndex(p0, obj, p1 + 1).Value) - 1) }, + { M(() => "".IndexOf (' ',0,0) ), L((obj,p0,p1,p2) => (Sql.CharIndex(p0, Sql.Left(obj, p2), p1) ?? 0) - 1) }, + { M(() => "".LastIndexOf("") ), L ((obj,p0) => p0.Length == 0 ? obj.Length - 1 : (Sql.CharIndex(p0, obj) .Value) == 0 ? -1 : obj.Length - (Sql.CharIndex(Sql.Reverse(p0), Sql.Reverse(obj)) .Value) - p0.Length + 1) }, + { M(() => "".LastIndexOf("",0) ), L ((obj,p0,p1) => p0.Length == 0 ? p1 : (Sql.CharIndex(p0, obj, p1 + 1).Value) == 0 ? -1 : obj.Length - (Sql.CharIndex(Sql.Reverse(p0), Sql.Reverse(obj.Substring(p1, obj.Length - p1))).Value) - p0.Length + 1) }, + { M(() => "".LastIndexOf("",0,0) ), L((obj,p0,p1,p2) => p0.Length == 0 ? p1 : (Sql.CharIndex(p0, Sql.Left(obj, p1 + p2), p1 + 1).Value) == 0 ? -1 : p1 + p2 - (Sql.CharIndex(Sql.Reverse(p0), Sql.Reverse(obj.Substring(p1, p2))) .Value) - p0.Length + 1) }, + { M(() => "".LastIndexOf(' ') ), L ((obj,p0) => (Sql.CharIndex(p0, obj) .Value) == 0 ? -1 : obj.Length - (Sql.CharIndex(p0, Sql.Reverse(obj)) .Value)) }, + { M(() => "".LastIndexOf(' ',0) ), L ((obj,p0,p1) => (Sql.CharIndex(p0, obj, p1 + 1) .Value) == 0 ? -1 : obj.Length - (Sql.CharIndex(p0, Sql.Reverse(obj.Substring(p1, obj.Length - p1))).Value)) }, + { M(() => "".LastIndexOf(' ',0,0) ), L((obj,p0,p1,p2) => (Sql.CharIndex(p0, Sql.Left(obj, p1 + p2), p1 + 1).Value) == 0 ? -1 : p1 + p2 - (Sql.CharIndex(p0, Sql.Reverse(obj.Substring(p1, p2))) .Value)) }, + { M(() => "".Insert (0,"") ), L ((obj,p0,p1) => obj.Length == p0 ? obj + p1 : Sql.Stuff(obj, p0 + 1, 0, p1)) }, + { M(() => "".Remove (0) ), L ((obj,p0) => Sql.Left (obj, p0)) }, + { M(() => "".Remove (0,0) ), L ((obj,p0,p1) => Sql.Stuff (obj, p0 + 1, p1, "")) }, + { M(() => "".PadLeft (0) ), L ((obj,p0) => Sql.PadLeft (obj, p0, ' ')) }, + { M(() => "".PadLeft (0,' ') ), L ((obj,p0,p1) => Sql.PadLeft (obj, p0, p1)) }, + { M(() => "".PadRight (0) ), L ((obj,p0) => Sql.PadRight (obj, p0, ' ')) }, + { M(() => "".PadRight (0,' ') ), L ((obj,p0,p1) => Sql.PadRight (obj, p0, p1)) }, + { M(() => "".Replace ("","") ), L ((obj,p0,p1) => Sql.Replace (obj, p0, p1)) }, + { M(() => "".Replace (' ',' ') ), L ((obj,p0,p1) => Sql.Replace (obj, p0, p1)) }, + { M(() => "".Trim () ), L ( obj => Sql.Trim (obj)) }, + { M(() => "".TrimEnd () ), L ((obj,ch) => TrimRight(obj, ch)) }, + { M(() => "".TrimStart () ), L ((obj,ch) => TrimLeft (obj, ch)) }, + { M(() => "".ToLower () ), L ( obj => Sql.Lower(obj)) }, + { M(() => "".ToUpper () ), L ( obj => Sql.Upper(obj)) }, + { M(() => "".CompareTo ("") ), L ((obj,p0) => ConvertToCaseCompareTo(obj, p0).Value ) }, + { M(() => "".CompareTo (1) ), L ((obj,p0) => ConvertToCaseCompareTo(obj, p0.ToString()).Value ) }, + + { M(() => string.IsNullOrEmpty ("") ), L ( p0 => p0 == null || p0.Length == 0) }, + { M(() => string.CompareOrdinal("","")), L ((s1,s2) => s1.CompareTo(s2)) }, + { M(() => string.CompareOrdinal("",0,"",0,0)), L ((s1,i1,s2,i2,l) => s1.Substring(i1, l).CompareTo(s2.Substring(i2, l))) }, + { M(() => string.Compare ("","")), L ((s1,s2) => s1.CompareTo(s2)) }, + { M(() => string.Compare ("",0,"",0,0)), L ((s1,i1,s2,i2,l) => s1.Substring(i1,l).CompareTo(s2.Substring(i2,l))) }, +#if !SILVERLIGHT + { M(() => string.Compare ("","",true)), L ((s1,s2,b) => b ? s1.ToLower().CompareTo(s2.ToLower()) : s1.CompareTo(s2)) }, + { M(() => string.Compare ("",0,"",0,0,true)), L((s1,i1,s2,i2,l,b) => b ? s1.Substring(i1,l).ToLower().CompareTo(s2.Substring(i2, l).ToLower()) : s1.Substring(i1, l).CompareTo(s2.Substring(i2, l))) }, +#endif + + { M(() => AltStuff("",0,0,"")), L((p0,p1,p2,p3) => Sql.Left(p0, p1 - 1) + p3 + Sql.Right(p0, p0.Length - (p1 + p2 - 1))) }, + + #endregion + + #region Binary + + { M(() => ((Binary)null).Length ), L(obj => Sql.Length(obj).Value) }, + + #endregion + + #region DateTime + + { M(() => Sql.GetDate() ), L (() => Sql.CurrentTimestamp2 ) }, + { M(() => DateTime.Now ), L (() => Sql.CurrentTimestamp2 ) }, + + { M(() => DateTime.Now.Year ), L (obj => Sql.DatePart(Sql.DateParts.Year, obj).Value ) }, + { M(() => DateTime.Now.Month ), L (obj => Sql.DatePart(Sql.DateParts.Month, obj).Value ) }, + { M(() => DateTime.Now.DayOfYear ), L (obj => Sql.DatePart(Sql.DateParts.DayOfYear, obj).Value ) }, + { M(() => DateTime.Now.Day ), L (obj => Sql.DatePart(Sql.DateParts.Day, obj).Value ) }, + { M(() => DateTime.Now.DayOfWeek ), L (obj => Sql.DatePart(Sql.DateParts.WeekDay, obj).Value - 1 ) }, + { M(() => DateTime.Now.Hour ), L (obj => Sql.DatePart(Sql.DateParts.Hour, obj).Value ) }, + { M(() => DateTime.Now.Minute ), L (obj => Sql.DatePart(Sql.DateParts.Minute, obj).Value ) }, + { M(() => DateTime.Now.Second ), L (obj => Sql.DatePart(Sql.DateParts.Second, obj).Value ) }, + { M(() => DateTime.Now.Millisecond ), L (obj => Sql.DatePart(Sql.DateParts.Millisecond, obj).Value ) }, + { M(() => DateTime.Now.Date ), L (obj => Sql.Convert2(Sql.Date, obj) ) }, + { M(() => DateTime.Now.TimeOfDay ), L (obj => Sql.DateToTime(Sql.Convert2(Sql.Time, obj)).Value ) }, + { M(() => DateTime.Now.AddYears (0)), L ((obj,p0) => Sql.DateAdd(Sql.DateParts.Year, p0, obj).Value ) }, + { M(() => DateTime.Now.AddMonths (0)), L ((obj,p0) => Sql.DateAdd(Sql.DateParts.Month, p0, obj).Value ) }, + { M(() => DateTime.Now.AddDays (0)), L ((obj,p0) => Sql.DateAdd(Sql.DateParts.Day, p0, obj).Value ) }, + { M(() => DateTime.Now.AddHours (0)), L ((obj,p0) => Sql.DateAdd(Sql.DateParts.Hour, p0, obj).Value ) }, + { M(() => DateTime.Now.AddMinutes (0)), L ((obj,p0) => Sql.DateAdd(Sql.DateParts.Minute, p0, obj).Value ) }, + { M(() => DateTime.Now.AddSeconds (0)), L ((obj,p0) => Sql.DateAdd(Sql.DateParts.Second, p0, obj).Value ) }, + { M(() => DateTime.Now.AddMilliseconds(0)), L ((obj,p0) => Sql.DateAdd(Sql.DateParts.Millisecond, p0, obj).Value ) }, + { M(() => new DateTime(0, 0, 0) ), L((y,m,d) => Sql.MakeDateTime(y, m, d).Value ) }, + + { M(() => Sql.MakeDateTime(0, 0, 0) ), L ((y,m,d) => Sql.Convert(Sql.Date, y.ToString() + "-" + m.ToString() + "-" + d.ToString())) }, + { M(() => new DateTime (0, 0, 0, 0, 0, 0) ), L ((y,m,d,h,mm,s) => Sql.MakeDateTime(y, m, d, h, mm, s).Value ) }, + { M(() => Sql.MakeDateTime(0, 0, 0, 0, 0, 0) ), L((y,m,d,h,mm,s) => Sql.Convert(Sql.DateTime2, + y.ToString() + "-" + m.ToString() + "-" + d.ToString() + " " + + h.ToString() + ":" + mm.ToString() + ":" + s.ToString())) }, + + #endregion + + #region Parse + + { M(() => Boolean. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, + { M(() => Byte. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, +#if !SILVERLIGHT + { M(() => Char. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, +#endif + { M(() => DateTime.Parse("")), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Decimal. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, + { M(() => Double. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, + { M(() => Int16. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, + { M(() => Int32. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, + { M(() => Int64. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, + { M(() => SByte. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, + { M(() => Single. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, + { M(() => UInt16. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, + { M(() => UInt32. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, + { M(() => UInt64. Parse("")), L (p0 => Sql.ConvertTo. From(p0) ) }, + + #endregion + + #region ToString + + { M(() => ((Boolean)true).ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => ((Byte) 0) .ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => ((Char) '0') .ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => ((Decimal) 0) .ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => ((Double) 0) .ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => ((Int16) 0) .ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => ((Int32) 0) .ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => ((Int64) 0) .ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => ((SByte) 0) .ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => ((Single) 0) .ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => ((String) "0") .ToString()), L(p0 => p0 ) }, + { M(() => ((UInt16) 0) .ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => ((UInt32) 0) .ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => ((UInt64) 0) .ToString()), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region Convert + + #region ToBoolean + + { M(() => Convert.ToBoolean((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToBoolean(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToBoolean((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((Double) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((Single) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToBoolean((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToByte + + { M(() => Convert.ToByte((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToByte((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToByte((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToByte(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToByte((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToByte((Double) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToByte((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToByte((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToByte((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToByte((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToByte((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToByte((Single) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToByte((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToByte((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToByte((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToByte((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToChar + +#if !SILVERLIGHT + { M(() => Convert.ToChar((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToChar((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToChar((Char) '0') ), L(p0 => p0 ) }, +#if !SILVERLIGHT + { M(() => Convert.ToChar(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToChar((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToChar((Double) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToChar((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToChar((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToChar((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToChar((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToChar((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToChar((Single) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToChar((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToChar((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToChar((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToChar((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToDateTime + + { M(() => Convert.ToDateTime((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToDateTime((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime(DateTime.Now) ), L(p0 => p0 ) }, + { M(() => Convert.ToDateTime((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime((Double) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime((Single) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDateTime((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + + #endregion + + #region ToDecimal + + { M(() => Convert.ToDecimal((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((Double) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((Single) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDecimal((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToDouble + + { M(() => Convert.ToDouble((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToDouble(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToDouble((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((Double) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((Single) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToDouble((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToInt64 + + { M(() => Convert.ToInt64((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt64((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt64((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToInt64(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToInt64((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToInt64((Double) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToInt64((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt64((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt64((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt64((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt64((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt64((Single) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToInt64((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt64((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt64((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt64((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToInt32 + + { M(() => Convert.ToInt32((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt32((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt32((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToInt32(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToInt32((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToInt32((Double) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToInt32((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt32((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt32((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt32((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt32((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt32((Single) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToInt32((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt32((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt32((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt32((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToInt16 + + { M(() => Convert.ToInt16((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt16((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt16((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToInt16(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToInt16((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToInt16((Double) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToInt16((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt16((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt16((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt16((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt16((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt16((Single) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToInt16((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt16((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt16((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToInt16((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToSByte + + { M(() => Convert.ToSByte((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSByte((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSByte((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToSByte(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToSByte((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToSByte((Double) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToSByte((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSByte((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSByte((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSByte((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSByte((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSByte((Single) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToSByte((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSByte((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSByte((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSByte((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToSingle + + { M(() => Convert.ToSingle((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToSingle(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToSingle((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((Double) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((Single) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToSingle((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToString + + { M(() => Convert.ToString((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString((Double) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString((Single) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToString((String) "0") ), L(p0 => p0 ) }, +#endif + { M(() => Convert.ToString((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToString((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToInt16 + + { M(() => Convert.ToUInt16((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt16((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt16((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToUInt16(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToUInt16((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToUInt16((Double) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToUInt16((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt16((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt16((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt16((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt16((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt16((Single) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToUInt16((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt16((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt16((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt16((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToInt32 + + { M(() => Convert.ToUInt32((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt32((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt32((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToUInt32(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToUInt32((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToUInt32((Double) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToUInt32((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt32((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt32((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt32((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt32((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt32((Single) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToUInt32((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt32((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt32((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt32((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #region ToUInt64 + + { M(() => Convert.ToUInt64((Boolean)true)), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt64((Byte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt64((Char) '0') ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#if !SILVERLIGHT + { M(() => Convert.ToUInt64(DateTime.Now) ), L(p0 => Sql.ConvertTo.From(p0) ) }, +#endif + { M(() => Convert.ToUInt64((Decimal) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToUInt64((Double) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToUInt64((Int16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt64((Int32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt64((Int64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt64((Object) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt64((SByte) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt64((Single) 0) ), L(p0 => Sql.ConvertTo.From(Sql.RoundToEven(p0)) ) }, + { M(() => Convert.ToUInt64((String) "0") ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt64((UInt16) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt64((UInt32) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Convert.ToUInt64((UInt64) 0) ), L(p0 => Sql.ConvertTo.From(p0) ) }, + + #endregion + + #endregion + + #region Math + + { M(() => Math.Abs ((Decimal)0)), L(p => Sql.Abs(p).Value ) }, + { M(() => Math.Abs ((Double) 0)), L (p => Sql.Abs(p).Value ) }, + { M(() => Math.Abs ((Int16) 0)), L (p => Sql.Abs(p).Value ) }, + { M(() => Math.Abs ((Int32) 0)), L (p => Sql.Abs(p).Value ) }, + { M(() => Math.Abs ((Int64) 0)), L (p => Sql.Abs(p).Value ) }, + { M(() => Math.Abs ((SByte) 0)), L (p => Sql.Abs(p).Value ) }, + { M(() => Math.Abs ((Single) 0)), L (p => Sql.Abs(p).Value ) }, + + { M(() => Math.Acos (0) ), L ( p => Sql.Acos (p) .Value ) }, + { M(() => Math.Asin (0) ), L ( p => Sql.Asin (p) .Value ) }, + { M(() => Math.Atan (0) ), L ( p => Sql.Atan (p) .Value ) }, + { M(() => Math.Atan2 (0,0) ), L((x,y) => Sql.Atan2 (x, y).Value ) }, +#if !SILVERLIGHT + { M(() => Math.Ceiling((M)0)), L ( p => Sql.Ceiling(p) .Value ) }, +#endif + { M(() => Math.Ceiling((F)0)), L ( p => Sql.Ceiling(p) .Value ) }, + { M(() => Math.Cos (0) ), L ( p => Sql.Cos (p) .Value ) }, + { M(() => Math.Cosh (0) ), L ( p => Sql.Cosh (p) .Value ) }, + { M(() => Math.Exp (0) ), L ( p => Sql.Exp (p) .Value ) }, +#if !SILVERLIGHT + { M(() => Math.Floor ((M)0)), L ( p => Sql.Floor (p) .Value ) }, +#endif + { M(() => Math.Floor ((F)0)), L ( p => Sql.Floor (p) .Value ) }, + { M(() => Math.Log (0) ), L ( p => Sql.Log (p) .Value ) }, + { M(() => Math.Log (0,0) ), L((m,n) => Sql.Log (n, m).Value ) }, + { M(() => Math.Log10 (0) ), L ( p => Sql.Log10 (p) .Value ) }, + + { M(() => Math.Max((Byte) 0, (Byte) 0)), L ((v1,v2) => v1 > v2 ? v1 : v2) }, + { M(() => Math.Max((Decimal)0, (Decimal)0)), L((v1,v2) => v1 > v2 ? v1 : v2) }, + { M(() => Math.Max((Double) 0, (Double) 0)), L ((v1,v2) => v1 > v2 ? v1 : v2) }, + { M(() => Math.Max((Int16) 0, (Int16) 0)), L ((v1,v2) => v1 > v2 ? v1 : v2) }, + { M(() => Math.Max((Int32) 0, (Int32) 0)), L ((v1,v2) => v1 > v2 ? v1 : v2) }, + { M(() => Math.Max((Int64) 0, (Int64) 0)), L ((v1,v2) => v1 > v2 ? v1 : v2) }, + { M(() => Math.Max((SByte) 0, (SByte) 0)), L ((v1,v2) => v1 > v2 ? v1 : v2) }, + { M(() => Math.Max((Single) 0, (Single) 0)), L ((v1,v2) => v1 > v2 ? v1 : v2) }, + { M(() => Math.Max((UInt16) 0, (UInt16) 0)), L ((v1,v2) => v1 > v2 ? v1 : v2) }, + { M(() => Math.Max((UInt32) 0, (UInt32) 0)), L ((v1,v2) => v1 > v2 ? v1 : v2) }, + { M(() => Math.Max((UInt64) 0, (UInt64) 0)), L ((v1,v2) => v1 > v2 ? v1 : v2) }, + + { M(() => Math.Min((Byte) 0, (Byte) 0)), L ((v1,v2) => v1 < v2 ? v1 : v2) }, + { M(() => Math.Min((Decimal)0, (Decimal)0)), L((v1,v2) => v1 < v2 ? v1 : v2) }, + { M(() => Math.Min((Double) 0, (Double) 0)), L ((v1,v2) => v1 < v2 ? v1 : v2) }, + { M(() => Math.Min((Int16) 0, (Int16) 0)), L ((v1,v2) => v1 < v2 ? v1 : v2) }, + { M(() => Math.Min((Int32) 0, (Int32) 0)), L ((v1,v2) => v1 < v2 ? v1 : v2) }, + { M(() => Math.Min((Int64) 0, (Int64) 0)), L ((v1,v2) => v1 < v2 ? v1 : v2) }, + { M(() => Math.Min((SByte) 0, (SByte) 0)), L ((v1,v2) => v1 < v2 ? v1 : v2) }, + { M(() => Math.Min((Single) 0, (Single) 0)), L ((v1,v2) => v1 < v2 ? v1 : v2) }, + { M(() => Math.Min((UInt16) 0, (UInt16) 0)), L ((v1,v2) => v1 < v2 ? v1 : v2) }, + { M(() => Math.Min((UInt32) 0, (UInt32) 0)), L ((v1,v2) => v1 < v2 ? v1 : v2) }, + { M(() => Math.Min((UInt64) 0, (UInt64) 0)), L ((v1,v2) => v1 < v2 ? v1 : v2) }, + + { M(() => Math.Pow (0,0)), L((x,y) => Sql.Power(x, y).Value ) }, + + { M(() => Sql.Round (0m) ), L ( d => Sql.Round(d, 0)) }, + { M(() => Sql.Round (0.0) ), L ( d => Sql.Round(d, 0)) }, + + { M(() => Sql.RoundToEven(0m) ), L ( d => d - Sql.Floor(d) == 0.5m && Sql.Floor(d) % 2 == 0? Sql.Floor(d) : Sql.Round(d)) }, + { M(() => Sql.RoundToEven(0.0) ), L ( d => d - Sql.Floor(d) == 0.5 && Sql.Floor(d) % 2 == 0? Sql.Floor(d) : Sql.Round(d)) }, + + { M(() => Sql.RoundToEven(0m, 0)), L((d,n) => d * 2 == Sql.Round(d * 2, n) && d != Sql.Round(d, n) ? Sql.Round(d / 2, n) * 2 : Sql.Round(d, n)) }, + { M(() => Sql.RoundToEven(0.0,0)), L((d,n) => d * 2 == Sql.Round(d * 2, n) && d != Sql.Round(d, n) ? Sql.Round(d / 2, n) * 2 : Sql.Round(d, n)) }, + + { M(() => Math.Round (0m) ), L ( d => Sql.RoundToEven(d).Value ) }, + { M(() => Math.Round (0.0) ), L ( d => Sql.RoundToEven(d).Value ) }, + + { M(() => Math.Round (0m, 0)), L ((d,n) => Sql.RoundToEven(d, n).Value ) }, + { M(() => Math.Round (0.0,0)), L ((d,n) => Sql.RoundToEven(d, n).Value ) }, + +#if !SILVERLIGHT + { M(() => Math.Round (0m, MidpointRounding.ToEven)), L((d, p) => p == MidpointRounding.ToEven ? Sql.RoundToEven(d). Value : Sql.Round(d). Value ) }, + { M(() => Math.Round (0.0, MidpointRounding.ToEven)), L((d, p) => p == MidpointRounding.ToEven ? Sql.RoundToEven(d). Value : Sql.Round(d). Value ) }, + + { M(() => Math.Round (0m, 0, MidpointRounding.ToEven)), L((d,n,p) => p == MidpointRounding.ToEven ? Sql.RoundToEven(d,n).Value : Sql.Round(d,n).Value ) }, + { M(() => Math.Round (0.0,0, MidpointRounding.ToEven)), L((d,n,p) => p == MidpointRounding.ToEven ? Sql.RoundToEven(d,n).Value : Sql.Round(d,n).Value ) }, +#endif + + { M(() => Math.Sign ((Decimal)0)), L(p => Sql.Sign(p).Value ) }, + { M(() => Math.Sign ((Double) 0)), L(p => Sql.Sign(p).Value ) }, + { M(() => Math.Sign ((Int16) 0)), L(p => Sql.Sign(p).Value ) }, + { M(() => Math.Sign ((Int32) 0)), L(p => Sql.Sign(p).Value ) }, + { M(() => Math.Sign ((Int64) 0)), L(p => Sql.Sign(p).Value ) }, + { M(() => Math.Sign ((SByte) 0)), L(p => Sql.Sign(p).Value ) }, + { M(() => Math.Sign ((Single) 0)), L(p => Sql.Sign(p).Value ) }, + + { M(() => Math.Sin (0)), L( p => Sql.Sin (p).Value ) }, + { M(() => Math.Sinh (0)), L( p => Sql.Sinh(p).Value ) }, + { M(() => Math.Sqrt (0)), L( p => Sql.Sqrt(p).Value ) }, + { M(() => Math.Tan (0)), L( p => Sql.Tan (p).Value ) }, + { M(() => Math.Tanh (0)), L( p => Sql.Tanh(p).Value ) }, + +#if !SILVERLIGHT + { M(() => Math.Truncate(0m)), L( p => Sql.Truncate(p).Value ) }, + { M(() => Math.Truncate(0.0)), L( p => Sql.Truncate(p).Value ) }, +#endif + + #endregion + + #region Visual Basic Compiler Services + +//#if !SILVERLIGHT +// { M(() => Operators.CompareString("","",false)), L((s1,s2,b) => b ? string.CompareOrdinal(s1.ToUpper(), s2.ToUpper()) : string.CompareOrdinal(s1, s2)) }, +//#endif + + #endregion + + }}, + + #region MsSql2012 + + { "MsSql2012", new Dictionary { + { M(() => Sql.PadRight("",0,' ')), L ((p0,p1,p2) => p0.Length > p1 ? p0 : p0 + Replicate(p2, p1 - p0.Length)) }, + { M(() => Sql.PadLeft ("",0,' ')), L ((p0,p1,p2) => p0.Length > p1 ? p0 : Replicate(p2, p1 - p0.Length) + p0) }, + { M(() => Sql.Trim ("") ), L ( p0 => Sql.TrimLeft(Sql.TrimRight(p0))) }, + { M(() => Sql.MakeDateTime(0,0,0)), L((y,m,d) => DateAdd(Sql.DateParts.Month, (y.Value - 1900) * 12 + m.Value - 1, d.Value - 1)) }, + + { M(() => Sql.Cosh(0) ), L ( v => (Sql.Exp(v) + Sql.Exp(-v)) / 2) }, + { M(() => Sql.Log(0m, 0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Log(0.0,0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Sinh(0) ), L ( v => (Sql.Exp(v) - Sql.Exp(-v)) / 2) }, + { M(() => Sql.Tanh(0) ), L ( v => (Sql.Exp(v) - Sql.Exp(-v)) / (Sql.Exp(v) + Sql.Exp(-v))) }, + }}, + + #endregion + + #region MsSql2008 + + { "MsSql2008", new Dictionary { + { M(() => Sql.PadRight("",0,' ')), L ((p0,p1,p2) => p0.Length > p1 ? p0 : p0 + Replicate(p2, p1 - p0.Length)) }, + { M(() => Sql.PadLeft ("",0,' ')), L ((p0,p1,p2) => p0.Length > p1 ? p0 : Replicate(p2, p1 - p0.Length) + p0) }, + { M(() => Sql.Trim ("") ), L ( p0 => Sql.TrimLeft(Sql.TrimRight(p0))) }, + { M(() => Sql.MakeDateTime(0,0,0)), L((y,m,d) => DateAdd(Sql.DateParts.Month, (y.Value - 1900) * 12 + m.Value - 1, d.Value - 1)) }, + + { M(() => Sql.Cosh(0) ), L ( v => (Sql.Exp(v) + Sql.Exp(-v)) / 2) }, + { M(() => Sql.Log(0m, 0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Log(0.0,0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Sinh(0) ), L ( v => (Sql.Exp(v) - Sql.Exp(-v)) / 2) }, + { M(() => Sql.Tanh(0) ), L ( v => (Sql.Exp(v) - Sql.Exp(-v)) / (Sql.Exp(v) + Sql.Exp(-v))) }, + }}, + + #endregion + + #region MsSql2000 + + { "MsSql2000", new Dictionary { + { M(() => Sql.PadRight("",0,' ')), L ((p0,p1,p2) => p0.Length > p1 ? p0 : p0 + Replicate(p2, p1 - p0.Length)) }, + { M(() => Sql.PadLeft ("",0,' ')), L ((p0,p1,p2) => p0.Length > p1 ? p0 : Replicate(p2, p1 - p0.Length) + p0) }, + { M(() => Sql.Trim ("") ), L ( p0 => Sql.TrimLeft(Sql.TrimRight(p0))) }, + { M(() => Sql.MakeDateTime(0,0,0)), L((y,m,d) => DateAdd(Sql.DateParts.Month, (y.Value - 1900) * 12 + m.Value - 1, d.Value - 1)) }, + { M(() => Sql.MakeDateTime(0, 0, 0, 0, 0, 0) ), L((y,m,d,h,mm,s) => Sql.Convert(Sql.DateTime2, + y.ToString() + "-" + m.ToString() + "-" + d.ToString() + " " + + h.ToString() + ":" + mm.ToString() + ":" + s.ToString(), 120)) }, + { M(() => Sql.Cosh(0) ), L ( v => (Sql.Exp(v) + Sql.Exp(-v)) / 2) }, + { M(() => Sql.Log(0m, 0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Log(0.0,0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Sinh(0) ), L ( v => (Sql.Exp(v) - Sql.Exp(-v)) / 2) }, + { M(() => Sql.Tanh(0) ), L ( v => (Sql.Exp(v) - Sql.Exp(-v)) / (Sql.Exp(v) + Sql.Exp(-v))) }, + + { M(() => DateTime.Parse("")), L(p0 => Sql.ConvertTo.From(p0) ) }, + { M(() => Sql.RoundToEven(0m) ), L(d => d - Sql.Floor(d) == 0.5m && (long)Sql.Floor(d) % 2 == 0? Sql.Floor(d) : Sql.Round(d)) }, + { M(() => Sql.RoundToEven(0.0)), L(d => d - Sql.Floor(d) == 0.5 && (long)Sql.Floor(d) % 2 == 0? Sql.Floor(d) : Sql.Round(d)) }, + + }}, + + #endregion + + #region MsSql2005 + + { "MsSql2005", new Dictionary { + { M(() => Sql.PadRight("",0,' ')), L ((p0,p1,p2) => p0.Length > p1 ? p0 : p0 + Replicate(p2, p1 - p0.Length)) }, + { M(() => Sql.PadLeft ("",0,' ')), L ((p0,p1,p2) => p0.Length > p1 ? p0 : Replicate(p2, p1 - p0.Length) + p0) }, + { M(() => Sql.Trim ("") ), L ( p0 => Sql.TrimLeft(Sql.TrimRight(p0))) }, + { M(() => Sql.MakeDateTime(0,0,0)), L((y,m,d) => DateAdd(Sql.DateParts.Month, (y.Value - 1900) * 12 + m.Value - 1, d.Value - 1)) }, + { M(() => Sql.MakeDateTime(0, 0, 0, 0, 0, 0) ), L((y,m,d,h,mm,s) => Sql.Convert(Sql.DateTime2, + y.ToString() + "-" + m.ToString() + "-" + d.ToString() + " " + + h.ToString() + ":" + mm.ToString() + ":" + s.ToString(), 120)) }, + { M(() => Sql.Cosh(0) ), L ( v => (Sql.Exp(v) + Sql.Exp(-v)) / 2) }, + { M(() => Sql.Log(0m, 0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Log(0.0,0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Sinh(0) ), L ( v => (Sql.Exp(v) - Sql.Exp(-v)) / 2) }, + { M(() => Sql.Tanh(0) ), L ( v => (Sql.Exp(v) - Sql.Exp(-v)) / (Sql.Exp(v) + Sql.Exp(-v))) }, + + { M(() => DateTime.Parse("")), L(p0 => Sql.ConvertTo.From(p0) ) }, + }}, + + #endregion + + #region SqlCe + + { "SqlCe", new Dictionary { + { M(() => Sql.Left ("",0) ), L ((p0,p1) => Sql.Substring(p0, 1, p1)) }, + { M(() => Sql.Right ("",0) ), L ((p0,p1) => Sql.Substring(p0, p0.Length - p1 + 1, p1)) }, + { M(() => Sql.PadRight("",0,' ')), L((p0,p1,p2) => p0.Length > p1 ? p0 : p0 + Replicate(p2, p1 - p0.Length)) }, + { M(() => Sql.PadLeft ("",0,' ')), L((p0,p1,p2) => p0.Length > p1 ? p0 : Replicate(p2, p1 - p0.Length) + p0) }, + { M(() => Sql.Trim ("") ), L ( p0 => Sql.TrimLeft(Sql.TrimRight(p0))) }, + + { M(() => Sql.Cosh(0) ), L ( v => (Sql.Exp(v) + Sql.Exp(-v)) / 2) }, + { M(() => Sql.Log (0m, 0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Log (0.0,0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Sinh(0) ), L ( v => (Sql.Exp(v) - Sql.Exp(-v)) / 2) }, + { M(() => Sql.Tanh(0) ), L ( v => (Sql.Exp(v) - Sql.Exp(-v)) / (Sql.Exp(v) + Sql.Exp(-v))) }, + }}, + + #endregion + + #region DB2 + + { "DB2", new Dictionary { + { M(() => Sql.Space (0) ), L ( p0 => Sql.Convert(Sql.VarChar(1000), Replicate(" ", p0))) }, + { M(() => Sql.Stuff ("",0,0,"")), L((p0,p1,p2,p3) => AltStuff(p0, p1, p2, p3)) }, + { M(() => Sql.PadRight("",0,' ') ), L ((p0,p1,p2) => p0.Length > p1 ? p0 : p0 + VarChar(Replicate(p2, p1 - p0.Length), 1000)) }, + { M(() => Sql.PadLeft ("",0,' ') ), L ((p0,p1,p2) => p0.Length > p1 ? p0 : VarChar(Replicate(p2, p1 - p0.Length), 1000) + p0) }, + + { M(() => Sql.ConvertTo.From((Decimal)0)), L(p => Sql.TrimLeft(Sql.Convert(p), '0')) }, + { M(() => Sql.ConvertTo.From(Guid.Empty)), L(p => Sql.Lower( + Sql.Substring(Hex(p), 7, 2) + Sql.Substring(Hex(p), 5, 2) + Sql.Substring(Hex(p), 3, 2) + Sql.Substring(Hex(p), 1, 2) + "-" + + Sql.Substring(Hex(p), 11, 2) + Sql.Substring(Hex(p), 9, 2) + "-" + + Sql.Substring(Hex(p), 15, 2) + Sql.Substring(Hex(p), 13, 2) + "-" + + Sql.Substring(Hex(p), 17, 4) + "-" + + Sql.Substring(Hex(p), 21, 12))) }, + + { M(() => Sql.Log(0m, 0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Log(0.0,0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + }}, + + #endregion + + #region Informix + + { "Informix", new Dictionary { + { M(() => Sql.Left ("",0) ), L ((p0,p1) => Sql.Substring(p0, 1, p1)) }, + { M(() => Sql.Right("",0) ), L ((p0,p1) => Sql.Substring(p0, p0.Length - p1 + 1, p1)) }, + { M(() => Sql.Stuff("",0,0,"")), L((p0,p1,p2,p3) => AltStuff (p0, p1, p2, p3)) }, + { M(() => Sql.Space(0) ), L ( p0 => Sql.PadRight (" ", p0, ' ')) }, + + { M(() => Sql.MakeDateTime(0,0,0)), L((y,m,d) => Mdy(m, d, y)) }, + + { M(() => Sql.Cot (0) ), L ( v => Sql.Cos(v) / Sql.Sin(v) ) }, + { M(() => Sql.Cosh(0) ), L ( v => (Sql.Exp(v) + Sql.Exp(-v)) / 2 ) }, + + { M(() => Sql.Degrees((Decimal?)0)), L( v => (Decimal?)(v.Value * (180 / (Decimal)Math.PI))) }, + { M(() => Sql.Degrees((Double?) 0)), L ( v => (Double?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int16?) 0)), L ( v => (Int16?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int32?) 0)), L ( v => (Int32?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int64?) 0)), L ( v => (Int64?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((SByte?) 0)), L ( v => (SByte?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Single?) 0)), L ( v => (Single?) (v.Value * (180 / Math.PI))) }, + + { M(() => Sql.Log(0m, 0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Log(0.0,0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + + { M(() => Sql.Sign((Decimal?)0)), L(p => p > 0 ? 1 : p < 0 ? -1 : 0 ) }, + { M(() => Sql.Sign((Double?) 0)), L(p => p > 0 ? 1 : p < 0 ? -1 : 0 ) }, + { M(() => Sql.Sign((Int16?) 0)), L(p => p > 0 ? 1 : p < 0 ? -1 : 0 ) }, + { M(() => Sql.Sign((Int32?) 0)), L(p => p > 0 ? 1 : p < 0 ? -1 : 0 ) }, + { M(() => Sql.Sign((Int64?) 0)), L(p => p > 0 ? 1 : p < 0 ? -1 : 0 ) }, + { M(() => Sql.Sign((SByte?) 0)), L(p => p > 0 ? 1 : p < 0 ? -1 : 0 ) }, + { M(() => Sql.Sign((Single?) 0)), L(p => p > 0 ? 1 : p < 0 ? -1 : 0 ) }, + + { M(() => Sql.Sinh(0)), L( v => (Sql.Exp(v) - Sql.Exp(-v)) / 2) }, + { M(() => Sql.Tanh(0)), L( v => (Sql.Exp(v) - Sql.Exp(-v)) / (Sql.Exp(v) +Sql.Exp(-v))) }, + }}, + + #endregion + + #region Oracle + + { "Oracle", new Dictionary { + { M(() => Sql.Left ("",0) ), L ((p0,p1) => Sql.Substring(p0, 1, p1)) }, + { M(() => Sql.Right("",0) ), L ((p0,p1) => Sql.Substring(p0, p0.Length - p1 + 1, p1)) }, + { M(() => Sql.Stuff("",0,0,"")), L((p0,p1,p2,p3) => AltStuff(p0, p1, p2, p3)) }, + { M(() => Sql.Space(0) ), L ( p0 => Sql.PadRight(" ", p0, ' ')) }, + + { M(() => Sql.ConvertTo.From(Guid.Empty)), L(p => Sql.Lower( + Sql.Substring(Sql.Convert2(Sql.Char(36), p), 7, 2) + Sql.Substring(Sql.Convert2(Sql.Char(36), p), 5, 2) + Sql.Substring(Sql.Convert2(Sql.Char(36), p), 3, 2) + Sql.Substring(Sql.Convert2(Sql.Char(36), p), 1, 2) + "-" + + Sql.Substring(Sql.Convert2(Sql.Char(36), p), 11, 2) + Sql.Substring(Sql.Convert2(Sql.Char(36), p), 9, 2) + "-" + + Sql.Substring(Sql.Convert2(Sql.Char(36), p), 15, 2) + Sql.Substring(Sql.Convert2(Sql.Char(36), p), 13, 2) + "-" + + Sql.Substring(Sql.Convert2(Sql.Char(36), p), 17, 4) + "-" + + Sql.Substring(Sql.Convert2(Sql.Char(36), p), 21, 12))) }, + + { M(() => Sql.Cot (0)), L(v => Sql.Cos(v) / Sql.Sin(v) ) }, + { M(() => Sql.Log10(0.0)), L(v => Sql.Log(10, v) ) }, + + { M(() => Sql.Degrees((Decimal?)0)), L( v => (Decimal?)(v.Value * (180 / (Decimal)Math.PI))) }, + { M(() => Sql.Degrees((Double?) 0)), L ( v => (Double?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int16?) 0)), L ( v => (Int16?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int32?) 0)), L ( v => (Int32?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int64?) 0)), L ( v => (Int64?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((SByte?) 0)), L ( v => (SByte?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Single?) 0)), L ( v => (Single?) (v.Value * (180 / Math.PI))) }, + }}, + + #endregion + + #region Firebird + + { "Firebird", new Dictionary { + { M(_ => Sql.Space(0 )), L ( p0 => Sql.PadRight(" ", p0, ' ')) }, + { M(s => Sql.Stuff(s, 0, 0, s)), L((p0,p1,p2,p3) => AltStuff(p0, p1, p2, p3)) }, + + { M(() => Sql.Degrees((Decimal?)0)), L( v => (Decimal?)(v.Value * 180 / DecimalPI())) }, + { M(() => Sql.Degrees((Double?) 0)), L ( v => (Double?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int16?) 0)), L ( v => (Int16?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int32?) 0)), L ( v => (Int32?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int64?) 0)), L ( v => (Int64?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((SByte?) 0)), L ( v => (SByte?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Single?) 0)), L ( v => (Single?) (v.Value * (180 / Math.PI))) }, + + { M(() => Sql.RoundToEven(0.0) ), L ( v => (double)Sql.RoundToEven((decimal)v)) }, + { M(() => Sql.RoundToEven(0.0,0)), L((v,p) => (double)Sql.RoundToEven((decimal)v, p)) }, + }}, + + #endregion + + #region MySql + + { "MySql", new Dictionary { + { M(s => Sql.Stuff(s, 0, 0, s)), L((p0,p1,p2,p3) => AltStuff(p0, p1, p2, p3)) }, + + { M(() => Sql.Cosh(0)), L(v => (Sql.Exp(v) + Sql.Exp(-v)) / 2) }, + { M(() => Sql.Sinh(0)), L(v => (Sql.Exp(v) - Sql.Exp(-v)) / 2) }, + { M(() => Sql.Tanh(0)), L(v => (Sql.Exp(v) - Sql.Exp(-v)) / (Sql.Exp(v) + Sql.Exp(-v))) }, + }}, + + #endregion + + #region PostgreSQL + + { "PostgreSQL", new Dictionary { + { M(() => Sql.Left ("",0) ), L ((p0,p1) => Sql.Substring(p0, 1, p1)) }, + { M(() => Sql.Right("",0) ), L ((p0,p1) => Sql.Substring(p0, p0.Length - p1 + 1, p1)) }, + { M(() => Sql.Stuff("",0,0,"")), L((p0,p1,p2,p3) => AltStuff(p0, p1, p2, p3)) }, + { M(() => Sql.Space(0) ), L ( p0 => Replicate(" ", p0)) }, + + { M(() => Sql.Cosh(0) ), L ( v => (Sql.Exp(v) + Sql.Exp(-v)) / 2 ) }, + { M(() => Sql.Round (0.0,0)), L ((v,p) => (double)Sql.Round ((decimal)v, p)) }, + { M(() => Sql.RoundToEven(0.0) ), L ( v => (double)Sql.RoundToEven((decimal)v)) }, + { M(() => Sql.RoundToEven(0.0,0)), L ((v,p) => (double)Sql.RoundToEven((decimal)v, p)) }, + + { M(() => Sql.Log ((double)0,0)), L ((m,n) => (F?)Sql.Log((M)m,(M)n).Value ) }, + { M(() => Sql.Sinh (0) ), L ( v => (Sql.Exp(v) - Sql.Exp(-v)) / 2) }, + { M(() => Sql.Tanh (0) ), L ( v => (Sql.Exp(v) - Sql.Exp(-v)) / (Sql.Exp(v) + Sql.Exp(-v))) }, + + { M(() => Sql.Truncate(0.0) ), L ( v => (double)Sql.Truncate((decimal)v)) }, + }}, + + #endregion + + #region SQLite + + { "SQLite", new Dictionary { + { M(() => Sql.Stuff ("",0,0,"")), L((p0,p1,p2,p3) => AltStuff(p0, p1, p2, p3)) }, + { M(() => Sql.PadRight("",0,' ') ), L ((p0,p1,p2) => p0.Length > p1 ? p0 : p0 + Replicate(p2, p1 - p0.Length)) }, + { M(() => Sql.PadLeft ("",0,' ') ), L ((p0,p1,p2) => p0.Length > p1 ? p0 : Replicate(p2, p1 - p0.Length) + p0) }, + + { M(() => Sql.MakeDateTime(0, 0, 0)), L((y,m,d) => Sql.Convert(Sql.Date, + y.ToString() + "-" + + (m.ToString().Length == 1 ? "0" + m.ToString() : m.ToString()) + "-" + + (d.ToString().Length == 1 ? "0" + d.ToString() : d.ToString()))) }, + + { M(() => Sql.MakeDateTime(0, 0, 0, 0, 0, 0)), L((y,m,d,h,i,s) => Sql.Convert(Sql.DateTime2, + y.ToString() + "-" + + (m.ToString().Length == 1 ? "0" + m.ToString() : m.ToString()) + "-" + + (d.ToString().Length == 1 ? "0" + d.ToString() : d.ToString()) + " " + + (h.ToString().Length == 1 ? "0" + h.ToString() : h.ToString()) + ":" + + (i.ToString().Length == 1 ? "0" + i.ToString() : i.ToString()) + ":" + + (s.ToString().Length == 1 ? "0" + s.ToString() : s.ToString()))) }, + + { M(() => Sql.ConvertTo.From(Guid.Empty)), L(p => Sql.Lower( + Sql.Substring(Hex(p), 7, 2) + Sql.Substring(Hex(p), 5, 2) + Sql.Substring(Hex(p), 3, 2) + Sql.Substring(Hex(p), 1, 2) + "-" + + Sql.Substring(Hex(p), 11, 2) + Sql.Substring(Hex(p), 9, 2) + "-" + + Sql.Substring(Hex(p), 15, 2) + Sql.Substring(Hex(p), 13, 2) + "-" + + Sql.Substring(Hex(p), 17, 4) + "-" + + Sql.Substring(Hex(p), 21, 12))) }, + + { M(() => Sql.Log (0m, 0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Log (0.0,0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + + { M(() => Sql.Truncate(0m)), L( v => v >= 0 ? Sql.Floor(v) : Sql.Ceiling(v)) }, + { M(() => Sql.Truncate(0.0)), L( v => v >= 0 ? Sql.Floor(v) : Sql.Ceiling(v)) }, + }}, + + #endregion + + #region Sybase + + { "Sybase", new Dictionary { + { M(() => Sql.PadRight("",0,' ')), L((p0,p1,p2) => p0.Length > p1 ? p0 : p0 + Replicate(p2, p1 - p0.Length)) }, + { M(() => Sql.PadLeft ("",0,' ')), L((p0,p1,p2) => p0.Length > p1 ? p0 : Replicate(p2, p1 - p0.Length) + p0) }, + { M(() => Sql.Trim ("") ), L ( p0 => Sql.TrimLeft(Sql.TrimRight(p0))) }, + + { M(() => Sql.Cosh(0) ), L ( v => (Sql.Exp(v) + Sql.Exp(-v)) / 2) }, + { M(() => Sql.Log (0m, 0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + { M(() => Sql.Log (0.0,0)), L((m,n) => Sql.Log(n) / Sql.Log(m)) }, + + { M(() => Sql.Degrees((Decimal?)0)), L( v => (Decimal?)(v.Value * (180 / (Decimal)Math.PI))) }, + { M(() => Sql.Degrees((Double?) 0)), L ( v => (Double?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int16?) 0)), L ( v => (Int16?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int32?) 0)), L ( v => (Int32?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int64?) 0)), L ( v => (Int64?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((SByte?) 0)), L ( v => (SByte?) (v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Single?) 0)), L ( v => (Single?) (v.Value * (180 / Math.PI))) }, + + { M(() => Sql.Sinh(0)), L( v => (Sql.Exp(v) - Sql.Exp(-v)) / 2) }, + { M(() => Sql.Tanh(0)), L( v => (Sql.Exp(v) - Sql.Exp(-v)) / (Sql.Exp(v) + Sql.Exp(-v))) }, + + { M(() => Sql.Truncate(0m)), L( v => v >= 0 ? Sql.Floor(v) : Sql.Ceiling(v)) }, + { M(() => Sql.Truncate(0.0)), L( v => v >= 0 ? Sql.Floor(v) : Sql.Ceiling(v)) }, + }}, + + #endregion + + #region Access + + { "Access", new Dictionary { + { M(() => Sql.Stuff ("",0,0,"")), L((p0,p1,p2,p3) => AltStuff(p0, p1, p2, p3)) }, + { M(() => Sql.PadRight("",0,' ') ), L ((p0,p1,p2) => p0.Length > p1 ? p0 : p0 + Replicate(p2, p1 - p0.Length)) }, + { M(() => Sql.PadLeft ("",0,' ') ), L ((p0,p1,p2) => p0.Length > p1 ? p0 : Replicate(p2, p1 - p0.Length) + p0) }, + { M(() => Sql.MakeDateTime(0,0,0)), L((y,m,d) => MakeDateTime2(y, m, d)) }, + + { M(() => Sql.ConvertTo.From(Guid.Empty)), L(p => Sql.Lower(Sql.Substring(p.ToString(), 2, 36))) }, + + { M(() => Sql.Ceiling((Decimal)0)), L(p => -Sql.Floor(-p) ) }, + { M(() => Sql.Ceiling((Double) 0)), L (p => -Sql.Floor(-p) ) }, + + { M(() => Sql.Cot (0) ), L ( v => Sql.Cos(v) / Sql.Sin(v) ) }, + { M(() => Sql.Cosh (0) ), L ( v => (Sql.Exp(v) + Sql.Exp(-v)) / 2) }, + { M(() => Sql.Log (0m, 0)), L((m,n) => Sql.Log(n) / Sql.Log(m) ) }, + { M(() => Sql.Log (0.0,0)), L((m,n) => Sql.Log(n) / Sql.Log(m) ) }, + { M(() => Sql.Log10(0.0) ), L ( n => Sql.Log(n) / Sql.Log(10.0) ) }, + + { M(() => Sql.Degrees((Decimal?)0)), L( v => (Decimal?) ( v.Value * (180 / (Decimal)Math.PI))) }, + { M(() => Sql.Degrees((Double?) 0)), L ( v => (Double?) ( v.Value * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int16?) 0)), L ( v => (Int16?) AccessInt(AccessInt(v.Value) * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int32?) 0)), L ( v => (Int32?) AccessInt(AccessInt(v.Value) * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Int64?) 0)), L ( v => (Int64?) AccessInt(AccessInt(v.Value) * (180 / Math.PI))) }, + { M(() => Sql.Degrees((SByte?) 0)), L ( v => (SByte?) AccessInt(AccessInt(v.Value) * (180 / Math.PI))) }, + { M(() => Sql.Degrees((Single?) 0)), L ( v => (Single?) ( v.Value * (180 / Math.PI))) }, + + { M(() => Sql.Round (0m) ), L ( d => d - Sql.Floor(d) == 0.5m && Sql.Floor(d) % 2 == 0? Sql.Ceiling(d) : AccessRound(d, 0)) }, + { M(() => Sql.Round (0.0) ), L ( d => d - Sql.Floor(d) == 0.5 && Sql.Floor(d) % 2 == 0? Sql.Ceiling(d) : AccessRound(d, 0)) }, + { M(() => Sql.Round (0m, 0)), L((v,p)=> + p == 1 ? Sql.Round(v * 10) / 10 : + p == 2 ? Sql.Round(v * 10) / 10 : + p == 3 ? Sql.Round(v * 10) / 10 : + p == 4 ? Sql.Round(v * 10) / 10 : + p == 5 ? Sql.Round(v * 10) / 10 : + Sql.Round(v * 10) / 10) }, + { M(() => Sql.Round (0.0,0)), L((v,p)=> + p == 1 ? Sql.Round(v * 10) / 10 : + p == 2 ? Sql.Round(v * 10) / 10 : + p == 3 ? Sql.Round(v * 10) / 10 : + p == 4 ? Sql.Round(v * 10) / 10 : + p == 5 ? Sql.Round(v * 10) / 10 : + Sql.Round(v * 10) / 10) }, + { M(() => Sql.RoundToEven(0m) ), L ( v => AccessRound(v, 0))}, + { M(() => Sql.RoundToEven(0.0) ), L ( v => AccessRound(v, 0))}, + { M(() => Sql.RoundToEven(0m, 0)), L((v,p)=> AccessRound(v, p))}, + { M(() => Sql.RoundToEven(0.0,0)), L((v,p)=> AccessRound(v, p))}, + + { M(() => Sql.Sinh(0)), L( v => (Sql.Exp(v) - Sql.Exp(-v)) / 2) }, + { M(() => Sql.Tanh(0)), L( v => (Sql.Exp(v) - Sql.Exp(-v)) / (Sql.Exp(v) + Sql.Exp(-v))) }, + + { M(() => Sql.Truncate(0m)), L( v => v >= 0 ? Sql.Floor(v) : Sql.Ceiling(v)) }, + { M(() => Sql.Truncate(0.0)), L( v => v >= 0 ? Sql.Floor(v) : Sql.Ceiling(v)) }, + }}, + + #endregion + }; + + #region Sql specific + + [CLSCompliant(false)] + [SqlFunction("RTrim", 0)] + public static string TrimRight(string str, char[] trimChars) + { + return str == null ? null : str.TrimEnd(trimChars); + } + + [CLSCompliant(false)] + [SqlFunction("LTrim", 0)] + public static string TrimLeft(string str, char[] trimChars) + { + return str == null ? null : str.TrimStart(trimChars); + } + + #endregion + + #region Provider specific functions + + [SqlFunction] + static int? ConvertToCaseCompareTo(string str, string value) + { + return str == null || value == null ? (int?)null : str.CompareTo(value); + } + + // Access, DB2, Firebird, Informix, MySql, Oracle, PostgreSQL, SQLite + // + [SqlFunction] + static string AltStuff(string str, int? startLocation, int? length, string value) + { + return Sql.Stuff(str, startLocation, length, value); + } + + // DB2 + // + [SqlFunction] + static string VarChar(object obj, int? size) + { + return obj.ToString(); + } + + // DB2 + // + [SqlFunction] + static string Hex(Guid? guid) + { + return guid == null ? null : guid.ToString(); + } + +#pragma warning disable 3019 + + // DB2, PostgreSQL, Access, MS SQL, SqlCe + // + [CLSCompliant(false)] + [SqlFunction] + [SqlFunction("DB2", "Repeat")] + [SqlFunction("PostgreSQL", "Repeat")] + [SqlFunction("Access", "String", 1, 0)] + static string Replicate(string str, int? count) + { + if (str == null || count == null) + return null; + + var sb = new StringBuilder(str.Length * count.Value); + + for (var i = 0; i < count; i++) + sb.Append(str); + + return sb.ToString(); + } + + [CLSCompliant(false)] + [SqlFunction] + [SqlFunction("DB2", "Repeat")] + [SqlFunction("PostgreSQL", "Repeat")] + [SqlFunction("Access", "String", 1, 0)] + static string Replicate(char? ch, int? count) + { + if (ch == null || count == null) + return null; + + var sb = new StringBuilder(count.Value); + + for (var i = 0; i < count; i++) + sb.Append(ch); + + return sb.ToString(); + } + + // MSSQL + // + [SqlFunction] + static DateTime? DateAdd(Sql.DateParts part, int? number, int? days) + { + return days == null ? null : Sql.DateAdd(part, number, new DateTime(1900, 1, days.Value + 1)); + } + + // MSSQL + // + [SqlFunction] static Decimal? Round(Decimal? value, int precision, int mode) { return 0; } + [SqlFunction] static Double? Round(Double? value, int precision, int mode) { return 0; } + + // Access + // + [SqlFunction("Access", "DateSerial")] + static DateTime? MakeDateTime2(int? year, int? month, int? day) + { + return year == null || month == null || day == null? + (DateTime?)null : + new DateTime(year.Value, month.Value, day.Value); + } + + // Access + // + [CLSCompliant(false)] + [SqlFunction("Int", 0)] + static T AccessInt(T value) + { + return value; + } + + // Access + // + [CLSCompliant(false)] + [SqlFunction("Round", 0, 1)] + static T AccessRound(T value, int? precision) { return value; } + + // Firebird + // + [SqlFunction("PI", ServerSideOnly = true)] static decimal DecimalPI() { return (decimal)Math.PI; } + [SqlFunction("PI", ServerSideOnly = true)] static double DoublePI () { return Math.PI; } + + // Informix + // + [SqlFunction] + static DateTime? Mdy(int? month, int? day, int? year) + { + return year == null || month == null || day == null ? + (DateTime?)null : + new DateTime(year.Value, month.Value, day.Value); + } + + #endregion + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Extensions.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Extensions.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,369 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Reflection; +using System.Text.RegularExpressions; + +using JetBrains.Annotations; + +namespace BLToolkit.Data.Linq +{ + using DataAccess; + + public static class Extensions + { + #region Table Helpers + + static public Table GetTable(this IDataContext dataContext) + where T : class + { + return new Table(dataContext); + } + + static public Table GetTable( + this IDataContext dataContext, + object instance, + [NotNull] MethodInfo methodInfo, + [NotNull] params object[] parameters) + where T : class + { + if (methodInfo == null) throw new ArgumentNullException("methodInfo"); + if (parameters == null) throw new ArgumentNullException("parameters"); + + if (!typeof(Table).IsAssignableFrom(methodInfo.ReturnType)) + throw new LinqException( + "Method '{0}.{1}' must return type 'Table<{2}>'", + methodInfo.Name, methodInfo.DeclaringType.FullName, typeof(T).FullName); + + Expression expr; + + if (parameters.Length > 0) + { + var pis = methodInfo.GetParameters(); + var args = new List(parameters.Length); + + for (var i = 0; i < parameters.Length; i++) + { + var type = pis[i].ParameterType; + args.Add(Expression.Constant(parameters[i], type.IsByRef ? type.GetElementType() : type)); + } + + expr = Expression.Call(Expression.Constant(instance), methodInfo, args); + } + else + expr = Expression.Call(Expression.Constant(instance), methodInfo); + + return new Table(dataContext, expr); + } + + #endregion + + #region Compile + + /// + /// Compiles the query. + /// + /// + /// A generic delegate that represents the compiled query. + /// + /// + /// + /// The query expression to be compiled. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Returned type of the delegate returned by the method. + /// + static public Func Compile( + [NotNull] this IDataContext dataContext, + [NotNull] Expression> query) + where TDc : IDataContext + { + return CompiledQuery.Compile(query); + } + + /// + /// Compiles the query. + /// + /// + /// A generic delegate that represents the compiled query. + /// + /// + /// + /// The query expression to be compiled. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Returned type of the delegate returned by the method. + /// + static public Func Compile( + [NotNull] this IDataContext dataContext, + [NotNull] Expression> query) + where TDc : IDataContext + { + return CompiledQuery.Compile(query); + } + + /// + /// Compiles the query. + /// + /// + /// A generic delegate that represents the compiled query. + /// + /// + /// + /// The query expression to be compiled. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Returned type of the delegate returned by the method. + /// + static public Func Compile( + [NotNull] this IDataContext dataContext, + [NotNull] Expression> query) + where TDc : IDataContext + { + return CompiledQuery.Compile(query); + } + + /// + /// Compiles the query. + /// + /// + /// A generic delegate that represents the compiled query. + /// + /// + /// + /// The query expression to be compiled. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Represents the type of the parameter that has to be passed in when executing the delegate returned by the method. + /// + /// + /// Returned type of the delegate returned by the method. + /// + static public Func Compile( + [NotNull] this IDataContext dataContext, + [NotNull] Expression> query) + where TDc : IDataContext + { + return CompiledQuery.Compile(query); + } + + #endregion + + #region Object Operations + + #region Insert + + public static int Insert([NotNull] this IDataContextInfo dataContextInfo, T obj) + { + if (dataContextInfo == null) throw new ArgumentNullException("dataContextInfo"); + return Query.Insert(dataContextInfo, obj); + } + + public static int Insert(this IDataContext dataContext, T obj) + { + return Query.Insert(DataContextInfo.Create(dataContext), obj); + } + + #endregion + + #region InsertOrUpdate + + [Obsolete("Use 'InsertOrReplace' instead.")] + public static int InsertOrUpdate(this IDataContextInfo dataContextInfo, T obj) + { + return InsertOrReplace(dataContextInfo, obj); + } + + public static int InsertOrReplace([NotNull] this IDataContextInfo dataContextInfo, T obj) + { + if (dataContextInfo == null) throw new ArgumentNullException("dataContextInfo"); + return Query.InsertOrReplace(dataContextInfo, obj); + } + + public static int InsertOrReplace([NotNull] this IDataContextInfo dataContextInfo, IEnumerable objs) + { + if (dataContextInfo == null) throw new ArgumentNullException("dataContextInfo"); + int cnt = 0; + foreach (var obj in objs) + { + cnt += Query.InsertOrReplace(dataContextInfo, obj); + } + return cnt; + } + + [Obsolete("Use 'InsertOrReplace' instead.")] + public static int InsertOrUpdate(this IDataContext dataContext, T obj) + { + return InsertOrReplace(dataContext, obj); + } + + public static int InsertOrReplace(this IDataContext dataContext, T obj) + { + return Query.InsertOrReplace(DataContextInfo.Create(dataContext), obj); + } + + public static int InsertOrReplace(this IDataContext dataContext, IEnumerable objs) + { + int cnt = 0; + foreach (var obj in objs) + { + cnt += Query.InsertOrReplace(DataContextInfo.Create(dataContext), obj); + } + return cnt; + } + + #endregion + + #region InsertBatch + +#if !SILVERLIGHT + + public static int InsertBatch(this DbManager dataContext, int maxBatchSize, IEnumerable list) + { + return new SqlQuery(dataContext).Insert(dataContext, maxBatchSize, list); + } + + public static int InsertBatch(this DbManager dataContext, IEnumerable list) + { + return InsertBatch(dataContext, int.MaxValue, list); + } + + public static int InsertBatch(this DbManager dataContext, T[] list) + { + return InsertBatch(dataContext, int.MaxValue, list); + } + + [Obsolete("Use InsertBatch instead.")] + public static int Insert(this DbManager dataContext, T[] list) + { + return Insert(dataContext, int.MaxValue, list); + } + + [Obsolete("Use InsertBatch instead.")] + public static int Insert(this DbManager dataContext, int maxBatchSize, IEnumerable list) + { + return new SqlQuery().Insert(dataContext, maxBatchSize, list); + } + + [Obsolete("Use InsertBatch instead.")] + public static int Insert(this DbManager dataContext, IEnumerable list) + { + return Insert(dataContext, int.MaxValue, list); + } + +#endif + + #endregion + + #region InsertWithIdentity + + public static object InsertWithIdentity([NotNull] this IDataContextInfo dataContextInfo, T obj) + { + if (dataContextInfo == null) throw new ArgumentNullException("dataContextInfo"); + return Query.InsertWithIdentity(dataContextInfo, obj); + } + + public static object InsertWithIdentity(this IDataContext dataContext, T obj) + { + return Query.InsertWithIdentity(DataContextInfo.Create(dataContext), obj); + } + + #endregion + + #region Update + + public static int Update([NotNull] this IDataContextInfo dataContextInfo, T obj) + { + if (dataContextInfo == null) throw new ArgumentNullException("dataContextInfo"); + return Query.Update(dataContextInfo, obj); + } + + public static int Update(this IDataContext dataContext, T obj) + { + return Query.Update(DataContextInfo.Create(dataContext), obj); + } + +#if !SILVERLIGHT + + public static int Update(this DbManager dataContext, int maxBatchSize, IEnumerable list) + { + return new SqlQuery(dataContext).Update(dataContext, maxBatchSize, list); + } + + public static int Update(this DbManager dataContext, IEnumerable list) + { + return Update(dataContext, int.MaxValue, list); + } + +#endif + + #endregion + + #region Delete + + public static int Delete([NotNull] this IDataContextInfo dataContextInfo, T obj) + { + if (dataContextInfo == null) throw new ArgumentNullException("dataContextInfo"); + return Query.Delete(dataContextInfo, obj); + } + + public static int Delete([NotNull] this IDataContext dataContext, T obj) + { + return Query.Delete(DataContextInfo.Create(dataContext), obj); + } + +#if !SILVERLIGHT + + public static int Delete(this DbManager dataContext, int maxBatchSize, IEnumerable list) + { + return new SqlQuery(dataContext).Delete(dataContext, maxBatchSize, list); + } + + public static int Delete(this DbManager dataContext, IEnumerable list) + { + return Delete(dataContext, int.MaxValue, list); + } + +#endif + + #endregion + + #endregion + + #region String Extensions + + public static int ContainsExactly(this string s, string value) + { + return Regex.Matches(s, string.Format(@"(^|\s){0}(\s|$)", value), RegexOptions.IgnoreCase).Count; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/IDataContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/IDataContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +using System; +using System.Data; + +namespace BLToolkit.Data.Linq +{ + using Data.Sql.SqlProvider; + using Mapping; + + public interface IDataContext : IMappingSchemaProvider, IDisposable + { + string ContextID { get; } + Func CreateSqlProvider { get; } + + object SetQuery (IQueryContext queryContext); + int ExecuteNonQuery (object query); + object ExecuteScalar (object query); + IDataReader ExecuteReader (object query); + void ReleaseQuery (object query); + + string GetSqlText (object query); + IDataContext Clone (bool forNestedQuery); + + event EventHandler OnClosing; + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/IDataContextInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/IDataContextInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,18 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + using Data.Sql.SqlProvider; + using Mapping; + + public interface IDataContextInfo + { + IDataContext DataContext { get; } + string ContextID { get; } + MappingSchema MappingSchema { get; } + bool DisposeContext { get; } + + ISqlProvider CreateSqlProvider(); + IDataContextInfo Clone(bool forNestedQuery); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/IExpressionQuery.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/IExpressionQuery.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + interface IExpressionQuery + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/IQueryContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/IQueryContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + using Data.Sql; + + public interface IQueryContext + { + SqlQuery SqlQuery { get; } + object Context { get; set; } + SqlParameter[] GetParameters(); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/ISelectInsertable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/ISelectInsertable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + public interface ISelectInsertable + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/ITable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/ITable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + interface ITable + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/IUpdatable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/IUpdatable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + public interface IUpdatable + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/IValueInsertable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/IValueInsertable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + public interface IValueInsertable + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/IgnoreIEnumerableAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/IgnoreIEnumerableAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + [AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] + public class IgnoreIEnumerableAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/LinqException.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/LinqException.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,87 @@ +using System; +using System.Runtime.Serialization; + +namespace BLToolkit.Data.Linq +{ + /// + /// Defines the base class for the namespace exceptions. + /// + /// + /// This class is the base class for exceptions that may occur during + /// execution of the namespace members. + /// + [Serializable] + public class LinqException : Exception + { + /// + /// Initializes a new instance of the class. + /// + /// + /// This constructor initializes the + /// property of the new instance + /// to a system-supplied message that describes the error, + /// such as "BLToolkit Linq error has occurred." + /// + public LinqException() + : base("A BLToolkit Linq error has occurred.") + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message. + /// + /// The message to display to the client when the exception is thrown. + /// An System.Object array containing zero or more objects to format. + /// + [JetBrains.Annotations.StringFormatMethod("args")] + public LinqException(string message, params object[] args) + : base(string.Format(message, args)) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message and InnerException property. + /// + /// The message to display to the client when the exception is thrown. + /// The InnerException, if any, that threw the current exception. + /// + /// + public LinqException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class + /// with the InnerException property. + /// + /// The InnerException, if any, that threw the current exception. + /// + public LinqException(Exception innerException) + : base(innerException.Message, innerException) + { + } + +#if !SILVERLIGHT + + /// + /// Initializes a new instance of the class + /// with serialized data. + /// + /// The object that holds the serialized object data. + /// The contextual information about the source or destination. + /// + /// This constructor is called during deserialization to + /// reconstitute the exception object transmitted over a stream. + /// + protected LinqException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + +#endif + } +} + diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/LinqExtensions.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/LinqExtensions.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,716 @@ +using System; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +using JetBrains.Annotations; + +namespace BLToolkit.Data.Linq +{ + public static class LinqExtensions + { + #region Table Helpers + + static public Table TableName([NotNull] this Table table, [NotNull] string name) + { + if (table == null) throw new ArgumentNullException("table"); + if (name == null) throw new ArgumentNullException("name"); + + table.Expression = Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { table.Expression, Expression.Constant(name) }); + + return table; + } + + static public Table DatabaseName([NotNull] this Table table, [NotNull] string name) + { + if (table == null) throw new ArgumentNullException("table"); + if (name == null) throw new ArgumentNullException("name"); + + table.Expression = Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { table.Expression, Expression.Constant(name) }); + + return table; + } + + static public Table OwnerName([NotNull] this Table table, [NotNull] string name) + { + if (table == null) throw new ArgumentNullException("table"); + if (name == null) throw new ArgumentNullException("name"); + + table.Expression = Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { table.Expression, Expression.Constant(name) }); + + return table; + } + + #endregion + + #region Scalar Select + + static public T Select([NotNull] this IDataContext dataContext, [NotNull, InstantHandle] Expression> selector) + { + if (dataContext == null) throw new ArgumentNullException("dataContext"); + if (selector == null) throw new ArgumentNullException("selector"); + + var q = new Table(dataContext, selector); + + foreach (var item in q) + return item; + + throw new InvalidOperationException(); + } + + #endregion + + #region Delete + + public static int Delete([NotNull] this IQueryable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return source.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { source.Expression })); + } + + public static int Delete( + [NotNull, InstantHandle] this IQueryable source, + [NotNull, InstantHandle] Expression> predicate) + { + if (source == null) throw new ArgumentNullException("source"); + if (predicate == null) throw new ArgumentNullException("predicate"); + + return source.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { source.Expression, Expression.Quote(predicate) })); + } + + #endregion + + #region Update + + public static int Update( + [NotNull] this IQueryable source, + [NotNull] Table target, + [NotNull, InstantHandle] Expression> setter) + { + if (source == null) throw new ArgumentNullException("source"); + if (target == null) throw new ArgumentNullException("target"); + if (setter == null) throw new ArgumentNullException("setter"); + + return source.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget) }), + new[] { source.Expression, ((IQueryable)target).Expression, Expression.Quote(setter) })); + } + + public static int Update( + [NotNull] this IQueryable source, + [NotNull, InstantHandle] Expression> setter) + { + if (source == null) throw new ArgumentNullException("source"); + if (setter == null) throw new ArgumentNullException("setter"); + + return source.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { source.Expression, Expression.Quote(setter) })); + } + + public static int Update( + [NotNull] this IQueryable source, + [NotNull, InstantHandle] Expression> predicate, + [NotNull, InstantHandle] Expression> setter) + { + if (source == null) throw new ArgumentNullException("source"); + if (predicate == null) throw new ArgumentNullException("predicate"); + if (setter == null) throw new ArgumentNullException("setter"); + + return source.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { source.Expression, Expression.Quote(predicate), Expression.Quote(setter) })); + } + + public static int Update([NotNull] this IUpdatable source) + { + if (source == null) throw new ArgumentNullException("source"); + + var query = ((Updatable)source).Query; + + return query.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { query.Expression })); + } + + class Updatable : IUpdatable + { + public IQueryable Query; + } + + public static IUpdatable AsUpdatable([NotNull] this IQueryable source) + { + if (source == null) throw new ArgumentNullException("source"); + + var query = source.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { source.Expression })); + + return new Updatable { Query = query }; + } + + public static IUpdatable Set( + [NotNull] this IQueryable source, + [NotNull, InstantHandle] Expression> extract, + [NotNull, InstantHandle] Expression> update) + { + if (source == null) throw new ArgumentNullException("source"); + if (extract == null) throw new ArgumentNullException("extract"); + if (update == null) throw new ArgumentNullException("update"); + + var query = source.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }), + new[] { source.Expression, Expression.Quote(extract), Expression.Quote(update) })); + + return new Updatable { Query = query }; + } + + public static IUpdatable Set( + [NotNull] this IUpdatable source, + [NotNull, InstantHandle] Expression> extract, + [NotNull, InstantHandle] Expression> update) + { + if (source == null) throw new ArgumentNullException("source"); + if (extract == null) throw new ArgumentNullException("extract"); + if (update == null) throw new ArgumentNullException("update"); + + var query = ((Updatable)source).Query; + + query = query.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }), + new[] { query.Expression, Expression.Quote(extract), Expression.Quote(update) })); + + return new Updatable { Query = query }; + } + + public static IUpdatable Set( + [NotNull] this IQueryable source, + [NotNull, InstantHandle] Expression> extract, + [NotNull, InstantHandle] Expression> update) + { + if (source == null) throw new ArgumentNullException("source"); + if (extract == null) throw new ArgumentNullException("extract"); + if (update == null) throw new ArgumentNullException("update"); + + var query = source.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }), + new[] { source.Expression, Expression.Quote(extract), Expression.Quote(update) })); + + return new Updatable { Query = query }; + } + + public static IUpdatable Set( + [NotNull] this IUpdatable source, + [NotNull, InstantHandle] Expression> extract, + [NotNull, InstantHandle] Expression> update) + { + if (source == null) throw new ArgumentNullException("source"); + if (extract == null) throw new ArgumentNullException("extract"); + if (update == null) throw new ArgumentNullException("update"); + + var query = ((Updatable)source).Query; + + query = query.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }), + new[] { query.Expression, Expression.Quote(extract), Expression.Quote(update) })); + + return new Updatable { Query = query }; + } + + public static IUpdatable Set( + [NotNull] this IQueryable source, + [NotNull, InstantHandle] Expression> extract, + TV value) + { + if (source == null) throw new ArgumentNullException("source"); + if (extract == null) throw new ArgumentNullException("extract"); + + var query = source.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }), + new[] { source.Expression, Expression.Quote(extract), Expression.Constant(value, typeof(TV)) })); + + return new Updatable { Query = query }; + } + + public static IUpdatable Set( + [NotNull] this IUpdatable source, + [NotNull, InstantHandle] Expression> extract, + TV value) + { + if (source == null) throw new ArgumentNullException("source"); + if (extract == null) throw new ArgumentNullException("extract"); + + var query = ((Updatable)source).Query; + + query = query.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }), + new[] { query.Expression, Expression.Quote(extract), Expression.Constant(value, typeof(TV)) })); + + return new Updatable { Query = query }; + } + + #endregion + + #region Insert + + public static int Insert( + [NotNull] this Table target, + [NotNull, InstantHandle] Expression> setter) + { + if (target == null) throw new ArgumentNullException("target"); + if (setter == null) throw new ArgumentNullException("setter"); + + IQueryable query = target; + + return query.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { query.Expression, Expression.Quote(setter) })); + } + + public static object InsertWithIdentity( + [NotNull] this Table target, + [NotNull, InstantHandle] Expression> setter) + { + if (target == null) throw new ArgumentNullException("target"); + if (setter == null) throw new ArgumentNullException("setter"); + + IQueryable query = target; + + return query.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { query.Expression, Expression.Quote(setter) })); + } + + #region ValueInsertable + + class ValueInsertable : IValueInsertable + { + public IQueryable Query; + } + + public static IValueInsertable Into(this IDataContext dataContext, [NotNull] Table target) + { + if (target == null) throw new ArgumentNullException("target"); + + IQueryable query = target; + + var q = query.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { Expression.Constant(null, typeof(IDataContext)), query.Expression })); + + return new ValueInsertable { Query = q }; + } + + public static IValueInsertable Value( + [NotNull] this Table source, + [NotNull, InstantHandle] Expression> field, + [NotNull, InstantHandle] Expression> value) + { + if (source == null) throw new ArgumentNullException("source"); + if (field == null) throw new ArgumentNullException("field"); + if (value == null) throw new ArgumentNullException("value"); + + var query = (IQueryable)source; + + var q = query.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }), + new[] { query.Expression, Expression.Quote(field), Expression.Quote(value) })); + + return new ValueInsertable { Query = q }; + } + + public static IValueInsertable Value( + [NotNull] this Table source, + [NotNull, InstantHandle] Expression> field, + TV value) + { + if (source == null) throw new ArgumentNullException("source"); + if (field == null) throw new ArgumentNullException("field"); + + var query = (IQueryable)source; + + var q = query.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }), + new[] { query.Expression, Expression.Quote(field), Expression.Constant(value, typeof(TV)) })); + + return new ValueInsertable { Query = q }; + } + + public static IValueInsertable Value( + [NotNull] this IValueInsertable source, + [NotNull, InstantHandle] Expression> field, + [NotNull, InstantHandle] Expression> value) + { + if (source == null) throw new ArgumentNullException("source"); + if (field == null) throw new ArgumentNullException("field"); + if (value == null) throw new ArgumentNullException("value"); + + var query = ((ValueInsertable)source).Query; + + var q = query.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }), + new[] { query.Expression, Expression.Quote(field), Expression.Quote(value) })); + + return new ValueInsertable { Query = q }; + } + + public static IValueInsertable Value( + [NotNull] this IValueInsertable source, + [NotNull, InstantHandle] Expression> field, + TV value) + { + if (source == null) throw new ArgumentNullException("source"); + if (field == null) throw new ArgumentNullException("field"); + + var query = ((ValueInsertable)source).Query; + + var q = query.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }), + new[] { query.Expression, Expression.Quote(field), Expression.Constant(value, typeof(TV)) })); + + return new ValueInsertable { Query = q }; + } + + public static int Insert([NotNull] this IValueInsertable source) + { + if (source == null) throw new ArgumentNullException("source"); + + var query = ((ValueInsertable)source).Query; + + return query.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { query.Expression })); + } + + public static object InsertWithIdentity([NotNull] this IValueInsertable source) + { + if (source == null) throw new ArgumentNullException("source"); + + var query = ((ValueInsertable)source).Query; + + return query.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { query.Expression })); + } + + #endregion + + #region SelectInsertable + + public static int Insert( + [NotNull] this IQueryable source, + [NotNull] Table target, + [NotNull, InstantHandle] Expression> setter) + { + if (source == null) throw new ArgumentNullException("source"); + if (target == null) throw new ArgumentNullException("target"); + if (setter == null) throw new ArgumentNullException("setter"); + + return source.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget) }), + new[] { source.Expression, ((IQueryable)target).Expression, Expression.Quote(setter) })); + } + + public static object InsertWithIdentity( + [NotNull] this IQueryable source, + [NotNull] Table target, + [NotNull, InstantHandle] Expression> setter) + { + if (source == null) throw new ArgumentNullException("source"); + if (target == null) throw new ArgumentNullException("target"); + if (setter == null) throw new ArgumentNullException("setter"); + + return source.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget) }), + new[] { source.Expression, ((IQueryable)target).Expression, Expression.Quote(setter) })); + } + + class SelectInsertable : ISelectInsertable + { + public IQueryable Query; + } + + public static ISelectInsertable Into( + [NotNull] this IQueryable source, + [NotNull] Table target) + { + if (target == null) throw new ArgumentNullException("target"); + + var q = source.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget) }), + new[] { source.Expression, ((IQueryable)target).Expression })); + + return new SelectInsertable { Query = q }; + } + + public static ISelectInsertable Value( + [NotNull] this ISelectInsertable source, + [NotNull, InstantHandle] Expression> field, + [NotNull, InstantHandle] Expression> value) + { + if (source == null) throw new ArgumentNullException("source"); + if (field == null) throw new ArgumentNullException("field"); + if (value == null) throw new ArgumentNullException("value"); + + var query = ((SelectInsertable)source).Query; + + var q = query.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget), typeof(TValue) }), + new[] { query.Expression, Expression.Quote(field), Expression.Quote(value) })); + + return new SelectInsertable { Query = q }; + } + + public static ISelectInsertable Value( + [NotNull] this ISelectInsertable source, + [NotNull, InstantHandle] Expression> field, + [NotNull, InstantHandle] Expression> value) + { + if (source == null) throw new ArgumentNullException("source"); + if (field == null) throw new ArgumentNullException("field"); + if (value == null) throw new ArgumentNullException("value"); + + var query = ((SelectInsertable)source).Query; + + var q = query.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget), typeof(TValue) }), + new[] { query.Expression, Expression.Quote(field), Expression.Quote(value) })); + + return new SelectInsertable { Query = q }; + } + + public static ISelectInsertable Value( + [NotNull] this ISelectInsertable source, + [NotNull, InstantHandle] Expression> field, + TValue value) + { + if (source == null) throw new ArgumentNullException("source"); + if (field == null) throw new ArgumentNullException("field"); + + var query = ((SelectInsertable)source).Query; + + var q = query.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget), typeof(TValue) }), + new[] { query.Expression, Expression.Quote(field), Expression.Constant(value, typeof(TValue)) })); + + return new SelectInsertable { Query = q }; + } + + public static int Insert([NotNull] this ISelectInsertable source) + { + if (source == null) throw new ArgumentNullException("source"); + + var query = ((SelectInsertable)source).Query; + + return query.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget) }), + new[] { query.Expression })); + } + + public static object InsertWithIdentity([NotNull] this ISelectInsertable source) + { + if (source == null) throw new ArgumentNullException("source"); + + var query = ((SelectInsertable)source).Query; + + return query.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget) }), + new[] { query.Expression })); + } + + #endregion + + #endregion + + #region InsertOrUpdate + + public static int InsertOrUpdate( + [NotNull] this Table target, + [NotNull, InstantHandle] Expression> insertSetter, + [NotNull, InstantHandle] Expression> onDuplicateKeyUpdateSetter) + { + if (target == null) throw new ArgumentNullException("target"); + if (insertSetter == null) throw new ArgumentNullException("insertSetter"); + if (onDuplicateKeyUpdateSetter == null) throw new ArgumentNullException("onDuplicateKeyUpdateSetter"); + + IQueryable query = target; + + return query.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] { query.Expression, Expression.Quote(insertSetter), Expression.Quote(onDuplicateKeyUpdateSetter) })); + } + + public static int InsertOrUpdate( + [NotNull] this Table target, + [NotNull, InstantHandle] Expression> insertSetter, + [NotNull, InstantHandle] Expression> onDuplicateKeyUpdateSetter, + [NotNull, InstantHandle] Expression> keySelector) + { + if (target == null) throw new ArgumentNullException("target"); + if (insertSetter == null) throw new ArgumentNullException("insertSetter"); + if (onDuplicateKeyUpdateSetter == null) throw new ArgumentNullException("onDuplicateKeyUpdateSetter"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + + IQueryable query = target; + + return query.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), + new[] + { + query.Expression, + Expression.Quote(insertSetter), + Expression.Quote(onDuplicateKeyUpdateSetter), + Expression.Quote(keySelector) + })); + } + + #endregion + + #region Take / Skip / ElementAt + + public static IQueryable Take( + [NotNull] this IQueryable source, + [NotNull, InstantHandle] Expression> count) + { + if (source == null) throw new ArgumentNullException("source"); + if (count == null) throw new ArgumentNullException("count"); + + return source.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource) }), + new[] { source.Expression, Expression.Quote(count) })); + } + + public static IQueryable Skip( + [NotNull] this IQueryable source, + [NotNull, InstantHandle] Expression> count) + { + if (source == null) throw new ArgumentNullException("source"); + if (count == null) throw new ArgumentNullException("count"); + + return source.Provider.CreateQuery( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource) }), + new[] { source.Expression, Expression.Quote(count) })); + } + + public static TSource ElementAt( + [NotNull] this IQueryable source, + [NotNull, InstantHandle] Expression> index) + { + if (source == null) throw new ArgumentNullException("source"); + if (index == null) throw new ArgumentNullException("index"); + + return source.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource) }), + new[] { source.Expression, Expression.Quote(index) })); + } + + public static TSource ElementAtOrDefault( + [NotNull] this IQueryable source, + [NotNull, InstantHandle] Expression> index) + { + if (source == null) throw new ArgumentNullException("source"); + if (index == null) throw new ArgumentNullException("index"); + + return source.Provider.Execute( + Expression.Call( + null, + ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource) }), + new[] { source.Expression, Expression.Quote(index) })); + } + + #endregion + + #region Stub helpers + + static TOutput Where(this TInput source, Func predicate) + { + throw new InvalidOperationException(); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/MemberInfoComparer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/MemberInfoComparer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace BLToolkit.Data.Linq +{ + using Reflection; + + class MemberInfoComparer : IEqualityComparer + { + public bool Equals(MemberInfo x, MemberInfo y) + { + return TypeHelper.Equals(x, y); + } + + public int GetHashCode(MemberInfo obj) + { + return obj == null ? 0 : obj.Name.GetHashCode(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/MethodExpressionAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/MethodExpressionAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + [AttributeUsageAttribute(AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] + public class MethodExpressionAttribute : Attribute + { + public MethodExpressionAttribute(string methodName) + { + MethodName = methodName; + } + + public MethodExpressionAttribute(string sqlProvider, string methodName) + { + SqlProvider = sqlProvider; + MethodName = methodName; + } + + public string SqlProvider { get; set; } + public string MethodName { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Query.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Query.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1120 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq +{ + using BLToolkit.Linq; + using Common; + using Data.Sql; + using Data.Sql.SqlProvider; + using Mapping; + using Builder; + using Reflection; + + public abstract class Query + { + #region Init + + public abstract void Init(IBuildContext parseContext, List sqlParameters); + + #endregion + + #region Compare + + public string ContextID; + public Expression Expression; + public MappingSchema MappingSchema; + + public bool Compare(string contextID, MappingSchema mappingSchema, Expression expr) + { + return + ContextID.Length == contextID.Length && + ContextID == contextID && + MappingSchema == mappingSchema && + ExpressionHelper.Compare(Expression, expr, _queryableAccessorDic); + } + + readonly Dictionary _queryableAccessorDic = new Dictionary(); + readonly List _queryableAccessorList = new List(); + + internal int AddQueryableAccessors(Expression expr, Expression> qe) + { + QueryableAccessor e; + + if (_queryableAccessorDic.TryGetValue(expr, out e)) + return _queryableAccessorList.IndexOf(e); + + e = new QueryableAccessor { Accessor = qe.Compile() }; + e.Queryable = e.Accessor(expr); + + _queryableAccessorDic. Add(expr, e); + _queryableAccessorList.Add(e); + + return _queryableAccessorList.Count - 1; + } + + public Expression GetIQueryable(int n, Expression expr) + { + return _queryableAccessorList[n].Accessor(expr).Expression; + } + + #endregion + } + + public class Query : Query + { + public Query() + { + GetIEnumerable = MakeEnumerable; + } + + public override void Init(IBuildContext parseContext, List sqlParameters) + { + Queries.Add(new QueryInfo + { + SqlQuery = parseContext.SqlQuery, + Parameters = sqlParameters, + }); + + ContextID = parseContext.Builder.DataContextInfo.ContextID; + MappingSchema = parseContext.Builder.MappingSchema; + CreateSqlProvider = parseContext.Builder.DataContextInfo.CreateSqlProvider; + Expression = parseContext.Builder.OriginalExpression; + //Parameters = parameters; + } + + #region Properties & Fields + + public Query Next; + public ParameterExpression[] CompiledParameters; + public List Queries = new List(1); + public Func CreateSqlProvider; + + private ISqlProvider _sqlProvider; + public ISqlProvider SqlProvider + { + get { return _sqlProvider ?? (_sqlProvider = CreateSqlProvider()); } + } + + public Func GetElement; + public Func> GetIEnumerable; + + IEnumerable MakeEnumerable(QueryContext qc, IDataContextInfo dci, Expression expr, object[] ps) + { + yield return ConvertTo.From(GetElement(qc, dci, expr, ps)); + } + + #endregion + + #region GetInfo + + static Query _first; + static readonly object _sync = new object(); + + const int CacheSize = 100; + + public static Query GetQuery(IDataContextInfo dataContextInfo, Expression expr) + { + var query = FindQuery(dataContextInfo, expr); + + if (query == null) + { + lock (_sync) + { + query = FindQuery(dataContextInfo, expr); + + if (query == null) + { + if (Configuration.Linq.GenerateExpressionTest) + { +#if FW4 || SILVERLIGHT + var testFile = new ExpressionTestGenerator().GenerateSource(expr); +#else + var testFile = ""; +#endif + +#if !SILVERLIGHT + DbManager.WriteTraceLine( + "Expression test code generated: '" + testFile + "'.", + DbManager.TraceSwitch.DisplayName); +#endif + } + + try + { + query = new ExpressionBuilder(new Query(), dataContextInfo, expr, null).Build(); + } + catch (Exception) + { + if (!Configuration.Linq.GenerateExpressionTest) + { +#if !SILVERLIGHT + DbManager.WriteTraceLine( + "To generate test code to diagnose the problem set 'BLToolkit.Common.Configuration.Linq.GenerateExpressionTest = true'.", + DbManager.TraceSwitch.DisplayName); +#endif + } + + throw; + } + + query.Next = _first; + _first = query; + } + } + } + + return query; + } + + static Query FindQuery(IDataContextInfo dataContextInfo, Expression expr) + { + Query prev = null; + var n = 0; + + for (var query = _first; query != null; query = query.Next) + { + if (query.Compare(dataContextInfo.ContextID, dataContextInfo.MappingSchema, expr)) + { + if (prev != null) + { + lock (_sync) + { + prev.Next = query.Next; + query.Next = _first; + _first = query; + } + } + + return query; + } + + if (n++ >= CacheSize) + { + query.Next = null; + return null; + } + + prev = query; + } + + return null; + } + + #endregion + + #region NonQueryQuery + + void FinalizeQuery() + { + foreach (var sql in Queries) + { + sql.SqlQuery = SqlProvider.Finalize(sql.SqlQuery); + sql.Parameters = sql.Parameters + .Select (p => new { p, idx = sql.SqlQuery.Parameters.IndexOf(p.SqlParameter) }) + .OrderBy(p => p.idx) + .Select (p => p.p) + .ToList(); + } + } + + public void SetNonQueryQuery() + { + FinalizeQuery(); + + if (Queries.Count != 1) + throw new InvalidOperationException(); + + SqlProvider.SqlQuery = Queries[0].SqlQuery; + + GetElement = (ctx,db,expr,ps) => NonQueryQuery(db, expr, ps); + } + + int NonQueryQuery(IDataContextInfo dataContextInfo, Expression expr, object[] parameters) + { + var dataContext = dataContextInfo.DataContext; + + object query = null; + + try + { + query = SetCommand(dataContext, expr, parameters, 0); + return dataContext.ExecuteNonQuery(query); + } + finally + { + if (query != null) + dataContext.ReleaseQuery(query); + + if (dataContextInfo.DisposeContext) + dataContext.Dispose(); + } + } + + public void SetNonQueryQuery2() + { + FinalizeQuery(); + + if (Queries.Count != 2) + throw new InvalidOperationException(); + + SqlProvider.SqlQuery = Queries[0].SqlQuery; + + GetElement = (ctx,db,expr,ps) => NonQueryQuery2(db, expr, ps); + } + + int NonQueryQuery2(IDataContextInfo dataContextInfo, Expression expr, object[] parameters) + { + var dataContext = dataContextInfo.DataContext; + + object query = null; + + try + { + query = SetCommand(dataContext, expr, parameters, 0); + + var n = dataContext.ExecuteNonQuery(query); + + if (n != 0) + return n; + + query = SetCommand(dataContext, expr, parameters, 1); + return dataContext.ExecuteNonQuery(query); + } + finally + { + if (query != null) + dataContext.ReleaseQuery(query); + + if (dataContextInfo.DisposeContext) + dataContext.Dispose(); + } + } + + #endregion + + #region ScalarQuery + + public void SetScalarQuery() + { + FinalizeQuery(); + + if (Queries.Count != 1) + throw new InvalidOperationException(); + + SqlProvider.SqlQuery = Queries[0].SqlQuery; + + GetElement = (ctx,db,expr,ps) => ScalarQuery(db, expr, ps); + } + + TS ScalarQuery(IDataContextInfo dataContextInfo, Expression expr, object[] parameters) + { + var dataContext = dataContextInfo.DataContext; + + object query = null; + + try + { + query = SetCommand(dataContext, expr, parameters, 0); + return (TS)dataContext.ExecuteScalar(query); + } + finally + { + if (query != null) + dataContext.ReleaseQuery(query); + + if (dataContextInfo.DisposeContext) + dataContext.Dispose(); + } + } + + #endregion + + #region Query + + int GetParameterIndex(ISqlExpression parameter) + { + for (var i = 0; i < Queries[0].Parameters.Count; i++) + { + var p = Queries[0].Parameters[i].SqlParameter; + + if (p == parameter) + return i; + } + + throw new InvalidOperationException(); + } + + IEnumerable RunQuery(IDataContextInfo dataContextInfo, Expression expr, object[] parameters, int queryNumber) + { + var dataContext = dataContextInfo.DataContext; + + object query = null; + + try + { + query = SetCommand(dataContext, expr, parameters, queryNumber); + + using (var dr = dataContext.ExecuteReader(query)) + while (dr.Read()) + yield return dr; + } + finally + { + if (query != null) + dataContext.ReleaseQuery(query); + + if (dataContextInfo.DisposeContext) + dataContext.Dispose(); + } + } + + object SetCommand(IDataContext dataContext, Expression expr, object[] parameters, int idx) + { + lock (this) + { + SetParameters(expr, parameters, idx); + return dataContext.SetQuery(Queries[idx]); + } + } + + void SetParameters(Expression expr, object[] parameters, int idx) + { + foreach (var p in Queries[idx].Parameters) + { + var value = p.Accessor(expr, parameters); + + if (value is IEnumerable) + { + var type = value.GetType(); + var etype = TypeHelper.GetElementType(type); + + if (etype == null || etype == typeof(object) || + etype.IsEnum || + (TypeHelper.IsNullableType(etype) && etype.GetGenericArguments()[0].IsEnum)) + { + var values = new List(); + + foreach (var v in (IEnumerable)value) + { + values.Add(v); + // Enum mapping done by parameter itself + //values.Add(v != null && v.GetType().IsEnum ? + // MappingSchema.MapEnumToValue(v, true) : + // v); + } + + value = values; + } + } + + p.SqlParameter.Value = value; + } + } + + #endregion + + #region GetSqlText + + public string GetSqlText(IDataContext dataContext, Expression expr, object[] parameters, int idx) + { + var query = SetCommand(dataContext, expr, parameters, 0); + return dataContext.GetSqlText(query); + } + + #endregion + + #region Inner Types + + internal delegate TElement Mapper( + Query query, + QueryContext qc, + IDataContext dc, + IDataReader rd, + MappingSchema ms, + Expression expr, + object[] ps); + + public class QueryInfo : IQueryContext + { + public QueryInfo() + { + SqlQuery = new SqlQuery(); + } + + public SqlQuery SqlQuery { get; set; } + public object Context { get; set; } + + public SqlParameter[] GetParameters() + { + var ps = new SqlParameter[Parameters.Count]; + + for (var i = 0; i < ps.Length; i++) + ps[i] = Parameters[i].SqlParameter; + + return ps; + } + + public List Parameters = new List(); + } + + #endregion + + #region Object Operations + + static class ObjectOperation + { + public static readonly Dictionary> Insert = new Dictionary>(); + public static readonly Dictionary> InsertWithIdentity = new Dictionary>(); + public static readonly Dictionary> InsertOrUpdate = new Dictionary>(); + public static readonly Dictionary> Update = new Dictionary>(); + public static readonly Dictionary> Delete = new Dictionary>(); + } + + static object ConvertNullable(TT value, TT defaultValue) + where TT : struct + { + return value.Equals(defaultValue) ? null : (object)value; + } + + static ParameterAccessor GetParameter(IDataContext dataContext, SqlField field) + { + var exprParam = Expression.Parameter(typeof(Expression), "expr"); + + Expression getter = Expression.Convert( + Expression.Property( + Expression.Convert(exprParam, typeof(ConstantExpression)), + ReflectionHelper.Constant.Value), + typeof(T)); + + var mm = field.MemberMapper; + var members = mm.MemberName.Split('.'); + var defValue = Expression.Constant( + mm.MapMemberInfo.DefaultValue ?? TypeHelper.GetDefaultValue(mm.MapMemberInfo.Type), + mm.MapMemberInfo.Type); + + for (var i = 0; i < members.Length; i++) + { + var member = members[i]; + var pof = Expression.PropertyOrField(getter, member) as Expression; + + if (i == 0) + { + if (members.Length == 1 && mm.IsExplicit) + { + if (getter.Type != typeof(object)) + getter = Expression.Convert(getter, typeof(object)); + + pof = Expression.Call( + Expression.Constant(mm), + ReflectionHelper.Expressor.MethodExpressor(m => m.GetValue(null)), + getter); + } + + getter = pof; + } + else + { + getter = Expression.Condition(Expression.Equal(getter, Expression.Constant(null)), defValue, pof); + } + } + + if (!mm.Type.IsClass && !mm.Type.IsInterface && mm.MapMemberInfo.Nullable && !TypeHelper.IsNullableType(mm.Type)) + { + var method = ReflectionHelper.Expressor.MethodExpressor(_ => ConvertNullable(0, 0)) + .GetGenericMethodDefinition() + .MakeGenericMethod(mm.Type); + + getter = Expression.Call(null, method, getter, Expression.Constant(mm.MapMemberInfo.NullValue)); + } + else + { + if (getter.Type != typeof(object)) + getter = Expression.Convert(getter, typeof(object)); + } + + var mapper = Expression.Lambda>( + getter, + new [] { exprParam, Expression.Parameter(typeof(object[]), "ps") }); + + var param = new ParameterAccessor + { + Expression = null, + Accessor = mapper.Compile(), + SqlParameter = new SqlParameter(field.SystemType, field.Name.Replace('.', '_'), null, dataContext.MappingSchema) + }; + + if (TypeHelper.IsEnumOrNullableEnum(field.SystemType)) + { + param.SqlParameter.SetEnumConverter(field.MemberMapper.ComplexMemberAccessor, dataContext.MappingSchema); + } + + return param; + } + + #region Insert + + public static int Insert(IDataContextInfo dataContextInfo, T obj) + { + if (Equals(default(T), obj)) + return 0; + + Query ei; + + var key = new { dataContextInfo.MappingSchema, dataContextInfo.ContextID }; + + if (!ObjectOperation.Insert.TryGetValue(key, out ei)) + lock (_sync) + if (!ObjectOperation.Insert.TryGetValue(key, out ei)) + { + var sqlTable = new SqlTable(dataContextInfo.MappingSchema); + var sqlQuery = new SqlQuery { QueryType = QueryType.Insert }; + + sqlQuery.Insert.Into = sqlTable; + + ei = new Query + { + MappingSchema = dataContextInfo.MappingSchema, + ContextID = dataContextInfo.ContextID, + CreateSqlProvider = dataContextInfo.CreateSqlProvider, + Queries = { new Query.QueryInfo { SqlQuery = sqlQuery, } } + }; + + foreach (var field in sqlTable.Fields) + { + if (field.Value.IsInsertable) + { + var param = GetParameter(dataContextInfo.DataContext, field.Value); + + ei.Queries[0].Parameters.Add(param); + + sqlQuery.Insert.Items.Add(new SqlQuery.SetExpression(field.Value, param.SqlParameter)); + } + else if (field.Value.IsIdentity) + { + var expr = ei.SqlProvider.GetIdentityExpression(sqlTable, field.Value, false); + + if (expr != null) + sqlQuery.Insert.Items.Add(new SqlQuery.SetExpression(field.Value, expr)); + } + } + + ei.SetNonQueryQuery(); + + ObjectOperation.Insert.Add(key, ei); + } + + return (int)ei.GetElement(null, dataContextInfo, Expression.Constant(obj), null); + } + + #endregion + + #region InsertWithIdentity + + public static object InsertWithIdentity(IDataContextInfo dataContextInfo, T obj) + { + if (Equals(default(T), obj)) + return 0; + + Query ei; + + var key = new { dataContextInfo.MappingSchema, dataContextInfo.ContextID }; + + if (!ObjectOperation.InsertWithIdentity.TryGetValue(key, out ei)) + lock (_sync) + if (!ObjectOperation.InsertWithIdentity.TryGetValue(key, out ei)) + { + var sqlTable = new SqlTable(dataContextInfo.MappingSchema); + var sqlQuery = new SqlQuery { QueryType = QueryType.Insert }; + + sqlQuery.Insert.Into = sqlTable; + sqlQuery.Insert.WithIdentity = true; + + ei = new Query + { + MappingSchema = dataContextInfo.MappingSchema, + ContextID = dataContextInfo.ContextID, + CreateSqlProvider = dataContextInfo.CreateSqlProvider, + Queries = { new Query.QueryInfo { SqlQuery = sqlQuery, } } + }; + + foreach (var field in sqlTable.Fields) + { + if (field.Value.IsInsertable) + { + var param = GetParameter(dataContextInfo.DataContext, field.Value); + + ei.Queries[0].Parameters.Add(param); + + sqlQuery.Insert.Items.Add(new SqlQuery.SetExpression(field.Value, param.SqlParameter)); + } + else if (field.Value.IsIdentity) + { + var expr = ei.SqlProvider.GetIdentityExpression(sqlTable, field.Value, true); + + if (expr != null) + sqlQuery.Insert.Items.Add(new SqlQuery.SetExpression(field.Value, expr)); + } + } + + ei.SetScalarQuery(); + + ObjectOperation.InsertWithIdentity.Add(key, ei); + } + + return ei.GetElement(null, dataContextInfo, Expression.Constant(obj), null); + } + + #endregion + + #region InsertOrReplace + + [Obsolete("Use 'InsertOrReplace' instead.")] + public static int InsertOrUpdate(IDataContextInfo dataContextInfo, T obj) + { + return InsertOrReplace(dataContextInfo, obj); + } + + public static int InsertOrReplace(IDataContextInfo dataContextInfo, T obj) + { + if (Equals(default(T), obj)) + return 0; + + Query ei; + + var key = new { dataContextInfo.MappingSchema, dataContextInfo.ContextID }; + + if (!ObjectOperation.InsertOrUpdate.TryGetValue(key, out ei)) + { + lock (_sync) + { + if (!ObjectOperation.InsertOrUpdate.TryGetValue(key, out ei)) + { + var fieldDic = new Dictionary(); + var sqlTable = new SqlTable(dataContextInfo.MappingSchema); + var sqlQuery = new SqlQuery { QueryType = QueryType.InsertOrUpdate }; + + ParameterAccessor param; + + sqlQuery.Insert.Into = sqlTable; + sqlQuery.Update.Table = sqlTable; + + sqlQuery.From.Table(sqlTable); + + ei = new Query + { + MappingSchema = dataContextInfo.MappingSchema, + ContextID = dataContextInfo.ContextID, + CreateSqlProvider = dataContextInfo.CreateSqlProvider, + Queries = { new Query.QueryInfo { SqlQuery = sqlQuery, } } + }; + + var supported = ei.SqlProvider.IsInsertOrUpdateSupported && ei.SqlProvider.CanCombineParameters; + + // Insert. + // + foreach (var field in sqlTable.Fields.Select(f => f.Value)) + { + if (field.IsInsertable) + { + if (!supported || !fieldDic.TryGetValue(field, out param)) + { + param = GetParameter(dataContextInfo.DataContext, field); + ei.Queries[0].Parameters.Add(param); + + if (supported) + fieldDic.Add(field, param); + } + + sqlQuery.Insert.Items.Add(new SqlQuery.SetExpression(field, param.SqlParameter)); + } + else if (field.IsIdentity) + { + throw new LinqException("InsertOrUpdate method does not support identity field '{0}.{1}'.", sqlTable.Name, field.Name); + } + } + + // Update. + // + var keys = sqlTable.GetKeys(true).Cast().ToList(); + var fields = sqlTable.Fields.Values.Where(f => f.IsUpdatable).Except(keys).ToList(); + + if (keys.Count == 0) + throw new LinqException("InsertOrUpdate method requires the '{0}' table to have a primary key.", sqlTable.Name); + + var q = + ( + from k in keys + join i in sqlQuery.Insert.Items on k equals i.Column + select new { k, i } + ).ToList(); + + var missedKey = keys.Except(q.Select(i => i.k)).FirstOrDefault(); + + if (missedKey != null) + throw new LinqException("InsertOrUpdate method requires the '{0}.{1}' field to be included in the insert setter.", + sqlTable.Name, + missedKey.Name); + + if (fields.Count == 0) + throw new LinqException( + string.Format("There are no fields to update in the type '{0}'.", sqlTable.Name)); + + foreach (var field in fields) + { + if (!supported || !fieldDic.TryGetValue(field, out param)) + { + param = GetParameter(dataContextInfo.DataContext, field); + ei.Queries[0].Parameters.Add(param); + + if (supported) + fieldDic.Add(field, param = GetParameter(dataContextInfo.DataContext, field)); + } + + sqlQuery.Update.Items.Add(new SqlQuery.SetExpression(field, param.SqlParameter)); + } + + sqlQuery.Update.Keys.AddRange(q.Select(i => i.i)); + + // Set the query. + // + if (ei.SqlProvider.IsInsertOrUpdateSupported) + ei.SetNonQueryQuery(); + else + ei.MakeAlternativeInsertOrUpdate(sqlQuery); + + ObjectOperation.InsertOrUpdate.Add(key, ei); + } + } + } + + return (int)ei.GetElement(null, dataContextInfo, Expression.Constant(obj), null); + } + + internal void MakeAlternativeInsertOrUpdate(SqlQuery sqlQuery) + { + var dic = new Dictionary(); + + var insertQuery = (SqlQuery)sqlQuery.Clone(dic, _ => true); + + insertQuery.QueryType = QueryType.Insert; + insertQuery.ClearUpdate(); + insertQuery.From.Tables.Clear(); + + Queries.Add(new QueryInfo + { + SqlQuery = insertQuery, + Parameters = Queries[0].Parameters + .Select(p => new ParameterAccessor + { + Expression = p.Expression, + Accessor = p.Accessor, + SqlParameter = dic.ContainsKey(p.SqlParameter) ? (SqlParameter)dic[p.SqlParameter] : null + }) + .Where(p => p.SqlParameter != null) + .ToList(), + }); + + var keys = sqlQuery.Update.Keys; + + foreach (var key in keys) + sqlQuery.Where.Expr(key.Column).Equal.Expr(key.Expression); + + sqlQuery.QueryType = QueryType.Update; + sqlQuery.ClearInsert(); + + SetNonQueryQuery2(); + + Queries.Add(new QueryInfo + { + SqlQuery = insertQuery, + Parameters = Queries[0].Parameters.ToList(), + }); + } + + #endregion + + #region Update + + public static int Update(IDataContextInfo dataContextInfo, T obj) + { + if (Equals(default(T), obj)) + return 0; + + Query ei; + + var key = new { dataContextInfo.MappingSchema, dataContextInfo.ContextID }; + + if (!ObjectOperation.Update.TryGetValue(key, out ei)) + lock (_sync) + if (!ObjectOperation.Update.TryGetValue(key, out ei)) + { + var sqlTable = new SqlTable(dataContextInfo.MappingSchema); + var sqlQuery = new SqlQuery { QueryType = QueryType.Update }; + + sqlQuery.From.Table(sqlTable); + + ei = new Query + { + MappingSchema = dataContextInfo.MappingSchema, + ContextID = dataContextInfo.ContextID, + CreateSqlProvider = dataContextInfo.CreateSqlProvider, + Queries = { new Query.QueryInfo { SqlQuery = sqlQuery, } } + }; + + var keys = sqlTable.GetKeys(true).Cast(); + var fields = sqlTable.Fields.Values.Where(f => f.IsUpdatable).Except(keys).ToList(); + + if (fields.Count == 0) + { + if (Configuration.Linq.IgnoreEmptyUpdate) + return 0; + + throw new LinqException( + string.Format("There are no fields to update in the type '{0}'.", sqlTable.Name)); + } + + foreach (var field in fields) + { + var param = GetParameter(dataContextInfo.DataContext, field); + + ei.Queries[0].Parameters.Add(param); + + sqlQuery.Update.Items.Add(new SqlQuery.SetExpression(field, param.SqlParameter)); + } + + foreach (var field in keys) + { + var param = GetParameter(dataContextInfo.DataContext, field); + + ei.Queries[0].Parameters.Add(param); + + sqlQuery.Where.Field(field).Equal.Expr(param.SqlParameter); + + if (field.Nullable) + sqlQuery.IsParameterDependent = true; + } + + ei.SetNonQueryQuery(); + + ObjectOperation.Update.Add(key, ei); + } + + return (int)ei.GetElement(null, dataContextInfo, Expression.Constant(obj), null); + } + + #endregion + + #region Delete + + public static int Delete(IDataContextInfo dataContextInfo, T obj) + { + if (Equals(default(T), obj)) + return 0; + + Query ei; + + var key = new { dataContextInfo.MappingSchema, dataContextInfo.ContextID }; + + if (!ObjectOperation.Delete.TryGetValue(key, out ei)) + lock (_sync) + if (!ObjectOperation.Delete.TryGetValue(key, out ei)) + { + var sqlTable = new SqlTable(dataContextInfo.MappingSchema); + var sqlQuery = new SqlQuery { QueryType = QueryType.Delete }; + + sqlQuery.From.Table(sqlTable); + + ei = new Query + { + MappingSchema = dataContextInfo.MappingSchema, + ContextID = dataContextInfo.ContextID, + CreateSqlProvider = dataContextInfo.CreateSqlProvider, + Queries = { new Query.QueryInfo { SqlQuery = sqlQuery, } } + }; + + var keys = sqlTable.GetKeys(true).Cast().ToList(); + + if (keys.Count == 0) + throw new LinqException( + string.Format("Table '{0}' does not have primary key.", sqlTable.Name)); + + foreach (var field in keys) + { + var param = GetParameter(dataContextInfo.DataContext, field); + + ei.Queries[0].Parameters.Add(param); + + sqlQuery.Where.Field(field).Equal.Expr(param.SqlParameter); + + if (field.Nullable) + sqlQuery.IsParameterDependent = true; + } + + ei.SetNonQueryQuery(); + + ObjectOperation.Delete.Add(key, ei); + } + + return (int)ei.GetElement(null, dataContextInfo, Expression.Constant(obj), null); + } + + #endregion + + #endregion + + #region New Builder Support + + public void SetElementQuery(Func mapper) + { + FinalizeQuery(); + + if (Queries.Count != 1) + throw new InvalidOperationException(); + + SqlProvider.SqlQuery = Queries[0].SqlQuery; + + GetElement = (ctx,db,expr,ps) => RunQuery(ctx, db,expr, ps, mapper); + } + + TE RunQuery( + QueryContext ctx, + IDataContextInfo dataContextInfo, + Expression expr, + object[] parameters, + Func mapper) + { + var dataContext = dataContextInfo.DataContext; + + object query = null; + + try + { + query = SetCommand(dataContext, expr, parameters, 0); + + using (var dr = dataContext.ExecuteReader(query)) + while (dr.Read()) + return mapper(ctx, dataContext, dr, expr, parameters); + + return Array.Empty.First(); + } + finally + { + if (query != null) + dataContext.ReleaseQuery(query); + + if (dataContextInfo.DisposeContext) + dataContext.Dispose(); + } + } + + Func> GetQuery() + { + FinalizeQuery(); + + if (Queries.Count != 1) + throw new InvalidOperationException(); + + Func> query = RunQuery; + + SqlProvider.SqlQuery = Queries[0].SqlQuery; + + var select = Queries[0].SqlQuery.Select; + + if (select.SkipValue != null && !SqlProvider.IsSkipSupported) + { + var q = query; + + if (select.SkipValue is SqlValue) + { + var n = (int)((IValueContainer)select.SkipValue).Value; + + if (n > 0) + query = (db, expr, ps, qn) => q(db, expr, ps, qn).Skip(n); + } + else if (select.SkipValue is SqlParameter) + { + var i = GetParameterIndex(select.SkipValue); + query = (db, expr, ps, qn) => q(db, expr, ps, qn).Skip((int)Queries[0].Parameters[i].Accessor(expr, ps)); + } + } + + if (select.TakeValue != null && !SqlProvider.IsTakeSupported) + { + var q = query; + + if (select.TakeValue is SqlValue) + { + var n = (int)((IValueContainer)select.TakeValue).Value; + + if (n > 0) + query = (db, expr, ps, qn) => q(db, expr, ps, qn).Take(n); + } + else if (select.TakeValue is SqlParameter) + { + var i = GetParameterIndex(select.TakeValue); + query = (db, expr, ps, qn) => q(db, expr, ps, qn).Take((int)Queries[0].Parameters[i].Accessor(expr, ps)); + } + } + + return query; + } + + internal void SetQuery(Func mapper) + { + var query = GetQuery(); + GetIEnumerable = (ctx,db,expr,ps) => Map(query(db, expr, ps, 0), ctx, db, expr, ps, mapper); + } + + static IEnumerable Map( + IEnumerable data, + QueryContext queryContext, + IDataContextInfo dataContextInfo, + Expression expr, + object[] ps, + Func mapper) + { + if (queryContext == null) + queryContext = new QueryContext(dataContextInfo, expr, ps); + + foreach (var dr in data) + yield return mapper(queryContext, dataContextInfo.DataContext, dr, expr, ps); + } + + internal void SetQuery(Func mapper) + { + var query = GetQuery(); + GetIEnumerable = (ctx,db,expr,ps) => Map(query(db, expr, ps, 0), ctx, db, expr, ps, mapper); + } + + static IEnumerable Map( + IEnumerable data, + QueryContext queryContext, + IDataContextInfo dataContextInfo, + Expression expr, + object[] ps, + Func mapper) + { + if (queryContext == null) + queryContext = new QueryContext(dataContextInfo, expr, ps); + + var counter = 0; + + foreach (var dr in data) + yield return mapper(queryContext, dataContextInfo.DataContext, dr, expr, ps, counter++); + } + + #endregion + } + + public class ParameterAccessor + { + public Expression Expression; + public Func Accessor; + public SqlParameter SqlParameter; + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/QueryContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/QueryContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq +{ + public class QueryContext + { + public class DataContextContext + { + public IDataContextInfo DataContextInfo; + public bool InUse; + } + + public QueryContext(IDataContextInfo dataContext, Expression expr, object[] compiledParameters) + { + RootDataContext = dataContext; + Expression = expr; + CompiledParameters = compiledParameters; + } + + public IDataContextInfo RootDataContext; + public Expression Expression; + public object[] CompiledParameters; + public int Counter; + + List _contexts; + + public DataContextContext GetDataContext() + { + if (_contexts == null) + { + RootDataContext.DataContext.OnClosing += OnRootClosing; + _contexts = new List(1); + } + + foreach (var context in _contexts) + { + if (!context.InUse) + { + context.InUse = true; + return context; + } + } + + var ctx = new DataContextContext { DataContextInfo = RootDataContext.Clone(true), InUse = true }; + + _contexts.Add(ctx); + + return ctx; + } + + public void ReleaseDataContext(DataContextContext context) + { + context.InUse = false; + } + + void OnRootClosing(object sender, EventArgs e) + { + foreach (var context in _contexts) + context.DataContextInfo.DataContext.Dispose(); + + RootDataContext.DataContext.OnClosing -= OnRootClosing; + + _contexts = null; + } + + public void AfterQuery() + { + Counter++; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/QueryableAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/QueryableAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using System; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq +{ + class QueryableAccessor + { + public IQueryable Queryable; + public Func Accessor; + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/ReflectionHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/ReflectionHelper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,299 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Xml; +#if !SILVERLIGHT +using System.Xml.Linq; +#endif + +using LinqBinary = System.Data.Linq.Binary; +using BLToolkit.Reflection; + +namespace BLToolkit.Data.Linq +{ + public class ReflectionHelper + { + public class Expressor + { + public static FieldInfo FieldExpressor(Expression> func) + { + return (FieldInfo)((MemberExpression)((UnaryExpression)func.Body).Operand).Member; + } + + public static MethodInfo PropertyExpressor(Expression> func) + { + return ((PropertyInfo)((MemberExpression)func.Body).Member).GetGetMethod(); + } + + public static MethodInfo MethodExpressor(Expression> func) + { + var ex = func.Body; + + if (ex is UnaryExpression) + ex = ((UnaryExpression)ex).Operand; + + //if (ex is MemberExpression) + // return ((PropertyInfo)((MemberExpression)ex).Member).GetGetMethod(); + + return ((MethodCallExpression)ex).Method; + } + } + + public static MemberInfo MemeberInfo(LambdaExpression func) + { + var ex = func.Body; + + if (ex is UnaryExpression) + ex = ((UnaryExpression)ex).Operand; + + return + ex is MemberExpression ? ((MemberExpression) ex).Member : + ex is MethodCallExpression ? ((MethodCallExpression)ex).Method : + (MemberInfo)((NewExpression) ex).Constructor; + } + + public class Binary : Expressor + { + public static MethodInfo Conversion = PropertyExpressor(e => e.Conversion); + public static MethodInfo Left = PropertyExpressor(e => e.Left); + public static MethodInfo Right = PropertyExpressor(e => e.Right); + } + + public class Unary : Expressor + { + public static MethodInfo Operand = PropertyExpressor(e => e.Operand); + } + + public class LambdaExpr : Expressor + { + public static MethodInfo Body = PropertyExpressor(e => e.Body); + public static MethodInfo Parameters = PropertyExpressor(e => e.Parameters); + } + + public class Constant : Expressor + { + public static MethodInfo Value = PropertyExpressor(e => e.Value); + } + + public class QueryableInt : Expressor + { + public static MethodInfo Expression = PropertyExpressor(e => e.Expression); + } + + public class MethodCall : Expressor + { + public static MethodInfo Object = PropertyExpressor(e => e.Object); + public static MethodInfo Arguments = PropertyExpressor(e => e.Arguments); + } + + public class Conditional : Expressor + { + public static MethodInfo Test = PropertyExpressor(e => e.Test); + public static MethodInfo IfTrue = PropertyExpressor(e => e.IfTrue); + public static MethodInfo IfFalse = PropertyExpressor(e => e.IfFalse); + } + + public class Invocation : Expressor + { + public static MethodInfo Expression = PropertyExpressor(e => e.Expression); + public static MethodInfo Arguments = PropertyExpressor(e => e.Arguments); + } + + public class ListInit : Expressor + { + public static MethodInfo NewExpression = PropertyExpressor(e => e.NewExpression); + public static MethodInfo Initializers = PropertyExpressor(e => e.Initializers); + } + + public class ElementInit : Expressor + { + public static MethodInfo Arguments = PropertyExpressor(e => e.Arguments); + } + + public class Member : Expressor + { + public static MethodInfo Expression = PropertyExpressor(e => e.Expression); + } + + public class MemberInit : Expressor + { + public static MethodInfo NewExpression = PropertyExpressor(e => e.NewExpression); + public static MethodInfo Bindings = PropertyExpressor(e => e.Bindings); + } + + public class New : Expressor + { + public static MethodInfo Arguments = PropertyExpressor(e => e.Arguments); + } + + public class NewArray : Expressor + { + public static MethodInfo Expressions = PropertyExpressor(e => e.Expressions); + } + + public class TypeBinary : Expressor + { + public static MethodInfo Expression = PropertyExpressor(e => e.Expression); + } + + public class IndexExpressor + { + public static MethodInfo IndexerExpressor(Expression, object>> func) + { + return ((MethodCallExpression)((UnaryExpression)func.Body).Operand).Method; + } + + public static MethodInfo Item = IndexerExpressor(c => c[0]); + } + + public class MemberAssignmentBind : Expressor + { + public static MethodInfo Expression = PropertyExpressor(e => e.Expression); + } + + public class MemberListBind : Expressor + { + public static MethodInfo Initializers = PropertyExpressor(e => e.Initializers); + } + + public class MemberMemberBind : Expressor + { + public static MethodInfo Bindings = PropertyExpressor(e => e.Bindings); + } + +#if FW4 || SILVERLIGHT + + public class Block : Expressor + { + public static MethodInfo Expressions = PropertyExpressor(e => e.Expressions); + public static MethodInfo Variables = PropertyExpressor(e => e.Variables); + } + +#endif + + public static MethodInfo ExprItem = IndexExpressor .Item; + public static MethodInfo ParamItem = IndexExpressor.Item; + public static MethodInfo ElemItem = IndexExpressor .Item; + + public class DataReader : Expressor + { + public static MethodInfo GetValue = MethodExpressor(rd => rd.GetValue(0)); + public static MethodInfo IsDBNull = MethodExpressor(rd => rd.IsDBNull(0)); + } + + internal class QueryCtx : Expressor + { + public static FieldInfo Counter = FieldExpressor(ctx => ctx.Counter); + } + + public class MapSchema : Expressor + { + public static MethodInfo MapValueToEnum = MethodExpressor(m => m.MapValueToEnum(null, (Type)null)); + public static MethodInfo MapValueToEnumWithMemberAccessor = MethodExpressor(m => m.MapValueToEnum(null, (MemberAccessor)null)); + public static MethodInfo ChangeType = MethodExpressor(m => m.ConvertChangeType(null, null)); + + public static Dictionary Converters = new Dictionary + { + // Primitive Types + // + { typeof(SByte), MethodExpressor(m => m.ConvertToSByte (null)) }, + { typeof(Int16), MethodExpressor(m => m.ConvertToInt16 (null)) }, + { typeof(Int32), MethodExpressor(m => m.ConvertToInt32 (null)) }, + { typeof(Int64), MethodExpressor(m => m.ConvertToInt64 (null)) }, + { typeof(Byte), MethodExpressor(m => m.ConvertToByte (null)) }, + { typeof(UInt16), MethodExpressor(m => m.ConvertToUInt16 (null)) }, + { typeof(UInt32), MethodExpressor(m => m.ConvertToUInt32 (null)) }, + { typeof(UInt64), MethodExpressor(m => m.ConvertToUInt64 (null)) }, + { typeof(Char), MethodExpressor(m => m.ConvertToChar (null)) }, + { typeof(Single), MethodExpressor(m => m.ConvertToSingle (null)) }, + { typeof(Double), MethodExpressor(m => m.ConvertToDouble (null)) }, + { typeof(Boolean), MethodExpressor(m => m.ConvertToBoolean (null)) }, + + // Simple Types + // + { typeof(String), MethodExpressor(m => m.ConvertToString (null)) }, + { typeof(DateTime), MethodExpressor(m => m.ConvertToDateTime (null)) }, + { typeof(TimeSpan), MethodExpressor(m => m.ConvertToTimeSpan (null)) }, + { typeof(DateTimeOffset), MethodExpressor(m => m.ConvertToDateTimeOffset (null)) }, + { typeof(Decimal), MethodExpressor(m => m.ConvertToDecimal (null)) }, + { typeof(Guid), MethodExpressor(m => m.ConvertToGuid (null)) }, + { typeof(Stream), MethodExpressor(m => m.ConvertToStream (null)) }, +#if !SILVERLIGHT + { typeof(XmlReader), MethodExpressor(m => m.ConvertToXmlReader (null)) }, + { typeof(XmlDocument), MethodExpressor(m => m.ConvertToXmlDocument (null)) }, + { typeof(XElement), MethodExpressor(m => m.ConvertToXElement (null)) }, +#endif + { typeof(Byte[]), MethodExpressor(m => m.ConvertToByteArray (null)) }, + { typeof(LinqBinary), MethodExpressor(m => m.ConvertToLinqBinary (null)) }, + { typeof(Char[]), MethodExpressor(m => m.ConvertToCharArray (null)) }, + + // Nullable Types + // + { typeof(SByte?), MethodExpressor(m => m.ConvertToNullableSByte (null)) }, + { typeof(Int16?), MethodExpressor(m => m.ConvertToNullableInt16 (null)) }, + { typeof(Int32?), MethodExpressor(m => m.ConvertToNullableInt32 (null)) }, + { typeof(Int64?), MethodExpressor(m => m.ConvertToNullableInt64 (null)) }, + { typeof(Byte?), MethodExpressor(m => m.ConvertToNullableByte (null)) }, + { typeof(UInt16?), MethodExpressor(m => m.ConvertToNullableUInt16 (null)) }, + { typeof(UInt32?), MethodExpressor(m => m.ConvertToNullableUInt32 (null)) }, + { typeof(UInt64?), MethodExpressor(m => m.ConvertToNullableUInt64 (null)) }, + { typeof(Char?), MethodExpressor(m => m.ConvertToNullableChar (null)) }, + { typeof(Double?), MethodExpressor(m => m.ConvertToNullableDouble (null)) }, + { typeof(Single?), MethodExpressor(m => m.ConvertToNullableSingle (null)) }, + { typeof(Boolean?), MethodExpressor(m => m.ConvertToNullableBoolean (null)) }, + { typeof(DateTime?), MethodExpressor(m => m.ConvertToNullableDateTime (null)) }, + { typeof(TimeSpan?), MethodExpressor(m => m.ConvertToNullableTimeSpan (null)) }, + { typeof(DateTimeOffset?), MethodExpressor(m => m.ConvertToNullableDateTimeOffset(null)) }, + { typeof(Decimal?), MethodExpressor(m => m.ConvertToNullableDecimal (null)) }, + { typeof(Guid?), MethodExpressor(m => m.ConvertToNullableGuid (null)) }, + +#if !SILVERLIGHT + + // SqlTypes + // + { typeof(SqlByte), MethodExpressor(m => m.ConvertToSqlByte (null)) }, + { typeof(SqlInt16), MethodExpressor(m => m.ConvertToSqlInt16 (null)) }, + { typeof(SqlInt32), MethodExpressor(m => m.ConvertToSqlInt32 (null)) }, + { typeof(SqlInt64), MethodExpressor(m => m.ConvertToSqlInt64 (null)) }, + { typeof(SqlSingle), MethodExpressor(m => m.ConvertToSqlSingle (null)) }, + { typeof(SqlBoolean), MethodExpressor(m => m.ConvertToSqlBoolean (null)) }, + { typeof(SqlDouble), MethodExpressor(m => m.ConvertToSqlDouble (null)) }, + { typeof(SqlDateTime), MethodExpressor(m => m.ConvertToSqlDateTime (null)) }, + { typeof(SqlDecimal), MethodExpressor(m => m.ConvertToSqlDecimal (null)) }, + { typeof(SqlMoney), MethodExpressor(m => m.ConvertToSqlMoney (null)) }, + { typeof(SqlString), MethodExpressor(m => m.ConvertToSqlString (null)) }, + { typeof(SqlBinary), MethodExpressor(m => m.ConvertToSqlBinary (null)) }, + { typeof(SqlGuid), MethodExpressor(m => m.ConvertToSqlGuid (null)) }, + { typeof(SqlBytes), MethodExpressor(m => m.ConvertToSqlBytes (null)) }, + { typeof(SqlChars), MethodExpressor(m => m.ConvertToSqlChars (null)) }, + { typeof(SqlXml), MethodExpressor(m => m.ConvertToSqlXml (null)) }, + +#endif + }; + } + + public class Functions + { + public class String : Expressor + { + //public static MethodInfo Contains = MethodExpressor(s => s.Contains("")); + //public static MethodInfo StartsWith = MethodExpressor(s => s.StartsWith("")); + //public static MethodInfo EndsWith = MethodExpressor(s => s.EndsWith("")); + +#if !SILVERLIGHT + public static MethodInfo Like11 = MethodExpressor(s => System.Data.Linq.SqlClient.SqlMethods.Like("", "")); + public static MethodInfo Like12 = MethodExpressor(s => System.Data.Linq.SqlClient.SqlMethods.Like("", "", ' ')); +#endif + + public static MethodInfo Like21 = MethodExpressor(s => Sql.Like(s, "")); + public static MethodInfo Like22 = MethodExpressor(s => Sql.Like(s, "", ' ')); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Settings.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Settings.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + public static class Settings + { +#if SILVERLIGHT + public static Func CreateDefaultDataContext = config => { throw new InvalidOperationException(); }; +#else + public static Func CreateDefaultDataContext = config => new DbManager(config ?? DbManager.DefaultConfiguration); +#endif + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/Sql.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/Sql.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,904 @@ +using System; +using System.Data.Linq; +using System.Globalization; +using System.Reflection; + +namespace BLToolkit.Data.Linq +{ + using Data.Sql; + using Reflection; + + public static class Sql + { + #region Common Functions + + [CLSCompliant(false)] + [SqlExpression("{0}", 0, ServerSideOnly = true)] + public static T AsSql(T obj) + { + return obj; + } + + [Obsolete("Use AsSql instead.")] + [CLSCompliant(false)] + [SqlExpression("{0}", 0, ServerSideOnly = true)] + public static T OnServer(T obj) + { + return obj; + } + + [CLSCompliant(false)] + [SqlExpression("{0}", 0)] + public static T ConvertNullable(T? value) + where T : struct + { + return value.Value; + } + + #endregion + + #region Guid Functions + + [SqlFunction ("Oracle", "Sys_Guid", ServerSideOnly=true)] + [SqlFunction ("Firebird", "Gen_Uuid", ServerSideOnly=true)] + [SqlFunction ("MySql", "Uuid", ServerSideOnly=true)] + [SqlExpression("Sybase", "NewID(1)", ServerSideOnly=true)] + [SqlFunction ( "NewID", ServerSideOnly=true)] + public static Guid NewGuid() + { + return Guid.NewGuid(); + } + + #endregion + + #region Convert Functions + + [CLSCompliant(false)] + [SqlFunction("Convert", 0, 1, ServerSideOnly = true)] + public static TTo Convert(TTo to, TFrom from) + { + var dt = Common.ConvertTo.From(from); + return dt; + } + + [CLSCompliant(false)] + [SqlFunction("Convert", 0, 1, 2, ServerSideOnly = true)] + public static TTo Convert(TTo to, TFrom from, int format) + { + var dt = Common.ConvertTo.From(from); + return dt; + } + + [CLSCompliant(false)] + [SqlFunction("Convert", 0, 1)] + public static TTo Convert2(TTo to, TFrom from) + { + return Common.ConvertTo.From(from); + } + + [CLSCompliant(false)] + [SqlFunction("$Convert$", 1, 2, 0)] + public static TTo Convert(TFrom obj) + { + return Common.ConvertTo.From(obj); + } + + public static class ConvertTo + { + [CLSCompliant(false)] + [SqlFunction("$Convert$", 1, 2, 0)] + public static TTo From(TFrom obj) + { + return Common.ConvertTo.From(obj); + } + } + + [SqlExpression("{0}")] + public static TimeSpan? DateToTime(DateTime? date) + { + return date == null ? null : (TimeSpan?)new TimeSpan(date.Value.Ticks); + } + + [SqlProperty("Informix", "Boolean", ServerSideOnly=true)] + [SqlProperty("PostgreSQL", "Boolean", ServerSideOnly=true)] + [SqlProperty("MySql", "Boolean", ServerSideOnly=true)] + [SqlProperty("SQLite", "Boolean", ServerSideOnly=true)] + [SqlProperty( "Bit", ServerSideOnly=true)] public static Boolean Bit { get { return false; } } + + [SqlProperty("Oracle", "Number(19)", ServerSideOnly=true)] + [SqlProperty( "BigInt", ServerSideOnly=true)] public static Int64 BigInt { get { return 0; } } + + [SqlProperty("MySql", "Signed", ServerSideOnly=true)] + [SqlProperty( "Int", ServerSideOnly=true)] public static Int32 Int { get { return 0; } } + + [SqlProperty("MySql", "Signed", ServerSideOnly=true)] + [SqlProperty( "SmallInt", ServerSideOnly=true)] public static Int16 SmallInt { get { return 0; } } + + [SqlProperty("DB2", "SmallInt", ServerSideOnly=true)] + [SqlProperty("Informix", "SmallInt", ServerSideOnly=true)] + [SqlProperty("Oracle", "Number(3)", ServerSideOnly=true)] + [SqlProperty("DB2", "SmallInt", ServerSideOnly=true)] + [SqlProperty("Firebird", "SmallInt", ServerSideOnly=true)] + [SqlProperty("PostgreSQL", "SmallInt", ServerSideOnly=true)] + [SqlProperty("MySql", "Unsigned", ServerSideOnly=true)] + [SqlProperty( "TinyInt", ServerSideOnly=true)] public static Byte TinyInt { get { return 0; } } + + [SqlProperty( "Decimal", ServerSideOnly=true)] public static Decimal DefaultDecimal { get { return 0; } } + [SqlFunction( ServerSideOnly=true)] public static Decimal Decimal(int precision) { return 0; } + [SqlFunction( ServerSideOnly=true)] public static Decimal Decimal(int precision, int scale) { return 0; } + + [SqlProperty("Oracle", "Number(19,4)", ServerSideOnly=true)] + [SqlProperty("Firebird", "Decimal(18,4)", ServerSideOnly=true)] + [SqlProperty("PostgreSQL", "Decimal(19,4)", ServerSideOnly=true)] + [SqlProperty("MySql", "Decimal(19,4)", ServerSideOnly=true)] + [SqlProperty( "Money", ServerSideOnly=true)] public static Decimal Money { get { return 0; } } + + [SqlProperty("Informix", "Decimal(10,4)", ServerSideOnly=true)] + [SqlProperty("Oracle", "Number(10,4)", ServerSideOnly=true)] + [SqlProperty("Firebird", "Decimal(10,4)", ServerSideOnly=true)] + [SqlProperty("PostgreSQL", "Decimal(10,4)", ServerSideOnly=true)] + [SqlProperty("MySql", "Decimal(10,4)", ServerSideOnly=true)] + [SqlProperty("SqlCe", "Decimal(10,4)", ServerSideOnly=true)] + [SqlProperty( "SmallMoney", ServerSideOnly=true)] public static Decimal SmallMoney { get { return 0; } } + + [SqlProperty("MySql", "Decimal(29,10)", ServerSideOnly=true)] + [SqlProperty( "Float", ServerSideOnly=true)] public static Double Float { get { return 0; } } + + [SqlProperty("MySql", "Decimal(29,10)", ServerSideOnly=true)] + [SqlProperty( "Real", ServerSideOnly=true)] public static Single Real { get { return 0; } } + + [SqlProperty("PostgreSQL", "TimeStamp", ServerSideOnly=true)] + [SqlProperty("Firebird", "TimeStamp", ServerSideOnly=true)] + [SqlProperty( "DateTime", ServerSideOnly=true)] public static DateTime DateTime { get { return DateTime.Now; } } + + [SqlProperty("MsSql2000", "DateTime", ServerSideOnly=true)] + [SqlProperty("MsSql2005", "DateTime", ServerSideOnly=true)] + [SqlProperty("PostgreSQL", "TimeStamp", ServerSideOnly=true)] + [SqlProperty("Firebird", "TimeStamp", ServerSideOnly=true)] + [SqlProperty("MySql", "DateTime", ServerSideOnly=true)] + [SqlProperty("SqlCe", "DateTime", ServerSideOnly=true)] + [SqlProperty("Sybase", "DateTime", ServerSideOnly=true)] + [SqlProperty( "DateTime2", ServerSideOnly=true)] public static DateTime DateTime2 { get { return DateTime.Now; } } + + [SqlProperty("PostgreSQL", "TimeStamp", ServerSideOnly=true)] + [SqlProperty("Firebird", "TimeStamp", ServerSideOnly=true)] + [SqlProperty("MySql", "DateTime", ServerSideOnly=true)] + [SqlProperty("SqlCe", "DateTime", ServerSideOnly=true)] + [SqlProperty( "SmallDateTime", ServerSideOnly=true)] public static DateTime SmallDateTime { get { return DateTime.Now; } } + + [SqlProperty("MsSql2000", "Datetime", ServerSideOnly=true)] + [SqlProperty("MsSql2005", "Datetime", ServerSideOnly=true)] + [SqlProperty("SqlCe", "Datetime", ServerSideOnly=true)] + [SqlProperty( "Date", ServerSideOnly=true)] public static DateTime Date { get { return DateTime.Now; } } + + [SqlProperty( "Time", ServerSideOnly=true)] public static DateTime Time { get { return DateTime.Now; } } + + [SqlProperty("PostgreSQL", "TimeStamp", ServerSideOnly=true)] + [SqlProperty("Firebird", "TimeStamp", ServerSideOnly=true)] + [SqlProperty("MsSql2008", "DateTimeOffset", ServerSideOnly=true)] + [SqlProperty("MsSql2012", "DateTimeOffset", ServerSideOnly=true)] + [SqlProperty( "DateTime", ServerSideOnly=true)] public static DateTimeOffset DateTimeOffset { get { return DateTimeOffset.Now; } } + + [SqlFunction("SqlCe", "NChar", ServerSideOnly=true)] + [SqlFunction( ServerSideOnly=true)] public static String Char(int length) { return ""; } + + [SqlProperty("SqlCe", "NChar", ServerSideOnly=true)] + [SqlProperty( "Char", ServerSideOnly=true)] public static String DefaultChar { get { return ""; } } + + [SqlFunction("MySql", "Char", ServerSideOnly=true)] + [SqlFunction("SqlCe", "NVarChar", ServerSideOnly=true)] + [SqlFunction( ServerSideOnly=true)] public static String VarChar(int length) { return ""; } + + [SqlProperty("MySql", "Char", ServerSideOnly=true)] + [SqlProperty("SqlCe", "NVarChar", ServerSideOnly=true)] + [SqlProperty( "VarChar", ServerSideOnly=true)] public static String DefaultVarChar { get { return ""; } } + + [SqlFunction("DB2", "Char", ServerSideOnly=true)] + [SqlFunction( ServerSideOnly=true)] public static String NChar(int length) { return ""; } + + [SqlProperty("DB2", "Char", ServerSideOnly=true)] + [SqlProperty( "NChar", ServerSideOnly=true)] public static String DefaultNChar { get { return ""; } } + + [SqlFunction("DB2", "Char", ServerSideOnly=true)] + [SqlFunction("Oracle", "VarChar2", ServerSideOnly=true)] + [SqlFunction("Firebird", "VarChar", ServerSideOnly=true)] + [SqlFunction("PostgreSQL", "VarChar", ServerSideOnly=true)] + [SqlFunction("MySql", "Char", ServerSideOnly=true)] + [SqlFunction( ServerSideOnly=true)] public static String NVarChar(int length) { return ""; } + + [SqlProperty("DB2", "Char", ServerSideOnly=true)] + [SqlProperty("Oracle", "VarChar2", ServerSideOnly=true)] + [SqlProperty("Firebird", "VarChar", ServerSideOnly=true)] + [SqlProperty("PostgreSQL", "VarChar", ServerSideOnly=true)] + [SqlProperty("MySql", "Char", ServerSideOnly=true)] + [SqlProperty( "NVarChar", ServerSideOnly=true)] public static String DefaultNVarChar { get { return ""; } } + + #endregion + + #region String Functions + + [SqlFunction( PreferServerSide = true)] + [SqlFunction("Access", "Len", PreferServerSide = true)] + [SqlFunction("Firebird", "Char_Length", PreferServerSide = true)] + [SqlFunction("MsSql2000", "Len", PreferServerSide = true)] + [SqlFunction("MsSql2005", "Len", PreferServerSide = true)] + [SqlFunction("MsSql2008", "Len", PreferServerSide = true)] + [SqlFunction("MsSql2012", "Len", PreferServerSide = true)] + [SqlFunction("SqlCe", "Len", PreferServerSide = true)] + [SqlFunction("Sybase", "Len", PreferServerSide = true)] + public static int? Length(string str) + { + return str == null ? null : (int?)str.Length; + } + + [SqlFunction] + [SqlFunction ("Access", "Mid")] + [SqlFunction ("DB2", "Substr")] + [SqlFunction ("Informix", "Substr")] + [SqlFunction ("Oracle", "Substr")] + [SqlFunction ("SQLite", "Substr")] + [SqlExpression("Firebird", "Substring({0} from {1} for {2})")] + public static string Substring(string str, int? startIndex, int? length) + { + return str == null || startIndex == null || length == null ? null : str.Substring(startIndex.Value, length.Value); + } + + [SqlFunction(ServerSideOnly = true)] + public static bool Like(string matchExpression, string pattern) + { +#if SILVERLIGHT + throw new InvalidOperationException(); +#else + return matchExpression == null || pattern == null ? false : System.Data.Linq.SqlClient.SqlMethods.Like(matchExpression, pattern); +#endif + } + + [SqlFunction(ServerSideOnly = true)] + public static bool Like(string matchExpression, string pattern, char? escapeCharacter) + { +#if SILVERLIGHT + throw new InvalidOperationException(); +#else + return matchExpression == null || pattern == null || escapeCharacter == null ? + false : + System.Data.Linq.SqlClient.SqlMethods.Like(matchExpression, pattern, escapeCharacter.Value); +#endif + } + + [SqlFunction] + [SqlFunction("DB2", "Locate")] + [SqlFunction("MySql", "Locate")] + public static int? CharIndex(string value, string str) + { + if (str == null || value == null) + return null; + + return str.IndexOf(value) + 1; + } + + [SqlFunction] + public static int? ContainsExactly(string value, string str) + { + if (str == null || value == null) + return null; + + return str.ContainsExactly(value); + } + + [SqlFunction] + [SqlFunction("DB2", "Locate")] + [SqlFunction("MySql", "Locate")] + public static int? CharIndex(string value, string str, int? startLocation) + { + if (str == null || value == null || startLocation == null) + return null; + + return str.IndexOf(value, startLocation.Value - 1) + 1; + } + + [SqlFunction] + [SqlFunction("DB2", "Locate")] + [SqlFunction("MySql", "Locate")] + public static int? CharIndex(char? value, string str) + { + if (value == null || str == null) + return null; + + return str.IndexOf(value.Value) + 1; + } + + [SqlFunction] + [SqlFunction("DB2", "Locate")] + [SqlFunction("MySql", "Locate")] + public static int? CharIndex(char? value, string str, int? startLocation) + { + if (str == null || value == null || startLocation == null) + return null; + + return str.IndexOf(value.Value, startLocation.Value - 1) + 1; + } + + [SqlFunction] + public static string Reverse(string str) + { + if (string.IsNullOrEmpty(str)) + return str; + + var chars = str.ToCharArray(); + Array.Reverse(chars); + return new string(chars); + } + + [SqlFunction] + [SqlFunction("SQLite", "LeftStr")] + public static string Left(string str, int? length) + { + return length == null || str == null || str.Length < length? null: str.Substring(1, length.Value); + } + + [SqlFunction] + [SqlFunction("SQLite", "RightStr")] + public static string Right(string str, int? length) + { + return length == null || str == null || str.Length < length? + null : + str.Substring(str.Length - length.Value); + } + + [SqlFunction] + public static string Stuff(string str, int? startLocation, int? length, string value) + { + return str == null || value == null || startLocation == null || length == null ? + null : + str.Remove(startLocation.Value - 1, length.Value).Insert(startLocation.Value - 1, value); + } + + [SqlFunction] + public static string Space(int? length) + { + return length == null ? null : "".PadRight(length.Value); + } + + [SqlFunction(Name = "LPad")] + public static string PadLeft(string str, int? totalWidth, char? paddingChar) + { + return str == null || totalWidth == null || paddingChar == null ? + null : + str.PadLeft(totalWidth.Value, paddingChar.Value); + } + + [SqlFunction(Name = "RPad")] + public static string PadRight(string str, int? totalWidth, char? paddingChar) + { + return str == null || totalWidth == null || paddingChar == null ? + null : + str.PadRight(totalWidth.Value, paddingChar.Value); + } + + [SqlFunction] + [SqlFunction("Sybase", "Str_Replace")] + public static string Replace(string str, string oldValue, string newValue) + { + return str == null || oldValue == null || newValue == null ? + null : + str.Replace(oldValue, newValue); + } + + [SqlFunction] + [SqlFunction("Sybase", "Str_Replace")] + public static string Replace(string str, char? oldValue, char? newValue) + { + return str == null || oldValue == null || newValue == null ? + null : + str.Replace(oldValue.Value, newValue.Value); + } + + [SqlFunction] + public static string Trim(string str) + { + return str == null ? null : str.Trim(); + } + + [SqlFunction("LTrim")] + public static string TrimLeft(string str) + { + return str == null ? null : str.TrimStart(); + } + + [SqlFunction("RTrim")] + public static string TrimRight(string str) + { + return str == null ? null : str.TrimEnd(); + } + + [SqlExpression("DB2", "Strip({0}, B, {1})")] + [SqlFunction] + public static string Trim(string str, char? ch) + { + return str == null || ch == null ? null : str.Trim(ch.Value); + } + + [SqlExpression("DB2", "Strip({0}, L, {1})")] + [SqlFunction ( "LTrim")] + public static string TrimLeft(string str, char? ch) + { + return str == null || ch == null ? null : str.TrimStart(ch.Value); + } + + [SqlExpression("DB2", "Strip({0}, T, {1})")] + [SqlFunction ( "RTrim")] + public static string TrimRight(string str, char? ch) + { + return str == null || ch == null ? null : str.TrimEnd(ch.Value); + } + + [SqlFunction] + [SqlFunction("Access", "LCase")] + public static string Lower(string str) + { + return str == null ? null : str.ToLower(); + } + + [SqlFunction] + [SqlFunction("Access", "UCase")] + public static string Upper(string str) + { + return str == null ? null : str.ToUpper(); + } + + #endregion + + #region Binary Functions + + [SqlFunction( PreferServerSide = true)] + [SqlFunction("Access", "Len", PreferServerSide = true)] + [SqlFunction("Firebird", "Octet_Length", PreferServerSide = true)] + [SqlFunction("MsSql2000", "DataLength", PreferServerSide = true)] + [SqlFunction("MsSql2005", "DataLength", PreferServerSide = true)] + [SqlFunction("MsSql2008", "DataLength", PreferServerSide = true)] + [SqlFunction("MsSql2012", "DataLength", PreferServerSide = true)] + [SqlFunction("SqlCe", "DataLength", PreferServerSide = true)] + [SqlFunction("Sybase", "DataLength", PreferServerSide = true)] + public static int? Length(Binary value) + { + return value == null ? null : (int?)value.Length; + } + + #endregion + + #region DateTime Functions + + [SqlProperty("CURRENT_TIMESTAMP")] + [SqlProperty("Informix", "CURRENT")] + [SqlProperty("Access", "Now")] + public static DateTime GetDate() + { + return DateTime.Now; + } + + [SqlProperty("CURRENT_TIMESTAMP", ServerSideOnly = true)] + [SqlProperty("Informix", "CURRENT", ServerSideOnly = true)] + [SqlProperty("Access", "Now", ServerSideOnly = true)] + [SqlFunction("SqlCe", "GetDate", ServerSideOnly = true)] + [SqlFunction("Sybase", "GetDate", ServerSideOnly = true)] + public static DateTime CurrentTimestamp + { + get { throw new LinqException("The 'CurrentTimestamp' is server side only property."); } + } + + [SqlProperty("CURRENT_TIMESTAMP")] + [SqlProperty("Informix", "CURRENT")] + [SqlProperty("Access", "Now")] + [SqlFunction("SqlCe", "GetDate")] + [SqlFunction("Sybase", "GetDate")] + public static DateTime CurrentTimestamp2 + { + get { return DateTime.Now; } + } + + [SqlFunction] + public static DateTime? ToDate(int? year, int? month, int? day, int? hour, int? minute, int? second, int? millisecond) + { + return year == null || month == null || day == null || hour == null || minute == null || second == null || millisecond == null ? + (DateTime?)null : + new DateTime(year.Value, month.Value, day.Value, hour.Value, minute.Value, second.Value, millisecond.Value); + } + + [SqlFunction] + public static DateTime? ToDate(int? year, int? month, int? day, int? hour, int? minute, int? second) + { + return year == null || month == null || day == null || hour == null || minute == null || second == null ? + (DateTime?)null : + new DateTime(year.Value, month.Value, day.Value, hour.Value, minute.Value, second.Value); + } + + [SqlFunction] + public static DateTime? ToDate(int? year, int? month, int? day) + { + return year == null || month == null || day == null ? + (DateTime?)null : + new DateTime(year.Value, month.Value, day.Value); + } + + [SqlEnum] + public enum DateParts + { + Year = 0, + Quarter = 1, + Month = 2, + DayOfYear = 3, + Day = 4, + Week = 5, + WeekDay = 6, + Hour = 7, + Minute = 8, + Second = 9, + Millisecond = 10, + } + + class DatePartAttribute : SqlExpressionAttribute + { + public DatePartAttribute(string sqlProvider, string expression, int datePartIndex, params int[] argIndices) + : this(sqlProvider, expression, Data.Sql.Precedence.Primary, false, null, datePartIndex, argIndices) + { + } + + public DatePartAttribute(string sqlProvider, string expression, bool isExpression, int datePartIndex, params int[] argIndices) + : this(sqlProvider, expression, Data.Sql.Precedence.Primary, isExpression, null, datePartIndex, argIndices) + { + } + + public DatePartAttribute(string sqlProvider, string expression, bool isExpression, string[] partMapping, int datePartIndex, params int[] argIndices) + : this(sqlProvider, expression, Data.Sql.Precedence.Primary, isExpression, partMapping, datePartIndex, argIndices) + { + } + + public DatePartAttribute(string sqlProvider, string expression, int precedence, bool isExpression, string[] partMapping, int datePartIndex, params int[] argIndices) + : base(sqlProvider, expression, argIndices) + { + _isExpression = isExpression; + _partMapping = partMapping; + _datePartIndex = datePartIndex; + Precedence = precedence; + } + + readonly bool _isExpression; + readonly string[] _partMapping; + readonly int _datePartIndex; + + public override ISqlExpression GetExpression(MemberInfo member, params ISqlExpression[] args) + { + var part = (DateParts)((SqlValue)args[_datePartIndex]).Value; + var pstr = _partMapping != null ? _partMapping[(int)part] : part.ToString(); + var str = string.Format(Expression, pstr ?? part.ToString()); + var type = TypeHelper.GetMemberType(member); + + + return _isExpression ? + new SqlExpression(type, str, Precedence, ConvertArgs(member, args)) : + (ISqlExpression)new SqlFunction (type, str, ConvertArgs(member, args)); + } + } + + [CLSCompliant(false)] + [SqlFunction] + [DatePart("Oracle", "Add{0}", false, 0, 2, 1)] + [DatePart("DB2", "{{1}} + {0}", Precedence.Additive, true, new[] { "{0} Year", "({0} * 3) Month", "{0} Month", "{0} Day", "{0} Day", "({0} * 7) Day", "{0} Day", "{0} Hour", "{0} Minute", "{0} Second", "({0} * 1000) Microsecond" }, 0, 1, 2)] + [DatePart("Informix", "{{1}} + Interval({0}", Precedence.Additive, true, new[] { "{0}) Year to Year", "{0}) Month to Month * 3", "{0}) Month to Month", "{0}) Day to Day", "{0}) Day to Day", "{0}) Day to Day * 7", "{0}) Day to Day", "{0}) Hour to Hour", "{0}) Minute to Minute", "{0}) Second to Second", null }, 0, 1, 2)] + [DatePart("PostgreSQL", "{{1}} + Interval '{{0}} {0}", Precedence.Additive, true, new[] { "Year'", "Month' * 3", "Month'", "Day'", "Day'", "Day' * 7", "Day'", "Hour'", "Minute'", "Second'", "Millisecond'" }, 0, 1, 2)] + [DatePart("MySql", "Date_Add({{1}}, Interval {{0}} {0})", true, new[] { null, null, null, "Day", null, null, "Day", null, null, null, null }, 0, 1, 2)] + [DatePart("SQLite", "DateTime({{1}}, '{{0}} {0}')", true, new[] { null, null, null, "Day", null, null, "Day", null, null, null, null }, 0, 1, 2)] + [DatePart("Access", "DateAdd({0}, {{0}}, {{1}})", true, new[] { "'yyyy'", "'q'", "'m'", "'y'", "'d'", "'ww'", "'w'", "'h'", "'n'", "'s'", null }, 0, 1, 2)] + public static DateTime? DateAdd(DateParts part, double? number, DateTime? date) + { + if (number == null || date == null) + return null; + + switch (part) + { + case DateParts.Year : return date.Value.AddYears ((int)number); + case DateParts.Quarter : return date.Value.AddMonths ((int)number * 3); + case DateParts.Month : return date.Value.AddMonths ((int)number); + case DateParts.DayOfYear : return date.Value.AddDays (number.Value); + case DateParts.Day : return date.Value.AddDays (number.Value); + case DateParts.Week : return date.Value.AddDays (number.Value * 7); + case DateParts.WeekDay : return date.Value.AddDays (number.Value); + case DateParts.Hour : return date.Value.AddHours (number.Value); + case DateParts.Minute : return date.Value.AddMinutes (number.Value); + case DateParts.Second : return date.Value.AddSeconds (number.Value); + case DateParts.Millisecond : return date.Value.AddMilliseconds(number.Value); + } + + throw new InvalidOperationException(); + } + + [CLSCompliant(false)] + [SqlFunction] + [DatePart("DB2", "{0}", false, new[] { null, null, null, null, null, null, "DayOfWeek", null, null, null, null }, 0, 1)] + [DatePart("Informix", "{0}", 0, 1)] + [DatePart("MySql", "Extract({0} from {{0}})", true, 0, 1)] + [DatePart("PostgreSQL", "Extract({0} from {{0}})", true, new[] { null, null, null, "DOY", null, null, "DOW", null, null, null, null }, 0, 1)] + [DatePart("Firebird", "Extract({0} from {{0}})", true, new[] { null, null, null, "YearDay", null, null, null, null, null, null, null }, 0, 1)] + [DatePart("Oracle", "To_Number(To_Char({{0}}, {0}))", true, new[] { "'YYYY'", "'Q'", "'MM'", "'DDD'", "'DD'", "'WW'", "'D'", "'HH24'", "'MI'", "'SS'", "'FF'" }, 0, 1)] + [DatePart("SQLite", "Cast(StrFTime({0}, {{0}}) as int)", true, new[] { "'%Y'", null, "'%m'", "'%j'", "'%d'", "'%W'", "'%w'", "'%H'", "'%M'", "'%S'", "'%f'" }, 0, 1)] + [DatePart("Access", "DatePart({0}, {{0}})", true, new[] { "'yyyy'", "'q'", "'m'", "'y'", "'d'", "'ww'", "'w'", "'h'", "'n'", "'s'", null }, 0, 1)] + public static int? DatePart(DateParts part, DateTime? date) + { + if (date == null) + return null; + + switch (part) + { + case DateParts.Year : return date.Value.Year; + case DateParts.Quarter : return (date.Value.Month - 1) / 3 + 1; + case DateParts.Month : return date.Value.Month; + case DateParts.DayOfYear : return date.Value.DayOfYear; + case DateParts.Day : return date.Value.Day; + case DateParts.Week : return CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date.Value, CalendarWeekRule.FirstDay, DayOfWeek.Sunday); + case DateParts.WeekDay : return ((int)date.Value.DayOfWeek + 1 + DateFirst + 6) % 7 + 1; + case DateParts.Hour : return date.Value.Hour; + case DateParts.Minute : return date.Value.Minute; + case DateParts.Second : return date.Value.Second; + case DateParts.Millisecond : return date.Value.Millisecond; + } + + throw new InvalidOperationException(); + } + + [CLSCompliant(false)] + [SqlFunction] + [SqlFunction("MySql", "TIMESTAMPDIFF")] + public static int? DateDiff(DateParts part, DateTime? startDate, DateTime? endDate) + { + if (startDate == null || endDate == null) + return null; + + switch (part) + { + case DateParts.Day : return (int)(endDate - startDate).Value.TotalDays; + case DateParts.Hour : return (int)(endDate - startDate).Value.TotalHours; + case DateParts.Minute : return (int)(endDate - startDate).Value.TotalMinutes; + case DateParts.Second : return (int)(endDate - startDate).Value.TotalSeconds; + case DateParts.Millisecond : return (int)(endDate - startDate).Value.TotalMilliseconds; + } + + throw new InvalidOperationException(); + } + + [SqlProperty("@@DATEFIRST")] + public static int DateFirst + { + get { return 7; } + } + + [SqlFunction] + public static DateTime? MakeDateTime(int? year, int? month, int? day) + { + return year == null || month == null || day == null ? + (DateTime?)null : + new DateTime(year.Value, month.Value, day.Value); + } + + [SqlFunction] + public static DateTime? MakeDateTime(int? year, int? month, int? day, int? hour, int? minute, int? second) + { + return year == null || month == null || day == null || hour == null || minute == null || second == null ? + (DateTime?)null : + new DateTime(year.Value, month.Value, day.Value, hour.Value, minute.Value, second.Value); + } + + #endregion + + #region Math Functions + + [SqlFunction] public static Decimal? Abs (Decimal? value) { return value == null ? null : (Decimal?)Math.Abs (value.Value); } + [SqlFunction] public static Double? Abs (Double? value) { return value == null ? null : (Double?) Math.Abs (value.Value); } + [SqlFunction] public static Int16? Abs (Int16? value) { return value == null ? null : (Int16?) Math.Abs (value.Value); } + [SqlFunction] public static Int32? Abs (Int32? value) { return value == null ? null : (Int32?) Math.Abs (value.Value); } + [SqlFunction] public static Int64? Abs (Int64? value) { return value == null ? null : (Int64?) Math.Abs (value.Value); } + [CLSCompliant(false)] + [SqlFunction] public static SByte? Abs (SByte? value) { return value == null ? null : (SByte?) Math.Abs (value.Value); } + [SqlFunction] public static Single? Abs (Single? value) { return value == null ? null : (Single?) Math.Abs (value.Value); } + + [SqlFunction] public static Double? Acos (Double? value) { return value == null ? null : (Double?) Math.Acos (value.Value); } + [SqlFunction] public static Double? Asin (Double? value) { return value == null ? null : (Double?) Math.Asin (value.Value); } + + [SqlFunction("Access", "Atn")] + [SqlFunction] public static Double? Atan (Double? value) { return value == null ? null : (Double?) Math.Atan (value.Value); } + + [CLSCompliant(false)] + [SqlFunction( "MsSql2012", "Atn2")] + [SqlFunction( "MsSql2008", "Atn2")] + [SqlFunction( "MsSql2000", "Atn2")] + [SqlFunction( "MsSql2005", "Atn2")] + [SqlFunction( "DB2", "Atan2", 1, 0)] + [SqlFunction( "SqlCe", "Atn2")] + [SqlFunction( "Sybase", "Atn2")] + [SqlFunction] public static Double? Atan2 (Double? x, Double? y) { return x == null || y == null? null : (Double?)Math.Atan2(x.Value, y.Value); } + + [SqlFunction("Informix", "Ceil")] + [SqlFunction("Oracle", "Ceil")] + [SqlFunction] public static Decimal? Ceiling(Decimal? value) { return value == null ? null : (Decimal?)decimal.Ceiling(value.Value); } + [SqlFunction("Informix", "Ceil")] + [SqlFunction("Oracle", "Ceil")] + [SqlFunction] public static Double? Ceiling(Double? value) { return value == null ? null : (Double?)Math.Ceiling(value.Value); } + + [SqlFunction] public static Double? Cos (Double? value) { return value == null ? null : (Double?)Math.Cos (value.Value); } + + [SqlFunction] public static Double? Cosh (Double? value) { return value == null ? null : (Double?)Math.Cosh (value.Value); } + + [SqlFunction] public static Double? Cot (Double? value) { return value == null ? null : (Double?)Math.Cos(value.Value) / Math.Sin(value.Value); } + + [SqlFunction] public static Decimal? Degrees(Decimal? value) { return value == null ? null : (Decimal?)(value.Value * 180m / (Decimal)Math.PI); } + [SqlFunction] public static Double? Degrees(Double? value) { return value == null ? null : (Double?) (value * 180 / Math.PI); } + [SqlFunction] public static Int16? Degrees(Int16? value) { return value == null ? null : (Int16?) (value * 180 / Math.PI); } + [SqlFunction] public static Int32? Degrees(Int32? value) { return value == null ? null : (Int32?) (value * 180 / Math.PI); } + [SqlFunction] public static Int64? Degrees(Int64? value) { return value == null ? null : (Int64?) (value * 180 / Math.PI); } + [CLSCompliant(false)] + [SqlFunction] public static SByte? Degrees(SByte? value) { return value == null ? null : (SByte?) (value * 180 / Math.PI); } + [SqlFunction] public static Single? Degrees(Single? value) { return value == null ? null : (Single?) (value * 180 / Math.PI); } + + [SqlFunction] public static Double? Exp (Double? value) { return value == null ? null : (Double?)Math.Exp (value.Value); } + + [SqlFunction("Access", "Int")] + [SqlFunction] public static Decimal? Floor (Decimal? value) { return value == null ? null : (Decimal?)decimal.Floor(value.Value); } + [SqlFunction("Access", "Int")] + [SqlFunction] public static Double? Floor (Double? value) { return value == null ? null : (Double?) Math. Floor(value.Value); } + + [SqlFunction("Informix", "LogN")] + [SqlFunction("Oracle", "Ln")] + [SqlFunction("Firebird", "Ln")] + [SqlFunction("PostgreSQL", "Ln")] + [SqlFunction] public static Decimal? Log (Decimal? value) { return value == null ? null : (Decimal?)Math.Log ((Double)value.Value); } + [SqlFunction("Informix", "LogN")] + [SqlFunction("Oracle", "Ln")] + [SqlFunction("Firebird", "Ln")] + [SqlFunction("PostgreSQL", "Ln")] + [SqlFunction] public static Double? Log (Double? value) { return value == null ? null : (Double?) Math.Log (value.Value); } + + [SqlFunction("PostgreSQL", "Log")] + [SqlFunction] public static Double? Log10 (Double? value) { return value == null ? null : (Double?) Math.Log10 (value.Value); } + + [SqlFunction] + public static double? Log(double? newBase, double? value) + { + return value == null || newBase == null ? null : (Double?)Math.Log(value.Value, newBase.Value); + } + + [SqlFunction] + public static decimal? Log(decimal? newBase, decimal? value) + { + return value == null || newBase == null ? null : (decimal?)Math.Log((double)value.Value, (double)newBase.Value); + } + + [SqlExpression("Access", "{0} ^ {1}", Precedence = Precedence.Multiplicative)] + [SqlFunction] + public static Double? Power(Double? x, Double? y) + { + return x == null || y == null ? null : (Double?)Math.Pow(x.Value, y.Value); + } + + [SqlFunction] + public static Decimal? RoundToEven(Decimal? value) + { +#if SILVERLIGHT + return value == null ? null : (Decimal?)Math.Round(value.Value); +#else + return value == null ? null : (Decimal?)Math.Round(value.Value, MidpointRounding.ToEven); +#endif + } + + [SqlFunction] + public static Double? RoundToEven(Double? value) + { +#if SILVERLIGHT + return value == null ? null : (Double?) Math.Round(value.Value); +#else + return value == null ? null : (Double?) Math.Round(value.Value, MidpointRounding.ToEven); +#endif + } + + [SqlFunction] public static Decimal? Round(Decimal? value) { return Round(value, 0); } + [SqlFunction] public static Double? Round(Double? value) { return Round(value, 0); } + + [SqlFunction] + public static Decimal? Round(Decimal? value, int? precision) + { +#if SILVERLIGHT + throw new InvalidOperationException(); +#else + return value == null || precision == null? null : (Decimal?)Math.Round(value.Value, precision.Value, MidpointRounding.AwayFromZero); +#endif + } + + [SqlFunction] + public static Double? Round(Double? value, int? precision) + { +#if SILVERLIGHT + throw new InvalidOperationException(); +#else + return value == null || precision == null? null : (Double?) Math.Round(value.Value, precision.Value, MidpointRounding.AwayFromZero); +#endif + } + + [SqlFunction] + public static Decimal? RoundToEven(Decimal? value, int? precision) + { +#if SILVERLIGHT + return value == null || precision == null? null : (Decimal?)Math.Round(value.Value, precision.Value); +#else + return value == null || precision == null? null : (Decimal?)Math.Round(value.Value, precision.Value, MidpointRounding.ToEven); +#endif + } + + [SqlFunction] + public static Double? RoundToEven(Double? value, int? precision) + { +#if SILVERLIGHT + return value == null || precision == null? null : (Double?) Math.Round(value.Value, precision.Value); +#else + return value == null || precision == null? null : (Double?) Math.Round(value.Value, precision.Value, MidpointRounding.ToEven); +#endif + } + + [SqlFunction("Access", "Sgn"), SqlFunction] public static int? Sign(Decimal? value) { return value == null ? null : (int?)Math.Sign(value.Value); } + [SqlFunction("Access", "Sgn"), SqlFunction] public static int? Sign(Double? value) { return value == null ? null : (int?)Math.Sign(value.Value); } + [SqlFunction("Access", "Sgn"), SqlFunction] public static int? Sign(Int16? value) { return value == null ? null : (int?)Math.Sign(value.Value); } + [SqlFunction("Access", "Sgn"), SqlFunction] public static int? Sign(Int32? value) { return value == null ? null : (int?)Math.Sign(value.Value); } + [SqlFunction("Access", "Sgn"), SqlFunction] public static int? Sign(Int64? value) { return value == null ? null : (int?)Math.Sign(value.Value); } + [CLSCompliant(false)] + [SqlFunction("Access", "Sgn"), SqlFunction] public static int? Sign(SByte? value) { return value == null ? null : (int?)Math.Sign(value.Value); } + [SqlFunction("Access", "Sgn"), SqlFunction] public static int? Sign(Single? value) { return value == null ? null : (int?)Math.Sign(value.Value); } + + [SqlFunction] public static Double? Sin (Double? value) { return value == null ? null : (Double?)Math.Sin (value.Value); } + [SqlFunction] public static Double? Sinh (Double? value) { return value == null ? null : (Double?)Math.Sinh(value.Value); } + [SqlFunction("Access", "Sqr")] + [SqlFunction] public static Double? Sqrt (Double? value) { return value == null ? null : (Double?)Math.Sqrt(value.Value); } + [SqlFunction] public static Double? Tan (Double? value) { return value == null ? null : (Double?)Math.Tan (value.Value); } + [SqlFunction] public static Double? Tanh (Double? value) { return value == null ? null : (Double?)Math.Tanh(value.Value); } + + [SqlExpression("MsSql2012", "Round({0}, 0, 1)")] + [SqlExpression("MsSql2008", "Round({0}, 0, 1)")] + [SqlExpression("MsSql2005", "Round({0}, 0, 1)")] + [SqlExpression("MsSql2000", "Round({0}, 0, 1)")] + [SqlExpression("DB2", "Truncate({0}, 0)")] + [SqlExpression("Informix", "Trunc({0}, 0)")] + [SqlExpression("Oracle", "Trunc({0}, 0)")] + [SqlExpression("Firebird", "Trunc({0}, 0)")] + [SqlExpression("PostgreSQL", "Trunc({0}, 0)")] + [SqlExpression("MySql", "Truncate({0}, 0)")] + [SqlExpression("SqlCe", "Round({0}, 0, 1)")] + [SqlFunction] + public static Decimal? Truncate(Decimal? value) + { +#if SILVERLIGHT + throw new InvalidOperationException(); +#else + return value == null ? null : (Decimal?)decimal.Truncate(value.Value); +#endif + } + + [SqlExpression("MsSql2012", "Round({0}, 0, 1)")] + [SqlExpression("MsSql2008", "Round({0}, 0, 1)")] + [SqlExpression("MsSql2005", "Round({0}, 0, 1)")] + [SqlExpression("MsSql2000", "Round({0}, 0, 1)")] + [SqlExpression("DB2", "Truncate({0}, 0)")] + [SqlExpression("Informix", "Trunc({0}, 0)")] + [SqlExpression("Oracle", "Trunc({0}, 0)")] + [SqlExpression("Firebird", "Trunc({0}, 0)")] + [SqlExpression("PostgreSQL", "Trunc({0}, 0)")] + [SqlExpression("MySql", "Truncate({0}, 0)")] + [SqlExpression("SqlCe", "Round({0}, 0, 1)")] + [SqlFunction] + public static Double? Truncate(Double? value) + { +#if SILVERLIGHT + throw new InvalidOperationException(); +#else + return value == null ? null : (Double?) Math.Truncate(value.Value); +#endif + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/SqlEnumAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/SqlEnumAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.Data.Linq +{ + [AttributeUsageAttribute(AttributeTargets.Enum, AllowMultiple = false, Inherited = false)] + public sealed class SqlEnumAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/SqlExpressionAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/SqlExpressionAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,55 @@ +using System; +using System.Reflection; + +namespace BLToolkit.Data.Linq +{ + using Data.Sql; + using Reflection; + + [SerializableAttribute] + [AttributeUsageAttribute(AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = true, Inherited = false)] + public class SqlExpressionAttribute : SqlFunctionAttribute + { + public SqlExpressionAttribute(string expression) + : base(expression) + { + Precedence = Data.Sql.Precedence.Primary; + } + + public SqlExpressionAttribute(string expression, params int[] argIndices) + : base(expression, argIndices) + { + Precedence = Data.Sql.Precedence.Primary; + } + + public SqlExpressionAttribute(string sqlProvider, string expression) + : base(sqlProvider, expression) + { + Precedence = Data.Sql.Precedence.Primary; + } + + public SqlExpressionAttribute(string sqlProvider, string expression, params int[] argIndices) + : base(sqlProvider, expression, argIndices) + { + Precedence = Data.Sql.Precedence.Primary; + } + + protected new string Name + { + get { return base.Name; } + } + + public string Expression + { + get { return base.Name; } + set { base.Name = value; } + } + + public int Precedence { get; set; } + + public override ISqlExpression GetExpression(MemberInfo member, params ISqlExpression[] args) + { + return new SqlExpression(TypeHelper.GetMemberType(member), Expression ?? member.Name, Precedence, ConvertArgs(member, args)); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/SqlFunctionAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/SqlFunctionAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,79 @@ +using System; +using System.Linq; +using System.Reflection; + +namespace BLToolkit.Data.Linq +{ + using Data.Sql; + using Reflection; + + [SerializableAttribute] + [AttributeUsageAttribute(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true, Inherited = false)] + public class SqlFunctionAttribute : Attribute + { + public SqlFunctionAttribute() + { + } + + public SqlFunctionAttribute(string name) + { + Name = name; + } + + public SqlFunctionAttribute(string name, params int[] argIndices) + { + Name = name; + ArgIndices = argIndices; + } + + public SqlFunctionAttribute(string sqlProvider, string name) + { + SqlProvider = sqlProvider; + Name = name; + } + + public SqlFunctionAttribute(string sqlProvider, string name, params int[] argIndices) + { + SqlProvider = sqlProvider; + Name = name; + ArgIndices = argIndices; + } + + public string SqlProvider { get; set; } + public string Name { get; set; } + public bool ServerSideOnly { get; set; } + public bool PreferServerSide { get; set; } + public int[] ArgIndices { get; set; } + + protected ISqlExpression[] ConvertArgs(MemberInfo member, ISqlExpression[] args) + { + if (member is MethodInfo) + { + var method = (MethodInfo)member; + + if (method.DeclaringType.IsGenericType) + args = args.Concat(method.DeclaringType.GetGenericArguments().Select(t => (ISqlExpression)SqlDataType.GetDataType(t))).ToArray(); + + if (method.IsGenericMethod) + args = args.Concat(method.GetGenericArguments().Select(t => (ISqlExpression)SqlDataType.GetDataType(t))).ToArray(); + } + + if (ArgIndices != null) + { + var idxs = new ISqlExpression[ArgIndices.Length]; + + for (var i = 0; i < ArgIndices.Length; i++) + idxs[i] = args[ArgIndices[i]]; + + return idxs; + } + + return args; + } + + public virtual ISqlExpression GetExpression(MemberInfo member, params ISqlExpression[] args) + { + return new SqlFunction(TypeHelper.GetMemberType(member), Name ?? member.Name, ConvertArgs(member, args)); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/SqlPropertyAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/SqlPropertyAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,32 @@ +using System; +using System.Reflection; +using BLToolkit.Reflection; + +namespace BLToolkit.Data.Linq +{ + using Data.Sql; + + [SerializableAttribute] + [AttributeUsageAttribute(AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = true, Inherited = false)] + public class SqlPropertyAttribute : SqlFunctionAttribute + { + public SqlPropertyAttribute() + { + } + + public SqlPropertyAttribute(string name) + : base(name) + { + } + + public SqlPropertyAttribute(string sqlProvider, string name) + : base(sqlProvider, name) + { + } + + public override ISqlExpression GetExpression(MemberInfo member, params ISqlExpression[] args) + { + return new SqlExpression(TypeHelper.GetMemberType(member), Name ?? member.Name, Precedence.Primary); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/TableExpressionAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/TableExpressionAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +using BLToolkit.Data.Sql; + +namespace BLToolkit.Data.Linq +{ + [SerializableAttribute] + [AttributeUsageAttribute(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] + public class TableExpressionAttribute : TableFunctionAttribute + { + public TableExpressionAttribute(string expression) + : base(expression) + { + } + + public TableExpressionAttribute(string expression, params int[] argIndices) + : base(expression, argIndices) + { + } + + public TableExpressionAttribute(string sqlProvider, string expression) + : base(sqlProvider, expression) + { + } + + public TableExpressionAttribute(string sqlProvider, string expression, params int[] argIndices) + : base(sqlProvider, expression, argIndices) + { + } + + protected new string Name + { + get { return base.Name; } + } + + public string Expression + { + get { return base.Name; } + set { base.Name = value; } + } + + public override void SetTable(SqlTable table, MemberInfo member, IEnumerable arguments, IEnumerable sqlArgs) + { + table.SqlTableType = SqlTableType.Expression; + table.Name = Expression ?? member.Name; + table.TableArguments = ConvertArgs(member, sqlArgs.ToArray()); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/TableFunctionAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/TableFunctionAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +using BLToolkit.Data.Sql; + +namespace BLToolkit.Data.Linq +{ + [SerializableAttribute] + [AttributeUsageAttribute(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] + public class TableFunctionAttribute : Attribute + { + public TableFunctionAttribute() + { + } + + public TableFunctionAttribute(string name) + { + Name = name; + } + + public TableFunctionAttribute(string name, params int[] argIndices) + { + Name = name; + ArgIndices = argIndices; + } + + public TableFunctionAttribute(string sqlProvider, string name) + { + SqlProvider = sqlProvider; + Name = name; + } + + public TableFunctionAttribute(string sqlProvider, string name, params int[] argIndices) + { + SqlProvider = sqlProvider; + Name = name; + ArgIndices = argIndices; + } + + public string SqlProvider { get; set; } + public string Name { get; set; } + public int[] ArgIndices { get; set; } + + protected ISqlExpression[] ConvertArgs(MemberInfo member, ISqlExpression[] args) + { + if (member is MethodInfo) + { + var method = (MethodInfo)member; + + if (method.DeclaringType.IsGenericType) + args = args.Concat(method.DeclaringType.GetGenericArguments().Select(t => (ISqlExpression)SqlDataType.GetDataType(t))).ToArray(); + + if (method.IsGenericMethod) + args = args.Concat(method.GetGenericArguments().Select(t => (ISqlExpression)SqlDataType.GetDataType(t))).ToArray(); + } + + if (ArgIndices != null) + { + var idxs = new ISqlExpression[ArgIndices.Length]; + + for (var i = 0; i < ArgIndices.Length; i++) + idxs[i] = args[ArgIndices[i]]; + + return idxs; + } + + return args; + } + + public virtual void SetTable(SqlTable table, MemberInfo member, IEnumerable arguments, IEnumerable sqlArgs) + { + table.SqlTableType = SqlTableType.Function; + table.Name = Name ?? member.Name; + table.PhysicalName = Name ?? member.Name; + table.TableArguments = ConvertArgs(member, sqlArgs.ToArray()); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Linq/TableT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Linq/TableT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,60 @@ +using System; +using System.Linq.Expressions; + +namespace BLToolkit.Data.Linq +{ + public class Table : ExpressionQuery, ITable + { + public Table(IDataContextInfo dataContextInfo, Expression expression) + { + Init(dataContextInfo, expression); + } + + public Table(IDataContextInfo dataContextInfo) + { + Init(dataContextInfo, null); + } + +#if !SILVERLIGHT + + public Table() + { + Init(null, null); + } + + public Table(Expression expression) + { + Init(null, expression); + } + +#endif + + public Table(IDataContext dataContext) + { + Init(dataContext == null ? null : new DataContextInfo(dataContext), null); + } + + public Table(IDataContext dataContext, Expression expression) + { + Init(dataContext == null ? null : new DataContextInfo(dataContext), expression); + } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return "Table(" + typeof (T).Name + ")"; + } + +#endif + + #endregion + + public object Select(object p) + { + throw new NotImplementedException(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/OperationExceptionEventArgs.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/OperationExceptionEventArgs.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +namespace BLToolkit.Data +{ + public delegate void OperationExceptionEventHandler(object sender, OperationExceptionEventArgs ea); + + public class OperationExceptionEventArgs : OperationTypeEventArgs + { + private readonly DataException _exception; + public DataException Exception + { + get { return _exception; } + } + + public OperationExceptionEventArgs(OperationType operation, DataException exception) + : base (operation) + { + _exception = exception; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/OperationType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/OperationType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; + +namespace BLToolkit.Data +{ + /// + /// Type of an operation being performed. + /// + public enum OperationType + { + OpenConnection, + CloseConnection, + BeginTransaction, + CommitTransaction, + RollbackTransaction, + DisposeTransaction, + DeriveParameters, + PrepareCommand, + ExecuteNonQuery, + [Obsolete] + ExecuteScalar, + ExecuteReader, + Fill, + Update, + Read + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/OperationTypeEventArgs.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/OperationTypeEventArgs.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; + +namespace BLToolkit.Data +{ + public delegate void OperationTypeEventHandler(object sender, OperationTypeEventArgs ea); + + public class OperationTypeEventArgs : EventArgs + { + private readonly OperationType _operation; + public OperationType Operation + { + get { return _operation; } + } + + public OperationTypeEventArgs(OperationType operation) + { + _operation = operation; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/ScalarSourceType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/ScalarSourceType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,32 @@ +namespace BLToolkit.Data +{ + /// + /// Defines the method how a scalar value is returned from the server. + /// + public enum ScalarSourceType + { + /// + /// A call to . + /// then .. + /// + DataReader, + + /// + /// A call to .. + /// An output parameter is used. + /// + OutputParameter, + + /// + /// A call to .. + /// The return parameter is used. + /// + ReturnValue, + + /// + /// Same as .. + /// Useful for an abstract . + /// + AffectedRows, + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/ChildContainer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/ChildContainer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; + +namespace BLToolkit.Data.Sql +{ + public class ChildContainer : Dictionary, IDictionary + where TC : IChild + where TP : class + { + internal ChildContainer() + { + } + + internal ChildContainer(TP parent) + { + _parent = parent; + } + + readonly TP _parent; + public TP Parent { get { return _parent; } } + + public void Add(TC item) + { + Add(item.Name, item); + } + + public new void Add(string key, TC value) + { + if (value.Parent != null) throw new InvalidOperationException("Invalid parent."); + value.Parent = _parent; + + base.Add(key, value); + } + + public void AddRange(IEnumerable collection) + { + foreach (var item in collection) + Add(item); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/Extensions.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/Extensions.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,27 @@ +using System; + +namespace BLToolkit.Data.Sql +{ + using FJoin = SqlQuery.FromClause.Join; + + public static class Extensions + { + public static FJoin InnerJoin (this ISqlTableSource table, params FJoin[] joins) { return SqlQuery.InnerJoin (table, joins); } + public static FJoin InnerJoin (this ISqlTableSource table, string alias, params FJoin[] joins) { return SqlQuery.InnerJoin (table, alias, joins); } + public static FJoin LeftJoin (this ISqlTableSource table, params FJoin[] joins) { return SqlQuery.LeftJoin (table, joins); } + public static FJoin LeftJoin (this ISqlTableSource table, string alias, params FJoin[] joins) { return SqlQuery.LeftJoin (table, alias, joins); } + public static FJoin Join (this ISqlTableSource table, params FJoin[] joins) { return SqlQuery.Join (table, joins); } + public static FJoin Join (this ISqlTableSource table, string alias, params FJoin[] joins) { return SqlQuery.Join (table, alias, joins); } + public static FJoin CrossApply (this ISqlTableSource table, params FJoin[] joins) { return SqlQuery.CrossApply (table, joins); } + public static FJoin CrossApply (this ISqlTableSource table, string alias, params FJoin[] joins) { return SqlQuery.CrossApply (table, alias, joins); } + public static FJoin OuterApply (this ISqlTableSource table, params FJoin[] joins) { return SqlQuery.OuterApply (table, joins); } + public static FJoin OuterApply (this ISqlTableSource table, string alias, params FJoin[] joins) { return SqlQuery.OuterApply (table, alias, joins); } + + public static FJoin WeakInnerJoin(this ISqlTableSource table, params FJoin[] joins) { return SqlQuery.WeakInnerJoin(table, joins); } + public static FJoin WeakInnerJoin(this ISqlTableSource table, string alias, params FJoin[] joins) { return SqlQuery.WeakInnerJoin(table, alias, joins); } + public static FJoin WeakLeftJoin (this ISqlTableSource table, params FJoin[] joins) { return SqlQuery.WeakLeftJoin (table, joins); } + public static FJoin WeakLeftJoin (this ISqlTableSource table, string alias, params FJoin[] joins) { return SqlQuery.WeakLeftJoin (table, alias, joins); } + public static FJoin WeakJoin (this ISqlTableSource table, params FJoin[] joins) { return SqlQuery.WeakJoin (table, joins); } + public static FJoin WeakJoin (this ISqlTableSource table, string alias, params FJoin[] joins) { return SqlQuery.WeakJoin (table, alias, joins); } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/IChild.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/IChild.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +using System; + +namespace BLToolkit.Data.Sql +{ + public interface IChild + { + string Name { get; } + T Parent { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/ICloneableElement.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/ICloneableElement.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; + +namespace BLToolkit.Data.Sql +{ + public interface ICloneableElement + { + ICloneableElement Clone(Dictionary objectTree, Predicate doClone); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/IQueryElement.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/IQueryElement.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BLToolkit.Data.Sql +{ + public interface IQueryElement //: ICloneableElement + { + QueryElementType ElementType { get; } + StringBuilder ToString (StringBuilder sb, Dictionary dic); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/ISqlExpression.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/ISqlExpression.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; + +namespace BLToolkit.Data.Sql +{ + public interface ISqlExpression : IQueryElement, IEquatable, ISqlExpressionWalkable, ICloneableElement + { + bool CanBeNull(); + bool Equals (ISqlExpression other, Func comparer); + + int Precedence { get; } + Type SystemType { get; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/ISqlExpressionWalkable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/ISqlExpressionWalkable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +using System; + +namespace BLToolkit.Data.Sql +{ + public interface ISqlExpressionWalkable + { + //[Obsolete] + ISqlExpression Walk(bool skipColumns, Func func); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/ISqlPredicate.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/ISqlPredicate.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +using System; + +namespace BLToolkit.Data.Sql +{ + public interface ISqlPredicate : IQueryElement, ISqlExpressionWalkable, ICloneableElement + { + bool CanBeNull(); + int Precedence { get; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/ISqlTableSource.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/ISqlTableSource.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace BLToolkit.Data.Sql +{ + public interface ISqlTableSource : ISqlExpression + { + SqlField All { get; } + int SourceID { get; } + SqlTableType SqlTableType { get; } + IList GetKeys(bool allIfEmpty); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/IValueContainer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/IValueContainer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.Data.Sql +{ + public interface IValueContainer + { + object Value { get; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/Join.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/Join.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BLToolkit.Data.Sql +{ + using Reflection.Extension; + + public class Join : IQueryElement, ICloneableElement + { + public Join() + { + } + + public Join(string tableName, params JoinOn[] joinOns) + : this(tableName, null, joinOns) + { + } + + public Join(string tableName, string alias, params JoinOn[] joinOns) + { + _tableName = tableName; + _alias = alias; + _joinOns.AddRange(joinOns); + } + + public Join(string tableName, string alias, IEnumerable joinOns) + { + _tableName = tableName; + _alias = alias; + _joinOns.AddRange(joinOns); + } + + public Join(AttributeExtension ext) + { + _tableName = (string)ext["TableName"]; + _alias = (string)ext["Alias"]; + + var col = ext.Attributes["On"]; + + foreach (AttributeExtension ae in col) + _joinOns.Add(new JoinOn(ae)); + } + + private string _tableName; + public string TableName { get { return _tableName; } set { _tableName = value; } } + + private string _alias; + public string Alias { get { return _alias; } set { _alias = value; } } + + readonly List _joinOns = new List(); + public List JoinOns + { + get { return _joinOns; } + } + + public Join Clone() + { + var join = new Join(_tableName, _alias); + + foreach (var on in JoinOns) + join.JoinOns.Add(new JoinOn(on.Field, on.OtherField, on.Expression)); + + return join; + } + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.Join; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + return sb; + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new Join( + _tableName, + _alias, + _joinOns.ConvertAll(j => (JoinOn)j.Clone(objectTree, doClone)))); + + return clone; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/JoinOn.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/JoinOn.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BLToolkit.Data.Sql +{ + using Reflection.Extension; + + public class JoinOn : IQueryElement, ICloneableElement + { + public JoinOn() + { + } + + public JoinOn(string field, string otherField) + { + _field = field; + _otherField = otherField; + } + + public JoinOn(string field, string otherField, string expression) + { + _field = field; + _otherField = otherField; + _expression = expression; + } + + public JoinOn(AttributeExtension ext) + { + _field = (string)ext["Field"]; + _otherField = (string)ext["OtherField"]; + _expression = (string)ext["Expression"]; + } + + private string _field; + public string Field { get { return _field; } set { _field = value; } } + + private string _otherField; + public string OtherField { get { return _otherField; } set { _otherField = value; } } + + private string _expression; + public string Expression { get { return _expression; } set { _expression = value; } } + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.JoinOn; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + return sb; + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new JoinOn(_field, _otherField, _expression)); + + return clone; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/Precedence.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/Precedence.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; + +namespace BLToolkit.Data.Sql +{ + public class Precedence + { + public const int Primary = 100; // (x) x.y f(x) a[x] x++ x-- new typeof sizeof checked unchecked + public const int Unary = 90; // + - ! ++x --x (T)x + public const int Multiplicative = 80; // * / % + public const int Subtraction = 70; // - + public const int Additive = 60; // + + public const int Comparison = 50; // ANY ALL SOME EXISTS, IS [NOT], IN, BETWEEN, LIKE, < > <= >=, == != + public const int Bitwise = 40; // ^ + public const int LogicalNegation = 30; // NOT + public const int LogicalConjunction = 20; // AND + public const int LogicalDisjunction = 10; // OR + public const int Unknown = 0; + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/QueryElementType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/QueryElementType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +using System; + +namespace BLToolkit.Data.Sql +{ + public enum QueryElementType + { + SqlField, + SqlFunction, + SqlParameter, + SqlExpression, + SqlBinaryExpression, + SqlValue, + SqlDataType, + SqlTable, + Join, + JoinOn, + + ExprPredicate, + NotExprPredicate, + ExprExprPredicate, + LikePredicate, + BetweenPredicate, + IsNullPredicate, + InSubQueryPredicate, + InListPredicate, + FuncLikePredicate, + + SqlQuery, + Column, + SearchCondition, + Condition, + TableSource, + JoinedTable, + + SelectClause, + InsertClause, + UpdateClause, + SetExpression, + DeleteClause, + FromClause, + WhereClause, + GroupByClause, + OrderByClause, + OrderByItem, + Union, + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/QueryType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/QueryType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; + +namespace BLToolkit.Data.Sql +{ + public enum QueryType + { + Select, + Delete, + Update, + Insert, + InsertOrUpdate + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/QueryVisitor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/QueryVisitor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1465 @@ +using System; +using System.Collections.Generic; + +namespace BLToolkit.Data.Sql +{ + using VisitFunc = Func; + using FindFunc = Func; + using ConvertFunc = Func; + + public class QueryVisitor + { + #region Visit + + readonly Dictionary _visitedElements = new Dictionary(); + public Dictionary VisitedElements + { + get { return _visitedElements; } + } + + bool _all; + Func _action1; + Action _action2; + + public void VisitParentFirst(IQueryElement element, Func action) + { + _visitedElements.Clear(); + _action1 = action; + Visit1(element); + } + + void Visit1(IQueryElement element) + { + if (element == null || _visitedElements.ContainsKey(element)) + return; + + _visitedElements.Add(element, element); + + if (!_action1(element)) + return; + + switch (element.ElementType) + { + case QueryElementType.SqlFunction: + { + foreach (var p in ((SqlFunction)element).Parameters) Visit1(p); + break; + } + + case QueryElementType.SqlExpression: + { + foreach (var v in ((SqlExpression)element).Parameters) Visit1(v); + break; + } + + case QueryElementType.SqlBinaryExpression: + { + //var bexpr = (SqlBinaryExpression)element; + Visit1(((SqlBinaryExpression)element).Expr1); + Visit1(((SqlBinaryExpression)element).Expr2); + break; + } + + case QueryElementType.SqlTable: + { + var table = (SqlTable)element; + + Visit1(table.All); + foreach (var field in table.Fields.Values) Visit1(field); + foreach (var join in table.Joins) Visit1(join); + + if (table.TableArguments != null) + foreach (var a in table.TableArguments) Visit1(a); + + break; + } + + case QueryElementType.Join: + { + foreach (var j in ((Join)element).JoinOns) Visit1(j); + break; + } + + case QueryElementType.Column: + { + Visit1(((SqlQuery.Column)element).Expression); + break; + } + + case QueryElementType.TableSource: + { + //var table = ((SqlQuery.TableSource)element); + + Visit1(((SqlQuery.TableSource)element).Source); + foreach (var j in ((SqlQuery.TableSource)element).Joins) Visit1(j); + break; + } + + case QueryElementType.JoinedTable: + { + //var join = (SqlQuery.JoinedTable)element; + Visit1(((SqlQuery.JoinedTable)element).Table); + Visit1(((SqlQuery.JoinedTable)element).Condition); + break; + } + + case QueryElementType.SearchCondition: + { + foreach (var c in ((SqlQuery.SearchCondition)element).Conditions) Visit1(c); + break; + } + + case QueryElementType.Condition: + { + Visit1(((SqlQuery.Condition)element).Predicate); + break; + } + + case QueryElementType.ExprPredicate: + { + Visit1(((SqlQuery.Predicate.Expr)element).Expr1); + break; + } + + case QueryElementType.NotExprPredicate: + { + Visit1(((SqlQuery.Predicate.NotExpr)element).Expr1); + break; + } + + case QueryElementType.ExprExprPredicate: + { + //var p = ((SqlQuery.Predicate.ExprExpr)element); + Visit1(((SqlQuery.Predicate.ExprExpr)element).Expr1); + Visit1(((SqlQuery.Predicate.ExprExpr)element).Expr2); + break; + } + + case QueryElementType.LikePredicate: + { + //var p = ((SqlQuery.Predicate.Like)element); + Visit1(((SqlQuery.Predicate.Like)element).Expr1); + Visit1(((SqlQuery.Predicate.Like)element).Expr2); + Visit1(((SqlQuery.Predicate.Like)element).Escape); + break; + } + + case QueryElementType.BetweenPredicate: + { + //var p = (SqlQuery.Predicate.Between)element; + Visit1(((SqlQuery.Predicate.Between)element).Expr1); + Visit1(((SqlQuery.Predicate.Between)element).Expr2); + Visit1(((SqlQuery.Predicate.Between)element).Expr3); + break; + } + + case QueryElementType.IsNullPredicate: + { + Visit1(((SqlQuery.Predicate.IsNull)element).Expr1); + break; + } + + case QueryElementType.InSubQueryPredicate: + { + //var p = (SqlQuery.Predicate.InSubQuery)element; + Visit1(((SqlQuery.Predicate.InSubQuery)element).Expr1); + Visit1(((SqlQuery.Predicate.InSubQuery)element).SubQuery); + break; + } + + case QueryElementType.InListPredicate: + { + //var p = (SqlQuery.Predicate.InList)element; + Visit1(((SqlQuery.Predicate.InList)element).Expr1); + foreach (var value in ((SqlQuery.Predicate.InList)element).Values) Visit1(value); + break; + } + + case QueryElementType.FuncLikePredicate: + { + Visit1(((SqlQuery.Predicate.FuncLike)element).Function); + break; + } + + case QueryElementType.SetExpression: + { + //var s = (SqlQuery.SetExpression)element; + Visit1(((SqlQuery.SetExpression)element).Column); + Visit1(((SqlQuery.SetExpression)element).Expression); + break; + } + + case QueryElementType.InsertClause: + { + //var sc = (SqlQuery.InsertClause)element; + + if (((SqlQuery.InsertClause)element).Into != null) + Visit1(((SqlQuery.InsertClause)element).Into); + + foreach (var c in ((SqlQuery.InsertClause)element).Items.ToArray()) Visit1(c); + break; + } + + case QueryElementType.UpdateClause: + { + //var sc = (SqlQuery.UpdateClause)element; + + if (((SqlQuery.UpdateClause)element).Table != null) + Visit1(((SqlQuery.UpdateClause)element).Table); + + foreach (var c in ((SqlQuery.UpdateClause)element).Items.ToArray()) Visit1(c); + foreach (var c in ((SqlQuery.UpdateClause)element).Keys. ToArray()) Visit1(c); + break; + } + + case QueryElementType.DeleteClause: + { + if (((SqlQuery.DeleteClause)element).Table != null) + Visit1(((SqlQuery.DeleteClause)element).Table); + break; + } + + case QueryElementType.SelectClause: + { + //var sc = (SqlQuery.SelectClause)element; + Visit1(((SqlQuery.SelectClause)element).TakeValue); + Visit1(((SqlQuery.SelectClause)element).SkipValue); + + foreach (var c in ((SqlQuery.SelectClause)element).Columns.ToArray()) Visit1(c); + break; + } + + case QueryElementType.FromClause: + { + foreach (var t in ((SqlQuery.FromClause)element).Tables) Visit1(t); + break; + } + + case QueryElementType.WhereClause: + { + Visit1(((SqlQuery.WhereClause)element).SearchCondition); + break; + } + + case QueryElementType.GroupByClause: + { + foreach (var i in ((SqlQuery.GroupByClause)element).Items) Visit1(i); + break; + } + + case QueryElementType.OrderByClause: + { + foreach (var i in ((SqlQuery.OrderByClause)element).Items) Visit1(i); + break; + } + + case QueryElementType.OrderByItem: + { + Visit1(((SqlQuery.OrderByItem)element).Expression); + break; + } + + case QueryElementType.Union: + Visit1(((SqlQuery.Union)element).SqlQuery); + break; + + case QueryElementType.SqlQuery: + { + if (_all) + { + if (_visitedElements.ContainsKey(element)) + return; + _visitedElements.Add(element, element); + } + + var q = (SqlQuery)element; + + switch (q.QueryType) + { + case QueryType.InsertOrUpdate : + Visit1(q.Insert); + Visit1(q.Update); + + if (q.From.Tables.Count == 0) + break; + + goto default; + + case QueryType.Update : + Visit1(q.Update); + break; + + case QueryType.Delete : + Visit1(q.Delete); + Visit1(q.Select); + break; + + case QueryType.Insert : + Visit1(q.Insert); + + if (q.From.Tables.Count != 0) + Visit1(q.Select); + + break; + + default : + Visit1(q.Select); + break; + } + + Visit1(q.From); + Visit1(q.Where); + Visit1(q.GroupBy); + Visit1(q.Having); + Visit1(q.OrderBy); + + if (q.HasUnion) + { + foreach (var i in q.Unions) + { + if (i.SqlQuery == q) + throw new InvalidOperationException(); + + Visit1(i); + } + } + + break; + } + } + } + + public void Visit(IQueryElement element, Action action) + { + _visitedElements.Clear(); + _all = false; + _action2 = action; + Visit2(element); + } + + public void VisitAll(IQueryElement element, Action action) + { + _visitedElements.Clear(); + _all = true; + _action2 = action; + Visit2(element); + } + + void Visit2(IQueryElement element) + { + if (element == null || !_all && _visitedElements.ContainsKey(element)) + return; + + switch (element.ElementType) + { + case QueryElementType.SqlFunction: + { + foreach (var p in ((SqlFunction)element).Parameters) Visit2(p); + break; + } + + case QueryElementType.SqlExpression: + { + foreach (var v in ((SqlExpression)element).Parameters) Visit2(v); + break; + } + + case QueryElementType.SqlBinaryExpression: + { + //var bexpr = (SqlBinaryExpression)element; + Visit2(((SqlBinaryExpression)element).Expr1); + Visit2(((SqlBinaryExpression)element).Expr2); + break; + } + + case QueryElementType.SqlTable: + { + var table = (SqlTable)element; + + Visit2(table.All); + foreach (var field in table.Fields.Values) Visit2(field); + foreach (var join in table.Joins) Visit2(join); + + if (table.TableArguments != null) + foreach (var a in table.TableArguments) Visit2(a); + + break; + } + + case QueryElementType.Join: + { + foreach (var j in ((Join)element).JoinOns) Visit2(j); + break; + } + + case QueryElementType.Column: + { + Visit2(((SqlQuery.Column)element).Expression); + break; + } + + case QueryElementType.TableSource: + { + //var table = ((SqlQuery.TableSource)element); + + Visit2(((SqlQuery.TableSource)element).Source); + foreach (var j in ((SqlQuery.TableSource)element).Joins) Visit2(j); + break; + } + + case QueryElementType.JoinedTable: + { + //var join = (SqlQuery.JoinedTable)element; + Visit2(((SqlQuery.JoinedTable)element).Table); + Visit2(((SqlQuery.JoinedTable)element).Condition); + break; + } + + case QueryElementType.SearchCondition: + { + foreach (var c in ((SqlQuery.SearchCondition)element).Conditions) Visit2(c); + break; + } + + case QueryElementType.Condition: + { + Visit2(((SqlQuery.Condition)element).Predicate); + break; + } + + case QueryElementType.ExprPredicate: + { + Visit2(((SqlQuery.Predicate.Expr)element).Expr1); + break; + } + + case QueryElementType.NotExprPredicate: + { + Visit2(((SqlQuery.Predicate.NotExpr)element).Expr1); + break; + } + + case QueryElementType.ExprExprPredicate: + { + //var p = ((SqlQuery.Predicate.ExprExpr)element); + Visit2(((SqlQuery.Predicate.ExprExpr)element).Expr1); + Visit2(((SqlQuery.Predicate.ExprExpr)element).Expr2); + break; + } + + case QueryElementType.LikePredicate: + { + //var p = ((SqlQuery.Predicate.Like)element); + Visit2(((SqlQuery.Predicate.Like)element).Expr1); + Visit2(((SqlQuery.Predicate.Like)element).Expr2); + Visit2(((SqlQuery.Predicate.Like)element).Escape); + break; + } + + case QueryElementType.BetweenPredicate: + { + //var p = (SqlQuery.Predicate.Between)element; + Visit2(((SqlQuery.Predicate.Between)element).Expr1); + Visit2(((SqlQuery.Predicate.Between)element).Expr2); + Visit2(((SqlQuery.Predicate.Between)element).Expr3); + break; + } + + case QueryElementType.IsNullPredicate: + { + Visit2(((SqlQuery.Predicate.IsNull)element).Expr1); + break; + } + + case QueryElementType.InSubQueryPredicate: + { + //var p = (SqlQuery.Predicate.InSubQuery)element; + Visit2(((SqlQuery.Predicate.InSubQuery)element).Expr1); + Visit2(((SqlQuery.Predicate.InSubQuery)element).SubQuery); + break; + } + + case QueryElementType.InListPredicate: + { + //var p = (SqlQuery.Predicate.InList)element; + Visit2(((SqlQuery.Predicate.InList)element).Expr1); + foreach (var value in ((SqlQuery.Predicate.InList)element).Values) Visit2(value); + break; + } + + case QueryElementType.FuncLikePredicate: + { + Visit2(((SqlQuery.Predicate.FuncLike)element).Function); + break; + } + + case QueryElementType.SetExpression: + { + //var s = (SqlQuery.SetExpression)element; + Visit2(((SqlQuery.SetExpression)element).Column); + Visit2(((SqlQuery.SetExpression)element).Expression); + break; + } + + case QueryElementType.InsertClause: + { + //var sc = (SqlQuery.InsertClause)element; + + if (((SqlQuery.InsertClause)element).Into != null) + Visit2(((SqlQuery.InsertClause)element).Into); + + foreach (var c in ((SqlQuery.InsertClause)element).Items.ToArray()) Visit2(c); + break; + } + + case QueryElementType.UpdateClause: + { + //var sc = (SqlQuery.UpdateClause)element; + + if (((SqlQuery.UpdateClause)element).Table != null) + Visit2(((SqlQuery.UpdateClause)element).Table); + + foreach (var c in ((SqlQuery.UpdateClause)element).Items.ToArray()) Visit2(c); + foreach (var c in ((SqlQuery.UpdateClause)element).Keys. ToArray()) Visit2(c); + break; + } + + case QueryElementType.DeleteClause: + { + if (((SqlQuery.DeleteClause)element).Table != null) + Visit2(((SqlQuery.DeleteClause)element).Table); + break; + } + + case QueryElementType.SelectClause: + { + //var sc = (SqlQuery.SelectClause)element; + Visit2(((SqlQuery.SelectClause)element).TakeValue); + Visit2(((SqlQuery.SelectClause)element).SkipValue); + + foreach (var c in ((SqlQuery.SelectClause)element).Columns.ToArray()) Visit2(c); + break; + } + + case QueryElementType.FromClause: + { + foreach (var t in ((SqlQuery.FromClause)element).Tables) Visit2(t); + break; + } + + case QueryElementType.WhereClause: + { + Visit2(((SqlQuery.WhereClause)element).SearchCondition); + break; + } + + case QueryElementType.GroupByClause: + { + foreach (var i in ((SqlQuery.GroupByClause)element).Items) Visit2(i); + break; + } + + case QueryElementType.OrderByClause: + { + foreach (var i in ((SqlQuery.OrderByClause)element).Items) Visit2(i); + break; + } + + case QueryElementType.OrderByItem: + { + Visit2(((SqlQuery.OrderByItem)element).Expression); + break; + } + + case QueryElementType.Union: + Visit2(((SqlQuery.Union)element).SqlQuery); + break; + + case QueryElementType.SqlQuery: + { + if (_all) + { + if (_visitedElements.ContainsKey(element)) + return; + _visitedElements.Add(element, element); + } + + var q = (SqlQuery)element; + + switch (q.QueryType) + { + case QueryType.InsertOrUpdate : + Visit2(q.Insert); + Visit2(q.Update); + + if (q.From.Tables.Count == 0) + break; + + goto default; + + case QueryType.Update : + Visit2(q.Update); + break; + + case QueryType.Delete : + Visit2(q.Delete); + Visit2(q.Select); + break; + + case QueryType.Insert : + Visit2(q.Insert); + + if (q.From.Tables.Count != 0) + Visit2(q.Select); + + break; + + default : + Visit2(q.Select); + break; + } + + // Visit2(q.From); + // + if (q.From != null && (_all || !_visitedElements.ContainsKey(q.From))) + { + foreach (var t in q.From.Tables) + { + //Visit2(t); + // + if (t != null && (_all || !_visitedElements.ContainsKey(t))) + { + Visit2(t.Source); + + foreach (var j in t.Joins) + Visit2(j); + + _action2(t); + if (!_all) + _visitedElements.Add(t, t); + } + } + _action2(q.From); + if (!_all) + _visitedElements.Add(q.From, q.From); + } + + Visit2(q.Where); + Visit2(q.GroupBy); + Visit2(q.Having); + Visit2(q.OrderBy); + + if (q.HasUnion) + { + foreach (var i in q.Unions) + { + if (i.SqlQuery == q) + throw new InvalidOperationException(); + + Visit2(i); + } + } + + break; + } + } + + _action2(element); + if (!_all) + _visitedElements.Add(element, element); + } + + #endregion + + #region Find + + IQueryElement Find(IEnumerable arr, FindFunc find) + where T : class, IQueryElement + { + if (arr == null) + return null; + + foreach (var item in arr) + { + var e = Find(item, find); + if (e != null) + return e; + } + + return null; + } + + public IQueryElement Find(IQueryElement element, FindFunc find) + { + if (element == null || find(element)) + return element; + + switch (element.ElementType) + { + case QueryElementType.SqlFunction : return Find(((SqlFunction) element).Parameters, find); + case QueryElementType.SqlExpression : return Find(((SqlExpression) element).Parameters, find); + case QueryElementType.Join : return Find(((Join) element).JoinOns, find); + case QueryElementType.Column : return Find(((SqlQuery.Column) element).Expression, find); + case QueryElementType.SearchCondition : return Find(((SqlQuery.SearchCondition) element).Conditions, find); + case QueryElementType.Condition : return Find(((SqlQuery.Condition) element).Predicate, find); + case QueryElementType.ExprPredicate : return Find(((SqlQuery.Predicate.Expr) element).Expr1, find); + case QueryElementType.NotExprPredicate : return Find(((SqlQuery.Predicate.NotExpr) element).Expr1, find); + case QueryElementType.IsNullPredicate : return Find(((SqlQuery.Predicate.IsNull) element).Expr1, find); + case QueryElementType.FromClause : return Find(((SqlQuery.FromClause) element).Tables, find); + case QueryElementType.WhereClause : return Find(((SqlQuery.WhereClause) element).SearchCondition, find); + case QueryElementType.GroupByClause : return Find(((SqlQuery.GroupByClause) element).Items, find); + case QueryElementType.OrderByClause : return Find(((SqlQuery.OrderByClause) element).Items, find); + case QueryElementType.OrderByItem : return Find(((SqlQuery.OrderByItem) element).Expression, find); + case QueryElementType.Union : return Find(((SqlQuery.Union) element).SqlQuery, find); + case QueryElementType.FuncLikePredicate : return Find(((SqlQuery.Predicate.FuncLike)element).Function, find); + + case QueryElementType.SqlBinaryExpression: + { + var bexpr = (SqlBinaryExpression)element; + return + Find(bexpr.Expr1, find) ?? + Find(bexpr.Expr2, find); + } + + case QueryElementType.SqlTable: + { + var table = (SqlTable)element; + return + Find(table.All, find) ?? + Find(table.Fields.Values, find) ?? + Find(table.Joins, find) ?? + Find(table.TableArguments, find); + } + + case QueryElementType.TableSource: + { + var table = (SqlQuery.TableSource)element; + return + Find(table.Source, find) ?? + Find(table.Joins, find); + } + + case QueryElementType.JoinedTable: + { + var join = (SqlQuery.JoinedTable)element; + return + Find(join.Table, find) ?? + Find(join.Condition, find); + } + + case QueryElementType.ExprExprPredicate: + { + var p = (SqlQuery.Predicate.ExprExpr)element; + return + Find(p.Expr1, find) ?? + Find(p.Expr2, find); + } + + case QueryElementType.LikePredicate: + { + var p = (SqlQuery.Predicate.Like)element; + return + Find(p.Expr1, find) ?? + Find(p.Expr2, find) ?? + Find(p.Escape, find); + } + + case QueryElementType.BetweenPredicate: + { + var p = (SqlQuery.Predicate.Between)element; + return + Find(p.Expr1, find) ?? + Find(p.Expr2, find) ?? + Find(p.Expr3, find); + } + + case QueryElementType.InSubQueryPredicate: + { + var p = (SqlQuery.Predicate.InSubQuery)element; + return + Find(p.Expr1, find) ?? + Find(p.SubQuery, find); + } + + case QueryElementType.InListPredicate: + { + var p = (SqlQuery.Predicate.InList)element; + return + Find(p.Expr1, find) ?? + Find(p.Values, find); + } + + case QueryElementType.SetExpression: + { + var s = (SqlQuery.SetExpression)element; + return + Find(s.Column, find) ?? + Find(s.Expression, find); + } + + case QueryElementType.InsertClause: + { + var sc = (SqlQuery.InsertClause)element; + return + Find(sc.Into, find) ?? + Find(sc.Items, find); + } + + case QueryElementType.UpdateClause: + { + var sc = (SqlQuery.UpdateClause)element; + return + Find(sc.Table, find) ?? + Find(sc.Items, find) ?? + Find(sc.Keys, find); + } + + case QueryElementType.DeleteClause: + { + var sc = (SqlQuery.DeleteClause)element; + return Find(sc.Table, find); + } + + case QueryElementType.SelectClause: + { + var sc = (SqlQuery.SelectClause)element; + return + Find(sc.TakeValue, find) ?? + Find(sc.SkipValue, find) ?? + Find(sc.Columns, find); + } + + case QueryElementType.SqlQuery: + { + var q = (SqlQuery)element; + return + Find(q.Select, find) ?? + (q.IsInsert ? Find(q.Insert, find) : null) ?? + (q.IsUpdate ? Find(q.Update, find) : null) ?? + Find(q.From, find) ?? + Find(q.Where, find) ?? + Find(q.GroupBy, find) ?? + Find(q.Having, find) ?? + Find(q.OrderBy, find) ?? + (q.HasUnion ? Find(q.Unions, find) : null); + } + } + + return null; + } + + #endregion + + #region Convert + + public T Convert(T element, ConvertFunc action) + where T : class, IQueryElement + { + _visitedElements.Clear(); + return (T)ConvertInternal(element, action) ?? element; + } + + IQueryElement ConvertInternal(IQueryElement element, ConvertFunc action) + { + if (element == null) + return null; + + IQueryElement newElement; + + if (_visitedElements.TryGetValue(element, out newElement)) + return newElement; + + switch (element.ElementType) + { + case QueryElementType.SqlFunction: + { + var func = (SqlFunction)element; + var parms = Convert(func.Parameters, action); + + if (parms != null && !ReferenceEquals(parms, func.Parameters)) + newElement = new SqlFunction(func.SystemType, func.Name, func.Precedence, parms); + + break; + } + + case QueryElementType.SqlExpression: + { + var expr = (SqlExpression)element; + var parameter = Convert(expr.Parameters, action); + + if (parameter != null && !ReferenceEquals(parameter, expr.Parameters)) + newElement = new SqlExpression(expr.SystemType, expr.Expr, expr.Precedence, parameter); + + break; + } + + case QueryElementType.SqlBinaryExpression: + { + var bexpr = (SqlBinaryExpression)element; + var expr1 = (ISqlExpression)ConvertInternal(bexpr.Expr1, action); + var expr2 = (ISqlExpression)ConvertInternal(bexpr.Expr2, action); + + if (expr1 != null && !ReferenceEquals(expr1, bexpr.Expr1) || + expr2 != null && !ReferenceEquals(expr2, bexpr.Expr2)) + newElement = new SqlBinaryExpression(bexpr.SystemType, expr1 ?? bexpr.Expr1, bexpr.Operation, expr2 ?? bexpr.Expr2, bexpr.Precedence); + + break; + } + + case QueryElementType.SqlTable: + { + var table = (SqlTable)element; + var fields1 = ToArray(table.Fields); + var fields2 = Convert(fields1, action, f => new SqlField(f)); + var joins = Convert(table.Joins, action, j => j.Clone()); + var targs = table.TableArguments == null ? null : Convert(table.TableArguments, action); + + var fe = fields2 == null || ReferenceEquals(fields1, fields2); + var je = joins == null || ReferenceEquals(table.Joins, joins); + var ta = ReferenceEquals(table.TableArguments, targs); + + if (!fe || !je || !ta) + { + if (fe) + { + fields2 = fields1; + + for (var i = 0; i < fields2.Length; i++) + { + var field = fields2[i]; + + fields2[i] = new SqlField(field); + + _visitedElements[field] = fields2[i]; + } + } + + newElement = new SqlTable(table, fields2, joins ?? table.Joins, targs ?? table.TableArguments); + + _visitedElements[((SqlTable)newElement).All] = table.All; + } + + break; + } + + case QueryElementType.Join: + { + var join = (Join)element; + var ons = Convert(join.JoinOns, action); + + if (ons != null && !ReferenceEquals(join.JoinOns, ons)) + newElement = new Join(join.TableName, join.Alias, ons); + + break; + } + + case QueryElementType.Column: + { + var col = (SqlQuery.Column)element; + var expr = (ISqlExpression)ConvertInternal(col.Expression, action); + + IQueryElement parent; + _visitedElements.TryGetValue(col.Parent, out parent); + + if (parent != null || expr != null && !ReferenceEquals(expr, col.Expression)) + newElement = new SqlQuery.Column(parent == null ? col.Parent : (SqlQuery)parent, expr ?? col.Expression, col._alias); + + break; + } + + case QueryElementType.TableSource: + { + var table = (SqlQuery.TableSource)element; + var source = (ISqlTableSource)ConvertInternal(table.Source, action); + var joins = Convert(table.Joins, action); + + if (source != null && !ReferenceEquals(source, table.Source) || + joins != null && !ReferenceEquals(table.Joins, joins)) + newElement = new SqlQuery.TableSource(source ?? table.Source, table._alias, joins ?? table.Joins); + + break; + } + + case QueryElementType.JoinedTable: + { + var join = (SqlQuery.JoinedTable)element; + var table = (SqlQuery.TableSource) ConvertInternal(join.Table, action); + var cond = (SqlQuery.SearchCondition)ConvertInternal(join.Condition, action); + + if (table != null && !ReferenceEquals(table, join.Table) || + cond != null && !ReferenceEquals(cond, join.Condition)) + newElement = new SqlQuery.JoinedTable(join.JoinType, table ?? join.Table, join.IsWeak, cond ?? join.Condition); + + break; + } + + case QueryElementType.SearchCondition: + { + var sc = (SqlQuery.SearchCondition)element; + var conds = Convert(sc.Conditions, action); + + if (conds != null && !ReferenceEquals(sc.Conditions, conds)) + newElement = new SqlQuery.SearchCondition(conds); + + break; + } + + case QueryElementType.Condition: + { + var c = (SqlQuery.Condition)element; + var p = (ISqlPredicate)ConvertInternal(c.Predicate, action); + + if (p != null && !ReferenceEquals(c.Predicate, p)) + newElement = new SqlQuery.Condition(c.IsNot, p, c.IsOr); + + break; + } + + case QueryElementType.ExprPredicate: + { + var p = (SqlQuery.Predicate.Expr)element; + var e = (ISqlExpression)ConvertInternal(p.Expr1, action); + + if (e != null && !ReferenceEquals(p.Expr1, e)) + newElement = new SqlQuery.Predicate.Expr(e, p.Precedence); + + break; + } + + case QueryElementType.NotExprPredicate: + { + var p = (SqlQuery.Predicate.NotExpr)element; + var e = (ISqlExpression)ConvertInternal(p.Expr1, action); + + if (e != null && !ReferenceEquals(p.Expr1, e)) + newElement = new SqlQuery.Predicate.NotExpr(e, p.IsNot, p.Precedence); + + break; + } + + case QueryElementType.ExprExprPredicate: + { + var p = (SqlQuery.Predicate.ExprExpr)element; + var e1 = (ISqlExpression)ConvertInternal(p.Expr1, action); + var e2 = (ISqlExpression)ConvertInternal(p.Expr2, action); + + if (e1 != null && !ReferenceEquals(p.Expr1, e1) || e2 != null && !ReferenceEquals(p.Expr2, e2)) + newElement = new SqlQuery.Predicate.ExprExpr(e1 ?? p.Expr1, p.Operator, e2 ?? p.Expr2); + + break; + } + + case QueryElementType.LikePredicate: + { + var p = (SqlQuery.Predicate.Like)element; + var e1 = (ISqlExpression)ConvertInternal(p.Expr1, action); + var e2 = (ISqlExpression)ConvertInternal(p.Expr2, action); + var es = (ISqlExpression)ConvertInternal(p.Escape, action); + + if (e1 != null && !ReferenceEquals(p.Expr1, e1) || + e2 != null && !ReferenceEquals(p.Expr2, e2) || + es != null && !ReferenceEquals(p.Escape, es)) + newElement = new SqlQuery.Predicate.Like(e1 ?? p.Expr1, p.IsNot, e2 ?? p.Expr2, es ?? p.Escape); + + break; + } + + case QueryElementType.BetweenPredicate: + { + var p = (SqlQuery.Predicate.Between)element; + var e1 = (ISqlExpression)ConvertInternal(p.Expr1, action); + var e2 = (ISqlExpression)ConvertInternal(p.Expr2, action); + var e3 = (ISqlExpression)ConvertInternal(p.Expr3, action); + + if (e1 != null && !ReferenceEquals(p.Expr1, e1) || + e2 != null && !ReferenceEquals(p.Expr2, e2) || + e3 != null && !ReferenceEquals(p.Expr3, e3)) + newElement = new SqlQuery.Predicate.Between(e1 ?? p.Expr1, p.IsNot, e2 ?? p.Expr2, e3 ?? p.Expr3); + + break; + } + + case QueryElementType.IsNullPredicate: + { + var p = (SqlQuery.Predicate.IsNull)element; + var e = (ISqlExpression)ConvertInternal(p.Expr1, action); + + if (e != null && !ReferenceEquals(p.Expr1, e)) + newElement = new SqlQuery.Predicate.IsNull(e, p.IsNot); + + break; + } + + case QueryElementType.InSubQueryPredicate: + { + var p = (SqlQuery.Predicate.InSubQuery)element; + var e = (ISqlExpression)ConvertInternal(p.Expr1, action); + var q = (SqlQuery)ConvertInternal(p.SubQuery, action); + + if (e != null && !ReferenceEquals(p.Expr1, e) || q != null && !ReferenceEquals(p.SubQuery, q)) + newElement = new SqlQuery.Predicate.InSubQuery(e ?? p.Expr1, p.IsNot, q ?? p.SubQuery); + + break; + } + + case QueryElementType.InListPredicate: + { + var p = (SqlQuery.Predicate.InList)element; + var e = (ISqlExpression)ConvertInternal(p.Expr1, action); + var v = Convert(p.Values, action); + + if (e != null && !ReferenceEquals(p.Expr1, e) || v != null && !ReferenceEquals(p.Values, v)) + newElement = new SqlQuery.Predicate.InList(e ?? p.Expr1, p.IsNot, v ?? p.Values); + + break; + } + + case QueryElementType.FuncLikePredicate: + { + var p = (SqlQuery.Predicate.FuncLike)element; + var f = (SqlFunction)ConvertInternal(p.Function, action); + + if (f != null && !ReferenceEquals(p.Function, f)) + newElement = new SqlQuery.Predicate.FuncLike(f); + + break; + } + + case QueryElementType.SetExpression: + { + var s = (SqlQuery.SetExpression)element; + var c = (ISqlExpression)ConvertInternal(s.Column, action); + var e = (ISqlExpression)ConvertInternal(s.Expression, action); + + if (c != null && !ReferenceEquals(s.Column, c) || e != null && !ReferenceEquals(s.Expression, e)) + newElement = new SqlQuery.SetExpression(c ?? s.Column, e ?? s.Expression); + + break; + } + + case QueryElementType.InsertClause: + { + var s = (SqlQuery.InsertClause)element; + var t = s.Into != null ? (SqlTable)ConvertInternal(s.Into, action) : null; + var i = Convert(s.Items, action); + + if (t != null && !ReferenceEquals(s.Into, t) || i != null && !ReferenceEquals(s.Items, i)) + { + var sc = new SqlQuery.InsertClause { Into = t ?? s.Into }; + + sc.Items.AddRange(i ?? s.Items); + sc.WithIdentity = s.WithIdentity; + + newElement = sc; + } + + break; + } + + case QueryElementType.UpdateClause: + { + var s = (SqlQuery.UpdateClause)element; + var t = s.Table != null ? (SqlTable)ConvertInternal(s.Table, action) : null; + var i = Convert(s.Items, action); + var k = Convert(s.Keys, action); + + if (t != null && !ReferenceEquals(s.Table, t) || + i != null && !ReferenceEquals(s.Items, i) || + k != null && !ReferenceEquals(s.Keys, k)) + { + var sc = new SqlQuery.UpdateClause { Table = t ?? s.Table }; + + sc.Items.AddRange(i ?? s.Items); + sc.Keys. AddRange(k ?? s.Keys); + + newElement = sc; + } + + break; + } + + case QueryElementType.DeleteClause: + { + var s = (SqlQuery.DeleteClause)element; + var t = s.Table != null ? (SqlTable)ConvertInternal(s.Table, action) : null; + + if (t != null && !ReferenceEquals(s.Table, t)) + { + newElement = new SqlQuery.DeleteClause { Table = t ?? s.Table }; + } + + break; + } + + case QueryElementType.SelectClause: + { + var sc = (SqlQuery.SelectClause)element; + var cols = Convert(sc.Columns, action); + var take = (ISqlExpression)ConvertInternal(sc.TakeValue, action); + var skip = (ISqlExpression)ConvertInternal(sc.SkipValue, action); + + IQueryElement parent; + _visitedElements.TryGetValue(sc.SqlQuery, out parent); + + if (parent != null || + cols != null && !ReferenceEquals(sc.Columns, cols) || + take != null && !ReferenceEquals(sc.TakeValue, take) || + skip != null && !ReferenceEquals(sc.SkipValue, skip)) + { + newElement = new SqlQuery.SelectClause(sc.IsDistinct, take ?? sc.TakeValue, skip ?? sc.SkipValue, cols ?? sc.Columns); + ((SqlQuery.SelectClause)newElement).SetSqlQuery((SqlQuery)parent); + } + + break; + } + + case QueryElementType.FromClause: + { + var fc = (SqlQuery.FromClause)element; + var ts = Convert(fc.Tables, action); + + IQueryElement parent; + _visitedElements.TryGetValue(fc.SqlQuery, out parent); + + if (parent != null || ts != null && !ReferenceEquals(fc.Tables, ts)) + { + newElement = new SqlQuery.FromClause(ts ?? fc.Tables); + ((SqlQuery.FromClause)newElement).SetSqlQuery((SqlQuery)parent); + } + + break; + } + + case QueryElementType.WhereClause: + { + var wc = (SqlQuery.WhereClause)element; + var cond = (SqlQuery.SearchCondition)ConvertInternal(wc.SearchCondition, action); + + IQueryElement parent; + _visitedElements.TryGetValue(wc.SqlQuery, out parent); + + if (parent != null || cond != null && !ReferenceEquals(wc.SearchCondition, cond)) + { + newElement = new SqlQuery.WhereClause(cond ?? wc.SearchCondition); + ((SqlQuery.WhereClause)newElement).SetSqlQuery((SqlQuery)parent); + } + + break; + } + + case QueryElementType.GroupByClause: + { + var gc = (SqlQuery.GroupByClause)element; + var es = Convert(gc.Items, action); + + IQueryElement parent; + _visitedElements.TryGetValue(gc.SqlQuery, out parent); + + if (parent != null || es != null && !ReferenceEquals(gc.Items, es)) + { + newElement = new SqlQuery.GroupByClause(es ?? gc.Items); + ((SqlQuery.GroupByClause)newElement).SetSqlQuery((SqlQuery)parent); + } + + break; + } + + case QueryElementType.OrderByClause: + { + var oc = (SqlQuery.OrderByClause)element; + var es = Convert(oc.Items, action); + + IQueryElement parent; + _visitedElements.TryGetValue(oc.SqlQuery, out parent); + + if (parent != null || es != null && !ReferenceEquals(oc.Items, es)) + { + newElement = new SqlQuery.OrderByClause(es ?? oc.Items); + ((SqlQuery.OrderByClause)newElement).SetSqlQuery((SqlQuery)parent); + } + + break; + } + + case QueryElementType.OrderByItem: + { + var i = (SqlQuery.OrderByItem)element; + var e = (ISqlExpression)ConvertInternal(i.Expression, action); + + if (e != null && !ReferenceEquals(i.Expression, e)) + newElement = new SqlQuery.OrderByItem(e, i.IsDescending); + + break; + } + + case QueryElementType.Union: + { + var u = (SqlQuery.Union)element; + var q = (SqlQuery)ConvertInternal(u.SqlQuery, action); + + if (q != null && !ReferenceEquals(u.SqlQuery, q)) + newElement = new SqlQuery.Union(q, u.IsAll); + + break; + } + + case QueryElementType.SqlQuery: + { + var q = (SqlQuery)element; + IQueryElement parent = null; + + var doConvert = q.ParentSql != null && !_visitedElements.TryGetValue(q.ParentSql, out parent); + + if (!doConvert) + { + doConvert = null != Find(q, e => + { + if (_visitedElements.ContainsKey(e) && _visitedElements[e] != e) + return true; + + var ret = action(e); + + if (ret != null && !ReferenceEquals(e, ret)) + { + _visitedElements.Add(e, ret); + return true; + } + + return false; + }); + } + + if (!doConvert) + break; + + var nq = new SqlQuery { QueryType = q.QueryType }; + + _visitedElements.Add(q, nq); + + var fc = (SqlQuery.FromClause) ConvertInternal(q.From, action) ?? q.From; + var sc = (SqlQuery.SelectClause) ConvertInternal(q.Select, action) ?? q.Select; + var ic = q.IsInsert ? ((SqlQuery.InsertClause)ConvertInternal(q.Insert, action) ?? q.Insert) : null; + var uc = q.IsUpdate ? ((SqlQuery.UpdateClause)ConvertInternal(q.Update, action) ?? q.Update) : null; + var dc = q.IsDelete ? ((SqlQuery.DeleteClause)ConvertInternal(q.Delete, action) ?? q.Delete) : null; + var wc = (SqlQuery.WhereClause) ConvertInternal(q.Where, action) ?? q.Where; + var gc = (SqlQuery.GroupByClause)ConvertInternal(q.GroupBy, action) ?? q.GroupBy; + var hc = (SqlQuery.WhereClause) ConvertInternal(q.Having, action) ?? q.Having; + var oc = (SqlQuery.OrderByClause)ConvertInternal(q.OrderBy, action) ?? q.OrderBy; + var us = q.HasUnion ? Convert(q.Unions, action) : q.Unions; + + var ps = new List(q.Parameters.Count); + + foreach (var p in q.Parameters) + { + IQueryElement e; + + if (_visitedElements.TryGetValue(p, out e)) + { + if (e == null) + ps.Add(p); + else if (e is SqlParameter) + ps.Add((SqlParameter)e); + } + } + + nq.Init(ic, uc, dc, sc, fc, wc, gc, hc, oc, us, (SqlQuery)parent, q.IsParameterDependent, ps); + + _visitedElements[q] = action(nq) ?? nq; + + return nq; + } + } + + newElement = newElement == null ? action(element) : (action(newElement) ?? newElement); + + _visitedElements.Add(element, newElement); + + return newElement; + } + + static TE[] ToArray(IDictionary dic) + { + var es = new TE[dic.Count]; + var i = 0; + + foreach (var e in dic.Values) + es[i++] = e; + + return es; + } + + delegate T Clone(T obj); + + T[] Convert(T[] arr, ConvertFunc action) + where T : class, IQueryElement + { + return Convert(arr, action, null); + } + + T[] Convert(T[] arr1, ConvertFunc action, Clone clone) + where T : class, IQueryElement + { + T[] arr2 = null; + + for (var i = 0; i < arr1.Length; i++) + { + var elem1 = arr1[i]; + var elem2 = (T)ConvertInternal(elem1, action); + + if (elem2 != null && !ReferenceEquals(elem1, elem2)) + { + if (arr2 == null) + { + arr2 = new T[arr1.Length]; + + for (var j = 0; j < i; j++) + arr2[j] = clone == null ? arr1[j] : clone(arr1[j]); + } + + arr2[i] = elem2; + } + else if (arr2 != null) + arr2[i] = clone == null ? elem1 : clone(elem1); + } + + return arr2; + } + + List Convert(List list, ConvertFunc action) + where T : class, IQueryElement + { + return Convert(list, action, null); + } + + List Convert(List list1, ConvertFunc action, Clone clone) + where T : class, IQueryElement + { + List list2 = null; + + for (var i = 0; i < list1.Count; i++) + { + var elem1 = list1[i]; + var elem2 = (T)ConvertInternal(elem1, action); + + if (elem2 != null && !ReferenceEquals(elem1, elem2)) + { + if (list2 == null) + { + list2 = new List(list1.Count); + + for (var j = 0; j < i; j++) + list2.Add(clone == null ? list1[j] : clone(list1[j])); + } + + list2.Add(elem2); + } + else if (list2 != null) + list2.Add(clone == null ? elem1 : clone(elem1)); + } + + return list2; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/ReservedWords.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/ReservedWords.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,529 @@ +ABORT +ABSOLUTE +ACCEPT +ACCESS +ACTION +ADD +ADMIN +AFTER +ALL +ALLOCATE +ALTER +ANALYZE +AND +ANY +ARCHIVE +ARCHIVELOG +ARE +ARRAY +ARRAYLEN +AS +ASC +ASENSITIVE +ASSERT +ASSERTION +ASSIGN +ASYMMETRIC +AT +ATOMIC +AUDIT +AUTHORIZATION +AVG +BACKUP +BASE_TABLE +BECOME +BEFORE +BEGIN +BETWEEN +BIGINT +BINARY +BINARY_INTEGER +BIT +BIT_LENGTH +BLOB +BLOCK +BODY +BOOLEAN +BOTH +BREADTH +BY +CACHE +CALL +CALLED +CANCEL +CASCADE +CASCADED +CASE +CAST +CATALOG +CHANGE +CHAR +CHAR_BASE +CHAR_LENGTH +CHARACTER +CHARACTER_LENGTH +CHECK +CHECKPOINT +CLOB +CLOSE +CLUSTER +CLUSTERS +COALESCE +COBOL +COLAUTH +COLLATE +COLLATION +COLUMN +COLUMNS +COMMENT +COMMIT +COMPILE +COMPRESS +CONDITION +CONNECT +CONNECTION +CONSTANT +CONSTRAINT +CONSTRAINTS +CONSTRUCTOR +CONTAINS +CONTENTS +CONTINUE +CONTROLFILE +CONVERT +CORRESPONDING +COUNT +CRASH +CREATE +CROSS +CUBE +CURRENT +CURRENT_DATE +CURRENT_DEFAULT_TRANSFORM_GROUP +CURRENT_PATH +CURRENT_ROLE +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_TRANSFORM_GROUP_FOR_TYPE +CURRENT_USER +CURRVAL +CURSOR +CYCLE +DATA +DATA_BASE +DATABASE +DATAFILE +DATE +DAY +DBA +DEALLOCATE +DEBUGOFF +DEBUGON +DEC +DECIMAL +DECLARE +DEFAULT +DEFERRABLE +DEFERRED +DEFINITION +DELAY +DELETE +DELTA +DEPTH +DEREF +DESC +DESCRIBE +DESCRIPTOR +DETERMINISTIC +DIAGNOSTICS +DIGITS +DISABLE +DISCONNECT +DISMOUNT +DISPOSE +DISTINCT +DO +DOMAIN +DOUBLE +DROP +DUMP +DYNAMIC +EACH +ELEMENT +ELSE +ELSEIF +ELSIF +ENABLE +END +ENTRY +EQUALS +ESCAPE +EVENTS +EXCEPT +EXCEPTION +EXCEPTION_INIT +EXCEPTIONS +EXCLUSIVE +EXEC +EXECUTE +EXISTS +EXIT +EXPLAIN +EXTENT +EXTERNAL +EXTERNALLY +EXTRACT +FALSE +FETCH +FILE +FILTER +FIRST +FLOAT +FLUSH +FOR +FORCE +FOREIGN +FORM +FORTRAN +FOUND +FREE +FREELIST +FREELISTS +FROM +FULL +FUNCTION +GENERAL +GENERIC +GET +GLOBAL +GO +GOTO +GRANT +GROUP +GROUPING +GROUPS +HANDLER +HAVING +HOLD +HOUR +IDENTIFIED +IDENTITY +IDENTITY_PARAMETER +IF +IMMEDIATE +IN +INCLUDING +INCREMEN +INDEX +INDEXES +INDICATOR +INITIAL +INITIALLY +INITRANS +INNER +INOUT +INPUT +INSENSITIVE +INSERT +INSTANCE +INT +INTEGER +INTERSECT +INTERVAL +INTO +IS +ISOLATION +ITERATE +JOIN +KEY +LANGUAGE +LARGE +LAST +LATERAL +LAYER +LEADING +LEAVE +LEFT +LEVEL +LIKE +LIMITED +LINK +LISTS +LOCAL +LOCALTIME +LOCALTIMESTAMP +LOCATOR +LOCK +LOGFILE +LONG +LOOP +LOWER +MANAGE +MANUAL +MAP +MATCH +MAX +MAXDATAFILES +MAXEXTENTS +MAXINSTANCES +MAXLOGFILES +MAXLOGHISTORY +MAXLOGMEMBERS +MAXTRANS +MAXVALUE +MEMBER +MERGE +METHOD +MIN +MINEXTENTS +MINUS +MINUTE +MINVALUE +MLSLABEL +MOD +MODE +MODIFIES +MODIFY +MODULE +MONTH +MOUNT +MULTISET +NAMES +NATIONAL +NATURAL +NCHAR +NCLOB +NEW +NEXT +NEXTVAL +NO +NOARCHIVELOG +NOAUDIT +NOCACHE +NOCOMPRESS +NOCYCLE +NOMAXVALUE +NOMINVALUE +NONE +NOORDER +NORESETLOGS +NORMAL +NOSORT +NOT +NOTFOUND +NOWAIT +NULL +NULLIF +NUMBER +NUMBER_BASE +NUMERIC +OBJECT +OCTET_LENGTH +OF +OFF +OFFLINE +OLD +ON +ONLINE +ONLY +OPEN +OPTIMAL +OPTION +OR +ORDER +ORDINALITY +OTHERS +OUT +OUTER +OUTPUT +OVER +OVERLAPS +OWN +PACKAGE +PAD +PARALLEL +PARAMETER +PARTIAL +PARTITION +PATH +PCTFREE +PCTINCREASE +PCTUSED +PLAN +PLI +POSITION +POSITIVE +PRAGMA +PRECISION +PREPARE +PRESERVE +PRIMARY +PRIOR +PRIVATE +PRIVILEGES +PROCEDURE +PROFILE +PUBLIC +QUOTA +RAISE +RANGE +RAW +READ +READS +REAL +RECORD +RECOVER +RECURSIVE +REF +REFERENCES +REFERENCING +RELATIVE +RELEASE +REMR +RENAME +REPEAT +RESETLOGS +RESIGNAL +RESOURCE +RESTRICT +RESTRICTED +RESULT +RETURN +RETURNS +REUSE +REVERSE +REVOKE +RIGHT +ROLE +ROLES +ROLLBACK +ROLLUP +ROUTINE +ROW +ROWID +ROWLABEL +ROWNUM +ROWS +ROWTYPE +RUN +SAVEPOINT +SCHEMA +SCN +SCOPE +SCROLL +SEARCH +SECOND +SECTION +SEGMENT +SELECT +SENSITIVE +SEPARATE +SEQUENCE +SESSION +SESSION_USER +SET +SETS +SHARE +SHARED +SIGNAL +SIMILAR +SIZE +SMALLINT +SNAPSHOT +SOME +SORT +SPACE +SPECIFIC +SPECIFICTYPE +SQL +SQLBUF +SQLCODE +SQLERRM +SQLERROR +SQLEXCEPTION +SQLSTATE +SQLWARNING +START +STATE +STATEMENT +STATEMENT_ID +STATIC +STATISTICS +STDDEV +STOP +STORAGE +SUBMULTISET +SUBSTRING +SUBTYPE +SUCCESSFUL +SUM +SWITCH +SYMMETRIC +SYNONYM +SYSDATE +SYSTEM +SYSTEM_USER +TABAUTH +TABLE +TABLES +TABLESAMPLE +TABLESPACE +TASK +TEMPORARY +TERMINATE +THEN +THREAD +TIME +TIMESTAMP +TIMEZONE_HOUR +TIMEZONE_MINUTE +TO +TRACING +TRAILING +TRANSACTION +TRANSLATE +TRANSLATION +TREAT +TRIGGER +TRIGGERS +TRIM +TRUE +TRUNCATE +TYPE +UID +UNDER +UNDO +UNION +UNIQUE +UNKNOWN +UNLIMITED +UNNEST +UNTIL +UPDATE +UPPER +USAGE +USE +USER +USING +VALIDATE +VALUE +VALUES +VARCHAR +VARCHAR2 +VARIANCE +VARYING +VIEW +VIEWS +WHEN +WHENEVER +WHERE +WHILE +WINDOW +WITH +WITHIN +WITHOUT +WORK +WRITE +XOR +YEAR +ZONE \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlBinaryExpression.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlBinaryExpression.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; + +namespace BLToolkit.Data.Sql +{ + [Serializable, DebuggerDisplay("SQL = {SqlText}")] + public class SqlBinaryExpression : ISqlExpression + { + public SqlBinaryExpression(Type systemType, ISqlExpression expr1, string operation, ISqlExpression expr2, int precedence) + { + if (expr1 == null) throw new ArgumentNullException("expr1"); + if (operation == null) throw new ArgumentNullException("operation"); + if (expr2 == null) throw new ArgumentNullException("expr2"); + + Expr1 = expr1; + Operation = operation; + Expr2 = expr2; + SystemType = systemType; + Precedence = precedence; + } + + public SqlBinaryExpression(Type systemType, ISqlExpression expr1, string operation, ISqlExpression expr2) + : this(systemType, expr1, operation, expr2, Sql.Precedence.Unknown) + { + } + + public ISqlExpression Expr1 { get; internal set; } + public string Operation { get; private set; } + public ISqlExpression Expr2 { get; internal set; } + public Type SystemType { get; private set; } + + public int Precedence { get; private set; } + + #region Overrides + + public string SqlText { get { return ToString(); } } + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + Expr1 = Expr1.Walk(skipColumns, func); + Expr2 = Expr2.Walk(skipColumns, func); + + return func(this); + } + + #endregion + + #region IEquatable Members + + bool IEquatable.Equals(ISqlExpression other) + { + return Equals(other, SqlExpression.DefaultComparer); + } + + #endregion + + #region ISqlExpression Members + + public bool CanBeNull() + { + return Expr1.CanBeNull() || Expr2.CanBeNull(); + } + + public bool Equals(ISqlExpression other, Func comparer) + { + if (this == other) + return true; + + var expr = other as SqlBinaryExpression; + + return + expr != null && + Operation == expr.Operation && + SystemType == expr.SystemType && + Expr1.Equals(expr.Expr1, comparer) && + Expr2.Equals(expr.Expr2, comparer) && + comparer(this, other); + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + { + objectTree.Add(this, clone = new SqlBinaryExpression( + SystemType, + (ISqlExpression)Expr1.Clone(objectTree, doClone), + Operation, + (ISqlExpression)Expr2.Clone(objectTree, doClone), + Precedence)); + } + + return clone; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.SqlBinaryExpression; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + Expr1 + .ToString(sb, dic) + .Append(' ') + .Append(Operation) + .Append(' '); + + return Expr2.ToString(sb, dic); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlDataType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlDataType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,555 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlTypes; +using System.Linq; +using System.Text; + +namespace BLToolkit.Data.Sql +{ + using Reflection; + + public class SqlDataType : ISqlExpression + { + #region Init + + public SqlDataType(SqlDbType dbType) + { + var defaultType = GetDataType(dbType); + + SqlDbType = dbType; + Type = defaultType.Type; + Length = defaultType.Length; + Precision = defaultType.Precision; + Scale = defaultType.Scale; + } + + public SqlDataType(SqlDbType dbType, int length) + { + if (length <= 0) throw new ArgumentOutOfRangeException("length"); + + SqlDbType = dbType; + Type = GetDataType(dbType).Type; + Length = length; + } + + public SqlDataType(SqlDbType dbType, int precision, int scale) + { + if (precision <= 0) throw new ArgumentOutOfRangeException("precision"); + if (scale < 0) throw new ArgumentOutOfRangeException("scale"); + + SqlDbType = dbType; + Type = GetDataType(dbType).Type; + Precision = precision; + Scale = scale; + } + + public SqlDataType([JetBrains.Annotations.NotNull]Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + var defaultType = GetDataType(type); + + SqlDbType = defaultType.SqlDbType; + Type = type; + Length = defaultType.Length; + Precision = defaultType.Precision; + Scale = defaultType.Scale; + } + + public SqlDataType([JetBrains.Annotations.NotNull] Type type, int length) + { + if (type == null) throw new ArgumentNullException ("type"); + if (length <= 0) throw new ArgumentOutOfRangeException("length"); + + SqlDbType = GetDataType(type).SqlDbType; + Type = type; + Length = length; + } + + public SqlDataType([JetBrains.Annotations.NotNull] Type type, int precision, int scale) + { + if (type == null) throw new ArgumentNullException ("type"); + if (precision <= 0) throw new ArgumentOutOfRangeException("precision"); + if (scale < 0) throw new ArgumentOutOfRangeException("scale"); + + SqlDbType = GetDataType(type).SqlDbType; + Type = type; + Precision = precision; + Scale = scale; + } + + public SqlDataType(SqlDbType dbType, [JetBrains.Annotations.NotNull]Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + var defaultType = GetDataType(dbType); + + SqlDbType = dbType; + Type = type; + Length = defaultType.Length; + Precision = defaultType.Precision; + Scale = defaultType.Scale; + } + + public SqlDataType(SqlDbType dbType, [JetBrains.Annotations.NotNull] Type type, int length) + { + if (type == null) throw new ArgumentNullException ("type"); + if (length <= 0) throw new ArgumentOutOfRangeException("length"); + + SqlDbType = dbType; + Type = type; + Length = length; + } + + public SqlDataType(SqlDbType dbType, [JetBrains.Annotations.NotNull] Type type, int precision, int scale) + { + if (type == null) throw new ArgumentNullException ("type"); + if (precision <= 0) throw new ArgumentOutOfRangeException("precision"); + if (scale < 0) throw new ArgumentOutOfRangeException("scale"); + + SqlDbType = dbType; + Type = type; + Precision = precision; + Scale = scale; + } + + #endregion + + #region Public Members + + public SqlDbType SqlDbType { get; private set; } + public Type Type { get; private set; } + public int Length { get; private set; } + public int Precision { get; private set; } + public int Scale { get; private set; } + + #endregion + + #region Static Members + + struct TypeInfo + { + public TypeInfo(SqlDbType dbType, int maxLength, int maxPrecision, int maxScale, int maxDisplaySize) + { + SqlDbType = dbType; + MaxLength = maxLength; + MaxPrecision = maxPrecision; + MaxScale = maxScale; + MaxDisplaySize = maxDisplaySize; + } + + public readonly SqlDbType SqlDbType; + public readonly int MaxLength; + public readonly int MaxPrecision; + public readonly int MaxScale; + public readonly int MaxDisplaySize; + } + + static TypeInfo[] SortTypeInfo(params TypeInfo[] info) + { + var sortedInfo = new TypeInfo[info.Max(ti => (int)ti.SqlDbType) + 1]; + + foreach (var typeInfo in info) + sortedInfo[(int)typeInfo.SqlDbType] = typeInfo; + + return sortedInfo; + } + + static int Len(object obj) + { + return obj.ToString().Length; + } + + static readonly TypeInfo[] _typeInfo = SortTypeInfo + ( + // DbType MaxLength MaxPrecision MaxScale MaxDisplaySize + // + new TypeInfo(SqlDbType.BigInt, 8, Len( long.MaxValue), 0, Len( long.MinValue)), + new TypeInfo(SqlDbType.Int, 4, Len( int.MaxValue), 0, Len( int.MinValue)), + new TypeInfo(SqlDbType.SmallInt, 2, Len(short.MaxValue), 0, Len(short.MinValue)), + new TypeInfo(SqlDbType.TinyInt, 1, Len( byte.MaxValue), 0, Len( byte.MaxValue)), + new TypeInfo(SqlDbType.Bit, 1, 1, 0, 1), + + new TypeInfo(SqlDbType.Decimal, 17, Len(decimal.MaxValue), Len(decimal.MaxValue), Len(decimal.MinValue)+1), + new TypeInfo(SqlDbType.Money, 8, 19, 4, 19 + 2), + new TypeInfo(SqlDbType.SmallMoney, 4, 10, 4, 10 + 2), + new TypeInfo(SqlDbType.Float, 8, 15, 15, 15 + 2 + 5), + new TypeInfo(SqlDbType.Real, 4, 7, 7, 7 + 2 + 4), + + new TypeInfo(SqlDbType.DateTime, 8, -1, -1, 23), +#if !MONO + new TypeInfo(SqlDbType.DateTime2, 8, -1, -1, 27), +#endif + new TypeInfo(SqlDbType.SmallDateTime, 4, -1, -1, 19), + new TypeInfo(SqlDbType.Date, 3, -1, -1, 10), + new TypeInfo(SqlDbType.Time, 5, -1, -1, 16), +#if !MONO + new TypeInfo(SqlDbType.DateTimeOffset, 10, -1, -1, 34), +#endif + + new TypeInfo(SqlDbType.Char, 8000, -1, -1, 8000), + new TypeInfo(SqlDbType.VarChar, 8000, -1, -1, 8000), + new TypeInfo(SqlDbType.Text, int.MaxValue, -1, -1, int.MaxValue), + new TypeInfo(SqlDbType.NChar, 4000, -1, -1, 4000), + new TypeInfo(SqlDbType.NVarChar, 4000, -1, -1, 4000), + new TypeInfo(SqlDbType.NText, int.MaxValue, -1, -1, int.MaxValue / 2), + + new TypeInfo(SqlDbType.Binary, 8000, -1, -1, -1), + new TypeInfo(SqlDbType.VarBinary, 8000, -1, -1, -1), + new TypeInfo(SqlDbType.Image, int.MaxValue, -1, -1, -1), + + new TypeInfo(SqlDbType.Timestamp, 8, -1, -1, -1), + new TypeInfo(SqlDbType.UniqueIdentifier, 16, -1, -1, 36), + + new TypeInfo(SqlDbType.Variant, -1, -1, -1, -1), + new TypeInfo(SqlDbType.Xml, -1, -1, -1, -1), +#if !MONO + new TypeInfo(SqlDbType.Structured, -1, -1, -1, -1), +#endif + new TypeInfo(SqlDbType.Udt, -1, -1, -1, -1) + ); + + public static int GetMaxLength (SqlDbType dbType) { return _typeInfo[(int)dbType].MaxLength; } + public static int GetMaxPrecision (SqlDbType dbType) { return _typeInfo[(int)dbType].MaxPrecision; } + public static int GetMaxScale (SqlDbType dbType) { return _typeInfo[(int)dbType].MaxScale; } + public static int GetMaxDisplaySize(SqlDbType dbType) { return _typeInfo[(int)dbType].MaxDisplaySize; } + + public static SqlDataType GetDataType(Type type) + { + var underlyingType = type; + + if (underlyingType.IsGenericType && underlyingType.GetGenericTypeDefinition() == typeof(Nullable<>)) + underlyingType = underlyingType.GetGenericArguments()[0]; + + if (underlyingType.IsEnum) + underlyingType = Enum.GetUnderlyingType(underlyingType); + + switch (Type.GetTypeCode(underlyingType)) + { + case TypeCode.Boolean : return Boolean; + case TypeCode.Char : return Char; + case TypeCode.SByte : return SByte; + case TypeCode.Byte : return Byte; + case TypeCode.Int16 : return Int16; + case TypeCode.UInt16 : return UInt16; + case TypeCode.Int32 : return Int32; + case TypeCode.UInt32 : return UInt32; + case TypeCode.Int64 : return Int64; + case TypeCode.UInt64 : return UInt64; + case TypeCode.Single : return Single; + case TypeCode.Double : return Double; + case TypeCode.Decimal : return Decimal; + case TypeCode.DateTime : return DateTime; + case TypeCode.String : return String; + case TypeCode.Object : + if (underlyingType == typeof(Guid)) return Guid; + if (underlyingType == typeof(byte[])) return ByteArray; + if (underlyingType == typeof(System.Data.Linq.Binary)) return LinqBinary; + if (underlyingType == typeof(char[])) return CharArray; +#if !MONO + if (underlyingType == typeof(DateTimeOffset)) return DateTimeOffset; +#endif + if (underlyingType == typeof(TimeSpan)) return TimeSpan; + break; + + case TypeCode.DBNull : + case TypeCode.Empty : + default : break; + } + +#if !SILVERLIGHT + + if (underlyingType == typeof(SqlByte)) return SqlByte; + if (underlyingType == typeof(SqlInt16)) return SqlInt16; + if (underlyingType == typeof(SqlInt32)) return SqlInt32; + if (underlyingType == typeof(SqlInt64)) return SqlInt64; + if (underlyingType == typeof(SqlSingle)) return SqlSingle; + if (underlyingType == typeof(SqlBoolean)) return SqlBoolean; + if (underlyingType == typeof(SqlDouble)) return SqlDouble; + if (underlyingType == typeof(SqlDateTime)) return SqlDateTime; + if (underlyingType == typeof(SqlDecimal)) return SqlDecimal; + if (underlyingType == typeof(SqlMoney)) return SqlMoney; + if (underlyingType == typeof(SqlString)) return SqlString; + if (underlyingType == typeof(SqlBinary)) return SqlBinary; + if (underlyingType == typeof(SqlGuid)) return SqlGuid; + if (underlyingType == typeof(SqlBytes)) return SqlBytes; + if (underlyingType == typeof(SqlChars)) return SqlChars; + if (underlyingType == typeof(SqlXml)) return SqlXml; + +#endif + + return DbVariant; + } + + public static SqlDataType GetDataType(SqlDbType type) + { + switch (type) + { + case SqlDbType.BigInt : return DbBigInt; + case SqlDbType.Binary : return DbBinary; + case SqlDbType.Bit : return DbBit; + case SqlDbType.Char : return DbChar; + case SqlDbType.DateTime : return DbDateTime; + case SqlDbType.Decimal : return DbDecimal; + case SqlDbType.Float : return DbFloat; + case SqlDbType.Image : return DbImage; + case SqlDbType.Int : return DbInt; + case SqlDbType.Money : return DbMoney; + case SqlDbType.NChar : return DbNChar; + case SqlDbType.NText : return DbNText; + case SqlDbType.NVarChar : return DbNVarChar; + case SqlDbType.Real : return DbReal; + case SqlDbType.UniqueIdentifier : return DbUniqueIdentifier; + case SqlDbType.SmallDateTime : return DbSmallDateTime; + case SqlDbType.SmallInt : return DbSmallInt; + case SqlDbType.SmallMoney : return DbSmallMoney; + case SqlDbType.Text : return DbText; + case SqlDbType.Timestamp : return DbTimestamp; + case SqlDbType.TinyInt : return DbTinyInt; + case SqlDbType.VarBinary : return DbVarBinary; + case SqlDbType.VarChar : return DbVarChar; + case SqlDbType.Variant : return DbVariant; +#if !SILVERLIGHT + case SqlDbType.Xml : return DbXml; +#endif + case SqlDbType.Udt : return DbUdt; +#if !MONO + case SqlDbType.Structured : return DbStructured; +#endif + case SqlDbType.Date : return DbDate; + case SqlDbType.Time : return DbTime; +#if !MONO + case SqlDbType.DateTime2 : return DbDateTime2; + case SqlDbType.DateTimeOffset : return DbDateTimeOffset; +#endif + } + + throw new InvalidOperationException(); + } + + public static bool CanBeNull(Type type) + { + if (type.IsValueType == false || + type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>) || + TypeHelper.IsSameOrParent(typeof(INullable), type)) + return true; + + return false; + } + + #endregion + + #region Default Types + + internal SqlDataType(SqlDbType dbType, Type type, int length, int precision, int scale) + { + SqlDbType = dbType; + Type = type; + Length = length; + Precision = precision; + Scale = scale; + } + + SqlDataType(SqlDbType dbType, Type type, Func length, int precision, int scale) + : this(dbType, type, length(dbType), precision, scale) + { + } + + SqlDataType(SqlDbType dbType, Type type, int length, Func precision, int scale) + : this(dbType, type, length, precision(dbType), scale) + { + } + + public static readonly SqlDataType DbBigInt = new SqlDataType(SqlDbType.BigInt, typeof(Int64), 0, 0, 0); + public static readonly SqlDataType DbInt = new SqlDataType(SqlDbType.Int, typeof(Int32), 0, 0, 0); + public static readonly SqlDataType DbSmallInt = new SqlDataType(SqlDbType.SmallInt, typeof(Int16), 0, 0, 0); + public static readonly SqlDataType DbTinyInt = new SqlDataType(SqlDbType.TinyInt, typeof(Byte), 0, 0, 0); + public static readonly SqlDataType DbBit = new SqlDataType(SqlDbType.Bit, typeof(Boolean), 0, 0, 0); + + public static readonly SqlDataType DbDecimal = new SqlDataType(SqlDbType.Decimal, typeof(Decimal), 0, GetMaxPrecision, 10); + public static readonly SqlDataType DbMoney = new SqlDataType(SqlDbType.Money, typeof(Decimal), 0, GetMaxPrecision, 4); + public static readonly SqlDataType DbSmallMoney = new SqlDataType(SqlDbType.SmallMoney, typeof(Decimal), 0, GetMaxPrecision, 4); + public static readonly SqlDataType DbFloat = new SqlDataType(SqlDbType.Float, typeof(Double), 0, 0, 0); + public static readonly SqlDataType DbReal = new SqlDataType(SqlDbType.Real, typeof(Single), 0, 0, 0); + + public static readonly SqlDataType DbDateTime = new SqlDataType(SqlDbType.DateTime, typeof(DateTime), 0, 0, 0); +#if !MONO + public static readonly SqlDataType DbDateTime2 = new SqlDataType(SqlDbType.DateTime2, typeof(DateTime), 0, 0, 0); +#else + public static readonly SqlDataType DbDateTime2 = new SqlDataType(SqlDbType.DateTime, typeof(DateTime), 0, 0, 0); +#endif + public static readonly SqlDataType DbSmallDateTime = new SqlDataType(SqlDbType.SmallDateTime, typeof(DateTime), 0, 0, 0); + public static readonly SqlDataType DbDate = new SqlDataType(SqlDbType.Date, typeof(DateTime), 0, 0, 0); + public static readonly SqlDataType DbTime = new SqlDataType(SqlDbType.Time, typeof(TimeSpan), 0, 0, 0); +#if !MONO + public static readonly SqlDataType DbDateTimeOffset = new SqlDataType(SqlDbType.DateTimeOffset, typeof(DateTimeOffset), 0, 0, 0); +#endif + + public static readonly SqlDataType DbChar = new SqlDataType(SqlDbType.Char, typeof(String), GetMaxLength, 0, 0); + public static readonly SqlDataType DbVarChar = new SqlDataType(SqlDbType.VarChar, typeof(String), GetMaxLength, 0, 0); + public static readonly SqlDataType DbText = new SqlDataType(SqlDbType.Text, typeof(String), GetMaxLength, 0, 0); + public static readonly SqlDataType DbNChar = new SqlDataType(SqlDbType.NChar, typeof(String), GetMaxLength, 0, 0); + public static readonly SqlDataType DbNVarChar = new SqlDataType(SqlDbType.NVarChar, typeof(String), GetMaxLength, 0, 0); + public static readonly SqlDataType DbNText = new SqlDataType(SqlDbType.NText, typeof(String), GetMaxLength, 0, 0); + + public static readonly SqlDataType DbBinary = new SqlDataType(SqlDbType.Binary, typeof(Byte[]), GetMaxLength, 0, 0); + public static readonly SqlDataType DbVarBinary = new SqlDataType(SqlDbType.VarBinary, typeof(Byte[]), GetMaxLength, 0, 0); + public static readonly SqlDataType DbImage = new SqlDataType(SqlDbType.Image, typeof(Byte[]), GetMaxLength, 0, 0); + + public static readonly SqlDataType DbTimestamp = new SqlDataType(SqlDbType.Timestamp, typeof(Byte[]), 0, 0, 0); + public static readonly SqlDataType DbUniqueIdentifier = new SqlDataType(SqlDbType.UniqueIdentifier, typeof(Guid), 0, 0, 0); + + public static readonly SqlDataType DbVariant = new SqlDataType(SqlDbType.Variant, typeof(Object), 0, 0, 0); +#if !SILVERLIGHT + public static readonly SqlDataType DbXml = new SqlDataType(SqlDbType.Xml, typeof(SqlXml), 0, 0, 0); +#endif + public static readonly SqlDataType DbUdt = new SqlDataType(SqlDbType.Udt, typeof(Object), 0, 0, 0); +#if !MONO + public static readonly SqlDataType DbStructured = new SqlDataType(SqlDbType.Structured, typeof(Object), 0, 0, 0); +#endif + + public static readonly SqlDataType Boolean = DbBit; + public static readonly SqlDataType Char = new SqlDataType(SqlDbType.Char, typeof(Char), 1, 0, 0); + public static readonly SqlDataType SByte = new SqlDataType(SqlDbType.SmallInt, typeof(SByte), 0, 0, 0); + public static readonly SqlDataType Byte = DbTinyInt; + public static readonly SqlDataType Int16 = DbSmallInt; + public static readonly SqlDataType UInt16 = new SqlDataType(SqlDbType.Int, typeof(UInt16), 0, 0, 0); + public static readonly SqlDataType Int32 = DbInt; + public static readonly SqlDataType UInt32 = new SqlDataType(SqlDbType.BigInt, typeof(UInt32), 0, 0, 0); + public static readonly SqlDataType Int64 = DbBigInt; + public static readonly SqlDataType UInt64 = new SqlDataType(SqlDbType.Decimal, typeof(UInt64), 0, ulong.MaxValue.ToString().Length, 0); + public static readonly SqlDataType Single = DbReal; + public static readonly SqlDataType Double = DbFloat; + public static readonly SqlDataType Decimal = DbDecimal; + public static readonly SqlDataType DateTime = DbDateTime2; + public static readonly SqlDataType String = DbNVarChar; + public static readonly SqlDataType Guid = DbUniqueIdentifier; + public static readonly SqlDataType ByteArray = DbVarBinary; + public static readonly SqlDataType LinqBinary = DbVarBinary; + public static readonly SqlDataType CharArray = new SqlDataType(SqlDbType.NVarChar, typeof(Char[]), GetMaxLength, 0, 0); +#if !MONO + public static readonly SqlDataType DateTimeOffset = DbDateTimeOffset; +#endif + public static readonly SqlDataType TimeSpan = DbTime; + +#if !SILVERLIGHT + public static readonly SqlDataType SqlByte = new SqlDataType(SqlDbType.TinyInt, typeof(SqlByte), 0, 0, 0); + public static readonly SqlDataType SqlInt16 = new SqlDataType(SqlDbType.SmallInt, typeof(SqlInt16), 0, 0, 0); + public static readonly SqlDataType SqlInt32 = new SqlDataType(SqlDbType.Int, typeof(SqlInt32), 0, 0, 0); + public static readonly SqlDataType SqlInt64 = new SqlDataType(SqlDbType.BigInt, typeof(SqlInt64), 0, 0, 0); + public static readonly SqlDataType SqlSingle = new SqlDataType(SqlDbType.Real, typeof(SqlSingle), 0, 0, 0); + public static readonly SqlDataType SqlBoolean = new SqlDataType(SqlDbType.Bit, typeof(SqlBoolean), 0, 0, 0); + public static readonly SqlDataType SqlDouble = new SqlDataType(SqlDbType.Float, typeof(SqlDouble), 0, 0, 0); + public static readonly SqlDataType SqlDateTime = new SqlDataType(SqlDbType.DateTime, typeof(SqlDateTime), 0, 0, 0); + public static readonly SqlDataType SqlDecimal = new SqlDataType(SqlDbType.Decimal, typeof(SqlDecimal), 0, GetMaxPrecision, 10); + public static readonly SqlDataType SqlMoney = new SqlDataType(SqlDbType.Money, typeof(SqlMoney), 0, GetMaxPrecision, 4); + public static readonly SqlDataType SqlString = new SqlDataType(SqlDbType.NVarChar, typeof(SqlString), GetMaxLength, 0, 0); + public static readonly SqlDataType SqlBinary = new SqlDataType(SqlDbType.Binary, typeof(SqlBinary), GetMaxLength, 0, 0); + public static readonly SqlDataType SqlGuid = new SqlDataType(SqlDbType.UniqueIdentifier, typeof(SqlGuid), 0, 0, 0); + public static readonly SqlDataType SqlBytes = new SqlDataType(SqlDbType.Image, typeof(SqlBytes), GetMaxLength, 0, 0); + public static readonly SqlDataType SqlChars = new SqlDataType(SqlDbType.Text, typeof(SqlChars), GetMaxLength, 0, 0); + public static readonly SqlDataType SqlXml = new SqlDataType(SqlDbType.Xml, typeof(SqlXml), 0, 0, 0); +#endif + + #endregion + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ISqlExpression Members + + public int Precedence + { + get { return Sql.Precedence.Primary; } + } + + public Type SystemType + { + get { return typeof(Type); } + } + + #endregion + + #region ISqlExpressionWalkable Members + + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + return func(this); + } + + #endregion + + #region IEquatable Members + + bool IEquatable.Equals(ISqlExpression other) + { + if (this == other) + return true; + + var value = (SqlDataType)other; + return Type == value.Type && Length == value.Length && Precision == value.Precision && Scale == value.Scale; + } + + #endregion + + #region ISqlExpression Members + + public bool CanBeNull() + { + return false; + } + + public bool Equals(ISqlExpression other, Func comparer) + { + return ((ISqlExpression)this).Equals(other) && comparer(this, other); + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new SqlDataType(SqlDbType, Type, Length, Precision, Scale)); + + return clone; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.SqlDataType; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + sb.Append(SqlDbType); + + if (Length != 0) + sb.Append('(').Append(Length).Append(')'); + else if (Precision != 0) + sb.Append('(').Append(Precision).Append(',').Append(Scale).Append(')'); + + return sb; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlException.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlException.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,44 @@ +using System; +using System.Runtime.Serialization; + +namespace BLToolkit.Data.Sql +{ + public class SqlException : Exception + { + public SqlException() + : base("A BLToolkit Sql error has occurred.") + { + } + + public SqlException(string message) + : base(message) + { + } + + [JetBrains.Annotations.StringFormatMethod("message")] + public SqlException(string message, params object[] args) + : base(string.Format(message, args)) + { + } + + public SqlException(string message, Exception innerException) + : base(message, innerException) + { + } + + public SqlException(Exception innerException) + : base(innerException.Message, innerException) + { + } + +#if !SILVERLIGHT + + protected SqlException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + +#endif + } +} + diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlExpression.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlExpression.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,180 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BLToolkit.Data.Sql +{ + public class SqlExpression : ISqlExpression + { + public SqlExpression(Type systemType, string expr, int precedence, params ISqlExpression[] parameters) + { + if (parameters == null) throw new ArgumentNullException("parameters"); + + foreach (var value in parameters) + if (value == null) throw new ArgumentNullException("parameters"); + + SystemType = systemType; + Expr = expr; + Precedence = precedence; + Parameters = parameters; + } + + public SqlExpression(string expr, int precedence, params ISqlExpression[] parameters) + : this(null, expr, precedence, parameters) + { + } + + public SqlExpression(Type systemType, string expr, params ISqlExpression[] parameters) + : this(systemType, expr, Sql.Precedence.Unknown, parameters) + { + } + + public SqlExpression(string expr, params ISqlExpression[] parameters) + : this(null, expr, Sql.Precedence.Unknown, parameters) + { + } + + public Type SystemType { get; private set; } + public string Expr { get; private set; } + + public int Precedence { get; private set; } + public ISqlExpression[] Parameters { get; private set; } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + for (var i = 0; i < Parameters.Length; i++) + Parameters[i] = Parameters[i].Walk(skipColumns, func); + + return func(this); + } + + #endregion + + #region IEquatable Members + + bool IEquatable.Equals(ISqlExpression other) + { + return Equals(other, DefaultComparer); + } + + #endregion + + #region ISqlExpression Members + + public bool CanBeNull() + { + foreach (var value in Parameters) + if (value.CanBeNull()) + return true; + + return false; + } + + public static Func DefaultComparer = (x, y) => true; + + public bool Equals(ISqlExpression other, Func comparer) + { + if (this == other) + return true; + + var expr = other as SqlExpression; + + if (expr == null || SystemType != expr.SystemType || Expr != expr.Expr || Parameters.Length != expr.Parameters.Length) + return false; + + for (var i = 0; i < Parameters.Length; i++) + if (!Parameters[i].Equals(expr.Parameters[i], comparer)) + return false; + + return comparer(this, other); + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + { + objectTree.Add(this, clone = new SqlExpression( + SystemType, + Expr, + Precedence, + Parameters.Select(e => (ISqlExpression)e.Clone(objectTree, doClone)).ToArray())); + } + + return clone; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.SqlExpression; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + var len = sb.Length; + var ss = Parameters.Select(p => + { + p.ToString(sb, dic); + var s = sb.ToString(len, sb.Length - len); + sb.Length = len; + return (object)s; + }); + + return sb.AppendFormat(Expr, ss.ToArray()); + } + + #endregion + + #region Public Static Members + + public static bool NeedsEqual(IQueryElement ex) + { + switch (ex.ElementType) + { + case QueryElementType.SqlParameter: + case QueryElementType.SqlField : + case QueryElementType.Column : return true; + case QueryElementType.SqlFunction : + + var f = (SqlFunction)ex; + + switch (f.Name) + { + case "EXISTS" : return false; + } + + return true; + } + + return false; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlField.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlField.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BLToolkit.Data.Sql +{ + using DataAccess; + using Mapping; + + public class SqlField : IChild, ISqlExpression + { + public SqlField() + { + } + + public SqlField(SqlField field) + : this(field.SystemType, field.Name, field.PhysicalName, field.Nullable, field.PrimaryKeyOrder, field._nonUpdatableAttribute, field.MemberMapper) + { + } + + public SqlField( + Type systemType, + string name, + string physicalName, + bool nullable, + int pkOrder, + NonUpdatableAttribute nonUpdatableAttribute, + MemberMapper memberMapper) + { + SystemType = systemType; + Alias = name.Replace('.', '_'); + Name = name; + Nullable = nullable; + PrimaryKeyOrder = pkOrder; + _memberMapper = memberMapper; + _physicalName = physicalName; + _nonUpdatableAttribute = nonUpdatableAttribute; + } + + public Type SystemType { get; set; } + public string Alias { get; set; } + public string Name { get; set; } + public bool Nullable { get; set; } + public int PrimaryKeyOrder { get; set; } + public ISqlTableSource Table { get; private set; } + + readonly MemberMapper _memberMapper; + public MemberMapper MemberMapper + { + get { return _memberMapper; } + } + + private string _physicalName; + public string PhysicalName + { + get { return _physicalName ?? Name; } + set { _physicalName = value; } + } + + public bool IsIdentity { get { return _nonUpdatableAttribute != null && _nonUpdatableAttribute.IsIdentity; } } + public bool IsInsertable { get { return _nonUpdatableAttribute == null || !_nonUpdatableAttribute.OnInsert; } } + public bool IsUpdatable { get { return _nonUpdatableAttribute == null || !_nonUpdatableAttribute.OnUpdate; } } + + public bool IsPrimaryKey { get { return PrimaryKeyOrder != int.MinValue; } } + + readonly NonUpdatableAttribute _nonUpdatableAttribute; + + ISqlTableSource IChild.Parent { get { return Table; } set { Table = value; } } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ISqlExpression Members + + public bool CanBeNull() + { + return Nullable; + } + + public bool Equals(ISqlExpression other, Func comparer) + { + return this == other; + } + + public int Precedence + { + get { return Sql.Precedence.Primary; } + } + + #endregion + + #region ISqlExpressionWalkable Members + + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + return func(this); + } + + #endregion + + #region IEquatable Members + + bool IEquatable.Equals(ISqlExpression other) + { + return this == other; + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + Table.Clone(objectTree, doClone); + return objectTree[this]; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.SqlField; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + return sb + .Append('t') + .Append(Table.SourceID) + .Append('.') + .Append(Name); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlFunction.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlFunction.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,192 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BLToolkit.Data.Sql +{ + public class SqlFunction : ISqlExpression//ISqlTableSource + { + [Obsolete] + public SqlFunction(string name, params ISqlExpression[] parameters) + : this(null, name, Sql.Precedence.Primary, parameters) + { + } + + [Obsolete] + public SqlFunction(string name, int precedence, params ISqlExpression[] parameters) + : this(null, name, precedence, parameters) + { + } + + public SqlFunction(Type systemType, string name, params ISqlExpression[] parameters) + : this(systemType, name, Sql.Precedence.Primary, parameters) + { + } + + public SqlFunction(Type systemType, string name, int precedence, params ISqlExpression[] parameters) + { + //_sourceID = Interlocked.Increment(ref SqlQuery.SourceIDCounter); + + if (parameters == null) throw new ArgumentNullException("parameters"); + + foreach (var p in parameters) + if (p == null) throw new ArgumentNullException("parameters"); + + SystemType = systemType; + Name = name; + Precedence = precedence; + Parameters = parameters; + } + + public Type SystemType { get; private set; } + public string Name { get; private set; } + + public int Precedence { get; private set; } + public ISqlExpression[] Parameters { get; private set; } + + public static SqlFunction CreateCount (Type type, ISqlTableSource table) { return new SqlFunction(type, "Count", table.All); } + + public static SqlFunction CreateAll (SqlQuery subQuery) { return new SqlFunction(typeof(bool), "ALL", Sql.Precedence.Comparison, subQuery); } + public static SqlFunction CreateSome (SqlQuery subQuery) { return new SqlFunction(typeof(bool), "SOME", Sql.Precedence.Comparison, subQuery); } + public static SqlFunction CreateAny (SqlQuery subQuery) { return new SqlFunction(typeof(bool), "ANY", Sql.Precedence.Comparison, subQuery); } + public static SqlFunction CreateExists(SqlQuery subQuery) { return new SqlFunction(typeof(bool), "EXISTS", Sql.Precedence.Comparison, subQuery); } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func action) + { + for (var i = 0; i < Parameters.Length; i++) + Parameters[i] = Parameters[i].Walk(skipColumns, action); + + return action(this); + } + + #endregion + + #region IEquatable Members + + bool IEquatable.Equals(ISqlExpression other) + { + return Equals(other, SqlExpression.DefaultComparer); + } + + #endregion + + #region ISqlTableSource Members + + /* + readonly int _sourceID; + public int SourceID { get { return _sourceID; } } + + SqlField _all; + SqlField ISqlTableSource.All + { + get + { + if (_all == null) + { + _all = new SqlField(null, "*", "*", true, -1, null, null); + ((IChild)_all).Parent = this; + } + + return _all; + } + } + + IList ISqlTableSource.GetKeys(bool allIfEmpty) + { + return null; + } + */ + + #endregion + + #region ISqlExpression Members + + public bool CanBeNull() + { + return true; + } + + public bool Equals(ISqlExpression other, Func comparer) + { + if (this == other) + return true; + + var func = other as SqlFunction; + + if (func == null || Name != func.Name || Parameters.Length != func.Parameters.Length && SystemType != func.SystemType) + return false; + + for (var i = 0; i < Parameters.Length; i++) + if (!Parameters[i].Equals(func.Parameters[i], comparer)) + return false; + + return comparer(this, other); + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + { + objectTree.Add(this, clone = new SqlFunction( + SystemType, + Name, + Precedence, + Parameters.Select(e => (ISqlExpression)e.Clone(objectTree, doClone)).ToArray())); + } + + return clone; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.SqlFunction; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + sb + .Append(Name) + .Append("("); + + foreach (var p in Parameters) + { + p.ToString(sb, dic); + sb.Append(", "); + } + + if (Parameters.Length > 0) + sb.Length -= 2; + + return sb.Append(")"); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlParameter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlParameter.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; + +namespace BLToolkit.Data.Sql +{ + using Mapping; + + public class SqlParameter : SqlValueBase, ISqlExpression + { + public SqlParameter(Type systemType, string name, object value, MappingSchema mappingSchema) + { + IsQueryParameter = true; + Name = name; + SystemType = systemType; + _value = value; + DbType = DbType.Object; + + if (systemType != null && mappingSchema != null && systemType.IsEnum) + { + } + } + + public SqlParameter(Type systemType, string name, object value, Converter valueConverter) + : this(systemType, name, value, (MappingSchema)null) + { + ValueConverter = valueConverter; + } + + [Obsolete] + public SqlParameter(string name, object value) + : this(value == null ? null : value.GetType(), name, value, (MappingSchema)null) + { + } + + [Obsolete] + public SqlParameter(string name, object value, Converter valueConverter) + : this(value == null ? null : value.GetType(), name, value, valueConverter) + { + } + + public string Name { get; set; } + public Type SystemType { get; set; } + public bool IsQueryParameter { get; set; } + public DbType DbType { get; set; } + public int DbSize { get; set; } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ISqlExpression Members + + public int Precedence + { + get { return Sql.Precedence.Primary; } + } + + #endregion + + #region ISqlExpressionWalkable Members + + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + return func(this); + } + + #endregion + + #region IEquatable Members + + bool IEquatable.Equals(ISqlExpression other) + { + if (this == other) + return true; + + var p = other as SqlParameter; + return (object)p != null && Name != null && p.Name != null && Name == p.Name && SystemType == p.SystemType; + } + + #endregion + + #region ISqlExpression Members + + public bool CanBeNull() + { + if (SystemType == null && _value == null) + return true; + + return SqlDataType.CanBeNull(SystemType ?? _value.GetType()); + } + + public bool Equals(ISqlExpression other, Func comparer) + { + return ((ISqlExpression)this).Equals(other) && comparer(this, other); + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + { + var p = new SqlParameter(SystemType, Name, _value, ValueConverter) { IsQueryParameter = IsQueryParameter, DbType = DbType, DbSize = DbSize }; + + objectTree.Add(this, clone = p); + } + + return clone; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.SqlParameter; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + return sb + .Append('@') + .Append(Name ?? "parameter") + .Append('[') + .Append(Value ?? "NULL") + .Append(']'); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/AccessSqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/AccessSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,429 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + using Reflection; + + public class AccessSqlProvider : BasicSqlProvider + { + public override int CommandCount(SqlQuery sqlQuery) + { + return sqlQuery.IsInsert && sqlQuery.Insert.WithIdentity ? 2 : 1; + } + + protected override void BuildCommand(int commandNumber, StringBuilder sb) + { + sb.AppendLine("SELECT @@IDENTITY"); + } + + //public override bool IsSkipSupported { get { return SqlQuery.Select.TakeValue != null; } } + public override bool IsSkipSupported { get { return false; } } + public override bool TakeAcceptsParameter { get { return false; } } + public override bool IsCountSubQuerySupported { get { return false; } } + public override bool IsNestedJoinSupported { get { return false; } } + public override bool IsInsertOrUpdateSupported { get { return false; } } + + public override bool ConvertCountSubQuery(SqlQuery subQuery) + { + return !subQuery.Where.IsEmpty; + } + + #region Skip / Take Support + + protected override string FirstFormat { get { return "TOP {0}"; } } + + protected override void BuildSql(StringBuilder sb) + { + if (NeedSkip) + { + AlternativeBuildSql2(sb, base.BuildSql); + return; + } + + if (SqlQuery.From.Tables.Count == 0 && SqlQuery.Select.Columns.Count == 1) + { + if (SqlQuery.Select.Columns[0].Expression is SqlFunction) + { + var func = (SqlFunction)SqlQuery.Select.Columns[0].Expression; + + if (func.Name == "Iif" && func.Parameters.Length == 3 && func.Parameters[0] is SqlQuery.SearchCondition) + { + var sc = (SqlQuery.SearchCondition)func.Parameters[0]; + + if (sc.Conditions.Count == 1 && sc.Conditions[0].Predicate is SqlQuery.Predicate.FuncLike) + { + var p = (SqlQuery.Predicate.FuncLike)sc.Conditions[0].Predicate; + + if (p.Function.Name == "EXISTS") + { + BuildAnyAsCount(sb); + return; + } + } + } + } + else if (SqlQuery.Select.Columns[0].Expression is SqlQuery.SearchCondition) + { + var sc = (SqlQuery.SearchCondition)SqlQuery.Select.Columns[0].Expression; + + if (sc.Conditions.Count == 1 && sc.Conditions[0].Predicate is SqlQuery.Predicate.FuncLike) + { + var p = (SqlQuery.Predicate.FuncLike)sc.Conditions[0].Predicate; + + if (p.Function.Name == "EXISTS") + { + BuildAnyAsCount(sb); + return; + } + } + } + } + + base.BuildSql(sb); + } + + SqlQuery.Column _selectColumn; + + void BuildAnyAsCount(StringBuilder sb) + { + SqlQuery.SearchCondition cond; + + if (SqlQuery.Select.Columns[0].Expression is SqlFunction) + { + var func = (SqlFunction)SqlQuery.Select.Columns[0].Expression; + cond = (SqlQuery.SearchCondition)func.Parameters[0]; + } + else + { + cond = (SqlQuery.SearchCondition)SqlQuery.Select.Columns[0].Expression; + } + + var exist = ((SqlQuery.Predicate.FuncLike)cond.Conditions[0].Predicate).Function; + var query = (SqlQuery)exist.Parameters[0]; + + _selectColumn = new SqlQuery.Column(SqlQuery, new SqlExpression(cond.Conditions[0].IsNot ? "Count(*) = 0" : "Count(*) > 0"), SqlQuery.Select.Columns[0].Alias); + + BuildSql(0, query, sb, 0, 0, false); + + _selectColumn = null; + } + + protected override IEnumerable GetSelectedColumns() + { + if (_selectColumn != null) + return new[] { _selectColumn }; + + if (NeedSkip && !SqlQuery.OrderBy.IsEmpty) + return AlternativeGetSelectedColumns(base.GetSelectedColumns); + + return base.GetSelectedColumns(); + } + + protected override void BuildSkipFirst(StringBuilder sb) + { + if (NeedSkip) + { + if (!NeedTake) + { + sb.AppendFormat(" TOP {0}", int.MaxValue); + } + else if (!SqlQuery.OrderBy.IsEmpty) + { + sb.Append(" TOP "); + BuildExpression(sb, Add(SqlQuery.Select.SkipValue, SqlQuery.Select.TakeValue)); + } + } + else + base.BuildSkipFirst(sb); + } + + #endregion + + protected override ISqlProvider CreateSqlProvider() + { + return new AccessSqlProvider(); + } + + protected override bool ParenthesizeJoin() + { + return true; + } + + public override ISqlPredicate ConvertPredicate(ISqlPredicate predicate) + { + if (predicate is SqlQuery.Predicate.Like) + { + var l = (SqlQuery.Predicate.Like)predicate; + + if (l.Escape != null) + { + if (l.Expr2 is SqlValue && l.Escape is SqlValue) + { + var text = ((SqlValue) l.Expr2).Value.ToString(); + var val = new SqlValue(ReescapeLikeText(text, (char)((SqlValue)l.Escape).Value)); + + return new SqlQuery.Predicate.Like(l.Expr1, l.IsNot, val, null); + } + + if (l.Expr2 is SqlParameter) + { + var p = (SqlParameter)l.Expr2; + var v = ""; + + if (p.ValueConverter != null) + v = p.ValueConverter(" ") as string; + + p.SetLikeConverter(v.StartsWith("%") ? "%" : "", v.EndsWith("%") ? "%" : ""); + + return new SqlQuery.Predicate.Like(l.Expr1, l.IsNot, p, null); + } + } + } + + return base.ConvertPredicate(predicate); + } + + static string ReescapeLikeText(string text, char esc) + { + var sb = new StringBuilder(text.Length); + + for (var i = 0; i < text.Length; i++) + { + var c = text[i]; + + if (c == esc) + { + sb.Append('['); + sb.Append(text[++i]); + sb.Append(']'); + } + else if (c == '[') + sb.Append("[[]"); + else + sb.Append(c); + } + + return sb.ToString(); + } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlBinaryExpression) + { + var be = (SqlBinaryExpression)expr; + + switch (be.Operation[0]) + { + case '%': return new SqlBinaryExpression(be.SystemType, be.Expr1, "MOD", be.Expr2, Precedence.Additive - 1); + case '&': + case '|': + case '^': throw new SqlException("Operator '{0}' is not supported by the {1}.", be.Operation, GetType().Name); + } + } + else if (expr is SqlFunction) + { + var func = (SqlFunction) expr; + + switch (func.Name) + { + case "Coalesce": + + if (func.Parameters.Length > 2) + { + var parms = new ISqlExpression[func.Parameters.Length - 1]; + + Array.Copy(func.Parameters, 1, parms, 0, parms.Length); + return new SqlFunction(func.SystemType, func.Name, func.Parameters[0], new SqlFunction(func.SystemType, func.Name, parms)); + } + + var sc = new SqlQuery.SearchCondition(); + + sc.Conditions.Add(new SqlQuery.Condition(false, new SqlQuery.Predicate.IsNull(func.Parameters[0], false))); + + return new SqlFunction(func.SystemType, "Iif", sc, func.Parameters[1], func.Parameters[0]); + + case "CASE" : return ConvertCase(func.SystemType, func.Parameters, 0); + case "CharIndex" : + return func.Parameters.Length == 2? + new SqlFunction(func.SystemType, "InStr", new SqlValue(1), func.Parameters[1], func.Parameters[0], new SqlValue(1)): + new SqlFunction(func.SystemType, "InStr", func.Parameters[2], func.Parameters[1], func.Parameters[0], new SqlValue(1)); + + case "Convert" : + { + switch (Type.GetTypeCode(TypeHelper.GetUnderlyingType(func.SystemType))) + { + case TypeCode.String : return new SqlFunction(func.SystemType, "CStr", func.Parameters[1]); + case TypeCode.DateTime : + if (IsDateDataType(func.Parameters[0], "Date")) + return new SqlFunction(func.SystemType, "DateValue", func.Parameters[1]); + + if (IsTimeDataType(func.Parameters[0])) + return new SqlFunction(func.SystemType, "TimeValue", func.Parameters[1]); + + return new SqlFunction(func.SystemType, "CDate", func.Parameters[1]); + + default: + if (func.SystemType == typeof(DateTime)) + goto case TypeCode.DateTime; + break; + } + + return func.Parameters[1]; + } + + /* + case "Convert" : + { + string name = null; + + switch (((SqlDataType)func.Parameters[0]).DbType) + { + case SqlDbType.BigInt : name = "CLng"; break; + case SqlDbType.TinyInt : name = "CByte"; break; + case SqlDbType.Int : + case SqlDbType.SmallInt : name = "CInt"; break; + case SqlDbType.Bit : name = "CBool"; break; + case SqlDbType.Char : + case SqlDbType.Text : + case SqlDbType.VarChar : + case SqlDbType.NChar : + case SqlDbType.NText : + case SqlDbType.NVarChar : name = "CStr"; break; + case SqlDbType.DateTime : + case SqlDbType.Date : + case SqlDbType.Time : + case SqlDbType.DateTime2 : + case SqlDbType.SmallDateTime : + case SqlDbType.DateTimeOffset : name = "CDate"; break; + case SqlDbType.Decimal : name = "CDec"; break; + case SqlDbType.Float : name = "CDbl"; break; + case SqlDbType.Money : + case SqlDbType.SmallMoney : name = "CCur"; break; + case SqlDbType.Real : name = "CSng"; break; + case SqlDbType.Image : + case SqlDbType.Binary : + case SqlDbType.UniqueIdentifier : + case SqlDbType.Timestamp : + case SqlDbType.VarBinary : + case SqlDbType.Variant : + case SqlDbType.Xml : + case SqlDbType.Udt : + case SqlDbType.Structured : name = "CVar"; break; + } + + return new SqlFunction(name, func.Parameters[1]); + } + */ + } + } + + return expr; + } + + SqlFunction ConvertCase(Type systemType, ISqlExpression[] parameters, int start) + { + var len = parameters.Length - start; + + if (len < 3) + throw new SqlException("CASE statement is not supported by the {0}.", GetType().Name); + + if (len == 3) + return new SqlFunction(systemType, "Iif", parameters[start], parameters[start + 1], parameters[start + 2]); + + return new SqlFunction(systemType, "Iif", parameters[start], parameters[start + 1], ConvertCase(systemType, parameters, start + 2)); + } + + public override void BuildValue(StringBuilder sb, object value) + { + if (value is bool) + sb.Append(value); + else if (value is Guid) + sb.Append("'").Append(((Guid)value).ToString("B")).Append("'"); + else + base.BuildValue(sb, value); + } + + public override SqlQuery Finalize(SqlQuery sqlQuery) + { + sqlQuery = base.Finalize(sqlQuery); + + switch (sqlQuery.QueryType) + { + case QueryType.Delete : return GetAlternativeDelete(sqlQuery); + default : return sqlQuery; + } + } + + protected override void BuildUpdateClause(StringBuilder sb) + { + base.BuildFromClause(sb); + sb.Remove(0, 4).Insert(0, "UPDATE"); + base.BuildUpdateSet(sb); + } + + protected override void BuildFromClause(StringBuilder sb) + { + if (!SqlQuery.IsUpdate) + base.BuildFromClause(sb); + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter: + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return "@" + value; + + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryFieldAlias: + case ConvertType.NameToQueryTableAlias: + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '[') + return value; + } + + return "[" + value + "]"; + + case ConvertType.NameToDatabase: + case ConvertType.NameToOwner: + case ConvertType.NameToQueryTable: + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '[') + return value; + + if (name.IndexOf('.') > 0) + value = string.Join("].[", name.Split('.')); + } + + return "[" + value + "]"; + + case ConvertType.SprocParameterToName: + if (value != null) + { + var str = value.ToString(); + return str.Length > 0 && str[0] == '@'? str.Substring(1): str; + } + + break; + } + + return value; + } + + protected override void BuildDateTime(StringBuilder sb, object value) + { + sb.Append(string.Format("#{0:yyyy-MM-dd HH:mm:ss}#", value)); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/BasicSqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/BasicSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3606 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Globalization; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + using Mapping; + using Linq; + using Reflection; + + public abstract class BasicSqlProvider : ISqlProvider + { + #region Init + + public SqlQuery SqlQuery { get; set; } + public int Indent { get; set; } + + private int _nextNesting = 1; + private int _nesting; + public int Nesting + { + get { return _nesting; } + } + + bool _skipAlias; + + public Step BuildStep { get; set; } + + #endregion + + #region Support Flags + + public virtual bool SkipAcceptsParameter { get { return true; } } + public virtual bool TakeAcceptsParameter { get { return true; } } + public virtual bool IsTakeSupported { get { return true; } } + public virtual bool IsSkipSupported { get { return true; } } + public virtual bool IsSubQueryTakeSupported { get { return true; } } + public virtual bool IsSubQueryColumnSupported { get { return true; } } + public virtual bool IsCountSubQuerySupported { get { return true; } } + public virtual bool IsNestedJoinSupported { get { return true; } } + public virtual bool IsNestedJoinParenthesisRequired { get { return false; } } + public virtual bool IsIdentityParameterRequired { get { return false; } } + public virtual bool IsApplyJoinSupported { get { return false; } } + public virtual bool IsInsertOrUpdateSupported { get { return true; } } + public virtual bool CanCombineParameters { get { return true; } } + public virtual bool IsGroupByExpressionSupported { get { return true; } } + public virtual int MaxInListValuesCount { get { return int.MaxValue; } } + + public virtual bool ConvertCountSubQuery(SqlQuery subQuery) + { + return true; + } + + #endregion + + #region CommandCount + + public virtual int CommandCount(SqlQuery sqlQuery) + { + return 1; + } + + #endregion + + #region BuildSql + + public virtual int BuildSql(int commandNumber, SqlQuery sqlQuery, StringBuilder sb, int indent, int nesting, bool skipAlias) + { + SqlQuery = sqlQuery; + Indent = indent; + _nesting = nesting; + _nextNesting = _nesting + 1; + _skipAlias = skipAlias; + + if (commandNumber == 0) + { + BuildSql(sb); + + if (sqlQuery.HasUnion) + { + foreach (var union in sqlQuery.Unions) + { + AppendIndent(sb); + sb.Append("UNION"); + if (union.IsAll) sb.Append(" ALL"); + sb.AppendLine(); + + CreateSqlProvider().BuildSql(commandNumber, union.SqlQuery, sb, indent, nesting, skipAlias); + } + } + } + else + { + BuildCommand(commandNumber, sb); + } + + return _nextNesting; + } + + protected virtual void BuildCommand(int commandNumber, StringBuilder sb) + { + } + + #endregion + + #region Overrides + + protected virtual int BuildSqlBuilder(SqlQuery sqlQuery, StringBuilder sb, int indent, int nesting, bool skipAlias) + { + if (!IsSkipSupported && sqlQuery.Select.SkipValue != null) + throw new SqlException("Skip for subqueries is not supported by the '{0}' provider.", Name); + + if (!IsTakeSupported && sqlQuery.Select.TakeValue != null) + throw new SqlException("Take for subqueries is not supported by the '{0}' provider.", Name); + + return CreateSqlProvider().BuildSql(0, sqlQuery, sb, indent, nesting, skipAlias); + } + + protected abstract ISqlProvider CreateSqlProvider(); + + protected virtual bool ParenthesizeJoin() + { + return false; + } + + protected virtual void BuildSql(StringBuilder sb) + { + switch (SqlQuery.QueryType) + { + case QueryType.Select : BuildSelectQuery (sb); break; + case QueryType.Delete : BuildDeleteQuery (sb); break; + case QueryType.Update : BuildUpdateQuery (sb); break; + case QueryType.Insert : BuildInsertQuery (sb); break; + case QueryType.InsertOrUpdate : BuildInsertOrUpdateQuery(sb); break; + default : BuildUnknownQuery (sb); break; + } + } + + protected virtual void BuildDeleteQuery(StringBuilder sb) + { + BuildStep = Step.DeleteClause; BuildDeleteClause (sb); + BuildStep = Step.FromClause; BuildFromClause (sb); + BuildStep = Step.WhereClause; BuildWhereClause (sb); + BuildStep = Step.GroupByClause; BuildGroupByClause(sb); + BuildStep = Step.HavingClause; BuildHavingClause (sb); + BuildStep = Step.OrderByClause; BuildOrderByClause(sb); + BuildStep = Step.OffsetLimit; BuildOffsetLimit (sb); + } + + protected virtual void BuildUpdateQuery(StringBuilder sb) + { + BuildStep = Step.UpdateClause; BuildUpdateClause (sb); + BuildStep = Step.FromClause; BuildFromClause (sb); + BuildStep = Step.WhereClause; BuildWhereClause (sb); + BuildStep = Step.GroupByClause; BuildGroupByClause(sb); + BuildStep = Step.HavingClause; BuildHavingClause (sb); + BuildStep = Step.OrderByClause; BuildOrderByClause(sb); + BuildStep = Step.OffsetLimit; BuildOffsetLimit (sb); + } + + protected virtual void BuildSelectQuery(StringBuilder sb) + { + BuildStep = Step.SelectClause; BuildSelectClause (sb); + BuildStep = Step.FromClause; BuildFromClause (sb); + BuildStep = Step.WhereClause; BuildWhereClause (sb); + BuildStep = Step.GroupByClause; BuildGroupByClause(sb); + BuildStep = Step.HavingClause; BuildHavingClause (sb); + BuildStep = Step.OrderByClause; BuildOrderByClause(sb); + BuildStep = Step.OffsetLimit; BuildOffsetLimit (sb); + } + + protected virtual void BuildInsertQuery(StringBuilder sb) + { + BuildStep = Step.InsertClause; BuildInsertClause(sb); + + if (SqlQuery.QueryType == QueryType.Insert && SqlQuery.From.Tables.Count != 0) + { + BuildStep = Step.SelectClause; BuildSelectClause (sb); + BuildStep = Step.FromClause; BuildFromClause (sb); + BuildStep = Step.WhereClause; BuildWhereClause (sb); + BuildStep = Step.GroupByClause; BuildGroupByClause(sb); + BuildStep = Step.HavingClause; BuildHavingClause (sb); + BuildStep = Step.OrderByClause; BuildOrderByClause(sb); + BuildStep = Step.OffsetLimit; BuildOffsetLimit (sb); + } + + if (SqlQuery.Insert.WithIdentity) + BuildGetIdentity(sb); + } + + protected virtual void BuildUnknownQuery(StringBuilder sb) + { + throw new SqlException("Unknown query type '{0}'.", SqlQuery.QueryType); + } + + public virtual StringBuilder BuildTableName(StringBuilder sb, string database, string owner, string table) + { + if (database != null) + { + if (owner == null) sb.Append(database).Append(".."); + else sb.Append(database).Append(".").Append(owner).Append("."); + } + else if (owner != null) sb.Append(owner).Append("."); + + return sb.Append(table); + } + + public virtual object Convert(object value, ConvertType convertType) + { + return value; + } + + #endregion + + #region Build Select + + protected virtual void BuildSelectClause(StringBuilder sb) + { + AppendIndent(sb); + sb.Append("SELECT"); + + if (SqlQuery.Select.IsDistinct) + sb.Append(" DISTINCT"); + + BuildSkipFirst(sb); + + sb.AppendLine(); + BuildColumns(sb); + } + + protected virtual IEnumerable GetSelectedColumns() + { + return SqlQuery.Select.Columns; + } + + protected virtual void BuildColumns(StringBuilder sb) + { + Indent++; + + var first = true; + + foreach (var col in GetSelectedColumns()) + { + if (!first) + sb.Append(',').AppendLine(); + first = false; + + var addAlias = true; + + AppendIndent(sb); + BuildColumnExpression(sb, col.Expression, col.Alias, ref addAlias); + + if (!_skipAlias && addAlias && col.Alias != null) + sb.Append(" as ").Append(Convert(col.Alias, ConvertType.NameToQueryFieldAlias)); + } + + if (first) + AppendIndent(sb).Append("*"); + + Indent--; + + sb.AppendLine(); + } + +// protected virtual void BuildColumn(StringBuilder sb, SqlQuery.Column col, ref bool addAlias) +// { +// BuildExpression(sb, col.Expression, true, true, col.Alias, ref addAlias); +// } + + protected virtual void BuildColumnExpression(StringBuilder sb, ISqlExpression expr, string alias, ref bool addAlias) + { + BuildExpression(sb, expr, true, true, alias, ref addAlias); + } + + #endregion + + #region Build Delete + + protected virtual void BuildDeleteClause(StringBuilder sb) + { + AppendIndent(sb); + sb.Append("DELETE "); + } + + #endregion + + #region Build Update + + protected virtual void BuildUpdateClause(StringBuilder sb) + { + BuildUpdateTable(sb); + BuildUpdateSet (sb); + } + + protected virtual void BuildUpdateTable(StringBuilder sb) + { + AppendIndent(sb) + .AppendLine("UPDATE") + .Append('\t'); + BuildUpdateTableName(sb); + sb.AppendLine(); + } + + protected virtual void BuildUpdateTableName(StringBuilder sb) + { + if (SqlQuery.Update.Table != null && SqlQuery.Update.Table != SqlQuery.From.Tables[0].Source) + BuildPhysicalTable(sb, SqlQuery.Update.Table, null); + else + BuildTableName(sb, SqlQuery.From.Tables[0], true, true); + } + + protected virtual void BuildUpdateSet(StringBuilder sb) + { + AppendIndent(sb) + .AppendLine("SET"); + + Indent++; + + var first = true; + + foreach (var expr in SqlQuery.Update.Items) + { + if (!first) + sb.Append(',').AppendLine(); + first = false; + + AppendIndent(sb); + BuildExpression(sb, expr.Column, false, true); + sb.Append(" = "); + + var addAlias = false; + + BuildColumnExpression(sb, expr.Expression, null, ref addAlias); + } + + Indent--; + + sb.AppendLine(); + } + + #endregion + + #region Build Insert + + protected void BuildInsertClause(StringBuilder sb) + { + BuildInsertClause(sb, "INSERT INTO ", true); + } + + protected virtual void BuildEmptyInsert(StringBuilder sb) + { + sb.AppendLine("DEFAULT VALUES"); + } + + protected virtual void BuildInsertClause(StringBuilder sb, string insertText, bool appendTableName) + { + AppendIndent(sb).Append(insertText); + + if (appendTableName) + BuildPhysicalTable(sb, SqlQuery.Insert.Into, null); + + if (SqlQuery.Insert.Items.Count == 0) + { + sb.Append(' '); + BuildEmptyInsert(sb); + } + else + { + sb.AppendLine(); + + AppendIndent(sb).AppendLine("("); + + Indent++; + + var first = true; + + foreach (var expr in SqlQuery.Insert.Items) + { + if (!first) + sb.Append(',').AppendLine(); + first = false; + + AppendIndent(sb); + BuildExpression(sb, expr.Column, false, true); + } + + Indent--; + + sb.AppendLine(); + AppendIndent(sb).AppendLine(")"); + + if (SqlQuery.QueryType == QueryType.InsertOrUpdate || SqlQuery.From.Tables.Count == 0) + { + AppendIndent(sb).AppendLine("VALUES"); + AppendIndent(sb).AppendLine("("); + + Indent++; + + first = true; + + foreach (var expr in SqlQuery.Insert.Items) + { + if (!first) + sb.Append(',').AppendLine(); + first = false; + + AppendIndent(sb); + BuildExpression(sb, expr.Expression); + } + + Indent--; + + sb.AppendLine(); + AppendIndent(sb).AppendLine(")"); + } + } + } + + protected virtual void BuildGetIdentity(StringBuilder sb) + { + //throw new SqlException("Insert with identity is not supported by the '{0}' sql provider.", Name); + } + + #endregion + + #region Build InsertOrUpdate + + protected virtual void BuildInsertOrUpdateQuery(StringBuilder sb) + { + throw new SqlException("InsertOrUpdate query type is not supported by {0} provider.", Name); + } + + protected void BuildInsertOrUpdateQueryAsMerge(StringBuilder sb, string fromDummyTable) + { + var table = SqlQuery.Insert.Into; + var targetAlias = Convert(SqlQuery.From.Tables[0].Alias, ConvertType.NameToQueryTableAlias).ToString(); + var sourceAlias = Convert(GetTempAliases(1, "s")[0], ConvertType.NameToQueryTableAlias).ToString(); + var keys = SqlQuery.Update.Keys; + + AppendIndent(sb).Append("MERGE INTO "); + BuildPhysicalTable(sb, table, null); + sb.Append(' ').AppendLine(targetAlias); + + AppendIndent(sb).Append("USING (SELECT "); + + for (var i = 0; i < keys.Count; i++) + { + BuildExpression(sb, keys[i].Expression, false, false); + sb.Append(" AS "); + BuildExpression(sb, keys[i].Column, false, false); + + if (i + 1 < keys.Count) + sb.Append(", "); + } + + if (!string.IsNullOrEmpty(fromDummyTable)) + sb.Append(' ').Append(fromDummyTable); + + sb.Append(") ").Append(sourceAlias).AppendLine(" ON"); + + AppendIndent(sb).AppendLine("("); + + Indent++; + + for (var i = 0; i < keys.Count; i++) + { + var key = keys[i]; + + AppendIndent(sb); + + sb.Append(targetAlias).Append('.'); + BuildExpression(sb, key.Column, false, false); + + sb.Append(" = ").Append(sourceAlias).Append('.'); + BuildExpression(sb, key.Column, false, false); + + if (i + 1 < keys.Count) + sb.Append(" AND"); + + sb.AppendLine(); + } + + Indent--; + + AppendIndent(sb).AppendLine(")"); + AppendIndent(sb).AppendLine("WHEN MATCHED THEN"); + + Indent++; + AppendIndent(sb).AppendLine("UPDATE "); + BuildUpdateSet(sb); + Indent--; + + AppendIndent(sb).AppendLine("WHEN NOT MATCHED THEN"); + + Indent++; + BuildInsertClause(sb, "INSERT", false); + Indent--; + + while (_endLine.Contains(sb[sb.Length - 1])) + sb.Length--; + } + + static readonly char[] _endLine = new[] { ' ', '\r', '\n' }; + + protected void BuildInsertOrUpdateQueryAsUpdateInsert(StringBuilder sb) + { + AppendIndent(sb).AppendLine("BEGIN TRAN").AppendLine(); + + BuildUpdateQuery(sb); + + AppendIndent(sb).AppendLine("WHERE"); + + var alias = Convert(SqlQuery.From.Tables[0].Alias, ConvertType.NameToQueryTableAlias).ToString(); + var exprs = SqlQuery.Update.Keys; + + Indent++; + + for (var i = 0; i < exprs.Count; i++) + { + var expr = exprs[i]; + + AppendIndent(sb); + + sb.Append(alias).Append('.'); + BuildExpression(sb, expr.Column, false, false); + + sb.Append(" = "); + BuildExpression(sb, Precedence.Comparison, expr.Expression); + + if (i + 1 < exprs.Count) + sb.Append(" AND"); + + sb.AppendLine(); + } + + Indent--; + + sb.AppendLine(); + AppendIndent(sb).AppendLine("IF @@ROWCOUNT = 0"); + AppendIndent(sb).AppendLine("BEGIN"); + + Indent++; + + BuildInsertQuery(sb); + + Indent--; + + AppendIndent(sb).AppendLine("END"); + + sb.AppendLine(); + AppendIndent(sb).AppendLine("COMMIT"); + } + + #endregion + + #region Build From + + protected virtual void BuildFromClause(StringBuilder sb) + { + if (SqlQuery.From.Tables.Count == 0) + return; + + AppendIndent(sb); + + sb.Append("FROM").AppendLine(); + + Indent++; + AppendIndent(sb); + + var first = true; + + foreach (var ts in SqlQuery.From.Tables) + { + if (!first) + { + sb.AppendLine(","); + AppendIndent(sb); + } + + first = false; + + var jn = ParenthesizeJoin() ? ts.GetJoinNumber() : 0; + + if (jn > 0) + { + jn--; + for (var i = 0; i < jn; i++) + sb.Append("("); + } + + BuildTableName(sb, ts, true, true); + + foreach (var jt in ts.Joins) + BuildJoinTable(sb, jt, ref jn); + } + + Indent--; + + sb.AppendLine(); + } + + protected void BuildPhysicalTable(StringBuilder sb, ISqlTableSource table, string alias) + { + switch (table.ElementType) + { + case QueryElementType.SqlTable : + case QueryElementType.TableSource : + sb.Append(GetTablePhysicalName(table, alias)); + break; + + case QueryElementType.SqlQuery : + sb.Append("(").AppendLine(); + _nextNesting = BuildSqlBuilder((SqlQuery)table, sb, Indent + 1, _nextNesting, false); + AppendIndent(sb).Append(")"); + + break; + + default: + throw new InvalidOperationException(); + } + } + + protected void BuildTableName(StringBuilder sb, SqlQuery.TableSource ts, bool buildName, bool buildAlias) + { + if (buildName) + { + var alias = GetTableAlias(ts); + BuildPhysicalTable(sb, ts.Source, alias); + } + + if (buildAlias) + { + if (ts.SqlTableType != SqlTableType.Expression) + { + var alias = GetTableAlias(ts); + + if (!string.IsNullOrEmpty(alias)) + { + if (buildName) + sb.Append(" "); + sb.Append(Convert(alias, ConvertType.NameToQueryTableAlias)); + } + + } + } + } + + void BuildJoinTable(StringBuilder sb, SqlQuery.JoinedTable join, ref int joinCounter) + { + sb.AppendLine(); + Indent++; + AppendIndent(sb); + + var buildOn = BuildJoinType(sb, join); + + if (IsNestedJoinParenthesisRequired && join.Table.Joins.Count != 0) + sb.Append('('); + + BuildTableName(sb, join.Table, true, true); + + if (IsNestedJoinSupported && join.Table.Joins.Count != 0) + { + foreach (var jt in join.Table.Joins) + BuildJoinTable(sb, jt, ref joinCounter); + + if (IsNestedJoinParenthesisRequired && join.Table.Joins.Count != 0) + sb.Append(')'); + + if (buildOn) + { + sb.AppendLine(); + AppendIndent(sb); + sb.Append("ON "); + } + } + else if (buildOn) + sb.Append(" ON "); + + if (buildOn) + { + if (join.Condition.Conditions.Count != 0) + BuildSearchCondition(sb, Precedence.Unknown, join.Condition); + else + sb.Append("1=1"); + } + + if (joinCounter > 0) + { + joinCounter--; + sb.Append(")"); + } + + if (!IsNestedJoinSupported) + foreach (var jt in join.Table.Joins) + BuildJoinTable(sb, jt, ref joinCounter); + + Indent--; + } + + protected virtual bool BuildJoinType(StringBuilder sb, SqlQuery.JoinedTable join) + { + switch (join.JoinType) + { + case SqlQuery.JoinType.Inner : sb.Append("INNER JOIN "); return true; + case SqlQuery.JoinType.Left : sb.Append("LEFT JOIN "); return true; + case SqlQuery.JoinType.CrossApply : sb.Append("CROSS APPLY "); return false; + case SqlQuery.JoinType.OuterApply : sb.Append("OUTER APPLY "); return false; + default: throw new InvalidOperationException(); + } + } + + #endregion + + #region Where Clause + + protected virtual bool BuildWhere() + { + return SqlQuery.Where.SearchCondition.Conditions.Count != 0; + } + + protected virtual void BuildWhereClause(StringBuilder sb) + { + if (!BuildWhere()) + return; + + AppendIndent(sb); + + sb.Append("WHERE").AppendLine(); + + Indent++; + AppendIndent(sb); + BuildWhereSearchCondition(sb, SqlQuery.Where.SearchCondition); + Indent--; + + sb.AppendLine(); + } + + #endregion + + #region GroupBy Clause + + protected virtual void BuildGroupByClause(StringBuilder sb) + { + if (SqlQuery.GroupBy.Items.Count == 0) + return; + + AppendIndent(sb); + + sb.Append("GROUP BY").AppendLine(); + + Indent++; + + for (var i = 0; i < SqlQuery.GroupBy.Items.Count; i++) + { + AppendIndent(sb); + + BuildExpression(sb, SqlQuery.GroupBy.Items[i]); + + if (i + 1 < SqlQuery.GroupBy.Items.Count) + sb.Append(','); + + sb.AppendLine(); + } + + Indent--; + } + + #endregion + + #region Having Clause + + protected virtual void BuildHavingClause(StringBuilder sb) + { + if (SqlQuery.Having.SearchCondition.Conditions.Count == 0) + return; + + AppendIndent(sb); + + sb.Append("HAVING").AppendLine(); + + Indent++; + AppendIndent(sb); + BuildWhereSearchCondition(sb, SqlQuery.Having.SearchCondition); + Indent--; + + sb.AppendLine(); + } + + #endregion + + #region OrderBy Clause + + protected virtual void BuildOrderByClause(StringBuilder sb) + { + if (SqlQuery.OrderBy.Items.Count == 0) + return; + + AppendIndent(sb); + + sb.Append("ORDER BY").AppendLine(); + + Indent++; + + for (var i = 0; i < SqlQuery.OrderBy.Items.Count; i++) + { + AppendIndent(sb); + + var item = SqlQuery.OrderBy.Items[i]; + + BuildExpression(sb, item.Expression); + + if (item.IsDescending) + sb.Append(" DESC"); + + if (i + 1 < SqlQuery.OrderBy.Items.Count) + sb.Append(','); + + sb.AppendLine(); + } + + Indent--; + } + + #endregion + + #region Skip/Take + + protected virtual bool SkipFirst { get { return true; } } + protected virtual string SkipFormat { get { return null; } } + protected virtual string FirstFormat { get { return null; } } + protected virtual string LimitFormat { get { return null; } } + protected virtual string OffsetFormat { get { return null; } } + protected virtual bool OffsetFirst { get { return false; } } + + protected bool NeedSkip { get { return SqlQuery.Select.SkipValue != null && IsSkipSupported; } } + protected bool NeedTake { get { return SqlQuery.Select.TakeValue != null && IsTakeSupported; } } + + protected virtual void BuildSkipFirst(StringBuilder sb) + { + if (SkipFirst && NeedSkip && SkipFormat != null) + sb.Append(' ').AppendFormat(SkipFormat, BuildExpression(new StringBuilder(), SqlQuery.Select.SkipValue)); + + if (NeedTake && FirstFormat != null) + sb.Append(' ').AppendFormat(FirstFormat, BuildExpression(new StringBuilder(), SqlQuery.Select.TakeValue)); + + if (!SkipFirst && NeedSkip && SkipFormat != null) + sb.Append(' ').AppendFormat(SkipFormat, BuildExpression(new StringBuilder(), SqlQuery.Select.SkipValue)); + } + + protected virtual void BuildOffsetLimit(StringBuilder sb) + { + var doSkip = NeedSkip && OffsetFormat != null; + var doTake = NeedTake && LimitFormat != null; + + if (doSkip || doTake) + { + AppendIndent(sb); + + if (doSkip && OffsetFirst) + { + sb.AppendFormat(OffsetFormat, BuildExpression(new StringBuilder(), SqlQuery.Select.SkipValue)); + + if (doTake) + sb.Append(' '); + } + + if (doTake) + { + sb.AppendFormat(LimitFormat, BuildExpression(new StringBuilder(), SqlQuery.Select.TakeValue)); + + if (doSkip) + sb.Append(' '); + } + + if (doSkip && !OffsetFirst) + sb.AppendFormat(OffsetFormat, BuildExpression(new StringBuilder(), SqlQuery.Select.SkipValue)); + + sb.AppendLine(); + } + } + + #endregion + + #region Builders + + #region BuildSearchCondition + + protected virtual void BuildWhereSearchCondition(StringBuilder sb, SqlQuery.SearchCondition condition) + { + BuildSearchCondition(sb, Precedence.Unknown, condition); + } + + protected virtual void BuildSearchCondition(StringBuilder sb, SqlQuery.SearchCondition condition) + { + var isOr = (bool?)null; + var len = sb.Length; + var parentPrecedence = condition.Precedence + 1; + + foreach (var cond in condition.Conditions) + { + if (isOr != null) + { + sb.Append(isOr.Value ? " OR" : " AND"); + + if (condition.Conditions.Count < 4 && sb.Length - len < 50 || condition != SqlQuery.Where.SearchCondition) + { + sb.Append(' '); + } + else + { + sb.AppendLine(); + AppendIndent(sb); + len = sb.Length; + } + } + + if (cond.IsNot) + sb.Append("NOT "); + + var precedence = GetPrecedence(cond.Predicate); + + BuildPredicate(sb, cond.IsNot ? Precedence.LogicalNegation : parentPrecedence, precedence, cond.Predicate); + + isOr = cond.IsOr; + } + } + + protected virtual void BuildSearchCondition(StringBuilder sb, int parentPrecedence, SqlQuery.SearchCondition condition) + { + var wrap = Wrap(GetPrecedence(condition as ISqlExpression), parentPrecedence); + + if (wrap) sb.Append('('); + BuildSearchCondition(sb, condition); + if (wrap) sb.Append(')'); + } + + #endregion + + #region BuildPredicate + + protected virtual void BuildPredicate(StringBuilder sb, ISqlPredicate predicate) + { + switch (predicate.ElementType) + { + case QueryElementType.ExprExprPredicate : + { + var expr = (SqlQuery.Predicate.ExprExpr)predicate; + + switch (expr.Operator) + { + case SqlQuery.Predicate.Operator.Equal : + case SqlQuery.Predicate.Operator.NotEqual : + { + ISqlExpression e = null; + + if (expr.Expr1 is SqlValueBase && ((SqlValueBase)expr.Expr1).Value == null) + e = expr.Expr2; + else if (expr.Expr2 is SqlValueBase && ((SqlValueBase)expr.Expr2).Value == null) + e = expr.Expr1; + + if (e != null) + { + BuildExpression(sb, GetPrecedence(expr), e); + sb.Append(expr.Operator == SqlQuery.Predicate.Operator.Equal ? " IS NULL" : " IS NOT NULL"); + return; + } + + break; + } + } + + BuildExpression(sb, GetPrecedence(expr), expr.Expr1); + + switch (expr.Operator) + { + case SqlQuery.Predicate.Operator.Equal : sb.Append(" = "); break; + case SqlQuery.Predicate.Operator.NotEqual : sb.Append(" <> "); break; + case SqlQuery.Predicate.Operator.Greater : sb.Append(" > "); break; + case SqlQuery.Predicate.Operator.GreaterOrEqual : sb.Append(" >= "); break; + case SqlQuery.Predicate.Operator.NotGreater : sb.Append(" !> "); break; + case SqlQuery.Predicate.Operator.Less : sb.Append(" < "); break; + case SqlQuery.Predicate.Operator.LessOrEqual : sb.Append(" <= "); break; + case SqlQuery.Predicate.Operator.NotLess : sb.Append(" !< "); break; + } + + BuildExpression(sb, GetPrecedence(expr), expr.Expr2); + } + + break; + + case QueryElementType.LikePredicate : + BuildLikePredicate(sb, (SqlQuery.Predicate.Like)predicate); + break; + + case QueryElementType.BetweenPredicate : + { + var p = (SqlQuery.Predicate.Between)predicate; + BuildExpression(sb, GetPrecedence(p), p.Expr1); + if (p.IsNot) sb.Append(" NOT"); + sb.Append(" BETWEEN "); + BuildExpression(sb, GetPrecedence(p), p.Expr2); + sb.Append(" AND "); + BuildExpression(sb, GetPrecedence(p), p.Expr3); + } + + break; + + case QueryElementType.IsNullPredicate : + { + var p = (SqlQuery.Predicate.IsNull)predicate; + BuildExpression(sb, GetPrecedence(p), p.Expr1); + sb.Append(p.IsNot ? " IS NOT NULL" : " IS NULL"); + } + + break; + + case QueryElementType.InSubQueryPredicate : + { + var p = (SqlQuery.Predicate.InSubQuery)predicate; + BuildExpression(sb, GetPrecedence(p), p.Expr1); + sb.Append(p.IsNot ? " NOT IN " : " IN "); + BuildExpression(sb, GetPrecedence(p), p.SubQuery); + } + + break; + + case QueryElementType.InListPredicate : + BuildInListPredicate(predicate, sb); + break; + + case QueryElementType.FuncLikePredicate : + { + var f = (SqlQuery.Predicate.FuncLike)predicate; + BuildExpression(sb, f.Function.Precedence, f.Function); + } + + break; + + case QueryElementType.SearchCondition : + BuildSearchCondition(sb, predicate.Precedence, (SqlQuery.SearchCondition)predicate); + break; + + case QueryElementType.NotExprPredicate : + { + var p = (SqlQuery.Predicate.NotExpr)predicate; + + if (p.IsNot) + sb.Append("NOT "); + + BuildExpression(sb, p.IsNot ? Precedence.LogicalNegation : GetPrecedence(p), p.Expr1); + } + + break; + + case QueryElementType.ExprPredicate : + { + var p = (SqlQuery.Predicate.Expr)predicate; + + if (p.Expr1 is SqlValue) + { + var value = ((SqlValue)p.Expr1).Value; + + if (value is bool) + { + sb.Append((bool)value ? "1 = 1" : "1 = 0"); + return; + } + } + + BuildExpression(sb, GetPrecedence(p), p.Expr1); + } + + break; + + default : + throw new InvalidOperationException(); + } + } + + static SqlField GetUnderlayingField(ISqlExpression expr) + { + switch (expr.ElementType) + { + case QueryElementType.SqlField: return (SqlField)expr; + case QueryElementType.Column : return GetUnderlayingField(((SqlQuery.Column)expr).Expression); + } + + throw new InvalidOperationException(); + } + + void BuildInListPredicate(ISqlPredicate predicate, StringBuilder sb) + { + var p = (SqlQuery.Predicate.InList)predicate; + + if (p.Values == null || p.Values.Count == 0) + { + BuildPredicate(sb, new SqlQuery.Predicate.Expr(new SqlValue(false))); + } + else + { + ICollection values = p.Values; + + if (p.Values.Count == 1 && p.Values[0] is SqlParameter && + !(p.Expr1.SystemType == typeof(string) && ((SqlParameter)p.Values[0]).Value is string)) + { + var pr = (SqlParameter)p.Values[0]; + + if (pr.Value == null) + { + BuildPredicate(sb, new SqlQuery.Predicate.Expr(new SqlValue(false))); + return; + } + + if (pr.Value is IEnumerable) + { + var items = (IEnumerable)pr.Value; + + if (p.Expr1 is ISqlTableSource) + { + var firstValue = true; + var table = (ISqlTableSource)p.Expr1; + var keys = table.GetKeys(true); + + if (keys == null || keys.Count == 0) + throw new SqlException("Cannot create IN expression."); + + if (keys.Count == 1) + { + foreach (var item in items) + { + if (firstValue) + { + firstValue = false; + BuildExpression(sb, GetPrecedence(p), keys[0]); + sb.Append(p.IsNot ? " NOT IN (" : " IN ("); + } + + var field = GetUnderlayingField(keys[0]); + var value = field.MemberMapper.GetValue(item); + + if (value is ISqlExpression) + BuildExpression(sb, (ISqlExpression)value); + else + BuildValue(sb, value); + + sb.Append(", "); + } + } + else + { + var len = sb.Length; + var rem = 1; + + foreach (var item in items) + { + if (firstValue) + { + firstValue = false; + sb.Append('('); + } + + foreach (var key in keys) + { + var field = GetUnderlayingField(key); + var value = field.MemberMapper.GetValue(item); + + BuildExpression(sb, GetPrecedence(p), key); + + if (value == null) + { + sb.Append(" IS NULL"); + } + else + { + sb.Append(" = "); + BuildValue(sb, value); + } + + sb.Append(" AND "); + } + + sb.Remove(sb.Length - 4, 4).Append("OR "); + + if (sb.Length - len >= 50) + { + sb.AppendLine(); + AppendIndent(sb); + sb.Append(' '); + len = sb.Length; + rem = 5 + Indent; + } + } + + if (!firstValue) + sb.Remove(sb.Length - rem, rem); + } + + if (firstValue) + BuildPredicate(sb, new SqlQuery.Predicate.Expr(new SqlValue(p.IsNot))); + else + sb.Remove(sb.Length - 2, 2).Append(')'); + } + else + { + BuildInListValues(sb, p, items); + } + + return; + } + } + + BuildInListValues(sb, p, values); + } + } + + void BuildInListValues(StringBuilder sb, SqlQuery.Predicate.InList predicate, IEnumerable values) + { + var firstValue = true; + var len = sb.Length; + var hasNull = false; + var count = 0; + var longList = false; + + foreach (var value in values) + { + if (count++ >= MaxInListValuesCount) + { + count = 1; + longList = true; + + // start building next bucked + firstValue = true; + sb.Remove(sb.Length - 2, 2).Append(')'); + sb.Append(" OR "); + } + + var val = value; + + if (val is IValueContainer) + val = ((IValueContainer)value).Value; + + if (val == null) + { + hasNull = true; + continue; + } + + if (firstValue) + { + firstValue = false; + BuildExpression(sb, GetPrecedence(predicate), predicate.Expr1); + sb.Append(predicate.IsNot ? " NOT IN (" : " IN ("); + } + + if (value is ISqlExpression) + BuildExpression(sb, (ISqlExpression)value); + else + BuildValue(sb, value); + + sb.Append(", "); + } + + if (firstValue) + { + BuildPredicate(sb, + hasNull ? + new SqlQuery.Predicate.IsNull(predicate.Expr1, predicate.IsNot) : + new SqlQuery.Predicate.Expr(new SqlValue(predicate.IsNot))); + } + else + { + sb.Remove(sb.Length - 2, 2).Append(')'); + + if (hasNull) + { + sb.Insert(len, "("); + sb.Append(" OR "); + BuildPredicate(sb, new SqlQuery.Predicate.IsNull(predicate.Expr1, predicate.IsNot)); + sb.Append(")"); + } + } + + if (longList && !hasNull) + { + sb.Insert(len, "("); + sb.Append(")"); + } + } + + protected void BuildPredicate(StringBuilder sb, int parentPrecedence, ISqlPredicate predicate) + { + BuildPredicate(sb, parentPrecedence, GetPrecedence(predicate), predicate); + } + + protected void BuildPredicate(StringBuilder sb, int parentPrecedence, int precedence, ISqlPredicate predicate) + { + var wrap = Wrap(precedence, parentPrecedence); + + if (wrap) sb.Append('('); + BuildPredicate(sb, predicate); + if (wrap) sb.Append(')'); + } + + protected virtual void BuildLikePredicate(StringBuilder sb, SqlQuery.Predicate.Like predicate) + { + var precedence = GetPrecedence(predicate); + + BuildExpression(sb, precedence, predicate.Expr1); + sb.Append(predicate.IsNot? " NOT LIKE ": " LIKE "); + BuildExpression(sb, precedence, predicate.Expr2); + + if (predicate.Escape != null) + { + sb.Append(" ESCAPE "); + BuildExpression(sb, predicate.Escape); + } + } + + #endregion + + #region BuildExpression + + protected virtual StringBuilder BuildExpression( + StringBuilder sb, + ISqlExpression expr, + bool buildTableName, + bool checkParentheses, + string alias, + ref bool addAlias) + { + expr = ConvertExpression(expr); + + switch (expr.ElementType) + { + case QueryElementType.SqlField: + { + var field = (SqlField)expr; + + if (field == field.Table.All) + { + sb.Append("*"); + } + else + { + if (buildTableName) + { + var ts = SqlQuery.GetTableSource(field.Table); + + if (ts == null) + { +#if DEBUG + SqlQuery.GetTableSource(field.Table); +#endif + + throw new SqlException(string.Format("Table '{0}' not found.", field.Table)); + } + + var table = GetTableAlias(ts); + + table = table == null ? + GetTablePhysicalName(field.Table, null) : + Convert(table, ConvertType.NameToQueryTableAlias).ToString(); + + if (string.IsNullOrEmpty(table)) + throw new SqlException(string.Format("Table {0} should have an alias.", field.Table)); + + addAlias = alias != field.PhysicalName; + + sb + .Append(table) + .Append('.'); + } + + sb.Append(Convert(field.PhysicalName, ConvertType.NameToQueryField)); + } + } + + break; + + case QueryElementType.Column: + { + var column = (SqlQuery.Column)expr; + +#if DEBUG + //if (column.ToString() == "t8.ParentID") + //{ + // column.ToString(); + //} + + var sql = SqlQuery.SqlText; +#endif + + var table = SqlQuery.GetTableSource(column.Parent); + + if (table == null) + { +#if DEBUG + table = SqlQuery.GetTableSource(column.Parent); +#endif + + throw new SqlException(string.Format("Table not found for '{0}'.", column)); + } + + var tableAlias = GetTableAlias(table) ?? GetTablePhysicalName(column.Parent, null); + + if (string.IsNullOrEmpty(tableAlias)) + throw new SqlException(string.Format("Table {0} should have an alias.", column.Parent)); + + addAlias = alias != column.Alias; + + sb + .Append(Convert(tableAlias, ConvertType.NameToQueryTableAlias)) + .Append('.') + .Append(Convert(column.Alias, ConvertType.NameToQueryField)); + } + + break; + + case QueryElementType.SqlQuery: + { + var hasParentheses = checkParentheses && sb[sb.Length - 1] == '('; + + if (!hasParentheses) + sb.Append("("); + sb.AppendLine(); + + _nextNesting = BuildSqlBuilder((SqlQuery)expr, sb, Indent + 1, _nextNesting, BuildStep != Step.FromClause); + + AppendIndent(sb); + + if (!hasParentheses) + sb.Append(")"); + } + + break; + + case QueryElementType.SqlValue: + BuildValue(sb, ((SqlValue)expr).Value); + break; + + case QueryElementType.SqlExpression: + { + var e = (SqlExpression)expr; + var s = new StringBuilder(); + + if (e.Parameters == null || e.Parameters.Length == 0) + sb.Append(e.Expr); + else + { + var values = new object[e.Parameters.Length]; + + for (var i = 0; i < values.Length; i++) + { + var value = e.Parameters[i]; + + s.Length = 0; + BuildExpression(s, GetPrecedence(e), value); + values[i] = s.ToString(); + } + + sb.AppendFormat(e.Expr, values); + } + } + + break; + + case QueryElementType.SqlBinaryExpression: + BuildBinaryExpression(sb, (SqlBinaryExpression)expr); + break; + + case QueryElementType.SqlFunction: + BuildFunction(sb, (SqlFunction)expr); + break; + + case QueryElementType.SqlParameter: + { + var parm = (SqlParameter)expr; + + if (parm.IsQueryParameter) + { + var name = Convert(parm.Name, ConvertType.NameToQueryParameter); + sb.Append(name); + } + else + BuildValue(sb, parm.Value); + } + + break; + + case QueryElementType.SqlDataType: + BuildDataType(sb, (SqlDataType)expr); + break; + + case QueryElementType.SearchCondition: + BuildSearchCondition(sb, expr.Precedence, (SqlQuery.SearchCondition)expr); + break; + + default: + throw new InvalidOperationException(); + } + + return sb; + } + + protected void BuildExpression(StringBuilder sb, int parentPrecedence, ISqlExpression expr, string alias, ref bool addAlias) + { + var wrap = Wrap(GetPrecedence(expr), parentPrecedence); + + if (wrap) sb.Append('('); + BuildExpression(sb, expr, true, true, alias, ref addAlias); + if (wrap) sb.Append(')'); + } + + protected StringBuilder BuildExpression(StringBuilder sb, ISqlExpression expr) + { + var dummy = false; + return BuildExpression(sb, expr, true, true, null, ref dummy); + } + + protected StringBuilder BuildExpression(StringBuilder sb, ISqlExpression expr, bool buildTableName, bool checkParentheses) + { + var dummy = false; + return BuildExpression(sb, expr, buildTableName, checkParentheses, null, ref dummy); + } + + protected void BuildExpression(StringBuilder sb, int precedence, ISqlExpression expr) + { + var dummy = false; + BuildExpression(sb, precedence, expr, null, ref dummy); + } + + #endregion + + #region BuildValue + + interface INullableValueReader + { + object GetValue(object value); + } + + class NullableValueReader : INullableValueReader where T : struct + { + public object GetValue(object value) + { + return ((T?)value).Value; + } + } + + static readonly Dictionary _nullableValueReader = new Dictionary(); + + public NumberFormatInfo NumberFormatInfo = new NumberFormatInfo + { + CurrencyDecimalDigits = NumberFormatInfo.InvariantInfo.CurrencyDecimalDigits, + CurrencyDecimalSeparator = NumberFormatInfo.InvariantInfo.CurrencyDecimalSeparator, + CurrencyGroupSeparator = NumberFormatInfo.InvariantInfo.CurrencyGroupSeparator, + CurrencyGroupSizes = NumberFormatInfo.InvariantInfo.CurrencyGroupSizes, + CurrencyNegativePattern = NumberFormatInfo.InvariantInfo.CurrencyNegativePattern, + CurrencyPositivePattern = NumberFormatInfo.InvariantInfo.CurrencyPositivePattern, + CurrencySymbol = NumberFormatInfo.InvariantInfo.CurrencySymbol, + NaNSymbol = NumberFormatInfo.InvariantInfo.NaNSymbol, + NegativeInfinitySymbol = NumberFormatInfo.InvariantInfo.NegativeInfinitySymbol, + NegativeSign = NumberFormatInfo.InvariantInfo.NegativeSign, + NumberDecimalDigits = NumberFormatInfo.InvariantInfo.NumberDecimalDigits, + NumberDecimalSeparator = ".", + NumberGroupSeparator = NumberFormatInfo.InvariantInfo.NumberGroupSeparator, + NumberGroupSizes = NumberFormatInfo.InvariantInfo.NumberGroupSizes, + NumberNegativePattern = NumberFormatInfo.InvariantInfo.NumberNegativePattern, + PercentDecimalDigits = NumberFormatInfo.InvariantInfo.PercentDecimalDigits, + PercentDecimalSeparator = ".", + PercentGroupSeparator = NumberFormatInfo.InvariantInfo.PercentGroupSeparator, + PercentGroupSizes = NumberFormatInfo.InvariantInfo.PercentGroupSizes, + PercentNegativePattern = NumberFormatInfo.InvariantInfo.PercentNegativePattern, + PercentPositivePattern = NumberFormatInfo.InvariantInfo.PercentPositivePattern, + PercentSymbol = NumberFormatInfo.InvariantInfo.PercentSymbol, + PerMilleSymbol = NumberFormatInfo.InvariantInfo.PerMilleSymbol, + PositiveInfinitySymbol = NumberFormatInfo.InvariantInfo.PositiveInfinitySymbol, + PositiveSign = NumberFormatInfo.InvariantInfo.PositiveSign, + }; + + public virtual void BuildValue(StringBuilder sb, object value) + { + if (value == null) sb.Append("NULL"); + else if (value is string) BuildString(sb, value.ToString()); + else if (value is char) BuildChar (sb, (char)value); + else if (value is bool) sb.Append((bool)value ? "1" : "0"); + else if (value is DateTime) BuildDateTime(sb, value); + else if (value is Guid) sb.Append('\'').Append(value).Append('\''); + else if (value is decimal) sb.Append(((decimal)value).ToString(NumberFormatInfo)); + else if (value is double) sb.Append(((double) value).ToString(NumberFormatInfo)); + else if (value is float) sb.Append(((float) value).ToString(NumberFormatInfo)); + else + { + var type = value.GetType(); + + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + type = type.GetGenericArguments()[0]; + + if (type.IsEnum) + { + lock (_nullableValueReader) + { + INullableValueReader reader; + + if (_nullableValueReader.TryGetValue(type, out reader) == false) + { + reader = (INullableValueReader)Activator.CreateInstance(typeof(NullableValueReader<>).MakeGenericType(type)); + _nullableValueReader.Add(type, reader); + } + + value = reader.GetValue(value); + } + } + } + + if (type.IsEnum) + { + value = Map.EnumToValue(value); + + if (value != null && !value.GetType().IsEnum) + BuildValue(sb, value); + else + sb.Append(value); + } + else + sb.Append(value); + } + } + + protected virtual void BuildString(StringBuilder sb, string value) + { + sb + .Append('\'') + .Append(value.Replace("'", "''")) + .Append('\''); + } + + protected virtual void BuildChar(StringBuilder sb, char value) + { + sb.Append('\''); + + if (value == '\'') sb.Append("''"); + else sb.Append(value); + + sb.Append('\''); + } + + protected virtual void BuildDateTime(StringBuilder sb, object value) + { + sb.Append(string.Format("'{0:yyyy-MM-dd HH:mm:ss.fff}'", value)); + } + + #endregion + + #region BuildBinaryExpression + + protected virtual void BuildBinaryExpression(StringBuilder sb, SqlBinaryExpression expr) + { + BuildBinaryExpression(sb, expr.Operation, expr); + } + + protected void BuildFunction(StringBuilder sb, string name, SqlBinaryExpression expr) + { + sb.Append(name); + sb.Append("("); + BuildExpression(sb, expr.Expr1); + sb.Append(", "); + BuildExpression(sb, expr.Expr2); + sb.Append(')'); + } + + protected void BuildBinaryExpression(StringBuilder sb, string op, SqlBinaryExpression expr) + { + if (expr.Operation == "*" && expr.Expr1 is SqlValue) + { + var value = (SqlValue)expr.Expr1; + + if (value.Value is int && (int)value.Value == -1) + { + sb.Append('-'); + BuildExpression(sb, GetPrecedence(expr), expr.Expr2); + return; + } + } + + BuildExpression(sb, GetPrecedence(expr), expr.Expr1); + sb.Append(' ').Append(op).Append(' '); + BuildExpression(sb, GetPrecedence(expr), expr.Expr2); + } + + #endregion + + #region BuildFunction + + protected virtual void BuildFunction(StringBuilder sb, SqlFunction func) + { + if (func.Name == "CASE") + { + sb.Append(func.Name).AppendLine(); + + Indent++; + + var i = 0; + + for (; i < func.Parameters.Length - 1; i += 2) + { + AppendIndent(sb).Append("WHEN "); + + var len = sb.Length; + + BuildExpression(sb, func.Parameters[i]); + + if (SqlExpression.NeedsEqual(func.Parameters[i])) + { + sb.Append(" = "); + BuildValue(sb, true); + } + + if (sb.Length - len > 20) + { + sb.AppendLine(); + AppendIndent(sb).Append("\tTHEN "); + } + else + sb.Append(" THEN "); + + BuildExpression(sb, func.Parameters[i+1]); + sb.AppendLine(); + } + + if (i < func.Parameters.Length) + { + AppendIndent(sb).Append("ELSE "); + BuildExpression(sb, func.Parameters[i]); + sb.AppendLine(); + } + + Indent--; + + AppendIndent(sb).Append("END"); + } + else + BuildFunction(sb, func.Name, func.Parameters); + } + + protected void BuildFunction(StringBuilder sb, string name, ISqlExpression[] exprs) + { + sb.Append(name).Append('('); + + var first = true; + + foreach (var parameter in exprs) + { + if (!first) + sb.Append(", "); + + BuildExpression(sb, parameter, true, !first || name == "EXISTS"); + + first = false; + } + + sb.Append(')'); + } + + #endregion + + #region BuildDataType + + protected virtual void BuildDataType(StringBuilder sb, SqlDataType type) + { + sb.Append(type.SqlDbType.ToString()); + + if (type.Length > 0) + sb.Append('(').Append(type.Length).Append(')'); + + if (type.Precision > 0) + sb.Append('(').Append(type.Precision).Append(',').Append(type.Scale).Append(')'); + } + + #endregion + + #region GetPrecedence + + protected virtual int GetPrecedence(ISqlExpression expr) + { + return expr.Precedence; + } + + protected virtual int GetPrecedence(ISqlPredicate predicate) + { + return predicate.Precedence; + } + + #endregion + + #endregion + + #region Internal Types + + public enum Step + { + SelectClause, + DeleteClause, + UpdateClause, + InsertClause, + FromClause, + WhereClause, + GroupByClause, + HavingClause, + OrderByClause, + OffsetLimit + } + + #endregion + + #region Alternative Builders + + protected virtual void BuildAliases(StringBuilder sb, string table, List columns, string postfix) + { + Indent++; + + var first = true; + + foreach (var col in columns) + { + if (!first) + sb.Append(',').AppendLine(); + first = false; + + AppendIndent(sb).AppendFormat("{0}.{1}", table, Convert(col.Alias, ConvertType.NameToQueryFieldAlias)); + + if (postfix != null) + sb.Append(postfix); + } + + Indent--; + + sb.AppendLine(); + } + + protected void AlternativeBuildSql(StringBuilder sb, bool implementOrderBy, Action buildSql) + { + if (NeedSkip) + { + var aliases = GetTempAliases(2, "t"); + var rnaliase = GetTempAliases(1, "rn")[0]; + + AppendIndent(sb).Append("SELECT *").AppendLine(); + AppendIndent(sb).Append("FROM"). AppendLine(); + AppendIndent(sb).Append("("). AppendLine(); + Indent++; + + AppendIndent(sb).Append("SELECT").AppendLine(); + + Indent++; + AppendIndent(sb).AppendFormat("{0}.*,", aliases[0]).AppendLine(); + AppendIndent(sb).Append("ROW_NUMBER() OVER"); + + if (!SqlQuery.OrderBy.IsEmpty && !implementOrderBy) + sb.Append("()"); + else + { + sb.AppendLine(); + AppendIndent(sb).Append("(").AppendLine(); + + Indent++; + + if (SqlQuery.OrderBy.IsEmpty) + { + AppendIndent(sb).Append("ORDER BY").AppendLine(); + BuildAliases(sb, aliases[0], SqlQuery.Select.Columns.Take(1).ToList(), null); + } + else + BuildAlternativeOrderBy(sb, true); + + Indent--; + AppendIndent(sb).Append(")"); + } + + sb.Append(" as ").Append(rnaliase).AppendLine(); + Indent--; + + AppendIndent(sb).Append("FROM").AppendLine(); + AppendIndent(sb).Append("(").AppendLine(); + + Indent++; + buildSql(sb); + Indent--; + + AppendIndent(sb).AppendFormat(") {0}", aliases[0]).AppendLine(); + + Indent--; + + AppendIndent(sb).AppendFormat(") {0}", aliases[1]).AppendLine(); + AppendIndent(sb).Append("WHERE").AppendLine(); + + Indent++; + + if (NeedTake) + { + var expr1 = Add(SqlQuery.Select.SkipValue, 1); + var expr2 = Add(SqlQuery.Select.SkipValue, SqlQuery.Select.TakeValue); + + if (expr1 is SqlValue && expr2 is SqlValue && Equals(((SqlValue)expr1).Value, ((SqlValue)expr2).Value)) + { + AppendIndent(sb).AppendFormat("{0}.{1} = ", aliases[1], rnaliase); + BuildExpression(sb, expr1); + } + else + { + AppendIndent(sb).AppendFormat("{0}.{1} BETWEEN ", aliases[1], rnaliase); + BuildExpression(sb, expr1); + sb.Append(" AND "); + BuildExpression(sb, expr2); + } + } + else + { + AppendIndent(sb).AppendFormat("{0}.{1} > ", aliases[1], rnaliase); + BuildExpression(sb, SqlQuery.Select.SkipValue); + } + + sb.AppendLine(); + Indent--; + } + else + buildSql(sb); + } + + protected void AlternativeBuildSql2(StringBuilder sb, Action buildSql) + { + var aliases = GetTempAliases(3, "t"); + + AppendIndent(sb).Append("SELECT *").AppendLine(); + AppendIndent(sb).Append("FROM") .AppendLine(); + AppendIndent(sb).Append("(") .AppendLine(); + Indent++; + + AppendIndent(sb).Append("SELECT TOP "); + BuildExpression(sb, SqlQuery.Select.TakeValue); + sb.Append(" *").AppendLine(); + AppendIndent(sb).Append("FROM").AppendLine(); + AppendIndent(sb).Append("(") .AppendLine(); + Indent++; + + if (SqlQuery.OrderBy.IsEmpty) + { + AppendIndent(sb).Append("SELECT TOP "); + + var p = SqlQuery.Select.SkipValue as SqlParameter; + + if (p != null && !p.IsQueryParameter && SqlQuery.Select.TakeValue is SqlValue) + BuildValue(sb, (int)p.Value + (int)((SqlValue)(SqlQuery.Select.TakeValue)).Value); + else + BuildExpression(sb, Add(SqlQuery.Select.SkipValue, SqlQuery.Select.TakeValue)); + + sb.Append(" *").AppendLine(); + AppendIndent(sb).Append("FROM").AppendLine(); + AppendIndent(sb).Append("(") .AppendLine(); + Indent++; + } + + buildSql(sb); + + if (SqlQuery.OrderBy.IsEmpty) + { + Indent--; + AppendIndent(sb).AppendFormat(") {0}", aliases[2]).AppendLine(); + AppendIndent(sb).Append("ORDER BY").AppendLine(); + BuildAliases(sb, aliases[2], SqlQuery.Select.Columns, null); + } + + Indent--; + AppendIndent(sb).AppendFormat(") {0}", aliases[1]).AppendLine(); + + if (SqlQuery.OrderBy.IsEmpty) + { + AppendIndent(sb).Append("ORDER BY").AppendLine(); + BuildAliases(sb, aliases[1], SqlQuery.Select.Columns, " DESC"); + } + else + { + BuildAlternativeOrderBy(sb, false); + } + + Indent--; + AppendIndent(sb).AppendFormat(") {0}", aliases[0]).AppendLine(); + + if (SqlQuery.OrderBy.IsEmpty) + { + AppendIndent(sb).Append("ORDER BY").AppendLine(); + BuildAliases(sb, aliases[0], SqlQuery.Select.Columns, null); + } + else + { + BuildAlternativeOrderBy(sb, true); + } + } + + protected void BuildAlternativeOrderBy(StringBuilder sb, bool ascending) + { + AppendIndent(sb).Append("ORDER BY").AppendLine(); + + var obys = GetTempAliases(SqlQuery.OrderBy.Items.Count, "oby"); + + Indent++; + + for (var i = 0; i < obys.Length; i++) + { + AppendIndent(sb).Append(obys[i]); + + if ( ascending && SqlQuery.OrderBy.Items[i].IsDescending || + !ascending && !SqlQuery.OrderBy.Items[i].IsDescending) + sb.Append(" DESC"); + + if (i + 1 < obys.Length) + sb.Append(','); + + sb.AppendLine(); + } + + Indent--; + } + + protected delegate IEnumerable ColumnSelector(); + + protected IEnumerable AlternativeGetSelectedColumns(ColumnSelector columnSelector) + { + foreach (var col in columnSelector()) + yield return col; + + var obys = GetTempAliases(SqlQuery.OrderBy.Items.Count, "oby"); + + for (var i = 0; i < obys.Length; i++) + yield return new SqlQuery.Column(SqlQuery, SqlQuery.OrderBy.Items[i].Expression, obys[i]); + } + + protected bool IsDateDataType(ISqlExpression expr, string dateName) + { + switch (expr.ElementType) + { + case QueryElementType.SqlDataType : return ((SqlDataType) expr).SqlDbType == SqlDbType.Date; + case QueryElementType.SqlExpression : return ((SqlExpression)expr).Expr == dateName; + } + + return false; + } + + protected bool IsTimeDataType(ISqlExpression expr) + { + switch (expr.ElementType) + { + case QueryElementType.SqlDataType : return ((SqlDataType)expr). SqlDbType == SqlDbType.Time; + case QueryElementType.SqlExpression : return ((SqlExpression)expr).Expr == "Time"; + } + + return false; + } + + protected ISqlExpression FloorBeforeConvert(SqlFunction func) + { + var par1 = func.Parameters[1]; + + return TypeHelper.IsFloatType(par1.SystemType) && TypeHelper.IsIntegerType(func.SystemType) ? + new SqlFunction(func.SystemType, "Floor", par1) : par1; + } + + protected ISqlExpression AlternativeConvertToBoolean(SqlFunction func, int paramNumber) + { + var par = func.Parameters[paramNumber]; + + if (TypeHelper.IsFloatType(par.SystemType) || TypeHelper.IsIntegerType(par.SystemType)) + { + var sc = new SqlQuery.SearchCondition(); + + sc.Conditions.Add( + new SqlQuery.Condition(false, new SqlQuery.Predicate.ExprExpr(par, SqlQuery.Predicate.Operator.Equal, new SqlValue(0)))); + + return ConvertExpression(new SqlFunction(func.SystemType, "CASE", sc, new SqlValue(false), new SqlValue(true))); + } + + return null; + } + + protected SqlQuery GetAlternativeDelete(SqlQuery sqlQuery) + { + if (sqlQuery.IsDelete && + (sqlQuery.From.Tables.Count > 1 || sqlQuery.From.Tables[0].Joins.Count > 0) && + sqlQuery.From.Tables[0].Source is SqlTable) + { + var sql = new SqlQuery { QueryType = QueryType.Delete, IsParameterDependent = sqlQuery.IsParameterDependent }; + + sqlQuery.ParentSql = sql; + sqlQuery.QueryType = QueryType.Select; + + var table = (SqlTable)sqlQuery.From.Tables[0].Source; + var copy = new SqlTable(table) { Alias = null }; + + var tableKeys = table.GetKeys(true); + var copyKeys = copy. GetKeys(true); + + if (sqlQuery.Where.SearchCondition.Conditions.Any(c => c.IsOr)) + { + var sc1 = new SqlQuery.SearchCondition(sqlQuery.Where.SearchCondition.Conditions); + var sc2 = new SqlQuery.SearchCondition(); + + for (var i = 0; i < tableKeys.Count; i++) + { + sc2.Conditions.Add(new SqlQuery.Condition( + false, + new SqlQuery.Predicate.ExprExpr(copyKeys[i], SqlQuery.Predicate.Operator.Equal, tableKeys[i]))); + } + + sqlQuery.Where.SearchCondition.Conditions.Clear(); + sqlQuery.Where.SearchCondition.Conditions.Add(new SqlQuery.Condition(false, sc1)); + sqlQuery.Where.SearchCondition.Conditions.Add(new SqlQuery.Condition(false, sc2)); + } + else + { + for (var i = 0; i < tableKeys.Count; i++) + sqlQuery.Where.Expr(copyKeys[i]).Equal.Expr(tableKeys[i]); + } + + sql.From.Table(copy).Where.Exists(sqlQuery); + sql.Parameters.AddRange(sqlQuery.Parameters); + + sqlQuery.Parameters.Clear(); + + sqlQuery = sql; + } + + return sqlQuery; + } + + protected SqlQuery GetAlternativeUpdate(SqlQuery sqlQuery) + { + if (sqlQuery.IsUpdate && (sqlQuery.From.Tables[0].Source is SqlTable || sqlQuery.Update.Table != null)) + { + if (sqlQuery.From.Tables.Count > 1 || sqlQuery.From.Tables[0].Joins.Count > 0) + { + var sql = new SqlQuery { QueryType = QueryType.Update, IsParameterDependent = sqlQuery.IsParameterDependent }; + + sqlQuery.ParentSql = sql; + sqlQuery.QueryType = QueryType.Select; + + var table = sqlQuery.Update.Table ?? (SqlTable)sqlQuery.From.Tables[0].Source; + + if (sqlQuery.Update.Table != null) + if (new QueryVisitor().Find(sqlQuery.From, t => t == table) == null) + table = (SqlTable)new QueryVisitor().Find(sqlQuery.From, + ex => ex is SqlTable && ((SqlTable)ex).ObjectType == table.ObjectType) ?? table; + + var copy = new SqlTable(table); + + var tableKeys = table.GetKeys(true); + var copyKeys = copy. GetKeys(true); + + for (var i = 0; i < tableKeys.Count; i++) + sqlQuery.Where + .Expr(copyKeys[i]).Equal.Expr(tableKeys[i]); + + sql.From.Table(copy).Where.Exists(sqlQuery); + + var map = new Dictionary(table.Fields.Count); + + foreach (var field in table.Fields.Values) + map.Add(field, copy[field.Name]); + + foreach (var item in sqlQuery.Update.Items) + { + var ex = new QueryVisitor().Convert(item, expr => + { + var fld = expr as SqlField; + return fld != null && map.TryGetValue(fld, out fld) ? fld : expr; + }); + + sql.Update.Items.Add(ex); + } + + sql.Parameters.AddRange(sqlQuery.Parameters); + sql.Update.Table = sqlQuery.Update.Table; + + sqlQuery.Parameters.Clear(); + sqlQuery.Update.Items.Clear(); + + sqlQuery = sql; + } + + sqlQuery.From.Tables[0].Alias = "$"; + } + + return sqlQuery; + } + + static bool IsBooleanParameter(ISqlExpression expr, int count, int i) + { + if ((i % 2 == 1 || i == count - 1) && expr.SystemType == typeof(bool) || expr.SystemType == typeof(bool?)) + { + switch (expr.ElementType) + { + case QueryElementType.SearchCondition : return true; + } + } + + return false; + } + + protected SqlFunction ConvertFunctionParameters(SqlFunction func) + { + if (func.Name == "CASE" && + func.Parameters.Select((p,i) => new { p, i }).Any(p => IsBooleanParameter(p.p, func.Parameters.Length, p.i))) + { + return new SqlFunction( + func.SystemType, + func.Name, + func.Precedence, + func.Parameters.Select((p,i) => + IsBooleanParameter(p, func.Parameters.Length, i) ? + ConvertExpression(new SqlFunction(typeof(bool), "CASE", p, new SqlValue(true), new SqlValue(false))) : + p + ).ToArray()); + } + + return func; + } + + #endregion + + #region Helpers + + protected SequenceNameAttribute GetSequenceNameAttribute(SqlTable table, bool throwException) + { + var identityField = table.GetIdentityField(); + + if (identityField == null) + if (throwException) + throw new SqlException("Identity field must be defined for '{0}'.", table.Name); + else + return null; + + if (table.ObjectType == null) + if (throwException) + throw new SqlException("Sequence name can not be retrieved for the '{0}' table.", table.Name); + else + return null; + + var attrs = table.SequenceAttributes; + + if (attrs == null) + if (throwException) + throw new SqlException("Sequence name can not be retrieved for the '{0}' table.", table.Name); + else + return null; + + SequenceNameAttribute defaultAttr = null; + + foreach (var attr in attrs) + { + if (attr.ProviderName == Name) + return attr; + + if (defaultAttr == null && attr.ProviderName == null) + defaultAttr = attr; + } + + if (defaultAttr == null) + if (throwException) + throw new SqlException("Sequence name can not be retrieved for the '{0}' table.", table.Name); + else + return null; + + return defaultAttr; + } + + static string SetAlias(string alias, int maxLen) + { + if (alias == null) + return null; + + alias = alias.TrimStart('_'); + + var cs = alias.ToCharArray(); + var replace = false; + + for (var i = 0; i < cs.Length; i++) + { + var c = cs[i]; + + if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '_') + continue; + + cs[i] = ' '; + replace = true; + } + + if (replace) + alias = new string(cs).Replace(" ", ""); + + return alias.Length == 0 || alias.Length > maxLen ? null : alias; + } + + protected void CheckAliases(SqlQuery sqlQuery, int maxLen) + { + new QueryVisitor().Visit(sqlQuery, e => + { + switch (e.ElementType) + { + case QueryElementType.SqlField : ((SqlField) e).Alias = SetAlias(((SqlField) e).Alias, maxLen); break; + case QueryElementType.SqlParameter : ((SqlParameter) e).Name = SetAlias(((SqlParameter) e).Name, maxLen); break; + case QueryElementType.SqlTable : ((SqlTable) e).Alias = SetAlias(((SqlTable) e).Alias, maxLen); break; + case QueryElementType.Join : ((Join) e).Alias = SetAlias(((Join) e).Alias, maxLen); break; + case QueryElementType.Column : ((SqlQuery.Column) e).Alias = SetAlias(((SqlQuery.Column) e).Alias, maxLen); break; + case QueryElementType.TableSource : ((SqlQuery.TableSource)e).Alias = SetAlias(((SqlQuery.TableSource)e).Alias, maxLen); break; + } + }); + } + + static bool Wrap(int precedence, int parentPrecedence) + { + return + precedence == 0 || + precedence < parentPrecedence || + (precedence == parentPrecedence && + (parentPrecedence == Precedence.Subtraction || + parentPrecedence == Precedence.LogicalNegation)); + } + + protected string[] GetTempAliases(int n, string defaultAlias) + { + return SqlQuery.GetTempAliases(n, defaultAlias + (Nesting == 0? "": "n" + Nesting)); + } + + protected static string GetTableAlias(ISqlTableSource table) + { + switch (table.ElementType) + { + case QueryElementType.TableSource : + var ts = (SqlQuery.TableSource)table; + var alias = string.IsNullOrEmpty(ts.Alias) ? GetTableAlias(ts.Source) : ts.Alias; + return alias != "$" ? alias : null; + + case QueryElementType.SqlTable : + return ((SqlTable)table).Alias; + + default : + throw new InvalidOperationException(); + } + } + + string GetTablePhysicalName(ISqlTableSource table, string alias) + { + switch (table.ElementType) + { + case QueryElementType.SqlTable : + { + var tbl = (SqlTable)table; + + var database = tbl.Database == null ? null : Convert(tbl.Database, ConvertType.NameToDatabase). ToString(); + var owner = tbl.Owner == null ? null : Convert(tbl.Owner, ConvertType.NameToOwner). ToString(); + var physicalName = tbl.PhysicalName == null ? null : Convert(tbl.PhysicalName, ConvertType.NameToQueryTable).ToString(); + + var sb = new StringBuilder(); + + if (tbl.SqlTableType == SqlTableType.Expression) + { + if (tbl.TableArguments == null) + physicalName = tbl.PhysicalName; + else + { + var values = new object[tbl.TableArguments.Length + 2]; + + values[0] = physicalName; + values[1] = Convert(alias, ConvertType.NameToQueryTableAlias); + + for (var i = 2; i < values.Length; i++) + { + var value = tbl.TableArguments[i - 2]; + + sb.Length = 0; + BuildExpression(sb, Precedence.Primary, value); + values[i] = sb.ToString(); + } + + physicalName = string.Format(tbl.Name, values); + + sb.Length = 0; + } + } + + BuildTableName(sb, database, owner, physicalName); + + if (tbl.SqlTableType == SqlTableType.Function) + { + sb.Append('('); + + if (tbl.TableArguments != null && tbl.TableArguments.Length > 0) + { + var first = true; + + foreach (var arg in tbl.TableArguments) + { + if (!first) + sb.Append(", "); + + BuildExpression(sb, arg, true, !first); + + first = false; + } + } + + sb.Append(')'); + } + + return sb.ToString(); + } + + case QueryElementType.TableSource : + return GetTablePhysicalName(((SqlQuery.TableSource)table).Source, alias); + + default : + throw new InvalidOperationException(); + } + } + + protected StringBuilder AppendIndent(StringBuilder sb) + { + if (Indent > 0) + sb.Append('\t', Indent); + + return sb; + } + + public ISqlExpression Add(ISqlExpression expr1, ISqlExpression expr2, Type type) + { + return ConvertExpression(new SqlBinaryExpression(type, expr1, "+", expr2, Precedence.Additive)); + } + + public ISqlExpression Add(ISqlExpression expr1, ISqlExpression expr2) + { + return Add(expr1, expr2, typeof(T)); + } + + public ISqlExpression Add(ISqlExpression expr1, int value) + { + return Add(expr1, new SqlValue(value)); + } + + public ISqlExpression Inc(ISqlExpression expr1) + { + return Add(expr1, 1); + } + + public ISqlExpression Sub(ISqlExpression expr1, ISqlExpression expr2, Type type) + { + return ConvertExpression(new SqlBinaryExpression(type, expr1, "-", expr2, Precedence.Subtraction)); + } + + public ISqlExpression Sub(ISqlExpression expr1, ISqlExpression expr2) + { + return Sub(expr1, expr2, typeof(T)); + } + + public ISqlExpression Sub(ISqlExpression expr1, int value) + { + return Sub(expr1, new SqlValue(value)); + } + + public ISqlExpression Dec(ISqlExpression expr1) + { + return Sub(expr1, 1); + } + + public ISqlExpression Mul(ISqlExpression expr1, ISqlExpression expr2, Type type) + { + return ConvertExpression(new SqlBinaryExpression(type, expr1, "*", expr2, Precedence.Multiplicative)); + } + + public ISqlExpression Mul(ISqlExpression expr1, ISqlExpression expr2) + { + return Mul(expr1, expr2, typeof(T)); + } + + public ISqlExpression Mul(ISqlExpression expr1, int value) + { + return Mul(expr1, new SqlValue(value)); + } + + public ISqlExpression Div(ISqlExpression expr1, ISqlExpression expr2, Type type) + { + return ConvertExpression(new SqlBinaryExpression(type, expr1, "/", expr2, Precedence.Multiplicative)); + } + + public ISqlExpression Div(ISqlExpression expr1, ISqlExpression expr2) + { + return Div(expr1, expr2, typeof(T)); + } + + public ISqlExpression Div(ISqlExpression expr1, int value) + { + return Div(expr1, new SqlValue(value)); + } + + #endregion + + #region DataTypes + + protected virtual int GetMaxLength (SqlDataType type) { return SqlDataType.GetMaxLength (type.SqlDbType); } + protected virtual int GetMaxPrecision (SqlDataType type) { return SqlDataType.GetMaxPrecision (type.SqlDbType); } + protected virtual int GetMaxScale (SqlDataType type) { return SqlDataType.GetMaxScale (type.SqlDbType); } + protected virtual int GetMaxDisplaySize(SqlDataType type) { return SqlDataType.GetMaxDisplaySize(type.SqlDbType); } + + protected virtual ISqlExpression ConvertConvertion(SqlFunction func) + { + var from = (SqlDataType)func.Parameters[1]; + var to = (SqlDataType)func.Parameters[0]; + + if (to.Type == typeof(object)) + return func.Parameters[2]; + + if (to.Precision > 0) + { + var maxPrecision = GetMaxPrecision(from); + var maxScale = GetMaxScale (from); + var newPrecision = maxPrecision >= 0 ? Math.Min(to.Precision, maxPrecision) : to.Precision; + var newScale = maxScale >= 0 ? Math.Min(to.Scale, maxScale) : to.Scale; + + if (to.Precision != newPrecision || to.Scale != newScale) + to = new SqlDataType(to.SqlDbType, to.Type, newPrecision, newScale); + } + else if (to.Length > 0) + { + var maxLength = to.Type == typeof(string) ? GetMaxDisplaySize(from) : GetMaxLength(from); + var newLength = maxLength >= 0 ? Math.Min(to.Length, maxLength) : to.Length; + + if (to.Length != newLength) + to = new SqlDataType(to.SqlDbType, to.Type, newLength); + } + else if (from.Type == typeof(short) && to.Type == typeof(int)) + return func.Parameters[2]; + + return ConvertExpression(new SqlFunction(func.SystemType, "Convert", to, func.Parameters[2])); + } + + #endregion + + #region ISqlProvider Members + + public virtual ISqlExpression ConvertExpression(ISqlExpression expression) + { + switch (expression.ElementType) + { + case QueryElementType.SqlBinaryExpression: + + #region SqlBinaryExpression + + { + var be = (SqlBinaryExpression)expression; + + switch (be.Operation) + { + case "+": + if (be.Expr1 is SqlValue) + { + var v1 = (SqlValue)be.Expr1; + if (v1.Value is int && (int) v1.Value == 0 || + v1.Value is string && (string)v1.Value == "") return be.Expr2; + } + + if (be.Expr2 is SqlValue) + { + var v2 = (SqlValue) be.Expr2; + + if (v2.Value is int) + { + if ((int)v2.Value == 0) return be.Expr1; + + if (be.Expr1 is SqlBinaryExpression) + { + var be1 = (SqlBinaryExpression) be.Expr1; + + if (be1.Expr2 is SqlValue) + { + var be1v2 = (SqlValue)be1.Expr2; + + if (be1v2.Value is int) + { + switch (be1.Operation) + { + case "+": + { + var value = (int)be1v2.Value + (int)v2.Value; + var oper = be1.Operation; + + if (value < 0) + { + value = - value; + oper = "-"; + } + + return new SqlBinaryExpression(be.SystemType, be1.Expr1, oper, new SqlValue(value), be.Precedence); + } + + case "-": + { + var value = (int)be1v2.Value - (int)v2.Value; + var oper = be1.Operation; + + if (value < 0) + { + value = - value; + oper = "+"; + } + + return new SqlBinaryExpression(be.SystemType, be1.Expr1, oper, new SqlValue(value), be.Precedence); + } + } + } + } + } + } + else if (v2.Value is string) + { + if ((string)v2.Value == "") return be.Expr1; + + if (be.Expr1 is SqlBinaryExpression) + { + var be1 = (SqlBinaryExpression)be.Expr1; + + if (be1.Expr2 is SqlValue) + { + var value = ((SqlValue)be1.Expr2).Value; + + if (value is string) + return new SqlBinaryExpression( + be1.SystemType, + be1.Expr1, + be1.Operation, + new SqlValue(string.Concat(value, v2.Value))); + } + } + } + } + + if (be.Expr1 is SqlValue && be.Expr2 is SqlValue) + { + var v1 = (SqlValue)be.Expr1; + var v2 = (SqlValue)be.Expr2; + if (v1.Value is int && v2.Value is int) return new SqlValue((int)v1.Value + (int)v2.Value); + if (v1.Value is string || v2.Value is string) return new SqlValue(v1.Value.ToString() + v2.Value); + } + + if (be.Expr1.SystemType == typeof(string) && be.Expr2.SystemType != typeof(string)) + { + var len = be.Expr2.SystemType == null ? 100 : SqlDataType.GetMaxDisplaySize(SqlDataType.GetDataType(be.Expr2.SystemType).SqlDbType); + + if (len <= 0) + len = 100; + + return new SqlBinaryExpression( + be.SystemType, + be.Expr1, + be.Operation, + ConvertExpression(new SqlFunction(typeof(string), "Convert", new SqlDataType(SqlDbType.VarChar, len), be.Expr2)), + be.Precedence); + } + + if (be.Expr1.SystemType != typeof(string) && be.Expr2.SystemType == typeof(string)) + { + var len = be.Expr1.SystemType == null ? 100 : SqlDataType.GetMaxDisplaySize(SqlDataType.GetDataType(be.Expr1.SystemType).SqlDbType); + + if (len <= 0) + len = 100; + + return new SqlBinaryExpression( + be.SystemType, + ConvertExpression(new SqlFunction(typeof(string), "Convert", new SqlDataType(SqlDbType.VarChar, len), be.Expr1)), + be.Operation, + be.Expr2, + be.Precedence); + } + + break; + + case "-": + if (be.Expr2 is SqlValue) + { + var v2 = (SqlValue) be.Expr2; + + if (v2.Value is int) + { + if ((int)v2.Value == 0) return be.Expr1; + + if (be.Expr1 is SqlBinaryExpression) + { + var be1 = (SqlBinaryExpression)be.Expr1; + + if (be1.Expr2 is SqlValue) + { + var be1v2 = (SqlValue)be1.Expr2; + + if (be1v2.Value is int) + { + switch (be1.Operation) + { + case "+": + { + var value = (int)be1v2.Value - (int)v2.Value; + var oper = be1.Operation; + + if (value < 0) + { + value = -value; + oper = "-"; + } + + return new SqlBinaryExpression(be.SystemType, be1.Expr1, oper, new SqlValue(value), be.Precedence); + } + + case "-": + { + var value = (int)be1v2.Value + (int)v2.Value; + var oper = be1.Operation; + + if (value < 0) + { + value = -value; + oper = "+"; + } + + return new SqlBinaryExpression(be.SystemType, be1.Expr1, oper, new SqlValue(value), be.Precedence); + } + } + } + } + } + } + } + + if (be.Expr1 is SqlValue && be.Expr2 is SqlValue) + { + var v1 = (SqlValue)be.Expr1; + var v2 = (SqlValue)be.Expr2; + if (v1.Value is int && v2.Value is int) return new SqlValue((int)v1.Value - (int)v2.Value); + } + + break; + + case "*": + if (be.Expr1 is SqlValue) + { + var v1 = (SqlValue)be.Expr1; + + if (v1.Value is int) + { + var v1v = (int)v1.Value; + + switch (v1v) + { + case 0 : return new SqlValue(0); + case 1 : return be.Expr2; + default : + { + var be2 = be.Expr2 as SqlBinaryExpression; + + if (be2 != null && be2.Operation == "*" && be2.Expr1 is SqlValue) + { + var be2v1 = be2.Expr1 as SqlValue; + + if (be2v1.Value is int) + return ConvertExpression( + new SqlBinaryExpression(be2.SystemType, new SqlValue(v1v * (int)be2v1.Value), "*", be2.Expr2)); + } + + break; + } + + } + } + } + + if (be.Expr2 is SqlValue) + { + var v2 = (SqlValue)be.Expr2; + if (v2.Value is int && (int)v2.Value == 1) return be.Expr1; + if (v2.Value is int && (int)v2.Value == 0) return new SqlValue(0); + } + + if (be.Expr1 is SqlValue && be.Expr2 is SqlValue) + { + var v1 = (SqlValue)be.Expr1; + var v2 = (SqlValue)be.Expr2; + + if (v1.Value is int) + { + if (v2.Value is int) return new SqlValue((int) v1.Value * (int) v2.Value); + if (v2.Value is double) return new SqlValue((int) v1.Value * (double)v2.Value); + } + else if (v1.Value is double) + { + if (v2.Value is int) return new SqlValue((double)v1.Value * (int) v2.Value); + if (v2.Value is double) return new SqlValue((double)v1.Value * (double)v2.Value); + } + } + + break; + } + } + + #endregion + + break; + + case QueryElementType.SqlFunction: + + #region SqlFunction + + { + var func = (SqlFunction)expression; + + switch (func.Name) + { + case "ConvertToCaseCompareTo": + return ConvertExpression(new SqlFunction(func.SystemType, "CASE", + new SqlQuery.SearchCondition().Expr(func.Parameters[0]). Greater .Expr(func.Parameters[1]).ToExpr(), new SqlValue(1), + new SqlQuery.SearchCondition().Expr(func.Parameters[0]). Equal .Expr(func.Parameters[1]).ToExpr(), new SqlValue(0), + new SqlValue(-1))); + + case "$Convert$": return ConvertConvertion(func); + case "Average" : return new SqlFunction(func.SystemType, "Avg", func.Parameters); + case "Max" : + case "Min" : + { + if (func.SystemType == typeof(bool) || func.SystemType == typeof(bool?)) + { + return new SqlFunction(typeof(int), func.Name, + new SqlFunction(func.SystemType, "CASE", func.Parameters[0], new SqlValue(1), new SqlValue(0))); + } + + break; + } + + case "CASE" : + { + var parms = func.Parameters; + var len = parms.Length; + + for (var i = 0; i < parms.Length - 1; i += 2) + { + var value = parms[i] as SqlValue; + + if (value != null) + { + if ((bool)value.Value == false) + { + var newParms = new ISqlExpression[parms.Length - 2]; + + if (i != 0) + Array.Copy(parms, 0, newParms, 0, i); + + Array.Copy(parms, i + 2, newParms, i, parms.Length - i - 2); + + parms = newParms; + i -= 2; + } + else + { + var newParms = new ISqlExpression[i + 1]; + + if (i != 0) + Array.Copy(parms, 0, newParms, 0, i); + + newParms[i] = parms[i + 1]; + + parms = newParms; + break; + } + } + } + + if (parms.Length == 1) + return parms[0]; + + if (parms.Length != len) + return new SqlFunction(func.SystemType, func.Name, func.Precedence, parms); + } + + break; + + case "Convert": + { + var from = func.Parameters[1] as SqlFunction; + var typef = TypeHelper.GetUnderlyingType(func.SystemType); + + if (from != null && from.Name == "Convert" && TypeHelper.GetUnderlyingType(from.Parameters[1].SystemType) == typef) + return from.Parameters[1]; + + var fe = func.Parameters[1] as SqlExpression; + + if (fe != null && fe.Expr == "Cast({0} as {1})" && TypeHelper.GetUnderlyingType(fe.Parameters[0].SystemType) == typef) + return fe.Parameters[0]; + } + + break; + } + } + + #endregion + + break; + + case QueryElementType.SearchCondition : + SqlQuery.OptimizeSearchCondition((SqlQuery.SearchCondition)expression); + break; + + case QueryElementType.SqlExpression : + { + var se = (SqlExpression)expression; + + if (se.Expr == "{0}" && se.Parameters.Length == 1 && se.Parameters[0] != null) + return se.Parameters[0]; + } + + break; + } + + return expression; + } + + public virtual ISqlPredicate ConvertPredicate(ISqlPredicate predicate) + { + switch (predicate.ElementType) + { + case QueryElementType.ExprExprPredicate: + { + var expr = (SqlQuery.Predicate.ExprExpr)predicate; + + if (expr.Operator == SqlQuery.Predicate.Operator.Equal && expr.Expr1 is SqlValue && expr.Expr2 is SqlValue) + { + var value = Equals(((SqlValue)expr.Expr1).Value, ((SqlValue)expr.Expr2).Value); + return new SqlQuery.Predicate.Expr(new SqlValue(value), Precedence.Comparison); + } + + switch (expr.Operator) + { + case SqlQuery.Predicate.Operator.Equal : + case SqlQuery.Predicate.Operator.NotEqual : + case SqlQuery.Predicate.Operator.Greater : + case SqlQuery.Predicate.Operator.GreaterOrEqual: + case SqlQuery.Predicate.Operator.Less : + case SqlQuery.Predicate.Operator.LessOrEqual : + predicate = OptimizeCase(expr); + break; + } + + if (predicate is SqlQuery.Predicate.ExprExpr) + { + expr = (SqlQuery.Predicate.ExprExpr)predicate; + + switch (expr.Operator) + { + case SqlQuery.Predicate.Operator.Equal : + case SqlQuery.Predicate.Operator.NotEqual : + var expr1 = expr.Expr1; + var expr2 = expr.Expr2; + + if (expr1.CanBeNull() && expr2.CanBeNull()) + { + if (expr1 is SqlParameter || expr2 is SqlParameter) + SqlQuery.IsParameterDependent = true; + else + if (expr1 is SqlQuery.Column || expr1 is SqlField) + if (expr2 is SqlQuery.Column || expr2 is SqlField) + predicate = ConvertEqualPredicate(expr); + } + + break; + } + } + } + + break; + + case QueryElementType.NotExprPredicate: + { + var expr = (SqlQuery.Predicate.NotExpr)predicate; + + if (expr.IsNot && expr.Expr1 is SqlQuery.SearchCondition) + { + var sc = (SqlQuery.SearchCondition)expr.Expr1; + + if (sc.Conditions.Count == 1) + { + var cond = sc.Conditions[0]; + + if (cond.IsNot) + return cond.Predicate; + + if (cond.Predicate is SqlQuery.Predicate.ExprExpr) + { + var ee = (SqlQuery.Predicate.ExprExpr)cond.Predicate; + + if (ee.Operator == SqlQuery.Predicate.Operator.Equal) + return new SqlQuery.Predicate.ExprExpr(ee.Expr1, SqlQuery.Predicate.Operator.NotEqual, ee.Expr2); + + if (ee.Operator == SqlQuery.Predicate.Operator.NotEqual) + return new SqlQuery.Predicate.ExprExpr(ee.Expr1, SqlQuery.Predicate.Operator.Equal, ee.Expr2); + } + } + } + } + + break; + } + + return predicate; + } + + protected ISqlPredicate ConvertEqualPredicate(SqlQuery.Predicate.ExprExpr expr) + { + var expr1 = expr.Expr1; + var expr2 = expr.Expr2; + var cond = new SqlQuery.SearchCondition(); + + if (expr.Operator == SqlQuery.Predicate.Operator.Equal) + cond + .Expr(expr1).IsNull. And .Expr(expr2).IsNull. Or + .Expr(expr1).IsNotNull. And .Expr(expr2).IsNotNull. And .Expr(expr1).Equal.Expr(expr2); + else + cond + .Expr(expr1).IsNull. And .Expr(expr2).IsNotNull. Or + .Expr(expr1).IsNotNull. And .Expr(expr2).IsNull. Or + .Expr(expr1).NotEqual.Expr(expr2); + + return cond; + } + + static SqlQuery.Predicate.Operator InvertOperator(SqlQuery.Predicate.Operator op, bool skipEqual) + { + switch (op) + { + case SqlQuery.Predicate.Operator.Equal : return skipEqual ? op : SqlQuery.Predicate.Operator.NotEqual; + case SqlQuery.Predicate.Operator.NotEqual : return skipEqual ? op : SqlQuery.Predicate.Operator.Equal; + case SqlQuery.Predicate.Operator.Greater : return SqlQuery.Predicate.Operator.LessOrEqual; + case SqlQuery.Predicate.Operator.NotLess : + case SqlQuery.Predicate.Operator.GreaterOrEqual : return SqlQuery.Predicate.Operator.Less; + case SqlQuery.Predicate.Operator.Less : return SqlQuery.Predicate.Operator.GreaterOrEqual; + case SqlQuery.Predicate.Operator.NotGreater : + case SqlQuery.Predicate.Operator.LessOrEqual : return SqlQuery.Predicate.Operator.Greater; + default: throw new InvalidOperationException(); + } + } + + ISqlPredicate OptimizeCase(SqlQuery.Predicate.ExprExpr expr) + { + var value = expr.Expr1 as SqlValue; + var func = expr.Expr2 as SqlFunction; + var valueFirst = false; + + if (value != null && func != null) + { + valueFirst = true; + } + else + { + value = expr.Expr2 as SqlValue; + func = expr.Expr1 as SqlFunction; + } + + if (value != null && func != null && func.Name == "CASE") + { + if (value.Value is int && func.Parameters.Length == 5) + { + var c1 = func.Parameters[0] as SqlQuery.SearchCondition; + var v1 = func.Parameters[1] as SqlValue; + var c2 = func.Parameters[2] as SqlQuery.SearchCondition; + var v2 = func.Parameters[3] as SqlValue; + var v3 = func.Parameters[4] as SqlValue; + + if (c1 != null && c1.Conditions.Count == 1 && v1 != null && v1.Value is int && + c2 != null && c2.Conditions.Count == 1 && v2 != null && v2.Value is int && v3 != null && v3.Value is int) + { + var ee1 = c1.Conditions[0].Predicate as SqlQuery.Predicate.ExprExpr; + var ee2 = c2.Conditions[0].Predicate as SqlQuery.Predicate.ExprExpr; + + if (ee1 != null && ee2 != null && ee1.Expr1.Equals(ee2.Expr1) && ee1.Expr2.Equals(ee2.Expr2)) + { + int e = 0, g = 0, l = 0; + + if (ee1.Operator == SqlQuery.Predicate.Operator.Equal || ee2.Operator == SqlQuery.Predicate.Operator.Equal) e = 1; + if (ee1.Operator == SqlQuery.Predicate.Operator.Greater || ee2.Operator == SqlQuery.Predicate.Operator.Greater) g = 1; + if (ee1.Operator == SqlQuery.Predicate.Operator.Less || ee2.Operator == SqlQuery.Predicate.Operator.Less) l = 1; + + if (e + g + l == 2) + { + var n = (int)value.Value; + var i1 = (int)v1.Value; + var i2 = (int)v2.Value; + var i3 = (int)v3.Value; + + var n1 = Compare(valueFirst ? n : i1, valueFirst ? i1 : n, expr.Operator) ? 1 : 0; + var n2 = Compare(valueFirst ? n : i2, valueFirst ? i2 : n, expr.Operator) ? 1 : 0; + var n3 = Compare(valueFirst ? n : i3, valueFirst ? i3 : n, expr.Operator) ? 1 : 0; + + if (n1 + n2 + n3 == 1) + { + if (n1 == 1) return ee1; + if (n2 == 1) return ee2; + + return ConvertPredicate(new SqlQuery.Predicate.ExprExpr( + ee1.Expr1, + e == 0 ? SqlQuery.Predicate.Operator.Equal : + g == 0 ? SqlQuery.Predicate.Operator.Greater : + SqlQuery.Predicate.Operator.Less, + ee1.Expr2)); + } + + // CASE + // WHEN [p].[FirstName] > 'John' + // THEN 1 + // WHEN [p].[FirstName] = 'John' + // THEN 0 + // ELSE -1 + // END <= 0 + if (ee1.Operator == SqlQuery.Predicate.Operator.Greater && i1 == 1 && + ee2.Operator == SqlQuery.Predicate.Operator.Equal && i2 == 0 && + i3 == -1 && n == 0) + { + return ConvertPredicate(new SqlQuery.Predicate.ExprExpr( + ee1.Expr1, + valueFirst ? InvertOperator(expr.Operator, true) : expr.Operator, + ee1.Expr2)); + } + } + } + } + } + else if (value.Value is bool && func.Parameters.Length == 3) + { + var c1 = func.Parameters[0] as SqlQuery.SearchCondition; + var v1 = func.Parameters[1] as SqlValue; + var v2 = func.Parameters[2] as SqlValue; + + if (c1 != null && c1.Conditions.Count == 1 && v1 != null && v1.Value is bool && v2 != null && v2.Value is bool) + { + var bv = (bool)value.Value; + var bv1 = (bool)v1.Value; + var bv2 = (bool)v2.Value; + + if (bv == bv1 && expr.Operator == SqlQuery.Predicate.Operator.Equal || + bv != bv1 && expr.Operator == SqlQuery.Predicate.Operator.NotEqual) + { + return c1; + } + + if (bv == bv2 && expr.Operator == SqlQuery.Predicate.Operator.NotEqual || + bv != bv1 && expr.Operator == SqlQuery.Predicate.Operator.Equal) + { + var ee = c1.Conditions[0].Predicate as SqlQuery.Predicate.ExprExpr; + + if (ee != null) + { + var op = InvertOperator(ee.Operator, false); + return new SqlQuery.Predicate.ExprExpr(ee.Expr1, op, ee.Expr2); + } + + var sc = new SqlQuery.SearchCondition(); + + sc.Conditions.Add(new SqlQuery.Condition(true, c1)); + + return sc; + } + } + } + else if (expr.Operator == SqlQuery.Predicate.Operator.Equal && func.Parameters.Length == 3) + { + var sc = func.Parameters[0] as SqlQuery.SearchCondition; + var v1 = func.Parameters[1] as SqlValue; + var v2 = func.Parameters[2] as SqlValue; + + if (sc != null && v1 != null && v2 != null) + { + if (Equals(value.Value, v1.Value)) + return sc; + + if (Equals(value.Value, v2.Value) && !sc.CanBeNull()) + return ConvertPredicate(new SqlQuery.Predicate.NotExpr(sc, true, Precedence.LogicalNegation)); + } + } + } + + return expr; + } + + static bool Compare(int v1, int v2, SqlQuery.Predicate.Operator op) + { + switch (op) + { + case SqlQuery.Predicate.Operator.Equal: return v1 == v2; + case SqlQuery.Predicate.Operator.NotEqual: return v1 != v2; + case SqlQuery.Predicate.Operator.Greater: return v1 > v2; + case SqlQuery.Predicate.Operator.NotLess: + case SqlQuery.Predicate.Operator.GreaterOrEqual: return v1 >= v2; + case SqlQuery.Predicate.Operator.Less: return v1 < v2; + case SqlQuery.Predicate.Operator.NotGreater: + case SqlQuery.Predicate.Operator.LessOrEqual: return v1 <= v2; + } + + throw new InvalidOperationException(); + } + + public virtual SqlQuery Finalize(SqlQuery sqlQuery) + { + sqlQuery.FinalizeAndValidate(IsApplyJoinSupported, IsGroupByExpressionSupported); + + if (!IsCountSubQuerySupported) sqlQuery = MoveCountSubQuery (sqlQuery); + if (!IsSubQueryColumnSupported) sqlQuery = MoveSubQueryColumn(sqlQuery); + + if (!IsCountSubQuerySupported || !IsSubQueryColumnSupported) + sqlQuery.FinalizeAndValidate(IsApplyJoinSupported, IsGroupByExpressionSupported); + + return sqlQuery; + } + + SqlQuery MoveCountSubQuery(SqlQuery sqlQuery) + { + new QueryVisitor().Visit(sqlQuery, MoveCountSubQuery); + return sqlQuery; + } + + void MoveCountSubQuery(IQueryElement element) + { + if (element.ElementType != QueryElementType.SqlQuery) + return; + + var query = (SqlQuery)element; + + for (var i = 0; i < query.Select.Columns.Count; i++) + { + var col = query.Select.Columns[i]; + + // The column is a subquery. + // + if (col.Expression.ElementType == QueryElementType.SqlQuery) + { + var subQuery = (SqlQuery)col.Expression; + var isCount = false; + + // Check if subquery is Count subquery. + // + if (subQuery.Select.Columns.Count == 1) + { + var subCol = subQuery.Select.Columns[0]; + + if (subCol.Expression.ElementType == QueryElementType.SqlFunction) + isCount = ((SqlFunction)subCol.Expression).Name == "Count"; + } + + if (!isCount) + continue; + + // Check if subquery where clause does not have ORs. + // + SqlQuery.OptimizeSearchCondition(subQuery.Where.SearchCondition); + + var allAnd = true; + + for (var j = 0; allAnd && j < subQuery.Where.SearchCondition.Conditions.Count - 1; j++) + { + var cond = subQuery.Where.SearchCondition.Conditions[j]; + + if (cond.IsOr) + allAnd = false; + } + + if (!allAnd || !ConvertCountSubQuery(subQuery)) + continue; + + // Collect tables. + // + var allTables = new HashSet(); + var levelTables = new HashSet(); + + new QueryVisitor().Visit(subQuery, e => + { + if (e is ISqlTableSource) + allTables.Add((ISqlTableSource)e); + }); + + new QueryVisitor().Visit(subQuery, e => + { + if (e is ISqlTableSource) + if (subQuery.From.IsChild((ISqlTableSource)e)) + levelTables.Add((ISqlTableSource)e); + }); + + Func checkTable = e => + { + switch (e.ElementType) + { + case QueryElementType.SqlField : return !allTables.Contains(((SqlField) e).Table); + case QueryElementType.Column : return !allTables.Contains(((SqlQuery.Column)e).Parent); + } + return false; + }; + + var join = SqlQuery.LeftJoin(subQuery); + + query.From.Tables[0].Joins.Add(join.JoinedTable); + + for (var j = 0; j < subQuery.Where.SearchCondition.Conditions.Count; j++) + { + var cond = subQuery.Where.SearchCondition.Conditions[j]; + + if (new QueryVisitor().Find(cond, checkTable) == null) + continue; + + var replaced = new Dictionary(); + + var nc = new QueryVisitor().Convert(cond, e => + { + var ne = e; + + switch (e.ElementType) + { + case QueryElementType.SqlField : + if (replaced.TryGetValue(e, out ne)) + return ne; + + if (levelTables.Contains(((SqlField)e).Table)) + { + subQuery.GroupBy.Expr((SqlField)e); + ne = subQuery.Select.Columns[subQuery.Select.Add((SqlField)e)]; + break; + } + + break; + + case QueryElementType.Column : + if (replaced.TryGetValue(e, out ne)) + return ne; + + if (levelTables.Contains(((SqlQuery.Column)e).Parent)) + { + subQuery.GroupBy.Expr((SqlQuery.Column)e); + ne = subQuery.Select.Columns[subQuery.Select.Add((SqlQuery.Column)e)]; + break; + } + + break; + } + + if (!ReferenceEquals(e, ne)) + replaced.Add(e, ne); + + return ne; + }); + + if (nc != null && !ReferenceEquals(nc, cond)) + { + join.JoinedTable.Condition.Conditions.Add(nc); + subQuery.Where.SearchCondition.Conditions.RemoveAt(j); + j--; + } + } + + if (!query.GroupBy.IsEmpty/* && subQuery.Select.Columns.Count > 1*/) + { + var oldFunc = (SqlFunction)subQuery.Select.Columns[0].Expression; + + subQuery.Select.Columns.RemoveAt(0); + + query.Select.Columns[i].Expression = + new SqlFunction(oldFunc.SystemType, oldFunc.Name, subQuery.Select.Columns[0]); + } + else + { + query.Select.Columns[i].Expression = subQuery.Select.Columns[0]; + } + } + } + } + + SqlQuery MoveSubQueryColumn(SqlQuery sqlQuery) + { + var dic = new Dictionary(); + + new QueryVisitor().Visit(sqlQuery, element => + { + if (element.ElementType != QueryElementType.SqlQuery) + return; + + var query = (SqlQuery)element; + + for (var i = 0; i < query.Select.Columns.Count; i++) + { + var col = query.Select.Columns[i]; + + if (col.Expression.ElementType == QueryElementType.SqlQuery) + { + var subQuery = (SqlQuery)col.Expression; + var allTables = new HashSet(); + var levelTables = new HashSet(); + + Func checkTable = e => + { + switch (e.ElementType) + { + case QueryElementType.SqlField : return !allTables.Contains(((SqlField)e).Table); + case QueryElementType.Column : return !allTables.Contains(((SqlQuery.Column)e).Parent); + } + return false; + }; + + new QueryVisitor().Visit(subQuery, e => + { + if (e is ISqlTableSource /*&& subQuery.From.IsChild((ISqlTableSource)e)*/) + allTables.Add((ISqlTableSource)e); + }); + + new QueryVisitor().Visit(subQuery, e => + { + if (e is ISqlTableSource && subQuery.From.IsChild((ISqlTableSource)e)) + levelTables.Add((ISqlTableSource)e); + }); + + if (IsSubQueryColumnSupported && new QueryVisitor().Find(subQuery, checkTable) == null) + continue; + + var join = SqlQuery.LeftJoin(subQuery); + + query.From.Tables[0].Joins.Add(join.JoinedTable); + + SqlQuery.OptimizeSearchCondition(subQuery.Where.SearchCondition); + + var isCount = false; + var isAggregated = false; + + if (subQuery.Select.Columns.Count == 1) + { + var subCol = subQuery.Select.Columns[0]; + + if (subCol.Expression.ElementType == QueryElementType.SqlFunction) + { + switch (((SqlFunction)subCol.Expression).Name) + { + case "Min" : + case "Max" : + case "Sum" : + case "Average" : isAggregated = true; break; + case "Count" : isAggregated = true; isCount = true; break; + } + } + } + + if (IsSubQueryColumnSupported && !isCount) + continue; + + var allAnd = true; + + for (var j = 0; allAnd && j < subQuery.Where.SearchCondition.Conditions.Count - 1; j++) + { + var cond = subQuery.Where.SearchCondition.Conditions[j]; + + if (cond.IsOr) + allAnd = false; + } + + if (!allAnd) + continue; + + var modified = false; + + for (var j = 0; j < subQuery.Where.SearchCondition.Conditions.Count; j++) + { + var cond = subQuery.Where.SearchCondition.Conditions[j]; + + if (new QueryVisitor().Find(cond, checkTable) == null) + continue; + + var replaced = new Dictionary(); + + var nc = new QueryVisitor().Convert(cond, delegate(IQueryElement e) + { + var ne = e; + + switch (e.ElementType) + { + case QueryElementType.SqlField : + if (replaced.TryGetValue(e, out ne)) + return ne; + + if (levelTables.Contains(((SqlField)e).Table)) + { + if (isAggregated) + subQuery.GroupBy.Expr((SqlField)e); + ne = subQuery.Select.Columns[subQuery.Select.Add((SqlField)e)]; + break; + } + + break; + + case QueryElementType.Column : + if (replaced.TryGetValue(e, out ne)) + return ne; + + if (levelTables.Contains(((SqlQuery.Column)e).Parent)) + { + if (isAggregated) + subQuery.GroupBy.Expr((SqlQuery.Column)e); + ne = subQuery.Select.Columns[subQuery.Select.Add((SqlQuery.Column)e)]; + break; + } + + break; + } + + if (!ReferenceEquals(e, ne)) + replaced.Add(e, ne); + + return ne; + }); + + if (nc != null && !ReferenceEquals(nc, cond)) + { + modified = true; + + join.JoinedTable.Condition.Conditions.Add(nc); + subQuery.Where.SearchCondition.Conditions.RemoveAt(j); + j--; + } + } + + if (modified || isAggregated) + { + if (isCount && !query.GroupBy.IsEmpty) + { + var oldFunc = (SqlFunction)subQuery.Select.Columns[0].Expression; + + subQuery.Select.Columns.RemoveAt(0); + + query.Select.Columns[i] = new SqlQuery.Column( + query, + new SqlFunction(oldFunc.SystemType, oldFunc.Name, subQuery.Select.Columns[0])); + } + else if (isAggregated && !query.GroupBy.IsEmpty) + { + var oldFunc = (SqlFunction)subQuery.Select.Columns[0].Expression; + + subQuery.Select.Columns.RemoveAt(0); + + var idx = subQuery.Select.Add(oldFunc.Parameters[0]); + + query.Select.Columns[i] = new SqlQuery.Column( + query, + new SqlFunction(oldFunc.SystemType, oldFunc.Name, subQuery.Select.Columns[idx])); + } + else + { + query.Select.Columns[i] = new SqlQuery.Column(query, subQuery.Select.Columns[0]); + } + + dic.Add(col, query.Select.Columns[i]); + } + } + } + }); + + sqlQuery = new QueryVisitor().Convert(sqlQuery, e => + { + IQueryElement ne; + return dic.TryGetValue(e, out ne) ? ne : e; + }); + + return sqlQuery; + } + + public virtual ISqlExpression GetIdentityExpression(SqlTable table, SqlField identityField, bool forReturning) + { + return null; + } + + private string _name; + public virtual string Name + { + get { return _name ?? (_name = GetType().Name.Replace("SqlProvider", "")); } + } + + #endregion + + #region Linq Support + + public virtual LambdaExpression ConvertMember(MemberInfo mi) + { + return Expressions.ConvertMember(Name, mi); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/DB2SqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/DB2SqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,321 @@ +using System; +using System.Text; + +using BLToolkit.Reflection; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + + public class DB2SqlProvider : BasicSqlProvider + { + public override bool TakeAcceptsParameter { get { return SqlQuery.Select.SkipValue != null; } } + + SqlField _identityField; + + public override int CommandCount(SqlQuery sqlQuery) + { + if (sqlQuery.IsInsert && sqlQuery.Insert.WithIdentity) + { + _identityField = sqlQuery.Insert.Into.GetIdentityField(); + + if (_identityField == null) + return 2; + } + + return 1; + } + + public override int BuildSql(int commandNumber, SqlQuery sqlQuery, StringBuilder sb, int indent, int nesting, bool skipAlias) + { + if (_identityField != null) + { + indent += 2; + + AppendIndent(sb).AppendLine("SELECT"); + AppendIndent(sb).Append("\t"); + BuildExpression(sb, _identityField, false, true); + sb.AppendLine(); + AppendIndent(sb).AppendLine("FROM"); + AppendIndent(sb).AppendLine("\tNEW TABLE"); + AppendIndent(sb).AppendLine("\t("); + } + + var ret = base.BuildSql(commandNumber, sqlQuery, sb, indent, nesting, skipAlias); + + if (_identityField != null) + sb.AppendLine("\t)"); + + return ret; + } + + protected override void BuildCommand(int commandNumber, StringBuilder sb) + { + sb.AppendLine("SELECT identity_val_local() FROM SYSIBM.SYSDUMMY1"); + } + + protected override ISqlProvider CreateSqlProvider() + { + return new DB2SqlProvider(); + } + + protected override void BuildSql(StringBuilder sb) + { + AlternativeBuildSql(sb, false, base.BuildSql); + } + + protected override void BuildSelectClause(StringBuilder sb) + { + if (SqlQuery.From.Tables.Count == 0) + { + AppendIndent(sb).AppendLine("SELECT"); + BuildColumns(sb); + AppendIndent(sb).AppendLine("FROM SYSIBM.SYSDUMMY1 FETCH FIRST 1 ROW ONLY"); + } + else + base.BuildSelectClause(sb); + } + + protected override string LimitFormat + { + get { return SqlQuery.Select.SkipValue == null ? "FETCH FIRST {0} ROWS ONLY" : null; } + } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlBinaryExpression) + { + var be = (SqlBinaryExpression)expr; + + switch (be.Operation) + { + case "%": + { + var expr1 = !TypeHelper.IsIntegerType(be.Expr1.SystemType) ? new SqlFunction(typeof(int), "Int", be.Expr1) : be.Expr1; + return new SqlFunction(be.SystemType, "Mod", expr1, be.Expr2); + } + case "&": return new SqlFunction(be.SystemType, "BitAnd", be.Expr1, be.Expr2); + case "|": return new SqlFunction(be.SystemType, "BitOr", be.Expr1, be.Expr2); + case "^": return new SqlFunction(be.SystemType, "BitXor", be.Expr1, be.Expr2); + case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; + } + } + else if (expr is SqlFunction) + { + var func = (SqlFunction) expr; + + switch (func.Name) + { + case "Convert" : + if (TypeHelper.GetUnderlyingType(func.SystemType) == typeof(bool)) + { + var ex = AlternativeConvertToBoolean(func, 1); + if (ex != null) + return ex; + } + + if (func.Parameters[0] is SqlDataType) + { + var type = (SqlDataType)func.Parameters[0]; + + if (type.Type == typeof(string) && func.Parameters[1].SystemType != typeof(string)) + return new SqlFunction(func.SystemType, "RTrim", new SqlFunction(typeof(string), "Char", func.Parameters[1])); + + if (type.Length > 0) + return new SqlFunction(func.SystemType, type.SqlDbType.ToString(), func.Parameters[1], new SqlValue(type.Length)); + + if (type.Precision > 0) + return new SqlFunction(func.SystemType, type.SqlDbType.ToString(), func.Parameters[1], new SqlValue(type.Precision), new SqlValue(type.Scale)); + + return new SqlFunction(func.SystemType, type.SqlDbType.ToString(), func.Parameters[1]); + } + + if (func.Parameters[0] is SqlFunction) + { + var f = (SqlFunction)func.Parameters[0]; + + return + f.Name == "Char" ? + new SqlFunction(func.SystemType, f.Name, func.Parameters[1]) : + f.Parameters.Length == 1 ? + new SqlFunction(func.SystemType, f.Name, func.Parameters[1], f.Parameters[0]) : + new SqlFunction(func.SystemType, f.Name, func.Parameters[1], f.Parameters[0], f.Parameters[1]); + } + + { + var e = (SqlExpression)func.Parameters[0]; + return new SqlFunction(func.SystemType, e.Expr, func.Parameters[1]); + } + + case "Millisecond" : return Div(new SqlFunction(func.SystemType, "Microsecond", func.Parameters), 1000); + case "SmallDateTime" : + case "DateTime" : + case "DateTime2" : return new SqlFunction(func.SystemType, "TimeStamp", func.Parameters); + case "TinyInt" : return new SqlFunction(func.SystemType, "SmallInt", func.Parameters); + case "Money" : return new SqlFunction(func.SystemType, "Decimal", func.Parameters[0], new SqlValue(19), new SqlValue(4)); + case "SmallMoney" : return new SqlFunction(func.SystemType, "Decimal", func.Parameters[0], new SqlValue(10), new SqlValue(4)); + case "VarChar" : + if (TypeHelper.GetUnderlyingType(func.Parameters[0].SystemType) == typeof(decimal)) + return new SqlFunction(func.SystemType, "Char", func.Parameters[0]); + break; + case "NChar" : + case "NVarChar" : return new SqlFunction(func.SystemType, "Char", func.Parameters); + case "DateDiff" : + { + switch ((Linq.Sql.DateParts)((SqlValue)func.Parameters[0]).Value) + { + case Linq.Sql.DateParts.Day : return new SqlExpression(typeof(int), "((Days({0}) - Days({1})) * 86400 + (MIDNIGHT_SECONDS({0}) - MIDNIGHT_SECONDS({1}))) / 86400", Precedence.Multiplicative, func.Parameters[2], func.Parameters[1]); + case Linq.Sql.DateParts.Hour : return new SqlExpression(typeof(int), "((Days({0}) - Days({1})) * 86400 + (MIDNIGHT_SECONDS({0}) - MIDNIGHT_SECONDS({1}))) / 3600", Precedence.Multiplicative, func.Parameters[2], func.Parameters[1]); + case Linq.Sql.DateParts.Minute : return new SqlExpression(typeof(int), "((Days({0}) - Days({1})) * 86400 + (MIDNIGHT_SECONDS({0}) - MIDNIGHT_SECONDS({1}))) / 60", Precedence.Multiplicative, func.Parameters[2], func.Parameters[1]); + case Linq.Sql.DateParts.Second : return new SqlExpression(typeof(int), "(Days({0}) - Days({1})) * 86400 + (MIDNIGHT_SECONDS({0}) - MIDNIGHT_SECONDS({1}))", Precedence.Additive, func.Parameters[2], func.Parameters[1]); + case Linq.Sql.DateParts.Millisecond : return new SqlExpression(typeof(int), "((Days({0}) - Days({1})) * 86400 + (MIDNIGHT_SECONDS({0}) - MIDNIGHT_SECONDS({1}))) * 1000 + (MICROSECOND({0}) - MICROSECOND({1})) / 1000", Precedence.Additive, func.Parameters[2], func.Parameters[1]); + } + } + + break; + } + } + + return expr; + } + + protected override void BuildFunction(StringBuilder sb, SqlFunction func) + { + func = ConvertFunctionParameters(func); + base.BuildFunction(sb, func); + } + + static void SetQueryParameter(IQueryElement element) + { + if (element.ElementType == QueryElementType.SqlParameter) + ((SqlParameter)element).IsQueryParameter = false; + } + + public override SqlQuery Finalize(SqlQuery sqlQuery) + { + new QueryVisitor().Visit(sqlQuery.Select, SetQueryParameter); + + //if (sqlQuery.QueryType == QueryType.InsertOrUpdate) + // foreach (var key in sqlQuery.Insert.Items) + // if (((SqlField)key.Column).IsPrimaryKey) + // new QueryVisitor().Visit(key.Expression, SetQueryParameter); + + sqlQuery = base.Finalize(sqlQuery); + + switch (sqlQuery.QueryType) + { + case QueryType.Delete : return GetAlternativeDelete(sqlQuery); + case QueryType.Update : return GetAlternativeUpdate(sqlQuery); + default : return sqlQuery; + } + } + + protected override void BuildFromClause(StringBuilder sb) + { + if (!SqlQuery.IsUpdate) + base.BuildFromClause(sb); + } + + public override void BuildValue(StringBuilder sb, object value) + { + if (value is Guid) + { + var s = ((Guid)value).ToString("N"); + + sb + .Append("Cast(x'") + .Append(s.Substring( 6, 2)) + .Append(s.Substring( 4, 2)) + .Append(s.Substring( 2, 2)) + .Append(s.Substring( 0, 2)) + .Append(s.Substring(10, 2)) + .Append(s.Substring( 8, 2)) + .Append(s.Substring(14, 2)) + .Append(s.Substring(12, 2)) + .Append(s.Substring(16, 16)) + .Append("' as char(16) for bit data)"); + } + else + base.BuildValue(sb, value); + } + + protected override void BuildColumnExpression(StringBuilder sb, ISqlExpression expr, string alias, ref bool addAlias) + { + var wrap = false; + + if (expr.SystemType == typeof(bool)) + { + if (expr is SqlQuery.SearchCondition) + wrap = true; + else + { + var ex = expr as SqlExpression; + wrap = ex != null && ex.Expr == "{0}" && ex.Parameters.Length == 1 && ex.Parameters[0] is SqlQuery.SearchCondition; + } + } + + if (wrap) sb.Append("CASE WHEN "); + base.BuildColumnExpression(sb, expr, alias, ref addAlias); + if (wrap) sb.Append(" THEN 1 ELSE 0 END"); + } + + public static bool QuoteIdentifiers = true; + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter: + return "@" + value; + + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return ":" + value; + + case ConvertType.SprocParameterToName: + if (value != null) + { + var str = value.ToString(); + return str.Length > 0 && str[0] == ':'? str.Substring(1): str; + } + + break; + + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryFieldAlias: + case ConvertType.NameToQueryTable: + case ConvertType.NameToQueryTableAlias: + if (QuoteIdentifiers) + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '"') + return value; + + return '"' + name + '"'; + } + + break; + } + + return value; + } + + protected override void BuildInsertOrUpdateQuery(StringBuilder sb) + { + BuildInsertOrUpdateQueryAsMerge(sb, "FROM SYSIBM.SYSDUMMY1 FETCH FIRST 1 ROW ONLY"); + } + + protected override void BuildEmptyInsert(StringBuilder sb) + { + sb.Append("VALUES "); + + foreach (var col in SqlQuery.Insert.Into.Fields) + sb.Append("(DEFAULT)"); + + sb.AppendLine(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/FirebirdSqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/FirebirdSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,299 @@ +using System; +using System.Data; +using System.Text; + +#region ReSharper disable +// ReSharper disable SuggestUseVarKeywordEverywhere +// ReSharper disable SuggestUseVarKeywordEvident +#endregion + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + using Mapping; + using Reflection; + + using Linq; + + public class FirebirdSqlProvider : BasicSqlProvider, IMappingSchemaProvider + { + public FirebirdSqlProvider() + { + } + +// public override int CommandCount(SqlQuery sqlQuery) +// { +// return sqlQuery.IsInsert && sqlQuery.Set.WithIdentity ? 2 : 1; +// } + +// protected override void BuildCommand(int commandNumber, StringBuilder sb) +// { +// SequenceNameAttribute attr = GetSequenceNameAttribute(true); +// +// AppendIndent(sb) +// .Append("SELECT gen_id(") +// .Append(attr.SequenceName) +// .AppendLine(", 0) FROM rdb$database"); +// } + + protected override ISqlProvider CreateSqlProvider() + { + return new FirebirdSqlProvider(); + } + + protected override void BuildSelectClause(StringBuilder sb) + { + if (SqlQuery.From.Tables.Count == 0) + { + AppendIndent(sb); + sb.Append("SELECT").AppendLine(); + BuildColumns(sb); + AppendIndent(sb); + sb.Append("FROM rdb$database").AppendLine(); + } + else + base.BuildSelectClause(sb); + } + + protected override bool SkipFirst { get { return false; } } + protected override string SkipFormat { get { return "SKIP {0}"; } } + protected override string FirstFormat { get { return "FIRST {0}"; } } + + public override bool IsIdentityParameterRequired { get { return true; } } + + protected override void BuildGetIdentity(StringBuilder sb) + { + var identityField = SqlQuery.Insert.Into.GetIdentityField(); + + if (identityField == null) + throw new SqlException("Identity field must be defined for '{0}'.", SqlQuery.Insert.Into.Name); + + AppendIndent(sb).AppendLine("RETURNING"); + AppendIndent(sb).Append("\t"); + BuildExpression(sb, identityField, false, true); + } + + public override ISqlExpression GetIdentityExpression(SqlTable table, SqlField identityField, bool forReturning) + { + if (table.SequenceAttributes != null) + return new SqlExpression("GEN_ID(" + table.SequenceAttributes[0].SequenceName + ", 1)", Precedence.Primary); + + return base.GetIdentityExpression(table, identityField, forReturning); + } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlBinaryExpression) + { + SqlBinaryExpression be = (SqlBinaryExpression)expr; + + switch (be.Operation) + { + case "%": return new SqlFunction(be.SystemType, "Mod", be.Expr1, be.Expr2); + case "&": return new SqlFunction(be.SystemType, "Bin_And", be.Expr1, be.Expr2); + case "|": return new SqlFunction(be.SystemType, "Bin_Or", be.Expr1, be.Expr2); + case "^": return new SqlFunction(be.SystemType, "Bin_Xor", be.Expr1, be.Expr2); + case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; + } + } + else if (expr is SqlFunction) + { + SqlFunction func = (SqlFunction)expr; + + switch (func.Name) + { + case "Convert" : + if (TypeHelper.GetUnderlyingType(func.SystemType) == typeof(bool)) + { + ISqlExpression ex = AlternativeConvertToBoolean(func, 1); + if (ex != null) + return ex; + } + + return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, FloorBeforeConvert(func), func.Parameters[0]); + + case "DateAdd" : + switch ((Sql.DateParts)((SqlValue)func.Parameters[0]).Value) + { + case Sql.DateParts.Quarter : + return new SqlFunction(func.SystemType, func.Name, new SqlValue(Sql.DateParts.Month), Mul(func.Parameters[1], 3), func.Parameters[2]); + case Sql.DateParts.DayOfYear: + case Sql.DateParts.WeekDay: + return new SqlFunction(func.SystemType, func.Name, new SqlValue(Sql.DateParts.Day), func.Parameters[1], func.Parameters[2]); + case Sql.DateParts.Week : + return new SqlFunction(func.SystemType, func.Name, new SqlValue(Sql.DateParts.Day), Mul(func.Parameters[1], 7), func.Parameters[2]); + } + + break; + } + } + else if (expr is SqlExpression) + { + SqlExpression e = (SqlExpression)expr; + + if (e.Expr.StartsWith("Extract(Quarter")) + return Inc(Div(Dec(new SqlExpression(e.SystemType, "Extract(Month from {0})", e.Parameters)), 3)); + + if (e.Expr.StartsWith("Extract(YearDay")) + return Inc(new SqlExpression(e.SystemType, e.Expr.Replace("Extract(YearDay", "Extract(yearDay"), e.Parameters)); + + if (e.Expr.StartsWith("Extract(WeekDay")) + return Inc(new SqlExpression(e.SystemType, e.Expr.Replace("Extract(WeekDay", "Extract(weekDay"), e.Parameters)); + } + + return expr; + } + + protected override void BuildFunction(StringBuilder sb, SqlFunction func) + { + func = ConvertFunctionParameters(func); + base.BuildFunction(sb, func); + } + + protected override void BuildDataType(StringBuilder sb, SqlDataType type) + { + switch (type.SqlDbType) + { + case SqlDbType.Decimal : + base.BuildDataType(sb, type.Precision > 18 ? new SqlDataType(type.SqlDbType, type.Type, 18, type.Scale) : type); + break; + case SqlDbType.TinyInt : sb.Append("SmallInt"); break; + case SqlDbType.Money : sb.Append("Decimal(18,4)"); break; + case SqlDbType.SmallMoney : sb.Append("Decimal(10,4)"); break; +#if !MONO + case SqlDbType.DateTime2 : +#endif + case SqlDbType.SmallDateTime : + case SqlDbType.DateTime : sb.Append("TimeStamp"); break; + case SqlDbType.NVarChar : + sb.Append("VarChar"); + if (type.Length > 0) + sb.Append('(').Append(type.Length).Append(')'); + break; + default : base.BuildDataType(sb, type); break; + } + } + + static void SetNonQueryParameter(IQueryElement element) + { + if (element.ElementType == QueryElementType.SqlParameter) + ((SqlParameter)element).IsQueryParameter = false; + } + + public override SqlQuery Finalize(SqlQuery sqlQuery) + { + CheckAliases(sqlQuery, int.MaxValue); + + new QueryVisitor().Visit(sqlQuery.Select, SetNonQueryParameter); + + if (sqlQuery.QueryType == QueryType.InsertOrUpdate) + { + foreach (var key in sqlQuery.Insert.Items) + new QueryVisitor().Visit(key.Expression, SetNonQueryParameter); + + foreach (var key in sqlQuery.Update.Items) + new QueryVisitor().Visit(key.Expression, SetNonQueryParameter); + + foreach (var key in sqlQuery.Update.Keys) + new QueryVisitor().Visit(key.Expression, SetNonQueryParameter); + } + + new QueryVisitor().Visit(sqlQuery, element => + { + if (element.ElementType == QueryElementType.InSubQueryPredicate) + new QueryVisitor().Visit(((SqlQuery.Predicate.InSubQuery)element).Expr1, SetNonQueryParameter); + }); + + sqlQuery = base.Finalize(sqlQuery); + + switch (sqlQuery.QueryType) + { + case QueryType.Delete : return GetAlternativeDelete(sqlQuery); + case QueryType.Update : return GetAlternativeUpdate(sqlQuery); + default : return sqlQuery; + } + } + + protected override void BuildFromClause(StringBuilder sb) + { + if (!SqlQuery.IsUpdate) + base.BuildFromClause(sb); + } + + protected override void BuildColumnExpression(StringBuilder sb, ISqlExpression expr, string alias, ref bool addAlias) + { + var wrap = false; + + if (expr.SystemType == typeof(bool)) + { + if (expr is SqlQuery.SearchCondition) + wrap = true; + else + { + var ex = expr as SqlExpression; + wrap = ex != null && ex.Expr == "{0}" && ex.Parameters.Length == 1 && ex.Parameters[0] is SqlQuery.SearchCondition; + } + } + + if (wrap) sb.Append("CASE WHEN "); + base.BuildColumnExpression(sb, expr, alias, ref addAlias); + if (wrap) sb.Append(" THEN 1 ELSE 0 END"); + } + + public static bool QuoteIdentifiers = false; + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryTable: + if (QuoteIdentifiers) + { + string name = value.ToString(); + + if (name.Length > 0 && name[0] == '"') + return value; + + return '"' + name + '"'; + } + + break; + + case ConvertType.NameToQueryParameter: + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return "@" + value; + + case ConvertType.SprocParameterToName: + if (value != null) + { + string str = value.ToString(); + return str.Length > 0 && str[0] == '@' ? str.Substring(1) : str; + } + + break; + } + + return value; + } + + protected override void BuildInsertOrUpdateQuery(StringBuilder sb) + { + BuildInsertOrUpdateQueryAsMerge(sb, "FROM rdb$database"); + } + + #region IMappingSchemaProvider Members + + readonly FirebirdMappingSchema _mappingSchema = new FirebirdMappingSchema(); + + MappingSchema IMappingSchemaProvider.MappingSchema + { + get { return _mappingSchema; } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/ISqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/ISqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,38 @@ +using System; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + + public interface ISqlProvider + { + int CommandCount (SqlQuery sqlQuery); + int BuildSql (int commandNumber, SqlQuery sqlQuery, StringBuilder sb, int indent, int nesting, bool skipAlias); + ISqlExpression ConvertExpression (ISqlExpression expression); + ISqlPredicate ConvertPredicate (ISqlPredicate predicate); + SqlQuery Finalize (SqlQuery sqlQuery); + + StringBuilder BuildTableName (StringBuilder sb, string database, string owner, string table); + object Convert (object value, ConvertType convertType); + LambdaExpression ConvertMember (MemberInfo mi); + ISqlExpression GetIdentityExpression(SqlTable table, SqlField identityField, bool forReturning); + + string Name { get; } + SqlQuery SqlQuery { get; set; } + + bool SkipAcceptsParameter { get; } + bool TakeAcceptsParameter { get; } + bool IsSkipSupported { get; } + bool IsTakeSupported { get; } + bool IsSubQueryTakeSupported { get; } + bool IsSubQueryColumnSupported { get; } + bool IsCountSubQuerySupported { get; } + bool IsIdentityParameterRequired { get; } + bool IsApplyJoinSupported { get; } + bool IsInsertOrUpdateSupported { get; } + bool CanCombineParameters { get; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/InformixSqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/InformixSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,274 @@ +using System; +using System.Data; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + using Reflection; + + public class InformixSqlProvider : BasicSqlProvider + { + public override int CommandCount(SqlQuery sqlQuery) + { + return sqlQuery.IsInsert && sqlQuery.Insert.WithIdentity ? 2 : 1; + } + + protected override void BuildCommand(int commandNumber, StringBuilder sb) + { + sb.AppendLine("SELECT DBINFO('sqlca.sqlerrd1') FROM systables where tabid = 1"); + } + + protected override ISqlProvider CreateSqlProvider() + { + return new InformixSqlProvider(); + } + + public override int BuildSql(int commandNumber, SqlQuery sqlQuery, StringBuilder sb, int indent, int nesting, bool skipAlias) + { + var n = base.BuildSql(commandNumber, sqlQuery, sb, indent, nesting, skipAlias); + + sb + .Replace("NULL IS NOT NULL", "1=0") + .Replace("NULL IS NULL", "1=1"); + + return n; + } + + protected override void BuildSelectClause(StringBuilder sb) + { + if (SqlQuery.From.Tables.Count == 0) + { + AppendIndent(sb).Append("SELECT FIRST 1").AppendLine(); + BuildColumns(sb); + AppendIndent(sb).Append("FROM SYSTABLES").AppendLine(); + } + else + base.BuildSelectClause(sb); + } + + public override bool IsSubQueryTakeSupported { get { return false; } } + public override bool IsInsertOrUpdateSupported { get { return false; } } + public override bool IsGroupByExpressionSupported { get { return false; } } + + protected override string FirstFormat { get { return "FIRST {0}"; } } + protected override string SkipFormat { get { return "SKIP {0}"; } } + + protected override void BuildLikePredicate(StringBuilder sb, SqlQuery.Predicate.Like predicate) + { + if (predicate.IsNot) + sb.Append("NOT "); + + var precedence = GetPrecedence(predicate); + + BuildExpression(sb, precedence, predicate.Expr1); + sb.Append(" LIKE "); + BuildExpression(sb, precedence, predicate.Expr2); + + if (predicate.Escape != null) + { + sb.Append(" ESCAPE "); + BuildExpression(sb, precedence, predicate.Escape); + } + } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlBinaryExpression) + { + var be = (SqlBinaryExpression)expr; + + switch (be.Operation) + { + case "%": return new SqlFunction(be.SystemType, "Mod", be.Expr1, be.Expr2); + case "&": return new SqlFunction(be.SystemType, "BitAnd", be.Expr1, be.Expr2); + case "|": return new SqlFunction(be.SystemType, "BitOr", be.Expr1, be.Expr2); + case "^": return new SqlFunction(be.SystemType, "BitXor", be.Expr1, be.Expr2); + case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; + } + } + else if (expr is SqlFunction) + { + var func = (SqlFunction)expr; + + switch (func.Name) + { + case "Coalesce" : return new SqlFunction(func.SystemType, "Nvl", func.Parameters); + case "Convert" : + { + var par0 = func.Parameters[0]; + var par1 = func.Parameters[1]; + + switch (Type.GetTypeCode(TypeHelper.GetUnderlyingType(func.SystemType))) + { + case TypeCode.String : return new SqlFunction(func.SystemType, "To_Char", func.Parameters[1]); + case TypeCode.Boolean : + { + var ex = AlternativeConvertToBoolean(func, 1); + if (ex != null) + return ex; + break; + } + + case TypeCode.UInt64: + if (TypeHelper.IsFloatType(func.Parameters[1].SystemType)) + par1 = new SqlFunction(func.SystemType, "Floor", func.Parameters[1]); + break; + + case TypeCode.DateTime : + if (IsDateDataType(func.Parameters[0], "Date")) + { + if (func.Parameters[1].SystemType == typeof(string)) + { + return new SqlFunction( + func.SystemType, + "Date", + new SqlFunction(func.SystemType, "To_Date", func.Parameters[1], new SqlValue("%Y-%m-%d"))); + } + + return new SqlFunction(func.SystemType, "Date", func.Parameters[1]); + } + + if (IsTimeDataType(func.Parameters[0])) + return new SqlExpression(func.SystemType, "Cast(Extend({0}, hour to second) as Char(8))", Precedence.Primary, func.Parameters[1]); + + return new SqlFunction(func.SystemType, "To_Date", func.Parameters[1]); + + default: + if (TypeHelper.GetUnderlyingType(func.SystemType) == typeof(DateTimeOffset)) + goto case TypeCode.DateTime; + break; + } + + return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, par1, par0); + } + + case "Quarter" : return Inc(Div(Dec(new SqlFunction(func.SystemType, "Month", func.Parameters)), 3)); + case "WeekDay" : return Inc(new SqlFunction(func.SystemType, "weekDay", func.Parameters)); + case "DayOfYear": + return + Inc(Sub( + new SqlFunction(null, "Mdy", + new SqlFunction(null, "Month", func.Parameters), + new SqlFunction(null, "Day", func.Parameters), + new SqlFunction(null, "Year", func.Parameters)), + new SqlFunction(null, "Mdy", + new SqlValue(1), + new SqlValue(1), + new SqlFunction(null, "Year", func.Parameters)))); + case "Week" : + return + new SqlExpression( + func.SystemType, + "((Extend({0}, year to day) - (Mdy(12, 31 - WeekDay(Mdy(1, 1, year({0}))), Year({0}) - 1) + Interval(1) day to day)) / 7 + Interval(1) day to day)::char(10)::int", + func.Parameters); + case "Hour" : + case "Minute" : + case "Second" : return new SqlExpression(func.SystemType, string.Format("({{0}}::datetime {0} to {0})::char(3)::int", func.Name), func.Parameters); + } + } + + return expr; + } + + protected override void BuildFunction(StringBuilder sb, SqlFunction func) + { + func = ConvertFunctionParameters(func); + base.BuildFunction(sb, func); + } + + public virtual object ConvertBooleanValue(bool value) + { + return value ? 't' : 'f'; + } + + public override void BuildValue(StringBuilder sb, object value) + { + if (value is bool || value is bool?) + sb.Append("'").Append(ConvertBooleanValue((bool)value)).Append("'"); + else + base.BuildValue(sb, value); + } + + protected override void BuildDataType(StringBuilder sb, SqlDataType type) + { + switch (type.SqlDbType) + { + case SqlDbType.TinyInt : sb.Append("SmallInt"); break; + case SqlDbType.SmallMoney : sb.Append("Decimal(10,4)"); break; + default : base.BuildDataType(sb, type); break; + } + } + + static void SetQueryParameter(IQueryElement element) + { + if (element.ElementType == QueryElementType.SqlParameter) + ((SqlParameter)element).IsQueryParameter = false; + } + + public override SqlQuery Finalize(SqlQuery sqlQuery) + { + CheckAliases(sqlQuery, int.MaxValue); + + new QueryVisitor().Visit(sqlQuery.Select, SetQueryParameter); + + //if (sqlQuery.QueryType == QueryType.InsertOrUpdate) + //{ + // foreach (var key in sqlQuery.Insert.Items) + // new QueryVisitor().Visit(key.Expression, SetQueryParameter); + // + // foreach (var key in sqlQuery.Update.Items) + // new QueryVisitor().Visit(key.Expression, SetQueryParameter); + //} + + sqlQuery = base.Finalize(sqlQuery); + + switch (sqlQuery.QueryType) + { + case QueryType.Delete : + sqlQuery = GetAlternativeDelete(sqlQuery); + sqlQuery.From.Tables[0].Alias = "$"; + break; + + case QueryType.Update : + sqlQuery = GetAlternativeUpdate(sqlQuery); + break; + } + + return sqlQuery; + } + + protected override void BuildFromClause(StringBuilder sb) + { + if (!SqlQuery.IsUpdate) + base.BuildFromClause(sb); + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter : return "?"; + case ConvertType.NameToCommandParameter : + case ConvertType.NameToSprocParameter : return ":" + value; + case ConvertType.SprocParameterToName : + if (value != null) + { + var str = value.ToString(); + return (str.Length > 0 && str[0] == ':')? str.Substring(1): str; + } + + break; + } + + return value; + } + + //protected override void BuildInsertOrUpdateQuery(StringBuilder sb) + //{ + // BuildInsertOrUpdateQueryAsMerge(sb, "FROM SYSTABLES"); + //} + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/MSSqlSqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/MSSqlSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,242 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + using Reflection; + + public abstract class MsSqlSqlProvider : BasicSqlProvider + { + public override bool IsApplyJoinSupported { get { return true; } } + + protected virtual bool BuildAlternativeSql { get { return true; } } + + protected override string FirstFormat + { + get { return SqlQuery.Select.SkipValue == null ? "TOP ({0})" : null; } + } + + protected override void BuildSql(StringBuilder sb) + { + if (BuildAlternativeSql) + AlternativeBuildSql(sb, true, base.BuildSql); + else + base.BuildSql(sb); + } + + protected override void BuildGetIdentity(StringBuilder sb) + { + sb + .AppendLine() + .AppendLine("SELECT SCOPE_IDENTITY()"); + } + + protected override void BuildOrderByClause(StringBuilder sb) + { + if (!BuildAlternativeSql || !NeedSkip) + base.BuildOrderByClause(sb); + } + + protected override IEnumerable GetSelectedColumns() + { + if (BuildAlternativeSql && NeedSkip && !SqlQuery.OrderBy.IsEmpty) + return AlternativeGetSelectedColumns(base.GetSelectedColumns); + return base.GetSelectedColumns(); + } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + switch (expr.ElementType) + { + case QueryElementType.SqlBinaryExpression: + { + var be = (SqlBinaryExpression)expr; + + switch (be.Operation) + { + case "%": + { + var type1 = TypeHelper.GetUnderlyingType(be.Expr1.SystemType); + + if (type1 == typeof(double) || type1 == typeof(float)) + { + return new SqlBinaryExpression( + be.Expr2.SystemType, + new SqlFunction(typeof(int), "Convert", SqlDataType.Int32, be.Expr1), + be.Operation, + be.Expr2); + } + + break; + } + } + + break; + } + + case QueryElementType.SqlFunction: + { + var func = (SqlFunction)expr; + + switch (func.Name) + { + case "Convert" : + { + if (TypeHelper.GetUnderlyingType(func.SystemType) == typeof(ulong) && + TypeHelper.IsFloatType(func.Parameters[1].SystemType)) + return new SqlFunction( + func.SystemType, + func.Name, + func.Precedence, + func.Parameters[0], + new SqlFunction(func.SystemType, "Floor", func.Parameters[1])); + + break; + } + } + + break; + } + } + + return expr; + } + + protected override void BuildDeleteClause(StringBuilder sb) + { + var table = SqlQuery.Delete.Table != null ? + (SqlQuery.From.FindTableSource(SqlQuery.Delete.Table) ?? SqlQuery.Delete.Table) : + SqlQuery.From.Tables[0]; + + AppendIndent(sb) + .Append("DELETE ") + .Append(Convert(GetTableAlias(table), ConvertType.NameToQueryTableAlias)) + .AppendLine(); + } + + protected override void BuildUpdateTableName(StringBuilder sb) + { + var table = SqlQuery.Update.Table != null ? + (SqlQuery.From.FindTableSource(SqlQuery.Update.Table) ?? SqlQuery.Update.Table) : + SqlQuery.From.Tables[0]; + + if (table is SqlTable) + BuildPhysicalTable(sb, table, null); + else + sb.Append(Convert(GetTableAlias(table), ConvertType.NameToQueryTableAlias)); + } + + protected override void BuildString(StringBuilder sb, string value) + { + foreach (var ch in value) + { + if (ch > 127) + { + sb.Append("N"); + break; + } + } + + base.BuildString(sb, value); + } + + protected override void BuildChar(StringBuilder sb, char value) + { + if (value > 127) + sb.Append("N"); + + base.BuildChar(sb, value); + } + + protected override void BuildColumnExpression(StringBuilder sb, ISqlExpression expr, string alias, ref bool addAlias) + { + var wrap = false; + + if (expr.SystemType == typeof(bool)) + { + if (expr is SqlQuery.SearchCondition) + wrap = true; + else + { + var ex = expr as SqlExpression; + wrap = ex != null && ex.Expr == "{0}" && ex.Parameters.Length == 1 && ex.Parameters[0] is SqlQuery.SearchCondition; + } + } + + if (wrap) sb.Append("CASE WHEN "); + base.BuildColumnExpression(sb, expr, alias, ref addAlias); + if (wrap) sb.Append(" THEN 1 ELSE 0 END"); + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter: + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return "@" + value; + + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryFieldAlias: + case ConvertType.NameToQueryTableAlias: + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '[') + return value; + } + + return "[" + value + "]"; + + case ConvertType.NameToDatabase: + case ConvertType.NameToOwner: + case ConvertType.NameToQueryTable: + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '[') + return value; + + if (name.IndexOf('.') > 0) + value = string.Join("].[", name.Split('.')); + } + + return "[" + value + "]"; + + case ConvertType.SprocParameterToName: + if (value != null) + { + var str = value.ToString(); + return str.Length > 0 && str[0] == '@'? str.Substring(1): str; + } + break; + } + + return value; + } + + protected override void BuildInsertOrUpdateQuery(StringBuilder sb) + { + BuildInsertOrUpdateQueryAsUpdateInsert(sb); + } + + protected override void BuildDateTime(StringBuilder sb, object value) + { + sb.Append(string.Format("'{0:yyyy-MM-ddTHH:mm:ss.fff}'", value)); + } + + public override void BuildValue(StringBuilder sb, object value) + { + if (value is sbyte) sb.Append((byte)(sbyte)value); + else if (value is ushort) sb.Append((short)(ushort)value); + else if (value is uint) sb.Append((int)(uint)value); + else if (value is ulong) sb.Append((long)(ulong)value); + else base.BuildValue(sb, value); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/MsSql2000SqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/MsSql2000SqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,90 @@ +using System; +using System.Data; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using Reflection; + + public class MsSql2000SqlProvider : MsSqlSqlProvider + { + protected override string FirstFormat { get { return "TOP {0}"; } } + + public override bool IsSkipSupported { get { return false; } } + public override bool IsApplyJoinSupported { get { return false; } } + public override bool TakeAcceptsParameter { get { return false; } } + public override bool IsCountSubQuerySupported { get { return false; } } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlFunction) + { + var func = (SqlFunction)expr; + + switch (Type.GetTypeCode(TypeHelper.GetUnderlyingType(func.SystemType))) + { + case TypeCode.DateTime : + + if (func.Name == "Convert") + { + var type1 = TypeHelper.GetUnderlyingType(func.Parameters[1].SystemType); + + if (IsTimeDataType(func.Parameters[0])) + { + if (type1 == typeof(DateTime) || type1 == typeof(DateTimeOffset)) + return new SqlExpression( + func.SystemType, "Cast(Convert(Char, {0}, 114) as DateTime)", Precedence.Primary, func.Parameters[1]); + + if (func.Parameters[1].SystemType == typeof(string)) + return func.Parameters[1]; + + return new SqlExpression( + func.SystemType, "Convert(Char, {0}, 114)", Precedence.Primary, func.Parameters[1]); + } + + if (type1 == typeof(DateTime) || type1 == typeof(DateTimeOffset)) + { + if (IsDateDataType(func.Parameters[0], "Datetime")) + return new SqlExpression( + func.SystemType, "Cast(Floor(Cast({0} as Float)) as DateTime)", Precedence.Primary, func.Parameters[1]); + } + + if (func.Parameters.Length == 2 && func.Parameters[0] is SqlDataType && func.Parameters[0] == SqlDataType.DateTime) + return new SqlFunction(func.SystemType, func.Name, func.Precedence, func.Parameters[0], func.Parameters[1], new SqlValue(120)); + } + + break; + } + } + + return expr; + } + + protected override void BuildFunction(StringBuilder sb, SqlFunction func) + { + func = ConvertFunctionParameters(func); + base.BuildFunction(sb, func); + } + + protected override ISqlProvider CreateSqlProvider() + { + return new MsSql2000SqlProvider(); + } + + protected override void BuildDataType(System.Text.StringBuilder sb, SqlDataType type) + { + switch (type.SqlDbType) + { +#if !MONO + case SqlDbType.DateTimeOffset : + case SqlDbType.DateTime2 : +#endif + case SqlDbType.Time : + case SqlDbType.Date : sb.Append("DateTime"); break; + default : base.BuildDataType(sb, type); break; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/MsSql2005SqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/MsSql2005SqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,83 @@ +using System; +using System.Data; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using Reflection; + + public class MsSql2005SqlProvider : MsSqlSqlProvider + { + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlFunction) + { + var func = (SqlFunction)expr; + + switch (Type.GetTypeCode(TypeHelper.GetUnderlyingType(func.SystemType))) + { + case TypeCode.DateTime : + + if (func.Name == "Convert") + { + var type1 = TypeHelper.GetUnderlyingType(func.Parameters[1].SystemType); + + if (IsTimeDataType(func.Parameters[0])) + { + if (type1 == typeof(DateTime) || type1 == typeof(DateTimeOffset)) + return new SqlExpression( + func.SystemType, "Cast(Convert(Char, {0}, 114) as DateTime)", Precedence.Primary, func.Parameters[1]); + + if (func.Parameters[1].SystemType == typeof(string)) + return func.Parameters[1]; + + return new SqlExpression( + func.SystemType, "Convert(Char, {0}, 114)", Precedence.Primary, func.Parameters[1]); + } + + if (type1 == typeof(DateTime) || type1 == typeof(DateTimeOffset)) + { + if (IsDateDataType(func.Parameters[0], "Datetime")) + return new SqlExpression( + func.SystemType, "Cast(Floor(Cast({0} as Float)) as DateTime)", Precedence.Primary, func.Parameters[1]); + } + + if (func.Parameters.Length == 2 && func.Parameters[0] is SqlDataType && func.Parameters[0] == SqlDataType.DateTime) + return new SqlFunction(func.SystemType, func.Name, func.Precedence, func.Parameters[0], func.Parameters[1], new SqlValue(120)); + } + + break; + } + } + + return expr; + } + + protected override void BuildFunction(StringBuilder sb, SqlFunction func) + { + func = ConvertFunctionParameters(func); + base.BuildFunction(sb, func); + } + + protected override ISqlProvider CreateSqlProvider() + { + return new MsSql2005SqlProvider(); + } + + protected override void BuildDataType(System.Text.StringBuilder sb, SqlDataType type) + { + switch (type.SqlDbType) + { +#if !MONO + case SqlDbType.DateTimeOffset : + case SqlDbType.DateTime2 : +#endif + case SqlDbType.Time : + case SqlDbType.Date : sb.Append("DateTime"); break; + default : base.BuildDataType(sb, type); break; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/MsSql2008SqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/MsSql2008SqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +using System; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + public class MsSql2008SqlProvider : MsSqlSqlProvider + { + protected override ISqlProvider CreateSqlProvider() + { + return new MsSql2008SqlProvider(); + } + + protected override void BuildFunction(StringBuilder sb, SqlFunction func) + { + func = ConvertFunctionParameters(func); + base.BuildFunction(sb, func); + } + + protected override void BuildInsertOrUpdateQuery(StringBuilder sb) + { + BuildInsertOrUpdateQueryAsMerge(sb, null); + sb.AppendLine(";"); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/MsSql2012SqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/MsSql2012SqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,89 @@ +using System; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + public class MsSql2012SqlProvider : MsSqlSqlProvider + { + protected override string LimitFormat { get { return SqlQuery.Select.SkipValue != null ? "FETCH NEXT {0} ROWS ONLY" : null; } } + protected override string OffsetFormat { get { return "OFFSET {0} ROWS"; } } + protected override bool OffsetFirst { get { return true; } } + protected override bool BuildAlternativeSql { get { return false; } } + + protected override ISqlProvider CreateSqlProvider() + { + return new MsSql2012SqlProvider(); + } + + protected override void BuildInsertOrUpdateQuery(StringBuilder sb) + { + BuildInsertOrUpdateQueryAsMerge(sb, null); + sb.AppendLine(";"); + } + + protected override void BuildSql(StringBuilder sb) + { + if (NeedSkip && SqlQuery.OrderBy.IsEmpty) + { + for (var i = 0; i < SqlQuery.Select.Columns.Count; i++) + SqlQuery.OrderBy.ExprAsc(new SqlValue(i + 1)); + } + + base.BuildSql(sb); + } + + protected override void BuildFunction(StringBuilder sb, SqlFunction func) + { + func = ConvertFunctionParameters(func); + + switch (func.Name) + { + case "CASE" : func = ConvertCase(func.SystemType, func.Parameters, 0); break; + case "Coalesce" : + + if (func.Parameters.Length > 2) + { + var parms = new ISqlExpression[func.Parameters.Length - 1]; + + Array.Copy(func.Parameters, 1, parms, 0, parms.Length); + BuildFunction(sb, new SqlFunction(func.SystemType, func.Name, func.Parameters[0], + new SqlFunction(func.SystemType, func.Name, parms))); + return; + } + + var sc = new SqlQuery.SearchCondition(); + + sc.Conditions.Add(new SqlQuery.Condition(false, new SqlQuery.Predicate.IsNull(func.Parameters[0], false))); + + func = new SqlFunction(func.SystemType, "IIF", sc, func.Parameters[1], func.Parameters[0]); + + break; + } + + base.BuildFunction(sb, func); + } + + static SqlFunction ConvertCase(Type systemType, ISqlExpression[] parameters, int start) + { + var len = parameters.Length - start; + var name = start == 0 ? "IIF" : "CASE"; + var cond = parameters[start]; + + if (start == 0 && SqlExpression.NeedsEqual(cond)) + { + cond = new SqlQuery.SearchCondition( + new SqlQuery.Condition( + false, + new SqlQuery.Predicate.ExprExpr(cond, SqlQuery.Predicate.Operator.Equal, new SqlValue(1)))); + } + + if (len == 3) + return new SqlFunction(systemType, name, cond, parameters[start + 1], parameters[start + 2]); + + return new SqlFunction(systemType, name, + cond, + parameters[start + 1], + ConvertCase(systemType, parameters, start + 2)); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/MySqlSqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/MySqlSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + using Reflection; + + public class MySqlSqlProvider : BasicSqlProvider + { + public override int CommandCount(SqlQuery sqlQuery) + { + return sqlQuery.IsInsert && sqlQuery.Insert.WithIdentity ? 2 : 1; + } + + protected override void BuildCommand(int commandNumber, StringBuilder sb) + { + sb.AppendLine("SELECT LAST_INSERT_ID()"); + } + + protected override ISqlProvider CreateSqlProvider() + { + return new MySqlSqlProvider(); + } + + protected override string LimitFormat { get { return "LIMIT {0}"; } } + + public override bool IsNestedJoinParenthesisRequired { get { return true; } } + + protected override void BuildOffsetLimit(StringBuilder sb) + { + if (SqlQuery.Select.SkipValue == null) + base.BuildOffsetLimit(sb); + else + { + AppendIndent(sb) + .AppendFormat( + "LIMIT {0},{1}", + BuildExpression(new StringBuilder(), SqlQuery.Select.SkipValue), + SqlQuery.Select.TakeValue == null ? + long.MaxValue.ToString() : + BuildExpression(new StringBuilder(), SqlQuery.Select.TakeValue).ToString()) + .AppendLine(); + } + } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlBinaryExpression) + { + var be = (SqlBinaryExpression)expr; + + switch (be.Operation) + { + case "+": + if (be.SystemType == typeof(string)) + { + if (be.Expr1 is SqlFunction) + { + var func = (SqlFunction)be.Expr1; + + if (func.Name == "Concat") + { + var list = new List(func.Parameters) { be.Expr2 }; + return new SqlFunction(be.SystemType, "Concat", list.ToArray()); + } + } + + return new SqlFunction(be.SystemType, "Concat", be.Expr1, be.Expr2); + } + + break; + } + } + else if (expr is SqlFunction) + { + var func = (SqlFunction) expr; + + switch (func.Name) + { + case "Convert" : + var ftype = TypeHelper.GetUnderlyingType(func.SystemType); + + if (ftype == typeof(bool)) + { + var ex = AlternativeConvertToBoolean(func, 1); + if (ex != null) + return ex; + } + + if ((ftype == typeof(double) || ftype == typeof(float)) && TypeHelper.GetUnderlyingType(func.Parameters[1].SystemType) == typeof(decimal)) + return func.Parameters[1]; + + return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, FloorBeforeConvert(func), func.Parameters[0]); + } + } + else if (expr is SqlExpression) + { + var e = (SqlExpression)expr; + + if (e.Expr.StartsWith("Extract(DayOfYear")) + return new SqlFunction(e.SystemType, "DayOfYear", e.Parameters); + + if (e.Expr.StartsWith("Extract(WeekDay")) + return Inc( + new SqlFunction(e.SystemType, + "WeekDay", + new SqlFunction( + null, + "Date_Add", + e.Parameters[0], + new SqlExpression(null, "interval 1 day")))); + } + + return expr; + } + + protected override void BuildDataType(StringBuilder sb, SqlDataType type) + { + switch (type.SqlDbType) + { + case SqlDbType.Int : + case SqlDbType.SmallInt : sb.Append("Signed"); break; + case SqlDbType.TinyInt : sb.Append("Unsigned"); break; + case SqlDbType.Money : sb.Append("Decimal(19,4)"); break; + case SqlDbType.SmallMoney : sb.Append("Decimal(10,4)"); break; +#if !MONO + case SqlDbType.DateTime2 : +#endif + case SqlDbType.SmallDateTime : sb.Append("DateTime"); break; + case SqlDbType.Bit : sb.Append("Boolean"); break; + case SqlDbType.Float : + case SqlDbType.Real : base.BuildDataType(sb, SqlDataType.Decimal); break; + case SqlDbType.VarChar : + case SqlDbType.NVarChar : + sb.Append("Char"); + if (type.Length > 0) + sb.Append('(').Append(type.Length).Append(')'); + break; + default: base.BuildDataType(sb, type); break; + } + } + + protected override void BuildDeleteClause(StringBuilder sb) + { + var table = SqlQuery.Delete.Table != null ? + (SqlQuery.From.FindTableSource(SqlQuery.Delete.Table) ?? SqlQuery.Delete.Table) : + SqlQuery.From.Tables[0]; + + AppendIndent(sb) + .Append("DELETE ") + .Append(Convert(GetTableAlias(table), ConvertType.NameToQueryTableAlias)) + .AppendLine(); + } + + protected override void BuildUpdateClause(StringBuilder sb) + { + base.BuildFromClause(sb); + sb.Remove(0, 4).Insert(0, "UPDATE"); + base.BuildUpdateSet(sb); + } + + protected override void BuildFromClause(StringBuilder sb) + { + if (!SqlQuery.IsUpdate) + base.BuildFromClause(sb); + } + + public static char ParameterSymbol { get; set; } + public static bool TryConvertParameterSymbol { get; set; } + + private static string _commandParameterPrefix = ""; + public static string CommandParameterPrefix + { + get { return _commandParameterPrefix; } + set { _commandParameterPrefix = string.IsNullOrEmpty(value) ? string.Empty : value; } + } + + private static string _sprocParameterPrefix = ""; + public static string SprocParameterPrefix + { + get { return _sprocParameterPrefix; } + set { _sprocParameterPrefix = string.IsNullOrEmpty(value) ? string.Empty : value; } + } + + private static List _convertParameterSymbols; + public static List ConvertParameterSymbols + { + get { return _convertParameterSymbols; } + set { _convertParameterSymbols = value ?? new List(); } + } + + public override object Convert(object value, ConvertType convertType) + { + if (value == null) + throw new ArgumentNullException("value"); + + switch (convertType) + { + case ConvertType.NameToQueryParameter: + return ParameterSymbol + value.ToString(); + + case ConvertType.NameToCommandParameter: + return ParameterSymbol + CommandParameterPrefix + value; + + case ConvertType.NameToSprocParameter: + { + var valueStr = value.ToString(); + + if(string.IsNullOrEmpty(valueStr)) + throw new ArgumentException("Argument 'value' must represent parameter name."); + + if (valueStr[0] == ParameterSymbol) + valueStr = valueStr.Substring(1); + + if (valueStr.StartsWith(SprocParameterPrefix, StringComparison.Ordinal)) + valueStr = valueStr.Substring(SprocParameterPrefix.Length); + + return ParameterSymbol + SprocParameterPrefix + valueStr; + } + + case ConvertType.SprocParameterToName: + { + var str = value.ToString(); + str = (str.Length > 0 && (str[0] == ParameterSymbol || (TryConvertParameterSymbol && ConvertParameterSymbols.Contains(str[0])))) ? str.Substring(1) : str; + + if (!string.IsNullOrEmpty(SprocParameterPrefix) && str.StartsWith(SprocParameterPrefix)) + str = str.Substring(SprocParameterPrefix.Length); + + return str; + } + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryFieldAlias: + case ConvertType.NameToQueryTableAlias: + { + var name = value.ToString(); + if (name.Length > 0 && name[0] == '`') + return value; + } + return "`" + value + "`"; + case ConvertType.NameToDatabase: + case ConvertType.NameToOwner: + case ConvertType.NameToQueryTable: + { + var name = value.ToString(); + if (name.Length > 0 && name[0] == '`') + return value; + + if (name.IndexOf('.') > 0) + value = string.Join("`.`", name.Split('.')); + } + return "`" + value + "`"; + + } + + return value; + } + + protected override StringBuilder BuildExpression(StringBuilder sb, ISqlExpression expr, bool buildTableName, bool checkParentheses, string alias, ref bool addAlias) + { + return base.BuildExpression( + sb, + expr, + buildTableName && SqlQuery.QueryType != QueryType.InsertOrUpdate, + checkParentheses, + alias, + ref addAlias); + } + + protected override void BuildInsertOrUpdateQuery(StringBuilder sb) + { + BuildInsertQuery(sb); + AppendIndent(sb).AppendLine("ON DUPLICATE KEY UPDATE"); + + Indent++; + + var first = true; + + foreach (var expr in SqlQuery.Update.Items) + { + if (!first) + sb.Append(',').AppendLine(); + first = false; + + AppendIndent(sb); + BuildExpression(sb, expr.Column, false, true); + sb.Append(" = "); + BuildExpression(sb, expr.Expression, false, true); + } + + Indent--; + + sb.AppendLine(); + } + + protected override void BuildEmptyInsert(StringBuilder sb) + { + sb.AppendLine("() VALUES ()"); + } + + public static bool GenerateOldGuid = false; + + public override void BuildValue(StringBuilder sb, object value) + { + if (GenerateOldGuid && value is Guid) + { + var bytes = ((Guid)value).ToByteArray(); + + sb.Append("X'").Append(ByteArrayToHex(bytes)).Append('\''); + } + else + base.BuildValue(sb, value); + } + + static string ByteArrayToHex(byte[] barray) + { + var c = new char[barray.Length * 2]; + + for (var i = 0; i < barray.Length; ++i) + { + var b = ((byte)(barray[i] >> 4)); + + c[i * 2] = (char)(b > 9 ? b + 0x37 : b + 0x30); + b = ((byte)(barray[i] & 0xF)); + c[i * 2 + 1] = (char)(b > 9 ? b + 0x37 : b + 0x30); + } + + return new string(c); + } + + protected override void BuildString(StringBuilder sb, string value) + { + base.BuildString(sb, value.Replace("\\", "\\\\")); + } + + protected override void BuildChar(StringBuilder sb, char value) + { + if (value == '\\') + sb.Append("\\\\"); + else + base.BuildChar(sb, value); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/OracleSqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/OracleSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,378 @@ +using System; +using System.Data; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + using Reflection; + + public class OracleSqlProvider : BasicSqlProvider + { + public override bool IsCountSubQuerySupported { get { return false; } } + public override bool IsIdentityParameterRequired { get { return true; } } + public override int MaxInListValuesCount { get { return 1000; } } + + protected override void BuildSelectClause(StringBuilder sb) + { + if (SqlQuery.From.Tables.Count == 0) + { + AppendIndent(sb).Append("SELECT").AppendLine(); + BuildColumns(sb); + AppendIndent(sb).Append("FROM SYS.DUAL").AppendLine(); + } + else + base.BuildSelectClause(sb); + } + + protected override void BuildGetIdentity(StringBuilder sb) + { + var identityField = SqlQuery.Insert.Into.GetIdentityField(); + + if (identityField == null) + throw new SqlException("Identity field must be defined for '{0}'.", SqlQuery.Insert.Into.Name); + + AppendIndent(sb).AppendLine("RETURNING"); + AppendIndent(sb).Append("\t"); + BuildExpression(sb, identityField, false, true); + sb.AppendLine(" INTO :IDENTITY_PARAMETER"); + } + + public override ISqlExpression GetIdentityExpression(SqlTable table, SqlField identityField, bool forReturning) + { + if (table.SequenceAttributes != null) + { + var attr = GetSequenceNameAttribute(table, false); + + if (attr != null) + return new SqlExpression(attr.SequenceName + ".nextval", Precedence.Primary); + } + + return base.GetIdentityExpression(table, identityField, forReturning); + } + + protected override bool BuildWhere() + { + return base.BuildWhere() || !NeedSkip && NeedTake && SqlQuery.OrderBy.IsEmpty && SqlQuery.Having.IsEmpty; + } + + string _rowNumberAlias; + + protected override ISqlProvider CreateSqlProvider() + { + return new OracleSqlProvider(); + } + + protected override void BuildSql(StringBuilder sb) + { + var buildRowNum = NeedSkip || NeedTake && (!SqlQuery.OrderBy.IsEmpty || !SqlQuery.Having.IsEmpty); + var aliases = null as string[]; + + if (buildRowNum) + { + aliases = GetTempAliases(2, "t"); + + if (_rowNumberAlias == null) + _rowNumberAlias = GetTempAliases(1, "rn")[0]; + + AppendIndent(sb).AppendFormat("SELECT {0}.*", aliases[1]).AppendLine(); + AppendIndent(sb).Append("FROM"). AppendLine(); + AppendIndent(sb).Append("("). AppendLine(); + Indent++; + + AppendIndent(sb).AppendFormat("SELECT {0}.*, ROWNUM as {1}", aliases[0], _rowNumberAlias).AppendLine(); + AppendIndent(sb).Append("FROM"). AppendLine(); + AppendIndent(sb).Append("("). AppendLine(); + Indent++; + } + + base.BuildSql(sb); + + if (buildRowNum) + { + Indent--; + AppendIndent(sb).Append(") ").Append(aliases[0]).AppendLine(); + + if (NeedTake && NeedSkip) + { + AppendIndent(sb).AppendLine("WHERE"); + AppendIndent(sb).Append("\tROWNUM <= "); + BuildExpression(sb, Add(SqlQuery.Select.SkipValue, SqlQuery.Select.TakeValue)); + sb.AppendLine(); + } + + Indent--; + AppendIndent(sb).Append(") ").Append(aliases[1]).AppendLine(); + AppendIndent(sb).Append("WHERE").AppendLine(); + + Indent++; + + if (NeedTake && NeedSkip) + { + AppendIndent(sb).AppendFormat("{0}.{1} > ", aliases[1], _rowNumberAlias); + BuildExpression(sb, SqlQuery.Select.SkipValue); + } + else if (NeedTake) + { + AppendIndent(sb).AppendFormat("{0}.{1} <= ", aliases[1], _rowNumberAlias); + BuildExpression(sb, Precedence.Comparison, SqlQuery.Select.TakeValue); + } + else + { + AppendIndent(sb).AppendFormat("{0}.{1} > ", aliases[1], _rowNumberAlias); + BuildExpression(sb, Precedence.Comparison, SqlQuery.Select.SkipValue); + } + + sb.AppendLine(); + Indent--; + } + } + + protected override void BuildWhereSearchCondition(StringBuilder sb, SqlQuery.SearchCondition condition) + { + if (NeedTake && !NeedSkip && SqlQuery.OrderBy.IsEmpty && SqlQuery.Having.IsEmpty) + { + BuildPredicate( + sb, + Precedence.LogicalConjunction, + new SqlQuery.Predicate.ExprExpr( + new SqlExpression(null, "ROWNUM", Precedence.Primary), + SqlQuery.Predicate.Operator.LessOrEqual, + SqlQuery.Select.TakeValue)); + + if (base.BuildWhere()) + { + sb.Append(" AND "); + BuildSearchCondition(sb, Precedence.LogicalConjunction, condition); + } + } + else + BuildSearchCondition(sb, Precedence.Unknown, condition); + } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlBinaryExpression) + { + var be = (SqlBinaryExpression)expr; + + switch (be.Operation) + { + case "%": return new SqlFunction(be.SystemType, "MOD", be.Expr1, be.Expr2); + case "&": return new SqlFunction(be.SystemType, "BITAND", be.Expr1, be.Expr2); + case "|": // (a + b) - BITAND(a, b) + return Sub( + Add(be.Expr1, be.Expr2, be.SystemType), + new SqlFunction(be.SystemType, "BITAND", be.Expr1, be.Expr2), + be.SystemType); + + case "^": // (a + b) - BITAND(a, b) * 2 + return Sub( + Add(be.Expr1, be.Expr2, be.SystemType), + Mul(new SqlFunction(be.SystemType, "BITAND", be.Expr1, be.Expr2), 2), + be.SystemType); + case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; + } + } + else if (expr is SqlFunction) + { + var func = (SqlFunction) expr; + + switch (func.Name) + { + case "Coalesce" : return new SqlFunction(func.SystemType, "Nvl", func.Parameters); + case "Convert" : + { + var ftype = TypeHelper.GetUnderlyingType(func.SystemType); + + if (ftype == typeof(bool)) + { + var ex = AlternativeConvertToBoolean(func, 1); + if (ex != null) + return ex; + } + + if (ftype == typeof(DateTime) || ftype == typeof(DateTimeOffset)) + { + if (IsTimeDataType(func.Parameters[0])) + { + if (func.Parameters[1].SystemType == typeof(string)) + return func.Parameters[1]; + + return new SqlFunction(func.SystemType, "To_Char", func.Parameters[1], new SqlValue("HH24:MI:SS")); + } + + if (TypeHelper.GetUnderlyingType(func.Parameters[1].SystemType) == typeof(DateTime) && + IsDateDataType(func.Parameters[0], "Date")) + { + return new SqlFunction(func.SystemType, "Trunc", func.Parameters[1], new SqlValue("DD")); + } + + return new SqlFunction(func.SystemType, "To_Timestamp", func.Parameters[1], new SqlValue("YYYY-MM-DD HH24:MI:SS")); + } + + return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, FloorBeforeConvert(func), func.Parameters[0]); + } + case "ContainsExactly": + return func.Parameters.Length == 2 ? + new SqlFunction(func.SystemType, "Contains", func.Parameters[1], func.Parameters[0]) : + new SqlFunction(func.SystemType, "Contains", func.Parameters[1], func.Parameters[0], func.Parameters[2]); + case "CharIndex" : + return func.Parameters.Length == 2? + new SqlFunction(func.SystemType, "InStr", func.Parameters[1], func.Parameters[0]): + new SqlFunction(func.SystemType, "InStr", func.Parameters[1], func.Parameters[0], func.Parameters[2]); + case "AddYear" : return new SqlFunction(func.SystemType, "Add_Months", func.Parameters[0], Mul(func.Parameters[1], 12)); + case "AddQuarter" : return new SqlFunction(func.SystemType, "Add_Months", func.Parameters[0], Mul(func.Parameters[1], 3)); + case "AddMonth" : return new SqlFunction(func.SystemType, "Add_Months", func.Parameters[0], func.Parameters[1]); + case "AddDayOfYear" : + case "AddWeekDay" : + case "AddDay" : return Add(func.Parameters[0], func.Parameters[1]); + case "AddWeek" : return Add(func.Parameters[0], Mul(func.Parameters[1], 7)); + case "AddHour" : return Add(func.Parameters[0], Div(func.Parameters[1], 24)); + case "AddMinute" : return Add(func.Parameters[0], Div(func.Parameters[1], 60 * 24)); + case "AddSecond" : return Add(func.Parameters[0], Div(func.Parameters[1], 60 * 60 * 24)); + case "AddMillisecond" : return Add(func.Parameters[0], Div(func.Parameters[1], 1000 * 60 * 60 * 24)); + case "Avg" : + return new SqlFunction( + func.SystemType, + "Round", + new SqlFunction(func.SystemType, "AVG", func.Parameters[0]), + new SqlValue(27)); + } + } + else if (expr is SqlExpression) + { + var e = (SqlExpression)expr; + + if (e.Expr.StartsWith("To_Number(To_Char(") && e.Expr.EndsWith(", 'FF'))")) + return Div(new SqlExpression(e.SystemType, e.Expr.Replace("To_Number(To_Char(", "to_Number(To_Char("), e.Parameters), 1000); + } + + return expr; + } + + protected override void BuildFunction(StringBuilder sb, SqlFunction func) + { + func = ConvertFunctionParameters(func); + base.BuildFunction(sb, func); + } + + protected override void BuildDataType(StringBuilder sb, SqlDataType type) + { + switch (type.SqlDbType) + { + case SqlDbType.BigInt : sb.Append("Number(19)"); break; + case SqlDbType.TinyInt : sb.Append("Number(3)"); break; + case SqlDbType.Money : sb.Append("Number(19,4)"); break; + case SqlDbType.SmallMoney : sb.Append("Number(10,4)"); break; + case SqlDbType.NVarChar : + sb.Append("VarChar2"); + if (type.Length > 0) + sb.Append('(').Append(type.Length).Append(')'); + break; + default : base.BuildDataType(sb, type); break; + } + } + + public override SqlQuery Finalize(SqlQuery sqlQuery) + { + CheckAliases(sqlQuery, 30); + + new QueryVisitor().Visit(sqlQuery.Select, element => + { + if (element.ElementType == QueryElementType.SqlParameter) + ((SqlParameter)element).IsQueryParameter = false; + }); + + sqlQuery = base.Finalize(sqlQuery); + + switch (sqlQuery.QueryType) + { + case QueryType.Delete : return GetAlternativeDelete(sqlQuery); + case QueryType.Update : return GetAlternativeUpdate(sqlQuery); + default : return sqlQuery; + } + } + + protected override void BuildFromClause(StringBuilder sb) + { + if (!SqlQuery.IsUpdate) + base.BuildFromClause(sb); + } + + public override void BuildValue(StringBuilder sb, object value) + { + if (value is Guid) + { + var s = ((Guid)value).ToString("N"); + + sb + .Append("Cast('") + .Append(s.Substring( 6, 2)) + .Append(s.Substring( 4, 2)) + .Append(s.Substring( 2, 2)) + .Append(s.Substring( 0, 2)) + .Append(s.Substring(10, 2)) + .Append(s.Substring( 8, 2)) + .Append(s.Substring(14, 2)) + .Append(s.Substring(12, 2)) + .Append(s.Substring(16, 16)) + .Append("' as raw(16))"); + } + else if (value is DateTime) + { + sb.AppendFormat("TO_TIMESTAMP('{0:yyyy-MM-dd HH:mm:ss.fffffff}', 'YYYY-MM-DD HH24:MI:SS.FF7')", value); + } + else + base.BuildValue(sb, value); + } + + protected override void BuildColumnExpression(StringBuilder sb, ISqlExpression expr, string alias, ref bool addAlias) + { + var wrap = false; + + if (expr.SystemType == typeof(bool)) + { + if (expr is SqlQuery.SearchCondition) + wrap = true; + else + { + var ex = expr as SqlExpression; + wrap = ex != null && ex.Expr == "{0}" && ex.Parameters.Length == 1 && ex.Parameters[0] is SqlQuery.SearchCondition; + } + } + + if (wrap) sb.Append("CASE WHEN "); + base.BuildColumnExpression(sb, expr, alias, ref addAlias); + if (wrap) sb.Append(" THEN 1 ELSE 0 END"); + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter: + return ":" + value; + } + + return value; + } + + protected override void BuildInsertOrUpdateQuery(StringBuilder sb) + { + BuildInsertOrUpdateQueryAsMerge(sb, "FROM SYS.DUAL"); + } + + protected override void BuildEmptyInsert(StringBuilder sb) + { + sb.Append("VALUES "); + + foreach (var col in SqlQuery.Insert.Into.Fields) + sb.Append("(DEFAULT)"); + + sb.AppendLine(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/PostgreSQLSqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/PostgreSQLSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,208 @@ +using System; +using System.Data; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + using Reflection; + + public class PostgreSQLSqlProvider : BasicSqlProvider + { + public override bool IsInsertOrUpdateSupported { get { return false; } } + + public override int CommandCount(SqlQuery sqlQuery) + { + return sqlQuery.IsInsert && sqlQuery.Insert.WithIdentity ? 2 : 1; + } + + protected override void BuildCommand(int commandNumber, StringBuilder sb) + { + var into = SqlQuery.Insert.Into; + var attr = GetSequenceNameAttribute(into, false); + var name = + attr != null ? + attr.SequenceName : + Convert( + string.Format("{0}_{1}_seq", into.PhysicalName, into.GetIdentityField().PhysicalName), + ConvertType.NameToQueryField); + + AppendIndent(sb) + .Append("SELECT currval('") + .Append(name) + .AppendLine("')"); + } + + protected override ISqlProvider CreateSqlProvider() + { + return new PostgreSQLSqlProvider(); + } + + protected override string LimitFormat { get { return "LIMIT {0}"; } } + protected override string OffsetFormat { get { return "OFFSET {0} "; } } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlBinaryExpression) + { + var be = (SqlBinaryExpression)expr; + + switch (be.Operation) + { + case "^": return new SqlBinaryExpression(be.SystemType, be.Expr1, "#", be.Expr2); + case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; + } + } + else if (expr is SqlFunction) + { + var func = (SqlFunction) expr; + + switch (func.Name) + { + case "Convert" : + if (TypeHelper.GetUnderlyingType(func.SystemType) == typeof(bool)) + { + var ex = AlternativeConvertToBoolean(func, 1); + if (ex != null) + return ex; + } + + return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, FloorBeforeConvert(func), func.Parameters[0]); + + case "CharIndex" : + return func.Parameters.Length == 2? + new SqlExpression(func.SystemType, "Position({0} in {1})", Precedence.Primary, func.Parameters[0], func.Parameters[1]): + Add( + new SqlExpression(func.SystemType, "Position({0} in {1})", Precedence.Primary, func.Parameters[0], + ConvertExpression(new SqlFunction(typeof(string), "Substring", + func.Parameters[1], + func.Parameters[2], + Sub(ConvertExpression(new SqlFunction(typeof(int), "Length", func.Parameters[1])), func.Parameters[2])))), + Sub(func.Parameters[2], 1)); + } + } + else if (expr is SqlExpression) + { + var e = (SqlExpression)expr; + + if (e.Expr.StartsWith("Extract(DOW")) + return Inc(new SqlExpression(expr.SystemType, e.Expr.Replace("Extract(DOW", "Extract(Dow"), e.Parameters)); + + if (e.Expr.StartsWith("Extract(Millisecond")) + return new SqlExpression(expr.SystemType, "Cast(To_Char({0}, 'MS') as int)", e.Parameters); + } + + return expr; + } + + public override void BuildValue(StringBuilder sb, object value) + { + if (value is bool) + sb.Append(value); + else + base.BuildValue(sb, value); + } + + protected override void BuildDataType(StringBuilder sb, SqlDataType type) + { + switch (type.SqlDbType) + { + case SqlDbType.TinyInt : sb.Append("SmallInt"); break; + case SqlDbType.Money : sb.Append("Decimal(19,4)"); break; + case SqlDbType.SmallMoney : sb.Append("Decimal(10,4)"); break; +#if !MONO + case SqlDbType.DateTime2 : +#endif + case SqlDbType.SmallDateTime : + case SqlDbType.DateTime : sb.Append("TimeStamp"); break; + case SqlDbType.Bit : sb.Append("Boolean"); break; + case SqlDbType.NVarChar : + sb.Append("VarChar"); + if (type.Length > 0) + sb.Append('(').Append(type.Length).Append(')'); + break; + default : base.BuildDataType(sb, type); break; + } + } + + public override SqlQuery Finalize(SqlQuery sqlQuery) + { + CheckAliases(sqlQuery, int.MaxValue); + + sqlQuery = base.Finalize(sqlQuery); + + switch (sqlQuery.QueryType) + { + case QueryType.Delete : return GetAlternativeDelete(sqlQuery); + case QueryType.Update : return GetAlternativeUpdate(sqlQuery); + default : return sqlQuery; + } + } + + protected override void BuildFromClause(StringBuilder sb) + { + if (!SqlQuery.IsUpdate) + base.BuildFromClause(sb); + } + + public static bool QuoteIdentifiers; + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryFieldAlias: + case ConvertType.NameToQueryTable: + case ConvertType.NameToQueryTableAlias: + if (QuoteIdentifiers) + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '"') + return value; + + return '"' + name + '"'; + } + + break; + + case ConvertType.NameToQueryParameter: + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return ":" + value; + + case ConvertType.SprocParameterToName: + if (value != null) + { + var str = value.ToString(); + return (str.Length > 0 && str[0] == ':')? str.Substring(1): str; + } + + break; + } + + return value; + } + + public override ISqlExpression GetIdentityExpression(SqlTable table, SqlField identityField, bool forReturning) + { + if (table.SequenceAttributes != null) + { + var attr = GetSequenceNameAttribute(table, false); + + if (attr != null) + return new SqlExpression("nextval('" + attr.SequenceName+"')", Precedence.Primary); + } + + return base.GetIdentityExpression(table, identityField, forReturning); + } + + //protected override void BuildInsertOrUpdateQuery(StringBuilder sb) + //{ + // BuildInsertOrUpdateQueryAsMerge(sb, null); + //} + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/SQLiteSqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/SQLiteSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,206 @@ +using System; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + using Reflection; + + public class SQLiteSqlProvider : BasicSqlProvider + { + public override int CommandCount(SqlQuery sqlQuery) + { + return sqlQuery.IsInsert && sqlQuery.Insert.WithIdentity ? 2 : 1; + } + + protected override void BuildCommand(int commandNumber, StringBuilder sb) + { + sb.AppendLine("SELECT last_insert_rowid()"); + } + + protected override ISqlProvider CreateSqlProvider() + { + return new SQLiteSqlProvider(); + } + + protected override string LimitFormat { get { return "LIMIT {0}"; } } + protected override string OffsetFormat { get { return "OFFSET {0}"; } } + + public override bool IsSkipSupported { get { return SqlQuery.Select.TakeValue != null; } } + public override bool IsNestedJoinSupported { get { return false; } } + public override bool IsInsertOrUpdateSupported { get { return false; } } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlBinaryExpression) + { + var be = (SqlBinaryExpression)expr; + + switch (be.Operation) + { + case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; + case "^": // (a + b) - (a & b) * 2 + return Sub( + Add(be.Expr1, be.Expr2, be.SystemType), + Mul(new SqlBinaryExpression(be.SystemType, be.Expr1, "&", be.Expr2), 2), be.SystemType); + } + } + else if (expr is SqlFunction) + { + var func = (SqlFunction) expr; + + switch (func.Name) + { + case "Space" : return new SqlFunction(func.SystemType, "PadR", new SqlValue(" "), func.Parameters[0]); + case "Convert" : + { + var ftype = TypeHelper.GetUnderlyingType(func.SystemType); + + if (ftype == typeof(bool)) + { + var ex = AlternativeConvertToBoolean(func, 1); + if (ex != null) + return ex; + } + + if (ftype == typeof(DateTime) || ftype == typeof(DateTimeOffset)) + { + if (IsDateDataType(func.Parameters[0], "Date")) + return new SqlFunction(func.SystemType, "Date", func.Parameters[1]); + return new SqlFunction(func.SystemType, "DateTime", func.Parameters[1]); + } + + return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, func.Parameters[1], func.Parameters[0]); + } + } + } + else if (expr is SqlExpression) + { + var e = (SqlExpression)expr; + + if (e.Expr.StartsWith("Cast(StrFTime(Quarter")) + return Inc(Div(Dec(new SqlExpression(e.SystemType, e.Expr.Replace("Cast(StrFTime(Quarter", "Cast(StrFTime('%m'"), e.Parameters)), 3)); + + if (e.Expr.StartsWith("Cast(StrFTime('%w'")) + return Inc(new SqlExpression(e.SystemType, e.Expr.Replace("Cast(StrFTime('%w'", "Cast(strFTime('%w'"), e.Parameters)); + + if (e.Expr.StartsWith("Cast(StrFTime('%f'")) + return new SqlExpression(e.SystemType, "Cast(strFTime('%f', {0}) * 1000 as int) % 1000", Precedence.Multiplicative, e.Parameters); + + if (e.Expr.StartsWith("DateTime")) + { + if (e.Expr.EndsWith("Quarter')")) + return new SqlExpression(e.SystemType, "DateTime({1}, '{0} Month')", Precedence.Primary, Mul(e.Parameters[0], 3), e.Parameters[1]); + + if (e.Expr.EndsWith("Week')")) + return new SqlExpression(e.SystemType, "DateTime({1}, '{0} Day')", Precedence.Primary, Mul(e.Parameters[0], 7), e.Parameters[1]); + } + } + + return expr; + } + + public override SqlQuery Finalize(SqlQuery sqlQuery) + { + sqlQuery = base.Finalize(sqlQuery); + + switch (sqlQuery.QueryType) + { + case QueryType.Delete : + sqlQuery = GetAlternativeDelete(base.Finalize(sqlQuery)); + sqlQuery.From.Tables[0].Alias = "$"; + break; + + case QueryType.Update : + sqlQuery = GetAlternativeUpdate(sqlQuery); + break; + } + + return sqlQuery; + } + + protected override void BuildFromClause(StringBuilder sb) + { + if (!SqlQuery.IsUpdate) + base.BuildFromClause(sb); + } + + public override void BuildValue(StringBuilder sb, object value) + { + if (value is Guid) + { + var s = ((Guid)value).ToString("N"); + + sb + .Append("Cast(x'") + .Append(s.Substring( 6, 2)) + .Append(s.Substring( 4, 2)) + .Append(s.Substring( 2, 2)) + .Append(s.Substring( 0, 2)) + .Append(s.Substring(10, 2)) + .Append(s.Substring( 8, 2)) + .Append(s.Substring(14, 2)) + .Append(s.Substring(12, 2)) + .Append(s.Substring(16, 16)) + .Append("' as blob)"); + } + else + base.BuildValue(sb, value); + } + + protected override void BuildDateTime(StringBuilder sb, object value) + { + sb + .Append(string.Format("'{0:yyyy-MM-dd HH:mm:ss.fff}", value).TrimEnd('0')) + .Append('\''); + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter: + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return "@" + value; + + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryFieldAlias: + case ConvertType.NameToQueryTableAlias: + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '[') + return value; + } + + return "[" + value + "]"; + + case ConvertType.NameToDatabase: + case ConvertType.NameToOwner: + case ConvertType.NameToQueryTable: + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '[') + return value; + + if (name.IndexOf('.') > 0) + value = string.Join("].[", name.Split('.')); + } + + return "[" + value + "]"; + + case ConvertType.SprocParameterToName: + { + var name = (string)value; + return name.Length > 0 && name[0] == '@'? name.Substring(1): name; + } + } + + return value; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/SequenceNameAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/SequenceNameAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ +using System; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + [AttributeUsageAttribute(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] + public class SequenceNameAttribute : Attribute + { + public SequenceNameAttribute(string providerName, string sequenceName) + { + ProviderName = providerName; + SequenceName = sequenceName; + } + + public SequenceNameAttribute(string sequenceName) + { + SequenceName = sequenceName; + } + + private string _providerName; public string ProviderName { get { return _providerName; } set { _providerName = value; } } + private string _sequenceName; public string SequenceName { get { return _sequenceName; } set { _sequenceName = value; } } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/SqlCeSqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/SqlCeSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,262 @@ +using System; +using System.Data; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + using Reflection; + + public class SqlCeSqlProvider : BasicSqlProvider + { + const int Version = 4; + + public override bool IsSkipSupported { get { return Version == 4; } } + public override bool IsTakeSupported { get { return Version == 4; } } + public override bool IsSubQueryTakeSupported { get { return Version == 4; } } + public override bool IsSubQueryColumnSupported { get { return false; } } + public override bool IsCountSubQuerySupported { get { return false; } } + public override bool IsApplyJoinSupported { get { return true; } } + public override bool IsInsertOrUpdateSupported { get { return false; } } + + protected override string FirstFormat { get { return SqlQuery.Select.SkipValue == null ? "TOP ({0})" : null; } } + protected override string LimitFormat { get { return SqlQuery.Select.SkipValue != null ? "FETCH NEXT {0} ROWS ONLY" : null; } } + protected override string OffsetFormat { get { return "OFFSET {0} ROWS"; } } + protected override bool OffsetFirst { get { return true; } } + + public override int CommandCount(SqlQuery sqlQuery) + { + return sqlQuery.IsInsert && sqlQuery.Insert.WithIdentity ? 2 : 1; + } + + protected override void BuildCommand(int commandNumber, StringBuilder sb) + { + sb.AppendLine("SELECT @@IDENTITY"); + } + + protected override ISqlProvider CreateSqlProvider() + { + return new SqlCeSqlProvider(); + } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlBinaryExpression) + { + var be = (SqlBinaryExpression)expr; + + switch (be.Operation) + { + case "%": + return TypeHelper.IsIntegerType(be.Expr1.SystemType)? + be : + new SqlBinaryExpression( + typeof(int), + new SqlFunction(typeof(int), "Convert", SqlDataType.Int32, be.Expr1), + be.Operation, + be.Expr2, + be.Precedence); + } + } + else if (expr is SqlFunction) + { + var func = (SqlFunction)expr; + + switch (func.Name) + { + case "Convert" : + switch (Type.GetTypeCode(TypeHelper.GetUnderlyingType(func.SystemType))) + { + case TypeCode.UInt64 : + if (TypeHelper.IsFloatType(func.Parameters[1].SystemType)) + return new SqlFunction( + func.SystemType, + func.Name, + func.Precedence, + func.Parameters[0], + new SqlFunction(func.SystemType, "Floor", func.Parameters[1])); + + break; + + case TypeCode.DateTime : + var type1 = TypeHelper.GetUnderlyingType(func.Parameters[1].SystemType); + + if (IsTimeDataType(func.Parameters[0])) + { + if (type1 == typeof(DateTime) || type1 == typeof(DateTimeOffset)) + return new SqlExpression( + func.SystemType, "Cast(Convert(NChar, {0}, 114) as DateTime)", Precedence.Primary, func.Parameters[1]); + + if (func.Parameters[1].SystemType == typeof(string)) + return func.Parameters[1]; + + return new SqlExpression( + func.SystemType, "Convert(NChar, {0}, 114)", Precedence.Primary, func.Parameters[1]); + } + + if (type1 == typeof(DateTime) || type1 == typeof(DateTimeOffset)) + { + if (IsDateDataType(func.Parameters[0], "Datetime")) + return new SqlExpression( + func.SystemType, "Cast(Floor(Cast({0} as Float)) as DateTime)", Precedence.Primary, func.Parameters[1]); + } + + break; + } + + break; + } + } + + return expr; + } + + protected override void BuildFunction(StringBuilder sb, SqlFunction func) + { + func = ConvertFunctionParameters(func); + base.BuildFunction(sb, func); + } + + public override SqlQuery Finalize(SqlQuery sqlQuery) + { + sqlQuery = base.Finalize(sqlQuery); + + new QueryVisitor().Visit(sqlQuery.Select, element => + { + if (element.ElementType == QueryElementType.SqlParameter) + { + ((SqlParameter)element).IsQueryParameter = false; + sqlQuery.IsParameterDependent = true; + } + }); + + switch (sqlQuery.QueryType) + { + case QueryType.Delete : + sqlQuery = GetAlternativeDelete(sqlQuery); + sqlQuery.From.Tables[0].Alias = "$"; + break; + + case QueryType.Update : + sqlQuery = GetAlternativeUpdate(sqlQuery); + break; + } + + return sqlQuery; + } + + protected override void BuildDataType(StringBuilder sb, SqlDataType type) + { + switch (type.SqlDbType) + { + case SqlDbType.Char : base.BuildDataType(sb, new SqlDataType(SqlDbType.NChar, type.Length)); break; + case SqlDbType.VarChar : base.BuildDataType(sb, new SqlDataType(SqlDbType.NVarChar, type.Length)); break; + case SqlDbType.SmallMoney : sb.Append("Decimal(10,4)"); break; +#if !MONO + case SqlDbType.DateTime2 : +#endif + case SqlDbType.Time : + case SqlDbType.Date : + case SqlDbType.SmallDateTime : sb.Append("DateTime"); break; + default : base.BuildDataType(sb, type); break; + } + } + + protected override void BuildFromClause(StringBuilder sb) + { + if (!SqlQuery.IsUpdate) + base.BuildFromClause(sb); + } + + protected override void BuildOrderByClause(StringBuilder sb) + { + if (SqlQuery.OrderBy.Items.Count == 0 && SqlQuery.Select.SkipValue != null) + { + AppendIndent(sb); + + sb.Append("ORDER BY").AppendLine(); + + Indent++; + + AppendIndent(sb); + + BuildExpression(sb, SqlQuery.Select.Columns[0].Expression); + sb.AppendLine(); + + Indent--; + } + else + base.BuildOrderByClause(sb); + } + + protected override void BuildColumnExpression(StringBuilder sb, ISqlExpression expr, string alias, ref bool addAlias) + { + var wrap = false; + + if (expr.SystemType == typeof(bool)) + { + if (expr is SqlQuery.SearchCondition) + wrap = true; + else + { + var ex = expr as SqlExpression; + wrap = ex != null && ex.Expr == "{0}" && ex.Parameters.Length == 1 && ex.Parameters[0] is SqlQuery.SearchCondition; + } + } + + if (wrap) sb.Append("CASE WHEN "); + base.BuildColumnExpression(sb, expr, alias, ref addAlias); + if (wrap) sb.Append(" THEN 1 ELSE 0 END"); + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter: + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return "@" + value; + + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryFieldAlias: + case ConvertType.NameToQueryTableAlias: + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '[') + return value; + } + + return "[" + value + "]"; + + case ConvertType.NameToDatabase: + case ConvertType.NameToOwner: + case ConvertType.NameToQueryTable: + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '[') + return value; + + if (name.IndexOf('.') > 0) + value = string.Join("].[", name.Split('.')); + } + + return "[" + value + "]"; + + case ConvertType.SprocParameterToName: + if (value != null) + { + var str = value.ToString(); + return str.Length > 0 && str[0] == '@'? str.Substring(1): str; + } + break; + } + + return value; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlProvider/SybaseSqlProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/SybaseSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,252 @@ +using System; +using System.Data; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + + public class SybaseSqlProvider : BasicSqlProvider + { + public SybaseSqlProvider() + { + } + + protected override void BuildGetIdentity(StringBuilder sb) + { + sb + .AppendLine() + .AppendLine("SELECT @@IDENTITY"); + } + + protected override string FirstFormat { get { return "TOP {0}"; } } + + public override bool IsSkipSupported { get { return false; } } + public override bool TakeAcceptsParameter { get { return false; } } + public override bool IsSubQueryTakeSupported { get { return false; } } + public override bool IsCountSubQuerySupported { get { return false; } } + public override bool CanCombineParameters { get { return false; } } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlFunction) + { + var func = (SqlFunction) expr; + + switch (func.Name) + { + case "CharIndex" : + if (func.Parameters.Length == 3) + return Add( + ConvertExpression(new SqlFunction(func.SystemType, "CharIndex", + func.Parameters[0], + ConvertExpression(new SqlFunction(typeof(string), "Substring", + func.Parameters[1], + func.Parameters[2], new SqlFunction(typeof(int), "Len", func.Parameters[1]))))), + Sub(func.Parameters[2], 1)); + break; + + case "Stuff" : + if (func.Parameters[3] is SqlValue) + { + var value = (SqlValue)func.Parameters[3]; + + if (value.Value is string && string.IsNullOrEmpty((string)value.Value)) + return new SqlFunction( + func.SystemType, + func.Name, + func.Precedence, + func.Parameters[0], + func.Parameters[1], + func.Parameters[1], + new SqlValue(null)); + } + + break; + } + } + + return expr; + } + + protected override void BuildFunction(StringBuilder sb, SqlFunction func) + { + func = ConvertFunctionParameters(func); + base.BuildFunction(sb, func); + } + + private bool _isSelect; + readonly bool _skipAliases; + + SybaseSqlProvider(bool skipAliases) + { + _skipAliases = skipAliases; + } + + protected override void BuildSelectClause(StringBuilder sb) + { + _isSelect = true; + base.BuildSelectClause(sb); + _isSelect = false; + } + + protected override void BuildColumnExpression(StringBuilder sb, ISqlExpression expr, string alias, ref bool addAlias) + { + var wrap = false; + + if (expr.SystemType == typeof(bool)) + { + if (expr is SqlQuery.SearchCondition) + wrap = true; + else + { + var ex = expr as SqlExpression; + wrap = ex != null && ex.Expr == "{0}" && ex.Parameters.Length == 1 && ex.Parameters[0] is SqlQuery.SearchCondition; + } + } + + if (wrap) sb.Append("CASE WHEN "); + base.BuildColumnExpression(sb, expr, alias, ref addAlias); + if (wrap) sb.Append(" THEN 1 ELSE 0 END"); + + if (_skipAliases) addAlias = false; + } + + protected override ISqlProvider CreateSqlProvider() + { + return new SybaseSqlProvider(_isSelect); + } + + protected override void BuildDataType(StringBuilder sb, SqlDataType type) + { + switch (type.SqlDbType) + { +#if !MONO + case SqlDbType.DateTime2 : sb.Append("DateTime"); break; +#endif + default : base.BuildDataType(sb, type); break; + } + } + + protected override void BuildDeleteClause(StringBuilder sb) + { + AppendIndent(sb); + sb.Append("DELETE FROM "); +// BuildTableName(sb, SqlQuery.From.Tables[0], true, false); + + ISqlTableSource table; + ISqlTableSource source; + + if (SqlQuery.Delete.Table != null) + table = source = SqlQuery.Delete.Table; + else + { + table = SqlQuery.From.Tables[0]; + source = SqlQuery.From.Tables[0].Source; + } + + var alias = GetTableAlias(table); + BuildPhysicalTable(sb, source, alias); + + sb.AppendLine(); + } + + protected override void BuildUpdateTableName(StringBuilder sb) + { + if (SqlQuery.Update.Table != null && SqlQuery.Update.Table != SqlQuery.From.Tables[0].Source) + BuildPhysicalTable(sb, SqlQuery.Update.Table, null); + else + BuildTableName(sb, SqlQuery.From.Tables[0], true, false); + } + + protected override void BuildString(StringBuilder sb, string value) + { + foreach (var ch in value) + { + if (ch > 127) + { + sb.Append("N"); + break; + } + } + + base.BuildString(sb, value); + } + + protected override void BuildChar(StringBuilder sb, char value) + { + if (value > 127) + sb.Append("N"); + + base.BuildChar(sb, value); + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter: + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + { + var name = "@" + value; + + if (name.Length > 27) + name = name.Substring(0, 27); + + return name; + } + + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryFieldAlias: + case ConvertType.NameToQueryTableAlias: + { + var name = value.ToString(); + + if (name.Length > 28 || name.Length > 0 && name[0] == '[') + return value; + } + + return "[" + value + "]"; + + case ConvertType.NameToDatabase: + case ConvertType.NameToOwner: + case ConvertType.NameToQueryTable: + { + var name = value.ToString(); + + if (name.Length > 28 || name.Length > 0 && (name[0] == '[' || name[0] == '#')) + return value; + + if (name.IndexOf('.') > 0) + value = string.Join("].[", name.Split('.')); + } + + return "[" + value + "]"; + + case ConvertType.SprocParameterToName: + if (value != null) + { + var str = value.ToString(); + return str.Length > 0 && str[0] == '@'? str.Substring(1): str; + } + + break; + } + + return value; + } + + protected override void BuildInsertOrUpdateQuery(StringBuilder sb) + { + BuildInsertOrUpdateQueryAsUpdateInsert(sb); + } + + protected override void BuildEmptyInsert(StringBuilder sb) + { + sb.AppendLine("VALUES ()"); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlQuery.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlQuery.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4850 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; + +using JetBrains.Annotations; + +namespace BLToolkit.Data.Sql +{ + using Reflection; + + using FJoin = SqlQuery.FromClause.Join; + + [DebuggerDisplay("SQL = {SqlText}")] + public class SqlQuery : ISqlTableSource + { + #region Init + + static readonly Dictionary _reservedWords = new Dictionary(); + + static SqlQuery() + { + using (var stream = typeof(SqlQuery).Assembly.GetManifestResourceStream(typeof(SqlQuery), "ReservedWords.txt")) + using (var reader = new StreamReader(stream)) + { + /* + var words = reader.ReadToEnd().Replace(' ', '\n').Replace('\t', '\n').Split('\n'); + var q = from w in words where w.Length > 0 orderby w select w; + + var text = string.Join("\n", q.Distinct().ToArray()); + */ + + string s; + while ((s = reader.ReadLine()) != null) + _reservedWords.Add(s, s); + } + } + + public SqlQuery() + { + SourceID = Interlocked.Increment(ref SourceIDCounter); + + _select = new SelectClause (this); + _from = new FromClause (this); + _where = new WhereClause (this); + _groupBy = new GroupByClause(this); + _having = new WhereClause (this); + _orderBy = new OrderByClause(this); + } + + internal SqlQuery(int id) + { + SourceID = id; + } + + internal void Init( + InsertClause insert, + UpdateClause update, + DeleteClause delete, + SelectClause select, + FromClause from, + WhereClause where, + GroupByClause groupBy, + WhereClause having, + OrderByClause orderBy, + List unions, + SqlQuery parentSql, + bool parameterDependent, + List parameters) + { + _insert = insert; + _update = update; + _delete = delete; + _select = select; + _from = from; + _where = where; + _groupBy = groupBy; + _having = having; + _orderBy = orderBy; + _unions = unions; + ParentSql = parentSql; + IsParameterDependent = parameterDependent; + _parameters.AddRange(parameters); + + foreach (var col in select.Columns) + col.Parent = this; + + _select. SetSqlQuery(this); + _from. SetSqlQuery(this); + _where. SetSqlQuery(this); + _groupBy.SetSqlQuery(this); + _having. SetSqlQuery(this); + _orderBy.SetSqlQuery(this); + } + + readonly List _parameters = new List(); + public List Parameters + { + get { return _parameters; } + } + + private List _properties; + public List Properties + { + get { return _properties ?? (_properties = new List()); } + } + + public bool IsParameterDependent { get; set; } + public SqlQuery ParentSql { get; set; } + + public bool IsSimple + { + get { return !Select.HasModifier && Where.IsEmpty && GroupBy.IsEmpty && Having.IsEmpty && OrderBy.IsEmpty; } + } + + private QueryType _queryType = QueryType.Select; + public QueryType QueryType + { + get { return _queryType; } + set { _queryType = value; } + } + + public bool IsSelect { get { return _queryType == QueryType.Select; } } + public bool IsDelete { get { return _queryType == QueryType.Delete; } } + public bool IsInsertOrUpdate { get { return _queryType == QueryType.InsertOrUpdate; } } + public bool IsInsert { get { return _queryType == QueryType.Insert || _queryType == QueryType.InsertOrUpdate; } } + public bool IsUpdate { get { return _queryType == QueryType.Update || _queryType == QueryType.InsertOrUpdate; } } + + #endregion + + #region Column + + public class Column : IEquatable, ISqlExpression, IChild + { + public Column(SqlQuery parent, ISqlExpression expression, string alias) + { + if (expression == null) throw new ArgumentNullException("expression"); + + Parent = parent; + Expression = expression; + _alias = alias; + +#if DEBUG + _columnNumber = ++_columnCounter; +#endif + } + + public Column(SqlQuery builder, ISqlExpression expression) + : this(builder, expression, null) + { + } + +#if DEBUG + readonly int _columnNumber; + static int _columnCounter; +#endif + + public ISqlExpression Expression { get; set; } + + internal string _alias; + public string Alias + { + get + { + if (_alias == null) + { + if (Expression is SqlField) + { + var field = (SqlField)Expression; + return field.Alias ?? field.PhysicalName; + } + + if (Expression is Column) + { + var col = (Column)Expression; + return col.Alias; + } + } + + return _alias; + } + set { _alias = value; } + } + + public bool Equals(Column other) + { + return Expression.Equals(other.Expression); + } + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #region ISqlExpression Members + + public bool CanBeNull() + { + return Expression.CanBeNull(); + } + + public bool Equals(ISqlExpression other, Func comparer) + { + if (this == other) + return true; + + return + other is Column && + Expression.Equals(((Column)other).Expression, comparer) && + comparer(this, other); + } + + public int Precedence + { + get { return Sql.Precedence.Primary; } + } + + public Type SystemType + { + get { return Expression.SystemType; } + } + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + var parent = (SqlQuery)Parent.Clone(objectTree, doClone); + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new Column( + parent, + (ISqlExpression)Expression.Clone(objectTree, doClone), + _alias)); + + return clone; + } + + #endregion + + #region IEquatable Members + + bool IEquatable.Equals(ISqlExpression other) + { + if (this == other) + return true; + + return other is Column && Equals((Column)other); + } + + #endregion + + #region ISqlExpressionWalkable Members + + [Obsolete] + public ISqlExpression Walk(bool skipColumns, Func func) + { + if (!(skipColumns && Expression is Column)) + Expression = Expression.Walk(skipColumns, func); + + return func(this); + } + + #endregion + + #region IChild Members + + string IChild.Name + { + get { return Alias; } + } + + public SqlQuery Parent { get; set; } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.Column; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + if (dic.ContainsKey(this)) + return sb.Append("..."); + + dic.Add(this, this); + + sb + .Append('t') + .Append(Parent.SourceID) + .Append("."); + +#if DEBUG + sb.Append('[').Append(_columnNumber).Append(']'); +#endif + + if (Expression is SqlQuery) + { + sb + .Append("(\n\t\t"); + var len = sb.Length; + Expression.ToString(sb, dic).Replace("\n", "\n\t\t", len, sb.Length - len); + sb.Append("\n\t)"); + } + /*else if (Expression is Column) + { + var col = (Column)Expression; + sb + .Append("t") + .Append(col.Parent.SourceID) + .Append(".") + .Append(col.Alias ?? "c" + (col.Parent.Select.Columns.IndexOf(col) + 1)); + }*/ + else + { + Expression.ToString(sb, dic); + } + + dic.Remove(this); + + return sb; + } + + #endregion + } + + #endregion + + #region TableSource + + public class TableSource : ISqlTableSource + { + public TableSource(ISqlTableSource source, string alias) + : this(source, alias, null) + { + } + + public TableSource(ISqlTableSource source, string alias, params JoinedTable[] joins) + { + if (source == null) throw new ArgumentNullException("source"); + + Source = source; + _alias = alias; + + if (joins != null) + _joins.AddRange(joins); + } + + public TableSource(ISqlTableSource source, string alias, IEnumerable joins) + { + if (source == null) throw new ArgumentNullException("source"); + + Source = source; + _alias = alias; + + if (joins != null) + _joins.AddRange(joins); + } + + public ISqlTableSource Source { get; set; } + public SqlTableType SqlTableType { get { return Source.SqlTableType; } } + + internal string _alias; + public string Alias + { + get + { + if (string.IsNullOrEmpty(_alias)) + { + if (Source is TableSource) + return (Source as TableSource).Alias; + + if (Source is SqlTable) + return ((SqlTable)Source).Alias; + } + + return _alias; + } + set { _alias = value; } + } + + public TableSource this[ISqlTableSource table] + { + get { return this[table, null]; } + } + + public TableSource this[ISqlTableSource table, string alias] + { + get + { + foreach (var tj in Joins) + { + var t = CheckTableSource(tj.Table, table, alias); + + if (t != null) + return t; + } + + return null; + } + } + + readonly List _joins = new List(); + public List Joins + { + get { return _joins; } + } + + public void ForEach(Action action, HashSet visitedQueries) + { + action(this); + foreach (var join in Joins) + join.Table.ForEach(action, visitedQueries); + + if (Source is SqlQuery && visitedQueries.Contains((SqlQuery)Source)) + ((SqlQuery)Source).ForEachTable(action, visitedQueries); + } + + public IEnumerable GetTables() + { + yield return Source; + + foreach (var join in Joins) + foreach (var table in join.Table.GetTables()) + yield return table; + } + + public int GetJoinNumber() + { + var n = Joins.Count; + + foreach (var join in Joins) + n += join.Table.GetJoinNumber(); + + return n; + } + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #region IEquatable Members + + bool IEquatable.Equals(ISqlExpression other) + { + return this == other; + } + + #endregion + + #region ISqlExpressionWalkable Members + + [Obsolete] + public ISqlExpression Walk(bool skipColumns, Func func) + { + Source = (ISqlTableSource)Source.Walk(skipColumns, func); + + foreach (var t in Joins) + ((ISqlExpressionWalkable)t).Walk(skipColumns, func); + + return this; + } + + #endregion + + #region ISqlTableSource Members + + public int SourceID { get { return Source.SourceID; } } + public SqlField All { get { return Source.All; } } + + IList ISqlTableSource.GetKeys(bool allIfEmpty) + { + return Source.GetKeys(allIfEmpty); + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + { + var ts = new TableSource((ISqlTableSource)Source.Clone(objectTree, doClone), _alias); + + objectTree.Add(this, clone = ts); + + ts._joins.AddRange(_joins.ConvertAll(jt => (JoinedTable)jt.Clone(objectTree, doClone))); + } + + return clone; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.TableSource; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + if (sb.Length > 500) + return sb; + + if (dic.ContainsKey(this)) + return sb.Append("..."); + + dic.Add(this, this); + + if (Source is SqlQuery) + { + sb.Append("(\n\t"); + var len = sb.Length; + Source.ToString(sb, dic).Replace("\n", "\n\t", len, sb.Length - len); + sb.Append("\n)"); + } + else + Source.ToString(sb, dic); + + sb + .Append(" as t") + .Append(SourceID); + + foreach (IQueryElement join in Joins) + { + sb.AppendLine().Append('\t'); + var len = sb.Length; + join.ToString(sb, dic).Replace("\n", "\n\t", len, sb.Length - len); + } + + dic.Remove(this); + + return sb; + } + + #endregion + + #region ISqlExpression Members + + public bool CanBeNull() + { + return Source.CanBeNull(); + } + + public bool Equals(ISqlExpression other, Func comparer) + { + return this == other; + } + + public int Precedence { get { return Source.Precedence; } } + public Type SystemType { get { return Source.SystemType; } } + + #endregion + } + + #endregion + + #region TableJoin + + public enum JoinType + { + Auto, + Inner, + Left, + CrossApply, + OuterApply + } + + public class JoinedTable : IQueryElement, ISqlExpressionWalkable, ICloneableElement + { + public JoinedTable(JoinType joinType, TableSource table, bool isWeak, SearchCondition searchCondition) + { + JoinType = joinType; + Table = table; + IsWeak = isWeak; + Condition = searchCondition; + CanConvertApply = true; + } + + public JoinedTable(JoinType joinType, TableSource table, bool isWeak) + : this(joinType, table, isWeak, new SearchCondition()) + { + } + + public JoinedTable(JoinType joinType, ISqlTableSource table, string alias, bool isWeak) + : this(joinType, new TableSource(table, alias), isWeak) + { + } + + public JoinType JoinType { get; set; } + public TableSource Table { get; set; } + public SearchCondition Condition { get; private set; } + public bool IsWeak { get; set; } + public bool CanConvertApply { get; set; } + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new JoinedTable( + JoinType, + (TableSource)Table.Clone(objectTree, doClone), + IsWeak, + (SearchCondition)Condition.Clone(objectTree, doClone))); + + return clone; + } + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #region ISqlExpressionWalkable Members + + [Obsolete] + public ISqlExpression Walk(bool skipColumns, Func action) + { + Condition = (SearchCondition)((ISqlExpressionWalkable)Condition).Walk(skipColumns, action); + +#pragma warning disable 0618 + Table.Walk(skipColumns, action); +#pragma warning restore 0618 + + return null; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.JoinedTable; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + if (dic.ContainsKey(this)) + return sb.Append("..."); + + dic.Add(this, this); + + switch (JoinType) + { + case JoinType.Inner : sb.Append("INNER JOIN "); break; + case JoinType.Left : sb.Append("LEFT JOIN "); break; + case JoinType.CrossApply : sb.Append("CROSS APPLY "); break; + case JoinType.OuterApply : sb.Append("OUTER APPLY "); break; + default : sb.Append("SOME JOIN "); break; + } + + ((IQueryElement)Table).ToString(sb, dic); + sb.Append(" ON "); + ((IQueryElement)Condition).ToString(sb, dic); + + dic.Remove(this); + + return sb; + } + + #endregion + } + + #endregion + + #region Predicate + + public abstract class Predicate : ISqlPredicate + { + public enum Operator + { + Equal, // = Is the operator used to test the equality between two expressions. + NotEqual, // <> != Is the operator used to test the condition of two expressions not being equal to each other. + Greater, // > Is the operator used to test the condition of one expression being greater than the other. + GreaterOrEqual, // >= Is the operator used to test the condition of one expression being greater than or equal to the other expression. + NotGreater, // !> Is the operator used to test the condition of one expression not being greater than the other expression. + Less, // < Is the operator used to test the condition of one expression being less than the other. + LessOrEqual, // <= Is the operator used to test the condition of one expression being less than or equal to the other expression. + NotLess // !< Is the operator used to test the condition of one expression not being less than the other expression. + } + + public class Expr : Predicate + { + public Expr([NotNull] ISqlExpression exp1, int precedence) + : base(precedence) + { + if (exp1 == null) throw new ArgumentNullException("exp1"); + + Expr1 = exp1; + } + + public Expr([NotNull] ISqlExpression exp1) + : base(exp1.Precedence) + { + if (exp1 == null) throw new ArgumentNullException("exp1"); + + Expr1 = exp1; + } + + public ISqlExpression Expr1 { get; set; } + + [Obsolete] + protected override void Walk(bool skipColumns, Func func) + { + Expr1 = Expr1.Walk(skipColumns, func); + + if (Expr1 == null) + throw new InvalidOperationException(); + } + + public override bool CanBeNull() + { + return Expr1.CanBeNull(); + } + + protected override ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new Expr((ISqlExpression)Expr1.Clone(objectTree, doClone), Precedence)); + + return clone; + } + + public override QueryElementType ElementType + { + get { return QueryElementType.ExprPredicate; } + } + + protected override void ToString(StringBuilder sb, Dictionary dic) + { + Expr1.ToString(sb, dic); + } + } + + public class NotExpr : Expr + { + public NotExpr(ISqlExpression exp1, bool isNot, int precedence) + : base(exp1, precedence) + { + IsNot = isNot; + } + + public bool IsNot { get; set; } + + protected override ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new NotExpr((ISqlExpression)Expr1.Clone(objectTree, doClone), IsNot, Precedence)); + + return clone; + } + + public override QueryElementType ElementType + { + get { return QueryElementType.NotExprPredicate; } + } + + protected override void ToString(StringBuilder sb, Dictionary dic) + { + if (IsNot) sb.Append("NOT ("); + base.ToString(sb, dic); + if (IsNot) sb.Append(")"); + } + } + + // { expression { = | <> | != | > | >= | ! > | < | <= | !< } expression + // + public class ExprExpr : Expr + { + public ExprExpr(ISqlExpression exp1, Operator op, ISqlExpression exp2) + : base(exp1, Sql.Precedence.Comparison) + { + this.Operator = op; + Expr2 = exp2; + } + + public new Operator Operator { get; private set; } + public ISqlExpression Expr2 { get; internal set; } + + [Obsolete] + protected override void Walk(bool skipColumns, Func func) + { +#pragma warning disable 0618 + base.Walk(skipColumns, func); +#pragma warning restore 0618 + Expr2 = Expr2.Walk(skipColumns, func); + } + + public override bool CanBeNull() + { + return base.CanBeNull() || Expr2.CanBeNull(); + } + + protected override ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new ExprExpr( + (ISqlExpression)Expr1.Clone(objectTree, doClone), this.Operator, (ISqlExpression)Expr2.Clone(objectTree, doClone))); + + return clone; + } + + public override QueryElementType ElementType + { + get { return QueryElementType.ExprExprPredicate; } + } + + protected override void ToString(StringBuilder sb, Dictionary dic) + { + Expr1.ToString(sb, dic); + + string op; + + switch (this.Operator) + { + case Operator.Equal : op = "="; break; + case Operator.NotEqual : op = "<>"; break; + case Operator.Greater : op = ">"; break; + case Operator.GreaterOrEqual: op = ">="; break; + case Operator.NotGreater : op = "!>"; break; + case Operator.Less : op = "<"; break; + case Operator.LessOrEqual : op = "<="; break; + case Operator.NotLess : op = "!<"; break; + default: throw new InvalidOperationException(); + } + + sb.Append(" ").Append(op).Append(" "); + + Expr2.ToString(sb, dic); + } + } + + // string_expression [ NOT ] LIKE string_expression [ ESCAPE 'escape_character' ] + // + public class Like : NotExpr + { + public Like(ISqlExpression exp1, bool isNot, ISqlExpression exp2, ISqlExpression escape) + : base(exp1, isNot, Sql.Precedence.Comparison) + { + Expr2 = exp2; + Escape = escape; + } + + public ISqlExpression Expr2 { get; internal set; } + public ISqlExpression Escape { get; internal set; } + + [Obsolete] + protected override void Walk(bool skipColumns, Func func) + { +#pragma warning disable 0618 + base.Walk(skipColumns, func); +#pragma warning restore 0618 + Expr2 = Expr2.Walk(skipColumns, func); + + if (Escape != null) + Escape = Escape.Walk(skipColumns, func); + } + + protected override ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new Like( + (ISqlExpression)Expr1.Clone(objectTree, doClone), IsNot, (ISqlExpression)Expr2.Clone(objectTree, doClone), Escape)); + + return clone; + } + + public override QueryElementType ElementType + { + get { return QueryElementType.LikePredicate; } + } + + protected override void ToString(StringBuilder sb, Dictionary dic) + { + Expr1.ToString(sb, dic); + + if (IsNot) sb.Append(" NOT"); + sb.Append(" LIKE "); + + Expr2.ToString(sb, dic); + + if (Escape != null) + { + sb.Append(" ESCAPE "); + Escape.ToString(sb, dic); + } + } + } + + // expression [ NOT ] BETWEEN expression AND expression + // + public class Between : NotExpr + { + public Between(ISqlExpression exp1, bool isNot, ISqlExpression exp2, ISqlExpression exp3) + : base(exp1, isNot, Sql.Precedence.Comparison) + { + Expr2 = exp2; + Expr3 = exp3; + } + + public ISqlExpression Expr2 { get; internal set; } + public ISqlExpression Expr3 { get; internal set; } + + [Obsolete] + protected override void Walk(bool skipColumns, Func func) + { +#pragma warning disable 0618 + base.Walk(skipColumns, func); +#pragma warning restore 0618 + Expr2 = Expr2.Walk(skipColumns, func); + Expr3 = Expr3.Walk(skipColumns, func); + } + + protected override ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new Between( + (ISqlExpression)Expr1.Clone(objectTree, doClone), + IsNot, + (ISqlExpression)Expr2.Clone(objectTree, doClone), + (ISqlExpression)Expr3.Clone(objectTree, doClone))); + + return clone; + } + + public override QueryElementType ElementType + { + get { return QueryElementType.BetweenPredicate; } + } + + protected override void ToString(StringBuilder sb, Dictionary dic) + { + Expr1.ToString(sb, dic); + + if (IsNot) sb.Append(" NOT"); + sb.Append(" BETWEEN "); + + Expr2.ToString(sb, dic); + sb.Append(" AND "); + Expr3.ToString(sb, dic); + } + } + + // expression IS [ NOT ] NULL + // + public class IsNull : NotExpr + { + public IsNull(ISqlExpression exp1, bool isNot) + : base(exp1, isNot, Sql.Precedence.Comparison) + { + } + + protected override ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new IsNull((ISqlExpression)Expr1.Clone(objectTree, doClone), IsNot)); + + return clone; + } + + protected override void ToString(StringBuilder sb, Dictionary dic) + { + Expr1.ToString(sb, dic); + sb + .Append(" IS ") + .Append(IsNot ? "NOT " : "") + .Append("NULL"); + } + + public override QueryElementType ElementType + { + get { return QueryElementType.IsNullPredicate; } + } + } + + // expression [ NOT ] IN ( subquery | expression [ ,...n ] ) + // + public class InSubQuery : NotExpr + { + public InSubQuery(ISqlExpression exp1, bool isNot, SqlQuery subQuery) + : base(exp1, isNot, Sql.Precedence.Comparison) + { + SubQuery = subQuery; + } + + public SqlQuery SubQuery { get; private set; } + + [Obsolete] + protected override void Walk(bool skipColumns, Func func) + { +#pragma warning disable 0618 + base.Walk(skipColumns, func); +#pragma warning restore 0618 + SubQuery = (SqlQuery)((ISqlExpression)SubQuery).Walk(skipColumns, func); + } + + protected override ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new InSubQuery( + (ISqlExpression)Expr1.Clone(objectTree, doClone), + IsNot, + (SqlQuery)SubQuery.Clone(objectTree, doClone))); + + return clone; + } + + public override QueryElementType ElementType + { + get { return QueryElementType.InSubQueryPredicate; } + } + + protected override void ToString(StringBuilder sb, Dictionary dic) + { + Expr1.ToString(sb, dic); + + if (IsNot) sb.Append(" NOT"); + sb.Append(" IN ("); + + ((IQueryElement)SubQuery).ToString(sb, dic); + sb.Append(")"); + } + } + + public class InList : NotExpr + { + public InList(ISqlExpression exp1, bool isNot, params ISqlExpression[] values) + : base(exp1, isNot, Sql.Precedence.Comparison) + { + if (values != null && values.Length > 0) + _values.AddRange(values); + } + + public InList(ISqlExpression exp1, bool isNot, IEnumerable values) + : base(exp1, isNot, Sql.Precedence.Comparison) + { + if (values != null) + _values.AddRange(values); + } + + readonly List _values = new List(); + public List Values { get { return _values; } } + + [Obsolete] + protected override void Walk(bool skipColumns, Func action) + { +#pragma warning disable 0618 + base.Walk(skipColumns, action); +#pragma warning restore 0618 + for (var i = 0; i < _values.Count; i++) + _values[i] = _values[i].Walk(skipColumns, action); + } + + protected override ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + { + objectTree.Add(this, clone = new InList( + (ISqlExpression)Expr1.Clone(objectTree, doClone), + IsNot, + _values.ConvertAll(e => (ISqlExpression)e.Clone(objectTree, doClone)).ToArray())); + } + + return clone; + } + + public override QueryElementType ElementType + { + get { return QueryElementType.InListPredicate; } + } + + protected override void ToString(StringBuilder sb, Dictionary dic) + { + Expr1.ToString(sb, dic); + + if (IsNot) sb.Append(" NOT"); + sb.Append(" IN ("); + + foreach (var value in Values) + { + value.ToString(sb, dic); + sb.Append(','); + } + + if (Values.Count > 0) + sb.Length--; + + sb.Append(")"); + } + } + + // CONTAINS ( { column | * } , '< contains_search_condition >' ) + // FREETEXT ( { column | * } , 'freetext_string' ) + // expression { = | <> | != | > | >= | !> | < | <= | !< } { ALL | SOME | ANY } ( subquery ) + // EXISTS ( subquery ) + + public class FuncLike : Predicate + { + public FuncLike(SqlFunction func) + : base(func.Precedence) + { + Function = func; + } + + public SqlFunction Function { get; private set; } + + [Obsolete] + protected override void Walk(bool skipColumns, Func func) + { + Function = (SqlFunction)((ISqlExpression)Function).Walk(skipColumns, func); + } + + public override bool CanBeNull() + { + return Function.CanBeNull(); + } + + protected override ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new FuncLike((SqlFunction)Function.Clone(objectTree, doClone))); + + return clone; + } + + public override QueryElementType ElementType + { + get { return QueryElementType.FuncLikePredicate; } + } + + protected override void ToString(StringBuilder sb, Dictionary dic) + { + ((IQueryElement)Function).ToString(sb, dic); + } + } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + protected Predicate(int precedence) + { + Precedence = precedence; + } + + #region IPredicate Members + + public int Precedence { get; private set; } + + public abstract bool CanBeNull(); + protected abstract ICloneableElement Clone (Dictionary objectTree, Predicate doClone); + [Obsolete] + protected abstract void Walk (bool skipColumns, Func action); + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + Walk(skipColumns, func); + return null; + } + + ICloneableElement ICloneableElement.Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + return Clone(objectTree, doClone); + } + + #endregion + + #region IQueryElement Members + + public abstract QueryElementType ElementType { get; } + + protected abstract void ToString(StringBuilder sb, Dictionary dic); + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + if (dic.ContainsKey(this)) + return sb.Append("..."); + + dic.Add(this, this); + ToString(sb, dic); + dic.Remove(this); + + return sb; + } + + #endregion + } + + #endregion + + #region Condition + + public class Condition : IQueryElement, ICloneableElement + { + public Condition(bool isNot, ISqlPredicate predicate) + { + IsNot = isNot; + Predicate = predicate; + } + + public Condition(bool isNot, ISqlPredicate predicate, bool isOr) + { + IsNot = isNot; + Predicate = predicate; + IsOr = isOr; + } + + public bool IsNot { get; set; } + public ISqlPredicate Predicate { get; set; } + public bool IsOr { get; set; } + + public int Precedence + { + get + { + return + IsNot ? Sql.Precedence.LogicalNegation : + IsOr ? Sql.Precedence.LogicalDisjunction : + Sql.Precedence.LogicalConjunction; + } + } + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new Condition(IsNot, (ISqlPredicate)Predicate.Clone(objectTree, doClone), IsOr)); + + return clone; + } + + public bool CanBeNull() + { + return Predicate.CanBeNull(); + } + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.Condition; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + if (dic.ContainsKey(this)) + return sb.Append("..."); + + dic.Add(this, this); + + sb.Append('('); + + if (IsNot) sb.Append("NOT "); + + Predicate.ToString(sb, dic); + sb.Append(')').Append(IsOr ? " OR " : " AND "); + + dic.Remove(this); + + return sb; + } + + #endregion + } + + #endregion + + #region SearchCondition + + public class SearchCondition : ConditionBase, ISqlPredicate, ISqlExpression + { + public SearchCondition() + { + } + + public SearchCondition(IEnumerable list) + { + _conditions.AddRange(list); + } + + public SearchCondition(params Condition[] list) + { + _conditions.AddRange(list); + } + + public class Next + { + internal Next(SearchCondition parent) + { + _parent = parent; + } + + readonly SearchCondition _parent; + + public SearchCondition Or { get { return _parent.SetOr(true); } } + public SearchCondition And { get { return _parent.SetOr(false); } } + + public ISqlExpression ToExpr() { return _parent; } + } + + readonly List _conditions = new List(); + public List Conditions + { + get { return _conditions; } + } + + protected override SearchCondition Search + { + get { return this; } + } + + protected override Next GetNext() + { + return new Next(this); + } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region IPredicate Members + + public int Precedence + { + get + { + if (_conditions.Count == 0) return Sql.Precedence.Unknown; + if (_conditions.Count == 1) return _conditions[0].Precedence; + + return _conditions.Select(_ => + _.IsNot ? Sql.Precedence.LogicalNegation : + _.IsOr ? Sql.Precedence.LogicalDisjunction : + Sql.Precedence.LogicalConjunction).Min(); + } + } + + public Type SystemType + { + get { return typeof(bool); } + } + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + foreach (var condition in Conditions) + condition.Predicate.Walk(skipColumns, func); + + return func(this); + } + + #endregion + + #region IEquatable Members + + bool IEquatable.Equals(ISqlExpression other) + { + return this == other; + } + + #endregion + + #region ISqlExpression Members + + public bool CanBeNull() + { + foreach (var c in Conditions) + if (c.CanBeNull()) + return true; + + return false; + } + + public bool Equals(ISqlExpression other, Func comparer) + { + return this == other; + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + { + var sc = new SearchCondition(); + + objectTree.Add(this, clone = sc); + + sc._conditions.AddRange(_conditions.ConvertAll(c => (Condition)c.Clone(objectTree, doClone))); + } + + return clone; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.SearchCondition; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + if (dic.ContainsKey(this)) + return sb.Append("..."); + + dic.Add(this, this); + + foreach (IQueryElement c in Conditions) + c.ToString(sb, dic); + + if (Conditions.Count > 0) + sb.Length -= 4; + + dic.Remove(this); + + return sb; + } + + #endregion + } + + #endregion + + #region ConditionBase + + interface IConditionExpr + { + T Expr (ISqlExpression expr); + T Field (SqlField field); + T SubQuery(SqlQuery sqlQuery); + T Value (object value); + } + + public abstract class ConditionBase : IConditionExpr.Expr_> + where T1 : ConditionBase + { + public class Expr_ + { + internal Expr_(ConditionBase condition, bool isNot, ISqlExpression expr) + { + _condition = condition; + _isNot = isNot; + _expr = expr; + } + + readonly ConditionBase _condition; + readonly bool _isNot; + readonly ISqlExpression _expr; + + T2 Add(ISqlPredicate predicate) + { + _condition.Search.Conditions.Add(new Condition(_isNot, predicate)); + return _condition.GetNext(); + } + + #region Predicate.ExprExpr + + public class Op_ : IConditionExpr + { + internal Op_(Expr_ expr, Predicate.Operator op) + { + _expr = expr; + _op = op; + } + + readonly Expr_ _expr; + readonly Predicate.Operator _op; + + public T2 Expr (ISqlExpression expr) { return _expr.Add(new Predicate.ExprExpr(_expr._expr, _op, expr)); } + public T2 Field (SqlField field) { return Expr(field); } + public T2 SubQuery(SqlQuery subQuery) { return Expr(subQuery); } + public T2 Value (object value) { return Expr(new SqlValue(value)); } + + public T2 All (SqlQuery subQuery) { return Expr(SqlFunction.CreateAll (subQuery)); } + public T2 Some (SqlQuery subQuery) { return Expr(SqlFunction.CreateSome(subQuery)); } + public T2 Any (SqlQuery subQuery) { return Expr(SqlFunction.CreateAny (subQuery)); } + } + + public Op_ Equal { get { return new Op_(this, Predicate.Operator.Equal); } } + public Op_ NotEqual { get { return new Op_(this, Predicate.Operator.NotEqual); } } + public Op_ Greater { get { return new Op_(this, Predicate.Operator.Greater); } } + public Op_ GreaterOrEqual { get { return new Op_(this, Predicate.Operator.GreaterOrEqual); } } + public Op_ NotGreater { get { return new Op_(this, Predicate.Operator.NotGreater); } } + public Op_ Less { get { return new Op_(this, Predicate.Operator.Less); } } + public Op_ LessOrEqual { get { return new Op_(this, Predicate.Operator.LessOrEqual); } } + public Op_ NotLess { get { return new Op_(this, Predicate.Operator.NotLess); } } + + #endregion + + #region Predicate.Like + + public T2 Like(ISqlExpression expression, SqlValue escape) { return Add(new Predicate.Like(_expr, false, expression, escape)); } + public T2 Like(ISqlExpression expression) { return Like(expression, null); } + public T2 Like(string expression, SqlValue escape) { return Like(new SqlValue(expression), escape); } + public T2 Like(string expression) { return Like(new SqlValue(expression), null); } + + #endregion + + #region Predicate.Between + + public T2 Between (ISqlExpression expr1, ISqlExpression expr2) { return Add(new Predicate.Between(_expr, false, expr1, expr2)); } + public T2 NotBetween(ISqlExpression expr1, ISqlExpression expr2) { return Add(new Predicate.Between(_expr, true, expr1, expr2)); } + + #endregion + + #region Predicate.IsNull + + public T2 IsNull { get { return Add(new Predicate.IsNull(_expr, false)); } } + public T2 IsNotNull { get { return Add(new Predicate.IsNull(_expr, true)); } } + + #endregion + + #region Predicate.In + + public T2 In (SqlQuery subQuery) { return Add(new Predicate.InSubQuery(_expr, false, subQuery)); } + public T2 NotIn(SqlQuery subQuery) { return Add(new Predicate.InSubQuery(_expr, true, subQuery)); } + + Predicate.InList CreateInList(bool isNot, object[] exprs) + { + var list = new Predicate.InList(_expr, isNot, null); + + if (exprs != null && exprs.Length > 0) + { + foreach (var item in exprs) + { + if (item == null || item is SqlValue && ((SqlValue)item).Value == null) + continue; + + if (item is ISqlExpression) + list.Values.Add((ISqlExpression)item); + else + list.Values.Add(new SqlValue(item)); + } + } + + return list; + } + + public T2 In (params object[] exprs) { return Add(CreateInList(false, exprs)); } + public T2 NotIn(params object[] exprs) { return Add(CreateInList(true, exprs)); } + + #endregion + } + + public class Not_ : IConditionExpr + { + internal Not_(ConditionBase condition) + { + _condition = condition; + } + + readonly ConditionBase _condition; + + public Expr_ Expr (ISqlExpression expr) { return new Expr_(_condition, true, expr); } + public Expr_ Field (SqlField field) { return Expr(field); } + public Expr_ SubQuery(SqlQuery subQuery) { return Expr(subQuery); } + public Expr_ Value (object value) { return Expr(new SqlValue(value)); } + + public T2 Exists(SqlQuery subQuery) + { + _condition.Search.Conditions.Add(new Condition(true, new Predicate.FuncLike(SqlFunction.CreateExists(subQuery)))); + return _condition.GetNext(); + } + } + + protected abstract SearchCondition Search { get; } + protected abstract T2 GetNext(); + + protected T1 SetOr(bool value) + { + Search.Conditions[Search.Conditions.Count - 1].IsOr = value; + return (T1)this; + } + + public Not_ Not { get { return new Not_(this); } } + + public Expr_ Expr (ISqlExpression expr) { return new Expr_(this, false, expr); } + public Expr_ Field (SqlField field) { return Expr(field); } + public Expr_ SubQuery(SqlQuery subQuery) { return Expr(subQuery); } + public Expr_ Value (object value) { return Expr(new SqlValue(value)); } + + public T2 Exists(SqlQuery subQuery) + { + Search.Conditions.Add(new Condition(false, new Predicate.FuncLike(SqlFunction.CreateExists(subQuery)))); + return GetNext(); + } + } + + #endregion + + #region OrderByItem + + public class OrderByItem : IQueryElement, ICloneableElement + { + public OrderByItem(ISqlExpression expression, bool isDescending) + { + Expression = expression; + IsDescending = isDescending; + } + + public ISqlExpression Expression { get; internal set; } + public bool IsDescending { get; private set; } + + [Obsolete] + internal void Walk(bool skipColumns, Func func) + { + Expression = Expression.Walk(skipColumns, func); + } + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new OrderByItem((ISqlExpression)Expression.Clone(objectTree, doClone), IsDescending)); + + return clone; + } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType + { + get { return QueryElementType.OrderByItem; } + } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + Expression.ToString(sb, dic); + + if (IsDescending) + sb.Append(" DESC"); + + return sb; + } + + #endregion + } + + #endregion + + #region ClauseBase + + public abstract class ClauseBase + { + protected ClauseBase(SqlQuery sqlQuery) + { + SqlQuery = sqlQuery; + } + + public SelectClause Select { get { return SqlQuery.Select; } } + public FromClause From { get { return SqlQuery.From; } } + public WhereClause Where { get { return SqlQuery.Where; } } + public GroupByClause GroupBy { get { return SqlQuery.GroupBy; } } + public WhereClause Having { get { return SqlQuery.Having; } } + public OrderByClause OrderBy { get { return SqlQuery.OrderBy; } } + public SqlQuery End() { return SqlQuery; } + + protected internal SqlQuery SqlQuery { get; private set; } + + internal void SetSqlQuery(SqlQuery sqlQuery) + { + SqlQuery = sqlQuery; + } + } + + public abstract class ClauseBase : ConditionBase + where T1 : ClauseBase + { + protected ClauseBase(SqlQuery sqlQuery) + { + SqlQuery = sqlQuery; + } + + public SelectClause Select { get { return SqlQuery.Select; } } + public FromClause From { get { return SqlQuery.From; } } + public GroupByClause GroupBy { get { return SqlQuery.GroupBy; } } + public WhereClause Having { get { return SqlQuery.Having; } } + public OrderByClause OrderBy { get { return SqlQuery.OrderBy; } } + public SqlQuery End() { return SqlQuery; } + + protected internal SqlQuery SqlQuery { get; private set; } + + internal void SetSqlQuery(SqlQuery sqlQuery) + { + SqlQuery = sqlQuery; + } + } + + #endregion + + #region SelectClause + + public class SelectClause : ClauseBase, IQueryElement, ISqlExpressionWalkable + { + #region Init + + internal SelectClause(SqlQuery sqlQuery) : base(sqlQuery) + { + } + + internal SelectClause( + SqlQuery sqlQuery, + SelectClause clone, + Dictionary objectTree, + Predicate doClone) + : base(sqlQuery) + { + _columns.AddRange(clone._columns.ConvertAll(c => (Column)c.Clone(objectTree, doClone))); + + IsDistinct = clone.IsDistinct; + TakeValue = clone.TakeValue == null ? null : (ISqlExpression)clone.TakeValue.Clone(objectTree, doClone); + SkipValue = clone.SkipValue == null ? null : (ISqlExpression)clone.SkipValue.Clone(objectTree, doClone); + } + + internal SelectClause(bool isDistinct, ISqlExpression takeValue, ISqlExpression skipValue, IEnumerable columns) + : base(null) + { + IsDistinct = isDistinct; + TakeValue = takeValue; + SkipValue = skipValue; + + _columns.AddRange(columns); + } + + #endregion + + #region Columns + + public SelectClause Field(SqlField field) + { + AddOrGetColumn(new Column(SqlQuery, field)); + return this; + } + + public SelectClause Field(SqlField field, string alias) + { + AddOrGetColumn(new Column(SqlQuery, field, alias)); + return this; + } + + public SelectClause SubQuery(SqlQuery subQuery) + { + if (subQuery.ParentSql != null && subQuery.ParentSql != SqlQuery) + throw new ArgumentException("SqlQuery already used as subquery"); + + subQuery.ParentSql = SqlQuery; + + AddOrGetColumn(new Column(SqlQuery, subQuery)); + return this; + } + + public SelectClause SubQuery(SqlQuery sqlQuery, string alias) + { + if (sqlQuery.ParentSql != null && sqlQuery.ParentSql != SqlQuery) + throw new ArgumentException("SqlQuery already used as subquery"); + + sqlQuery.ParentSql = SqlQuery; + + AddOrGetColumn(new Column(SqlQuery, sqlQuery, alias)); + return this; + } + + public SelectClause Expr(ISqlExpression expr) + { + AddOrGetColumn(new Column(SqlQuery, expr)); + return this; + } + + public SelectClause Expr(ISqlExpression expr, string alias) + { + AddOrGetColumn(new Column(SqlQuery, expr, alias)); + return this; + } + + public SelectClause Expr(string expr, params ISqlExpression[] values) + { + AddOrGetColumn(new Column(SqlQuery, new SqlExpression(null, expr, values))); + return this; + } + + public SelectClause Expr(Type systemType, string expr, params ISqlExpression[] values) + { + AddOrGetColumn(new Column(SqlQuery, new SqlExpression(systemType, expr, values))); + return this; + } + + public SelectClause Expr(string expr, int priority, params ISqlExpression[] values) + { + AddOrGetColumn(new Column(SqlQuery, new SqlExpression(null, expr, priority, values))); + return this; + } + + public SelectClause Expr(Type systemType, string expr, int priority, params ISqlExpression[] values) + { + AddOrGetColumn(new Column(SqlQuery, new SqlExpression(systemType, expr, priority, values))); + return this; + } + + public SelectClause Expr(string alias, string expr, int priority, params ISqlExpression[] values) + { + AddOrGetColumn(new Column(SqlQuery, new SqlExpression(null, expr, priority, values))); + return this; + } + + public SelectClause Expr(Type systemType, string alias, string expr, int priority, params ISqlExpression[] values) + { + AddOrGetColumn(new Column(SqlQuery, new SqlExpression(systemType, expr, priority, values))); + return this; + } + + public SelectClause Expr(ISqlExpression expr1, string operation, ISqlExpression expr2) + { + AddOrGetColumn(new Column(SqlQuery, new SqlBinaryExpression(typeof(T), expr1, operation, expr2))); + return this; + } + + public SelectClause Expr(ISqlExpression expr1, string operation, ISqlExpression expr2, int priority) + { + AddOrGetColumn(new Column(SqlQuery, new SqlBinaryExpression(typeof(T), expr1, operation, expr2, priority))); + return this; + } + + public SelectClause Expr(string alias, ISqlExpression expr1, string operation, ISqlExpression expr2, int priority) + { + AddOrGetColumn(new Column(SqlQuery, new SqlBinaryExpression(typeof(T), expr1, operation, expr2, priority), alias)); + return this; + } + + public int Add(ISqlExpression expr) + { + if (expr is Column && ((Column)expr).Parent == SqlQuery) + throw new InvalidOperationException(); + + return Columns.IndexOf(AddOrGetColumn(new Column(SqlQuery, expr))); + } + + public int Add(ISqlExpression expr, string alias) + { + return Columns.IndexOf(AddOrGetColumn(new Column(SqlQuery, expr, alias))); + } + + Column AddOrGetColumn(Column col) + { + foreach (var c in Columns) + if (c.Equals(col)) + return col; + +#if DEBUG + + switch (col.Expression.ElementType) + { + case QueryElementType.SqlField : + { + var table = ((SqlField)col.Expression).Table; + + //if (SqlQuery.From.GetFromTables().Any(_ => _ == table)) + // throw new InvalidOperationException("Wrong field usage."); + + break; + } + + case QueryElementType.Column : + { + var query = ((Column)col.Expression).Parent; + + //if (!SqlQuery.From.GetFromQueries().Any(_ => _ == query)) + // throw new InvalidOperationException("Wrong column usage."); + + break; + } + + case QueryElementType.SqlQuery : + { + if (col.Expression == SqlQuery) + throw new InvalidOperationException("Wrong query usage."); + break; + } + } + +#endif + + Columns.Add(col); + + return col; + } + + readonly List _columns = new List(); + public List Columns + { + get { return _columns; } + } + + #endregion + + #region HasModifier + + public bool HasModifier + { + get { return IsDistinct || SkipValue != null || TakeValue != null; } + } + + #endregion + + #region Distinct + + public SelectClause Distinct + { + get { IsDistinct = true; return this; } + } + + public bool IsDistinct { get; set; } + + #endregion + + #region Take + + public SelectClause Take(int value) + { + TakeValue = new SqlValue(value); + return this; + } + + public SelectClause Take(ISqlExpression value) + { + TakeValue = value; + return this; + } + + public ISqlExpression TakeValue { get; set; } + + #endregion + + #region Skip + + public SelectClause Skip(int value) + { + SkipValue = new SqlValue(value); + return this; + } + + public SelectClause Skip(ISqlExpression value) + { + SkipValue = value; + return this; + } + + public ISqlExpression SkipValue { get; set; } + + #endregion + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + for (var i = 0; i < Columns.Count; i++) + { + var col = Columns[i]; +#pragma warning disable 0618 + var expr = col.Walk(skipColumns, func); +#pragma warning restore 0618 + + if (expr is Column) + Columns[i] = (Column)expr; + else + Columns[i] = new Column(col.Parent, expr, col.Alias); + } + + if (TakeValue != null) TakeValue = TakeValue.Walk(skipColumns, func); + if (SkipValue != null) SkipValue = SkipValue.Walk(skipColumns, func); + + return null; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.SelectClause; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + if (dic.ContainsKey(this)) + return sb.Append("..."); + + dic.Add(this, this); + + sb.Append("SELECT "); + + if (IsDistinct) sb.Append("DISTINCT "); + + if (SkipValue != null) + { + sb.Append("SKIP "); + SkipValue.ToString(sb, dic); + sb.Append(" "); + } + + if (TakeValue != null) + { + sb.Append("TAKE "); + TakeValue.ToString(sb, dic); + sb.Append(" "); + } + + sb.AppendLine(); + + if (Columns.Count == 0) + sb.Append("\t*, \n"); + else + foreach (var c in Columns) + { + sb.Append("\t"); + ((IQueryElement)c).ToString(sb, dic); + sb + .Append(" as ") + .Append(c.Alias ?? "c" + (Columns.IndexOf(c) + 1)) + .Append(", \n"); + } + + sb.Length -= 3; + + dic.Remove(this); + + return sb; + } + + #endregion + } + + private SelectClause _select; + public SelectClause Select + { + get { return _select; } + } + + #endregion + + #region InsertClause + + public class SetExpression : IQueryElement, ISqlExpressionWalkable, ICloneableElement + { + public SetExpression(ISqlExpression column, ISqlExpression expression) + { + Column = column; + Expression = expression; + + if (expression is SqlParameter) + { + var p = (SqlParameter)expression; + + //if (type.IsEnum) + // p.SetEnumConverter(type, mappingSchema); + + if (column is SqlField) + { + var field = (SqlField)column; + + if (field.MemberMapper != null) + { + if (field.MemberMapper.MapMemberInfo.IsDbTypeSet) + p.DbType = field.MemberMapper.MapMemberInfo.DbType; + + if (field.MemberMapper.MapMemberInfo.IsDbSizeSet) + p.DbSize = field.MemberMapper.MapMemberInfo.DbSize; + } + } + } + } + + public ISqlExpression Column { get; set; } + public ISqlExpression Expression { get; set; } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + { + objectTree.Add(this, clone = new SetExpression( + (ISqlExpression)Column. Clone(objectTree, doClone), + (ISqlExpression)Expression.Clone(objectTree, doClone))); + } + + return clone; + } + + #endregion + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + Column = Column. Walk(skipColumns, func); + Expression = Expression.Walk(skipColumns, func); + return null; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.SetExpression; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + Column.ToString(sb, dic); + sb.Append(" = "); + Expression.ToString(sb, dic); + + return sb; + } + + #endregion + } + + public class InsertClause : IQueryElement, ISqlExpressionWalkable, ICloneableElement + { + public InsertClause() + { + Items = new List(); + } + + public List Items { get; private set; } + public SqlTable Into { get; set; } + public bool WithIdentity { get; set; } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + var clone = new InsertClause { WithIdentity = WithIdentity }; + + if (Into != null) + clone.Into = (SqlTable)Into.Clone(objectTree, doClone); + + foreach (var item in Items) + clone.Items.Add((SetExpression)item.Clone(objectTree, doClone)); + + objectTree.Add(this, clone); + + return clone; + } + + #endregion + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + if (Into != null) + ((ISqlExpressionWalkable)Into).Walk(skipColumns, func); + + foreach (var t in Items) + ((ISqlExpressionWalkable)t).Walk(skipColumns, func); + + return null; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.InsertClause; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + sb.Append("VALUES "); + + if (Into != null) + ((IQueryElement)Into).ToString(sb, dic); + + sb.AppendLine(); + + foreach (var e in Items) + { + sb.Append("\t"); + ((IQueryElement)e).ToString(sb, dic); + sb.AppendLine(); + } + + return sb; + } + + #endregion + } + + private InsertClause _insert; + public InsertClause Insert + { + get { return _insert ?? (_insert = new InsertClause()); } + } + + public void ClearInsert() + { + _insert = null; + } + + #endregion + + #region UpdateClause + + public class UpdateClause : IQueryElement, ISqlExpressionWalkable, ICloneableElement + { + public UpdateClause() + { + Items = new List(); + Keys = new List(); + } + + public List Items { get; private set; } + public List Keys { get; private set; } + public SqlTable Table { get; set; } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + var clone = new UpdateClause(); + + if (Table != null) + clone.Table = (SqlTable)Table.Clone(objectTree, doClone); + + foreach (var item in Items) + clone.Items.Add((SetExpression)item.Clone(objectTree, doClone)); + + foreach (var item in Keys) + clone.Keys.Add((SetExpression)item.Clone(objectTree, doClone)); + + objectTree.Add(this, clone); + + return clone; + } + + #endregion + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + if (Table != null) + ((ISqlExpressionWalkable)Table).Walk(skipColumns, func); + + foreach (var t in Items) + ((ISqlExpressionWalkable)t).Walk(skipColumns, func); + + foreach (var t in Keys) + ((ISqlExpressionWalkable)t).Walk(skipColumns, func); + + return null; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.UpdateClause; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + sb.Append("SET "); + + if (Table != null) + ((IQueryElement)Table).ToString(sb, dic); + + sb.AppendLine(); + + foreach (var e in Items) + { + sb.Append("\t"); + ((IQueryElement)e).ToString(sb, dic); + sb.AppendLine(); + } + + return sb; + } + + #endregion + } + + private UpdateClause _update; + public UpdateClause Update + { + get { return _update ?? (_update = new UpdateClause()); } + } + + public void ClearUpdate() + { + _update = null; + } + + #endregion + + #region DeleteClause + + public class DeleteClause : IQueryElement, ISqlExpressionWalkable, ICloneableElement + { + public SqlTable Table { get; set; } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + var clone = new DeleteClause(); + + if (Table != null) + clone.Table = (SqlTable)Table.Clone(objectTree, doClone); + + objectTree.Add(this, clone); + + return clone; + } + + #endregion + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + if (Table != null) + ((ISqlExpressionWalkable)Table).Walk(skipColumns, func); + + return null; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.DeleteClause; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + sb.Append("DELETE FROM "); + + if (Table != null) + ((IQueryElement)Table).ToString(sb, dic); + + sb.AppendLine(); + + return sb; + } + + #endregion + } + + private DeleteClause _delete; + public DeleteClause Delete + { + get { return _delete ?? (_delete = new DeleteClause()); } + } + + public void ClearDelete() + { + _delete = null; + } + + #endregion + + #region FromClause + + public class FromClause : ClauseBase, IQueryElement, ISqlExpressionWalkable + { + #region Join + + public class Join : ConditionBase + { + public class Next + { + internal Next(Join parent) + { + _parent = parent; + } + + readonly Join _parent; + + public Join Or { get { return _parent.SetOr(true); } } + public Join And { get { return _parent.SetOr(false); } } + + public static implicit operator Join(Next next) + { + return next._parent; + } + } + + protected override SearchCondition Search + { + get { return JoinedTable.Condition; } + } + + protected override Next GetNext() + { + return new Next(this); + } + + internal Join(JoinType joinType, ISqlTableSource table, string alias, bool isWeak, ICollection joins) + { + JoinedTable = new JoinedTable(joinType, table, alias, isWeak); + + if (joins != null && joins.Count > 0) + foreach (var join in joins) + JoinedTable.Table.Joins.Add(join.JoinedTable); + } + + public JoinedTable JoinedTable { get; private set; } + } + + #endregion + + internal FromClause(SqlQuery sqlQuery) : base(sqlQuery) + { + } + + internal FromClause( + SqlQuery sqlQuery, + FromClause clone, + Dictionary objectTree, + Predicate doClone) + : base(sqlQuery) + { + _tables.AddRange(clone._tables.ConvertAll(ts => (TableSource)ts.Clone(objectTree, doClone))); + } + + internal FromClause(IEnumerable tables) + : base(null) + { + _tables.AddRange(tables); + } + + public FromClause Table(ISqlTableSource table, params FJoin[] joins) + { + return Table(table, null, joins); + } + + public FromClause Table(ISqlTableSource table, string alias, params FJoin[] joins) + { + var ts = AddOrGetTable(table, alias); + + if (joins != null && joins.Length > 0) + foreach (var join in joins) + ts.Joins.Add(join.JoinedTable); + + return this; + } + + TableSource GetTable(ISqlTableSource table, string alias) + { + foreach (var ts in Tables) + if (ts.Source == table) + if (alias == null || ts.Alias == alias) + return ts; + else + throw new ArgumentException("alias"); + + return null; + } + + TableSource AddOrGetTable(ISqlTableSource table, string alias) + { + var ts = GetTable(table, alias); + + if (ts != null) + return ts; + + var t = new TableSource(table, alias); + + Tables.Add(t); + + return t; + } + + public TableSource this[ISqlTableSource table] + { + get { return this[table, null]; } + } + + public TableSource this[ISqlTableSource table, string alias] + { + get + { + foreach (var ts in Tables) + { + var t = CheckTableSource(ts, table, alias); + + if (t != null) + return t; + } + + return null; + } + } + + public bool IsChild(ISqlTableSource table) + { + foreach (var ts in Tables) + if (ts.Source == table || CheckChild(ts.Joins, table)) + return true; + return false; + } + + static bool CheckChild(IEnumerable joins, ISqlTableSource table) + { + foreach (var j in joins) + if (j.Table.Source == table || CheckChild(j.Table.Joins, table)) + return true; + return false; + } + + readonly List _tables = new List(); + public List Tables + { + get { return _tables; } + } + + static IEnumerable GetJoinTables(TableSource source, QueryElementType elementType) + { + if (source.Source.ElementType == elementType) + yield return source.Source; + + foreach (var join in source.Joins) + foreach (var table in GetJoinTables(join.Table, elementType)) + yield return table; + } + + internal IEnumerable GetFromTables() + { + return Tables.SelectMany(_ => GetJoinTables(_, QueryElementType.SqlTable)); + } + + internal IEnumerable GetFromQueries() + { + return Tables.SelectMany(_ => GetJoinTables(_, QueryElementType.SqlQuery)); + } + + static TableSource FindTableSource(TableSource source, SqlTable table) + { + if (source.Source == table) + return source; + + foreach (var join in source.Joins) + { + var ts = FindTableSource(join.Table, table); + if (ts != null) + return ts; + } + + return null; + } + + public ISqlTableSource FindTableSource(SqlTable table) + { + foreach (var source in Tables) + { + var ts = FindTableSource(source, table); + if (ts != null) + return ts; + } + + return null; + } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + for (var i = 0; i < Tables.Count; i++) + ((ISqlExpressionWalkable)Tables[i]).Walk(skipColumns, func); + + return null; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.FromClause; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + sb.Append(" \nFROM \n"); + + if (Tables.Count > 0) + { + foreach (IQueryElement ts in Tables) + { + sb.Append('\t'); + var len = sb.Length; + ts.ToString(sb, dic).Replace("\n", "\n\t", len, sb.Length - len); + sb.Append(", "); + } + + sb.Length -= 2; + } + + return sb; + } + + #endregion + } + + public static FJoin InnerJoin (ISqlTableSource table, params FJoin[] joins) { return new FJoin(JoinType.Inner, table, null, false, joins); } + public static FJoin InnerJoin (ISqlTableSource table, string alias, params FJoin[] joins) { return new FJoin(JoinType.Inner, table, alias, false, joins); } + public static FJoin LeftJoin (ISqlTableSource table, params FJoin[] joins) { return new FJoin(JoinType.Left, table, null, false, joins); } + public static FJoin LeftJoin (ISqlTableSource table, string alias, params FJoin[] joins) { return new FJoin(JoinType.Left, table, alias, false, joins); } + public static FJoin Join (ISqlTableSource table, params FJoin[] joins) { return new FJoin(JoinType.Auto, table, null, false, joins); } + public static FJoin Join (ISqlTableSource table, string alias, params FJoin[] joins) { return new FJoin(JoinType.Auto, table, alias, false, joins); } + public static FJoin CrossApply (ISqlTableSource table, params FJoin[] joins) { return new FJoin(JoinType.CrossApply, table, null, false, joins); } + public static FJoin CrossApply (ISqlTableSource table, string alias, params FJoin[] joins) { return new FJoin(JoinType.CrossApply, table, alias, false, joins); } + public static FJoin OuterApply (ISqlTableSource table, params FJoin[] joins) { return new FJoin(JoinType.OuterApply, table, null, false, joins); } + public static FJoin OuterApply (ISqlTableSource table, string alias, params FJoin[] joins) { return new FJoin(JoinType.OuterApply, table, alias, false, joins); } + + public static FJoin WeakInnerJoin(ISqlTableSource table, params FJoin[] joins) { return new FJoin(JoinType.Inner, table, null, true, joins); } + public static FJoin WeakInnerJoin(ISqlTableSource table, string alias, params FJoin[] joins) { return new FJoin(JoinType.Inner, table, alias, true, joins); } + public static FJoin WeakLeftJoin (ISqlTableSource table, params FJoin[] joins) { return new FJoin(JoinType.Left, table, null, true, joins); } + public static FJoin WeakLeftJoin (ISqlTableSource table, string alias, params FJoin[] joins) { return new FJoin(JoinType.Left, table, alias, true, joins); } + public static FJoin WeakJoin (ISqlTableSource table, params FJoin[] joins) { return new FJoin(JoinType.Auto, table, null, true, joins); } + public static FJoin WeakJoin (ISqlTableSource table, string alias, params FJoin[] joins) { return new FJoin(JoinType.Auto, table, alias, true, joins); } + + private FromClause _from; + public FromClause From + { + get { return _from; } + } + + #endregion + + #region WhereClause + + public class WhereClause : ClauseBase, IQueryElement, ISqlExpressionWalkable + { + public class Next : ClauseBase + { + internal Next(WhereClause parent) : base(parent.SqlQuery) + { + _parent = parent; + } + + readonly WhereClause _parent; + + public WhereClause Or { get { return _parent.SetOr(true); } } + public WhereClause And { get { return _parent.SetOr(false); } } + } + + internal WhereClause(SqlQuery sqlQuery) : base(sqlQuery) + { + SearchCondition = new SearchCondition(); + } + + internal WhereClause( + SqlQuery sqlQuery, + WhereClause clone, + Dictionary objectTree, + Predicate doClone) + : base(sqlQuery) + { + SearchCondition = (SearchCondition)clone.SearchCondition.Clone(objectTree, doClone); + } + + internal WhereClause(SearchCondition searchCondition) : base(null) + { + SearchCondition = searchCondition; + } + + public SearchCondition SearchCondition { get; private set; } + + public bool IsEmpty + { + get { return SearchCondition.Conditions.Count == 0; } + } + + protected override SearchCondition Search + { + get { return SearchCondition; } + } + + protected override Next GetNext() + { + return new Next(this); + } + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func action) + { + SearchCondition = (SearchCondition)((ISqlExpressionWalkable)SearchCondition).Walk(skipColumns, action); + return null; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType + { + get { return QueryElementType.WhereClause; } + } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + if (Search.Conditions.Count == 0) + return sb; + + sb.Append("\nWHERE\n\t"); + return ((IQueryElement)Search).ToString(sb, dic); + } + + #endregion + } + + private WhereClause _where; + public WhereClause Where + { + get { return _where; } + } + + #endregion + + #region GroupByClause + + public class GroupByClause : ClauseBase, IQueryElement, ISqlExpressionWalkable + { + internal GroupByClause(SqlQuery sqlQuery) : base(sqlQuery) + { + } + + internal GroupByClause( + SqlQuery sqlQuery, + GroupByClause clone, + Dictionary objectTree, + Predicate doClone) + : base(sqlQuery) + { + _items.AddRange(clone._items.ConvertAll(e => (ISqlExpression)e.Clone(objectTree, doClone))); + } + + internal GroupByClause(IEnumerable items) : base(null) + { + _items.AddRange(items); + } + + public GroupByClause Expr(ISqlExpression expr) + { + Add(expr); + return this; + } + + public GroupByClause Field(SqlField field) + { + return Expr(field); + } + + void Add(ISqlExpression expr) + { + foreach (var e in Items) + if (e.Equals(expr)) + return; + + Items.Add(expr); + } + + readonly List _items = new List(); + public List Items + { + get { return _items; } + } + + public bool IsEmpty + { + get { return Items.Count == 0; } + } + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + for (var i = 0; i < Items.Count; i++) + Items[i] = Items[i].Walk(skipColumns, func); + + return null; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.GroupByClause; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + if (Items.Count == 0) + return sb; + + sb.Append(" \nGROUP BY \n"); + + foreach (var item in Items) + { + sb.Append('\t'); + item.ToString(sb, dic); + sb.Append(","); + } + + sb.Length--; + + return sb; + } + + #endregion + } + + private GroupByClause _groupBy; + public GroupByClause GroupBy + { + get { return _groupBy; } + } + + #endregion + + #region HavingClause + + private WhereClause _having; + public WhereClause Having + { + get { return _having; } + } + + #endregion + + #region OrderByClause + + public class OrderByClause : ClauseBase, IQueryElement, ISqlExpressionWalkable + { + internal OrderByClause(SqlQuery sqlQuery) : base(sqlQuery) + { + } + + internal OrderByClause( + SqlQuery sqlQuery, + OrderByClause clone, + Dictionary objectTree, + Predicate doClone) + : base(sqlQuery) + { + _items.AddRange(clone._items.ConvertAll(item => (OrderByItem)item.Clone(objectTree, doClone))); + } + + internal OrderByClause(IEnumerable items) : base(null) + { + _items.AddRange(items); + } + + public OrderByClause Expr(ISqlExpression expr, bool isDescending) + { + Add(expr, isDescending); + return this; + } + + public OrderByClause Expr (ISqlExpression expr) { return Expr(expr, false); } + public OrderByClause ExprAsc (ISqlExpression expr) { return Expr(expr, false); } + public OrderByClause ExprDesc (ISqlExpression expr) { return Expr(expr, true); } + public OrderByClause Field (SqlField field, bool isDescending) { return Expr(field, isDescending); } + public OrderByClause Field (SqlField field) { return Expr(field, false); } + public OrderByClause FieldAsc (SqlField field) { return Expr(field, false); } + public OrderByClause FieldDesc(SqlField field) { return Expr(field, true); } + + void Add(ISqlExpression expr, bool isDescending) + { + foreach (var item in Items) + if (item.Expression.Equals(expr, (x, y) => + { + var col = x as Column; + return col == null || !col.Parent.HasUnion || x == y; + })) + return; + + Items.Add(new OrderByItem(expr, isDescending)); + } + + readonly List _items = new List(); + public List Items + { + get { return _items; } + } + + public bool IsEmpty + { + get { return Items.Count == 0; } + } + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { +#pragma warning disable 0618 + foreach (var t in Items) + t.Walk(skipColumns, func); +#pragma warning restore 0618 + return null; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.OrderByClause; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + if (Items.Count == 0) + return sb; + + sb.Append(" \nORDER BY \n"); + + foreach (IQueryElement item in Items) + { + sb.Append('\t'); + item.ToString(sb, dic); + sb.Append(", "); + } + + sb.Length -= 2; + + return sb; + } + + #endregion + } + + private OrderByClause _orderBy; + public OrderByClause OrderBy + { + get { return _orderBy; } + } + + #endregion + + #region Union + + public class Union : IQueryElement + { + public Union() + { + } + + public Union(SqlQuery sqlQuery, bool isAll) + { + SqlQuery = sqlQuery; + IsAll = isAll; + } + + public SqlQuery SqlQuery { get; private set; } + public bool IsAll { get; private set; } + + public QueryElementType ElementType + { + get { return QueryElementType.Union; } + } + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + sb.Append(" \nUNION").Append(IsAll ? " ALL" : "").Append(" \n"); + return ((IQueryElement)SqlQuery).ToString(sb, dic); + } + } + + private List _unions; + public List Unions + { + get { return _unions ?? (_unions = new List()); } + } + + public bool HasUnion { get { return _unions != null && _unions.Count > 0; } } + + public void AddUnion(SqlQuery union, bool isAll) + { + Unions.Add(new Union(union, isAll)); + } + + #endregion + + #region FinalizeAndValidate + + public void FinalizeAndValidate(bool isApplySupported, bool optimizeColumns) + { +#if DEBUG + var sqlText = SqlText; + + var dic = new Dictionary(); + + new QueryVisitor().VisitAll(this, e => + { + var sql = e as SqlQuery; + + if (sql != null) + { + if (dic.ContainsKey(sql)) + throw new InvalidOperationException("SqlQuery circle reference detected."); + + dic.Add(sql, sql); + } + }); +#endif + + OptimizeUnions(); + FinalizeAndValidateInternal(isApplySupported, optimizeColumns, true, new List()); + ResolveFields(); + SetAliases(); + +#if DEBUG + sqlText = SqlText; +#endif + } + + class QueryData + { + public SqlQuery Query; + public List Fields = new List(); + public List Queries = new List(); + } + + void ResolveFields() + { + var root = GetQueryData(); + + ResolveFields(root); + } + + QueryData GetQueryData() + { + var data = new QueryData { Query = this }; + + new QueryVisitor().VisitParentFirst(this, e => + { + switch (e.ElementType) + { + case QueryElementType.SqlField : + { + var field = (SqlField)e; + + if (field.Name.Length != 1 || field.Name[0] != '*') + data.Fields.Add(field); + + break; + } + + case QueryElementType.SqlQuery : + { + if (e != this) + { + data.Queries.Add(((SqlQuery)e).GetQueryData()); + return false; + } + + break; + } + + case QueryElementType.Column : + return ((Column)e).Parent == this; + + case QueryElementType.SqlTable : + return false; + } + + return true; + }); + + return data; + } + + static TableSource FindField(SqlField field, TableSource table) + { + if (field.Table == table.Source) + return table; + + foreach (var @join in table.Joins) + { + var t = FindField(field, @join.Table); + + if (t != null) + return @join.Table; + } + + return null; + } + + static ISqlExpression GetColumn(QueryData data, SqlField field) + { + foreach (var query in data.Queries) + { + var q = query.Query; + + foreach (var table in q.From.Tables) + { + var t = FindField(field, table); + + if (t != null) + { + var n = q.Select.Columns.Count; + var idx = q.Select.Add(field); + + if (n != q.Select.Columns.Count) + if (!q.GroupBy.IsEmpty || q.Select.Columns.Exists(c => IsAggregationFunction(c.Expression))) + q.GroupBy.Items.Add(field); + + return q.Select.Columns[idx]; + } + } + } + + return null; + } + + static void ResolveFields(QueryData data) + { + if (data.Queries.Count == 0) + return; + + var dic = new Dictionary(); + + foreach (SqlField field in data.Fields) + { + if (dic.ContainsKey(field)) + continue; + + var found = false; + + foreach (var table in data.Query.From.Tables) + { + found = FindField(field, table) != null; + + if (found) + break; + } + + if (!found) + { + var expr = GetColumn(data, field); + + if (expr != null) + dic.Add(field, expr); + } + } + + if (dic.Count > 0) + new QueryVisitor().VisitParentFirst(data.Query, e => + { + ISqlExpression ex; + + switch (e.ElementType) + { + case QueryElementType.SqlQuery : + return e == data.Query; + + case QueryElementType.SqlFunction : + { + var parms = ((SqlFunction)e).Parameters; + + for (var i = 0; i < parms.Length; i++) + if (dic.TryGetValue(parms[i], out ex)) + parms[i] = ex; + + break; + } + + case QueryElementType.SqlExpression : + { + var parms = ((SqlExpression)e).Parameters; + + for (var i = 0; i < parms.Length; i++) + if (dic.TryGetValue(parms[i], out ex)) + parms[i] = ex; + + break; + } + + case QueryElementType.SqlBinaryExpression : + { + var expr = (SqlBinaryExpression)e; + if (dic.TryGetValue(expr.Expr1, out ex)) expr.Expr1 = ex; + if (dic.TryGetValue(expr.Expr2, out ex)) expr.Expr2 = ex; + break; + } + + case QueryElementType.ExprPredicate : + case QueryElementType.NotExprPredicate : + case QueryElementType.IsNullPredicate : + case QueryElementType.InSubQueryPredicate : + { + var expr = (Predicate.Expr)e; + if (dic.TryGetValue(expr.Expr1, out ex)) expr.Expr1 = ex; + break; + } + + case QueryElementType.ExprExprPredicate : + { + var expr = (Predicate.ExprExpr)e; + if (dic.TryGetValue(expr.Expr1, out ex)) expr.Expr1 = ex; + if (dic.TryGetValue(expr.Expr2, out ex)) expr.Expr2 = ex; + break; + } + + case QueryElementType.LikePredicate : + { + var expr = (Predicate.Like)e; + if (dic.TryGetValue(expr.Expr1, out ex)) expr.Expr1 = ex; + if (dic.TryGetValue(expr.Expr2, out ex)) expr.Expr2 = ex; + if (dic.TryGetValue(expr.Escape, out ex)) expr.Escape = ex; + break; + } + + case QueryElementType.BetweenPredicate : + { + var expr = (Predicate.Between)e; + if (dic.TryGetValue(expr.Expr1, out ex)) expr.Expr1 = ex; + if (dic.TryGetValue(expr.Expr2, out ex)) expr.Expr2 = ex; + if (dic.TryGetValue(expr.Expr3, out ex)) expr.Expr3 = ex; + break; + } + + case QueryElementType.InListPredicate : + { + var expr = (Predicate.InList)e; + + if (dic.TryGetValue(expr.Expr1, out ex)) expr.Expr1 = ex; + + for (var i = 0; i < expr.Values.Count; i++) + if (dic.TryGetValue(expr.Values[i], out ex)) + expr.Values[i] = ex; + + break; + } + + case QueryElementType.Column : + { + var expr = (Column)e; + + if (expr.Parent != data.Query) + return false; + + if (dic.TryGetValue(expr.Expression, out ex)) expr.Expression = ex; + + break; + } + + case QueryElementType.SetExpression : + { + var expr = (SetExpression)e; + if (dic.TryGetValue(expr.Expression, out ex)) expr.Expression = ex; + break; + } + + case QueryElementType.GroupByClause : + { + var expr = (GroupByClause)e; + + for (var i = 0; i < expr.Items.Count; i++) + if (dic.TryGetValue(expr.Items[i], out ex)) + expr.Items[i] = ex; + + break; + } + + case QueryElementType.OrderByItem : + { + var expr = (OrderByItem)e; + if (dic.TryGetValue(expr.Expression, out ex)) expr.Expression = ex; + break; + } + } + + return true; + }); + + foreach (var query in data.Queries) + if (query.Queries.Count > 0) + ResolveFields(query); + } + + void OptimizeUnions() + { + var exprs = new Dictionary(); + + new QueryVisitor().Visit(this, e => + { + var sql = e as SqlQuery; + + if (sql == null || sql.From.Tables.Count != 1 || !sql.IsSimple || sql._insert != null || sql._update != null || sql._delete != null) + return; + + var table = sql.From.Tables[0]; + + if (table.Joins.Count != 0 || !(table.Source is SqlQuery)) + return; + + var union = (SqlQuery)table.Source; + + if (!union.HasUnion) + return; + + for (var i = 0; i < sql.Select.Columns.Count; i++) + { + var scol = sql. Select.Columns[i]; + var ucol = union.Select.Columns[i]; + + if (scol.Expression != ucol) + return; + } + + exprs.Add(union, sql); + + for (var i = 0; i < sql.Select.Columns.Count; i++) + { + var scol = sql. Select.Columns[i]; + var ucol = union.Select.Columns[i]; + + scol.Expression = ucol.Expression; + scol._alias = ucol._alias; + + exprs.Add(ucol, scol); + } + + for (var i = sql.Select.Columns.Count; i < union.Select.Columns.Count; i++) + sql.Select.Expr(union.Select.Columns[i].Expression); + + sql.From.Tables.Clear(); + sql.From.Tables.AddRange(union.From.Tables); + + sql.Where. SearchCondition.Conditions.AddRange(union.Where. SearchCondition.Conditions); + sql.Having. SearchCondition.Conditions.AddRange(union.Having.SearchCondition.Conditions); + sql.GroupBy.Items. AddRange(union.GroupBy.Items); + sql.OrderBy.Items. AddRange(union.OrderBy.Items); + sql.Unions.InsertRange(0, union.Unions); + }); + + ((ISqlExpressionWalkable)this).Walk(false, expr => + { + ISqlExpression e; + + if (exprs.TryGetValue(expr, out e)) + return e; + + return expr; + }); + } + + void FinalizeAndValidateInternal(bool isApplySupported, bool optimizeColumns, bool optimizeSearchCondition, List tables) + { + OptimizeSearchCondition(Where. SearchCondition); + OptimizeSearchCondition(Having.SearchCondition); + + if (optimizeSearchCondition) + { + ForEachTable(table => + { + foreach (var join in table.Joins) + OptimizeSearchCondition(join.Condition); + }, new HashSet()); + } + + new QueryVisitor().Visit(this, e => + { + var sql = e as SqlQuery; + + if (sql != null && sql != this) + { + sql.ParentSql = this; + sql.FinalizeAndValidateInternal(isApplySupported, optimizeColumns, false, tables); + + if (sql.IsParameterDependent) + IsParameterDependent = true; + } + }); + + ResolveWeakJoins(tables); + OptimizeColumns(); + OptimizeApplies (isApplySupported, optimizeColumns); + OptimizeSubQueries(isApplySupported, optimizeColumns); + OptimizeApplies (isApplySupported, optimizeColumns); + + new QueryVisitor().Visit(this, e => + { + var sql = e as SqlQuery; + + if (sql != null && sql != this) + sql.RemoveOrderBy(); + }); + } + + internal static void OptimizeSearchCondition(SearchCondition searchCondition) + { + // This 'if' could be replaced by one simple match: + // + // match (searchCondition.Conditions) + // { + // | [SearchCondition(true, _) sc] => + // searchCondition.Conditions = sc.Conditions; + // OptimizeSearchCondition(searchCodition) + // + // | [SearchCondition(false, [SearchCondition(true, [ExprExpr]) sc])] => ... + // + // | [Expr(true, SqlValue(true))] + // | [Expr(false, SqlValue(false))] + // searchCondition.Conditions = [] + // } + // + // One day I am going to rewrite all this crap in Nemerle. + // + if (searchCondition.Conditions.Count == 1) + { + var cond = searchCondition.Conditions[0]; + + if (cond.Predicate is SearchCondition) + { + var sc = (SearchCondition)cond.Predicate; + + if (!cond.IsNot) + { + searchCondition.Conditions.Clear(); + searchCondition.Conditions.AddRange(sc.Conditions); + + OptimizeSearchCondition(searchCondition); + return; + } + + if (sc.Conditions.Count == 1) + { + var c1 = sc.Conditions[0]; + + if (!c1.IsNot && c1.Predicate is Predicate.ExprExpr) + { + var ee = (Predicate.ExprExpr)c1.Predicate; + Predicate.Operator op; + + switch (ee.Operator) + { + case Predicate.Operator.Equal : op = Predicate.Operator.NotEqual; break; + case Predicate.Operator.NotEqual : op = Predicate.Operator.Equal; break; + case Predicate.Operator.Greater : op = Predicate.Operator.LessOrEqual; break; + case Predicate.Operator.NotLess : + case Predicate.Operator.GreaterOrEqual : op = Predicate.Operator.Less; break; + case Predicate.Operator.Less : op = Predicate.Operator.GreaterOrEqual; break; + case Predicate.Operator.NotGreater : + case Predicate.Operator.LessOrEqual : op = Predicate.Operator.Greater; break; + default: throw new InvalidOperationException(); + } + + c1.Predicate = new Predicate.ExprExpr(ee.Expr1, op, ee.Expr2); + + searchCondition.Conditions.Clear(); + searchCondition.Conditions.AddRange(sc.Conditions); + + OptimizeSearchCondition(searchCondition); + return; + } + } + } + + if (cond.Predicate.ElementType == QueryElementType.ExprPredicate) + { + var expr = (Predicate.Expr)cond.Predicate; + + if (expr.Expr1 is SqlValue) + { + var value = (SqlValue)expr.Expr1; + + if (value.Value is bool) + if (cond.IsNot ? !(bool)value.Value : (bool)value.Value) + searchCondition.Conditions.Clear(); + } + } + } + + for (var i = 0; i < searchCondition.Conditions.Count; i++) + { + var cond = searchCondition.Conditions[i]; + + if (cond.Predicate is Predicate.Expr) + { + var expr = (Predicate.Expr)cond.Predicate; + + if (expr.Expr1 is SqlValue) + { + var value = (SqlValue)expr.Expr1; + + if (value.Value is bool) + { + if (cond.IsNot ? !(bool)value.Value : (bool)value.Value) + { + if (i > 0) + { + if (searchCondition.Conditions[i-1].IsOr) + { + searchCondition.Conditions.RemoveRange(0, i); + OptimizeSearchCondition(searchCondition); + + break; + } + } + } + } + } + } + else if (cond.Predicate is SearchCondition) + { + var sc = (SearchCondition)cond.Predicate; + OptimizeSearchCondition(sc); + } + } + } + + void ForEachTable(Action action, HashSet visitedQueries) + { + if (!visitedQueries.Add(this)) + return; + + foreach (var table in From.Tables) + table.ForEach(action, visitedQueries); + + new QueryVisitor().Visit(this, e => + { + if (e is SqlQuery && e != this) + ((SqlQuery)e).ForEachTable(action, visitedQueries); + }); + } + + void RemoveOrderBy() + { + if (OrderBy.Items.Count > 0 && Select.SkipValue == null && Select.TakeValue == null) + OrderBy.Items.Clear(); + } + + internal void ResolveWeakJoins(List tables) + { + Func findTable = null; findTable = table => + { + if (tables.Contains(table.Source)) + return true; + + foreach (var join in table.Joins) + { + if (findTable(join.Table)) + { + join.IsWeak = false; + return true; + } + } + + if (table.Source is SqlQuery) + foreach (var t in ((SqlQuery)table.Source).From.Tables) + if (findTable(t)) + return true; + + return false; + }; + + var areTablesCollected = false; + + ForEachTable(table => + { + for (var i = 0; i < table.Joins.Count; i++) + { + var join = table.Joins[i]; + + if (join.IsWeak) + { + if (!areTablesCollected) + { + areTablesCollected = true; + + Action tableCollector = expr => + { + var field = expr as SqlField; + + if (field != null && !tables.Contains(field.Table)) + tables.Add(field.Table); + }; + + var visitor = new QueryVisitor(); + + visitor.VisitAll(Select, tableCollector); + visitor.VisitAll(Where, tableCollector); + visitor.VisitAll(GroupBy, tableCollector); + visitor.VisitAll(Having, tableCollector); + visitor.VisitAll(OrderBy, tableCollector); + + if (_insert != null) + visitor.VisitAll(Insert, tableCollector); + + if (_update != null) + visitor.VisitAll(Update, tableCollector); + + if (_delete != null) + visitor.VisitAll(Delete, tableCollector); + + visitor.VisitAll(From, expr => + { + var tbl = expr as SqlTable; + + if (tbl != null && tbl.TableArguments != null) + { + var v = new QueryVisitor(); + + foreach (var arg in tbl.TableArguments) + v.VisitAll(arg, tableCollector); + } + }); + } + + if (findTable(join.Table)) + { + join.IsWeak = false; + } + else + { + table.Joins.RemoveAt(i); + i--; + } + } + } + }, new HashSet()); + } + + TableSource OptimizeSubQuery( + TableSource source, + bool optimizeWhere, + bool allColumns, + bool isApplySupported, + bool optimizeValues, + bool optimizeColumns) + { + foreach (var jt in source.Joins) + { + var table = OptimizeSubQuery( + jt.Table, + jt.JoinType == JoinType.Inner || jt.JoinType == JoinType.CrossApply, + false, + isApplySupported, + jt.JoinType == JoinType.Inner || jt.JoinType == JoinType.CrossApply, + optimizeColumns); + + if (table != jt.Table) + { + var sql = jt.Table.Source as SqlQuery; + + if (sql != null && sql.OrderBy.Items.Count > 0) + foreach (var item in sql.OrderBy.Items) + OrderBy.Expr(item.Expression, item.IsDescending); + + jt.Table = table; + } + } + + return source.Source is SqlQuery ? + RemoveSubQuery(source, optimizeWhere, allColumns && !isApplySupported, optimizeValues, optimizeColumns) : + source; + } + + static bool CheckColumn(Column column, ISqlExpression expr, SqlQuery query, bool optimizeValues, bool optimizeColumns) + { + if (expr is SqlField || expr is Column) + return false; + + if (expr is SqlValue) + return !optimizeValues && 1.Equals(((SqlValue)expr).Value); + + if (expr is SqlBinaryExpression) + { + var e = (SqlBinaryExpression)expr; + + if (e.Operation == "*" && e.Expr1 is SqlValue) + { + var value = (SqlValue)e.Expr1; + + if (value.Value is int && (int)value.Value == -1) + return CheckColumn(column, e.Expr2, query, optimizeValues, optimizeColumns); + } + } + + var visitor = new QueryVisitor(); + + if (optimizeColumns && + visitor.Find(expr, e => e is SqlQuery || IsAggregationFunction(e)) == null) + { + var n = 0; + var q = query.ParentSql ?? query; + + visitor.VisitAll(q, e => { if (e == column) n++; }); + + return n > 2; + } + + return true; + } + + TableSource RemoveSubQuery( + TableSource childSource, + bool concatWhere, + bool allColumns, + bool optimizeValues, + bool optimizeColumns) + { + var query = (SqlQuery)childSource.Source; + + var isQueryOK = query.From.Tables.Count == 1; + + isQueryOK = isQueryOK && (concatWhere || query.Where.IsEmpty && query.Having.IsEmpty); + isQueryOK = isQueryOK && !query.HasUnion && query.GroupBy.IsEmpty && !query.Select.HasModifier; + + if (!isQueryOK) + return childSource; + + var isColumnsOK = + (allColumns && !query.Select.Columns.Exists(c => IsAggregationFunction(c.Expression))) || + !query.Select.Columns.Exists(c => CheckColumn(c, c.Expression, query, optimizeValues, optimizeColumns)); + + if (!isColumnsOK) + return childSource; + + var map = new Dictionary(query.Select.Columns.Count); + + foreach (var c in query.Select.Columns) + map.Add(c, c.Expression); + + var top = this; + + while (top.ParentSql != null) + top = top.ParentSql; + + ((ISqlExpressionWalkable)top).Walk(false, expr => + { + ISqlExpression fld; + return map.TryGetValue(expr, out fld) ? fld : expr; + }); + + new QueryVisitor().Visit(top, expr => + { + if (expr.ElementType == QueryElementType.InListPredicate) + { + var p = (Predicate.InList)expr; + + if (p.Expr1 == query) + p.Expr1 = query.From.Tables[0]; + } + }); + + query.From.Tables[0].Joins.AddRange(childSource.Joins); + + if (query.From.Tables[0].Alias == null) + query.From.Tables[0].Alias = childSource.Alias; + + if (!query.Where. IsEmpty) ConcatSearchCondition(Where, query.Where); + if (!query.Having.IsEmpty) ConcatSearchCondition(Having, query.Having); + + ((ISqlExpressionWalkable)top).Walk(false, expr => + { + if (expr is SqlQuery) + { + var sql = (SqlQuery)expr; + + if (sql.ParentSql == query) + sql.ParentSql = query.ParentSql ?? this; + } + + return expr; + }); + + return query.From.Tables[0]; + } + + static bool IsAggregationFunction(IQueryElement expr) + { + if (expr is SqlFunction) + switch (((SqlFunction)expr).Name) + { + case "Count" : + case "Average" : + case "Min" : + case "Max" : + case "Sum" : return true; + } + + return false; + } + + void OptimizeApply(TableSource tableSource, JoinedTable joinTable, bool isApplySupported, bool optimizeColumns) + { + var joinSource = joinTable.Table; + + foreach (var join in joinSource.Joins) + if (join.JoinType == JoinType.CrossApply || join.JoinType == JoinType.OuterApply) + OptimizeApply(joinSource, join, isApplySupported, optimizeColumns); + + if (isApplySupported && !joinTable.CanConvertApply) + return; + + if (joinSource.Source.ElementType == QueryElementType.SqlQuery) + { + var sql = (SqlQuery)joinSource.Source; + var isAgg = sql.Select.Columns.Exists(c => IsAggregationFunction(c.Expression)); + + if (isApplySupported && (isAgg || sql.Select.TakeValue != null || sql.Select.SkipValue != null)) + return; + + var searchCondition = new List(sql.Where.SearchCondition.Conditions); + + sql.Where.SearchCondition.Conditions.Clear(); + + if (!ContainsTable(tableSource.Source, sql)) + { + joinTable.JoinType = joinTable.JoinType == JoinType.CrossApply ? JoinType.Inner : JoinType.Left; + joinTable.Condition.Conditions.AddRange(searchCondition); + } + else + { + sql.Where.SearchCondition.Conditions.AddRange(searchCondition); + + var table = OptimizeSubQuery( + joinTable.Table, + joinTable.JoinType == JoinType.Inner || joinTable.JoinType == JoinType.CrossApply, + joinTable.JoinType == JoinType.CrossApply, + isApplySupported, + joinTable.JoinType == JoinType.Inner || joinTable.JoinType == JoinType.CrossApply, + optimizeColumns); + + if (table != joinTable.Table) + { + var q = joinTable.Table.Source as SqlQuery; + + if (q != null && q.OrderBy.Items.Count > 0) + foreach (var item in q.OrderBy.Items) + OrderBy.Expr(item.Expression, item.IsDescending); + + joinTable.Table = table; + + OptimizeApply(tableSource, joinTable, isApplySupported, optimizeColumns); + } + } + } + else + { + if (!ContainsTable(tableSource.Source, joinSource.Source)) + joinTable.JoinType = joinTable.JoinType == JoinType.CrossApply ? JoinType.Inner : JoinType.Left; + } + } + + static bool ContainsTable(ISqlTableSource table, IQueryElement sql) + { + return null != new QueryVisitor().Find(sql, e => + e == table || + e.ElementType == QueryElementType.SqlField && table == ((SqlField)e).Table || + e.ElementType == QueryElementType.Column && table == ((Column) e).Parent); + } + + static void ConcatSearchCondition(WhereClause where1, WhereClause where2) + { + if (where1.IsEmpty) + { + where1.SearchCondition.Conditions.AddRange(where2.SearchCondition.Conditions); + } + else + { + if (where1.SearchCondition.Precedence < Sql.Precedence.LogicalConjunction) + { + var sc1 = new SearchCondition(); + + sc1.Conditions.AddRange(where1.SearchCondition.Conditions); + + where1.SearchCondition.Conditions.Clear(); + where1.SearchCondition.Conditions.Add(new Condition(false, sc1)); + } + + if (where2.SearchCondition.Precedence < Sql.Precedence.LogicalConjunction) + { + var sc2 = new SearchCondition(); + + sc2.Conditions.AddRange(where2.SearchCondition.Conditions); + + where1.SearchCondition.Conditions.Add(new Condition(false, sc2)); + } + else + where1.SearchCondition.Conditions.AddRange(where2.SearchCondition.Conditions); + } + } + + void OptimizeSubQueries(bool isApplySupported, bool optimizeColumns) + { + for (var i = 0; i < From.Tables.Count; i++) + { + var table = OptimizeSubQuery(From.Tables[i], true, false, isApplySupported, true, optimizeColumns); + + if (table != From.Tables[i]) + { + var sql = From.Tables[i].Source as SqlQuery; + + if (!Select.Columns.All(c => IsAggregationFunction(c.Expression))) + if (sql != null && sql.OrderBy.Items.Count > 0) + foreach (var item in sql.OrderBy.Items) + OrderBy.Expr(item.Expression, item.IsDescending); + + From.Tables[i] = table; + } + } + } + + void OptimizeApplies(bool isApplySupported, bool optimizeColumns) + { + foreach (var table in From.Tables) + foreach (var join in table.Joins) + if (join.JoinType == JoinType.CrossApply || join.JoinType == JoinType.OuterApply) + OptimizeApply(table, join, isApplySupported, optimizeColumns); + } + + void OptimizeColumns() + { + ((ISqlExpressionWalkable)Select).Walk(false, expr => + { + var query = expr as SqlQuery; + + if (query != null && query.From.Tables.Count == 0 && query.Select.Columns.Count == 1) + { + new QueryVisitor().Visit(query.Select.Columns[0].Expression, e => + { + if (e.ElementType == QueryElementType.SqlQuery) + { + var q = (SqlQuery)e; + + if (q.ParentSql == query) + q.ParentSql = query.ParentSql; + } + }); + + return query.Select.Columns[0].Expression; + } + + return expr; + }); + } + + IDictionary _aliases; + + public void RemoveAlias(string alias) + { + if (_aliases != null) + { + alias = alias.ToUpper(); + if (_aliases.ContainsKey(alias)) + _aliases.Remove(alias); + } + } + + public string GetAlias(string desiredAlias, string defaultAlias) + { + if (_aliases == null) + _aliases = new Dictionary(); + + var alias = desiredAlias; + + if (string.IsNullOrEmpty(desiredAlias) || desiredAlias.Length > 30) + { + desiredAlias = defaultAlias; + alias = defaultAlias + "1"; + } + + for (var i = 1; ; i++) + { + var s = alias.ToUpper(); + + if (!_aliases.ContainsKey(s) && !_reservedWords.ContainsKey(s)) + { + _aliases.Add(s, s); + break; + } + + alias = desiredAlias + i; + } + + return alias; + } + + public string[] GetTempAliases(int n, string defaultAlias) + { + var aliases = new string[n]; + + for (var i = 0; i < aliases.Length; i++) + aliases[i] = GetAlias(defaultAlias, defaultAlias); + + foreach (var t in aliases) + RemoveAlias(t); + + return aliases; + } + + void SetAliases() + { + _aliases = null; + + var objs = new Dictionary(); + + Parameters.Clear(); + + new QueryVisitor().VisitAll(this, expr => + { + switch (expr.ElementType) + { + case QueryElementType.SqlParameter: + { + var p = (SqlParameter)expr; + + if (p.IsQueryParameter) + { + if (!objs.ContainsKey(expr)) + { + objs.Add(expr, expr); + p.Name = GetAlias(p.Name, "p"); + } + + Parameters.Add(p); + } + else + IsParameterDependent = true; + } + + break; + + case QueryElementType.Column: + { + if (!objs.ContainsKey(expr)) + { + objs.Add(expr, expr); + + var c = (Column)expr; + + if (c.Alias != "*") + c.Alias = GetAlias(c.Alias, "c"); + } + } + + break; + + case QueryElementType.TableSource: + { + var table = (TableSource)expr; + + if (!objs.ContainsKey(table)) + { + objs.Add(table, table); + table.Alias = GetAlias(table.Alias, "t"); + } + } + + break; + + case QueryElementType.SqlQuery: + { + var sql = (SqlQuery)expr; + + if (sql.HasUnion) + { + for (var i = 0; i < sql.Select.Columns.Count; i++) + { + var col = sql.Select.Columns[i]; + + foreach (var t in sql.Unions) + { + var union = t.SqlQuery.Select; + + objs.Remove(union.Columns[i].Alias); + + union.Columns[i].Alias = col.Alias; + } + } + } + } + + break; + } + }); + } + + #endregion + + #region ProcessParameters + + public SqlQuery ProcessParameters() + { + if (IsParameterDependent) + { + var query = new QueryVisitor().Convert(this, e => + { + switch (e.ElementType) + { + case QueryElementType.SqlParameter : + { + var p = (SqlParameter)e; + + if (p.Value == null) + return new SqlValue(null); + } + + break; + + case QueryElementType.ExprExprPredicate : + { + var ee = (Predicate.ExprExpr)e; + + if (ee.Operator == Predicate.Operator.Equal || ee.Operator == Predicate.Operator.NotEqual) + { + object value1; + object value2; + + if (ee.Expr1 is SqlValue) + value1 = ((SqlValue)ee.Expr1).Value; + else if (ee.Expr1 is SqlParameter) + value1 = ((SqlParameter)ee.Expr1).Value; + else + break; + + if (ee.Expr2 is SqlValue) + value2 = ((SqlValue)ee.Expr2).Value; + else if (ee.Expr2 is SqlParameter) + value2 = ((SqlParameter)ee.Expr2).Value; + else + break; + + var value = Equals(value1, value2); + + if (ee.Operator == Predicate.Operator.NotEqual) + value = !value; + + return new Predicate.Expr(new SqlValue(value), Sql.Precedence.Comparison); + } + } + + break; + + case QueryElementType.InListPredicate : + return ConvertInListPredicate((Predicate.InList)e); + } + + return null; + }); + + if (query != this) + { + query.Parameters.Clear(); + + new QueryVisitor().VisitAll(query, expr => + { + if (expr.ElementType == QueryElementType.SqlParameter) + { + var p = (SqlParameter)expr; + if (p.IsQueryParameter) + query.Parameters.Add(p); + } + }); + } + + return query; + } + + return this; + } + + static Predicate ConvertInListPredicate(Predicate.InList p) + { + if (p.Values == null || p.Values.Count == 0) + return new Predicate.Expr(new SqlValue(p.IsNot)); + + if (p.Values.Count == 1 && p.Values[0] is SqlParameter) + { + var pr = (SqlParameter)p.Values[0]; + + if (pr.Value == null) + return new Predicate.Expr(new SqlValue(p.IsNot)); + + if (pr.Value is IEnumerable) + { + if (p.Expr1 is ISqlTableSource) + { + var items = (IEnumerable)pr.Value; + var table = (ISqlTableSource)p.Expr1; + var keys = table.GetKeys(true); + + if (keys == null || keys.Count == 0) + throw new SqlException("Cant create IN expression."); + + if (keys.Count == 1) + { + var values = new List(); + var field = GetUnderlayingField(keys[0]); + + foreach (var item in items) + { + var value = field.MemberMapper.GetValue(item); + values.Add(new SqlValue(value)); + } + + if (values.Count == 0) + return new Predicate.Expr(new SqlValue(p.IsNot)); + + return new Predicate.InList(keys[0], p.IsNot, values); + } + + { + var sc = new SearchCondition(); + + foreach (var item in items) + { + var itemCond = new SearchCondition(); + + foreach (var key in keys) + { + var field = GetUnderlayingField(key); + var value = field.MemberMapper.GetValue(item); + var cond = value == null ? + new Condition(false, new Predicate.IsNull (field, false)) : + new Condition(false, new Predicate.ExprExpr(field, Predicate.Operator.Equal, new SqlValue(value))); + + itemCond.Conditions.Add(cond); + } + + sc.Conditions.Add(new Condition(false, new Predicate.Expr(itemCond), true)); + } + + if (sc.Conditions.Count == 0) + return new Predicate.Expr(new SqlValue(p.IsNot)); + + if (p.IsNot) + return new Predicate.NotExpr(sc, true, Sql.Precedence.LogicalNegation); + + return new Predicate.Expr(sc, Sql.Precedence.LogicalDisjunction); + } + } + + if (p.Expr1 is SqlExpression) + { + var expr = (SqlExpression)p.Expr1; + + if (expr.Expr.Length > 1 && expr.Expr[0] == '\x1') + { + var type = TypeHelper.GetListItemType(pr.Value); + var ta = TypeAccessor.GetAccessor(type); + var items = (IEnumerable)pr.Value; + var names = expr.Expr.Substring(1).Split(','); + + if (expr.Parameters.Length == 1) + { + var values = new List(); + + foreach (var item in items) + { + var value = ta[names[0]].GetValue(item); + values.Add(new SqlValue(value)); + } + + if (values.Count == 0) + return new Predicate.Expr(new SqlValue(p.IsNot)); + + return new Predicate.InList(expr.Parameters[0], p.IsNot, values); + } + + { + var sc = new SearchCondition(); + + foreach (var item in items) + { + var itemCond = new SearchCondition(); + + for (var i = 0; i < expr.Parameters.Length; i++) + { + var sql = expr.Parameters[i]; + var value = ta[names[i]].GetValue(item); + var cond = value == null ? + new Condition(false, new Predicate.IsNull (sql, false)) : + new Condition(false, new Predicate.ExprExpr(sql, Predicate.Operator.Equal, new SqlValue(value))); + + itemCond.Conditions.Add(cond); + } + + sc.Conditions.Add(new Condition(false, new Predicate.Expr(itemCond), true)); + } + + if (sc.Conditions.Count == 0) + return new Predicate.Expr(new SqlValue(p.IsNot)); + + if (p.IsNot) + return new Predicate.NotExpr(sc, true, Sql.Precedence.LogicalNegation); + + return new Predicate.Expr(sc, Sql.Precedence.LogicalDisjunction); + } + } + } + + /* + var itemType = items.GetType().GetItemType(); + + if (itemType == typeof(DateTime) || itemType == typeof(DateTimeOffset) || + itemType == typeof(DateTime?) || itemType == typeof(DateTimeOffset?)) + { + var list = new List(); + + foreach (var item in items) + list.Add(new SqlParameter(itemType, "p", item, (MappingSchema)null)); + + return new Predicate.InList(p.Expr1, p.IsNot, list); + } + */ + } + } + + return null; + } + + static SqlField GetUnderlayingField(ISqlExpression expr) + { + switch (expr.ElementType) + { + case QueryElementType.SqlField: return (SqlField)expr; + case QueryElementType.Column : return GetUnderlayingField(((Column)expr).Expression); + } + + throw new InvalidOperationException(); + } + + #endregion + + #region Clone + + SqlQuery(SqlQuery clone, Dictionary objectTree, Predicate doClone) + { + objectTree.Add(clone, this); + objectTree.Add(clone.All, All); + + SourceID = Interlocked.Increment(ref SourceIDCounter); + + _queryType = clone._queryType; + + if (IsInsert) _insert = (InsertClause)clone._insert.Clone(objectTree, doClone); + if (IsUpdate) _update = (UpdateClause)clone._update.Clone(objectTree, doClone); + if (IsDelete) _delete = (DeleteClause)clone._delete.Clone(objectTree, doClone); + + _select = new SelectClause (this, clone._select, objectTree, doClone); + _from = new FromClause (this, clone._from, objectTree, doClone); + _where = new WhereClause (this, clone._where, objectTree, doClone); + _groupBy = new GroupByClause(this, clone._groupBy, objectTree, doClone); + _having = new WhereClause (this, clone._having, objectTree, doClone); + _orderBy = new OrderByClause(this, clone._orderBy, objectTree, doClone); + + _parameters.AddRange(clone._parameters.ConvertAll(p => (SqlParameter)p.Clone(objectTree, doClone))); + IsParameterDependent = clone.IsParameterDependent; + + new QueryVisitor().Visit(this, expr => + { + var sb = expr as SqlQuery; + + if (sb != null && sb.ParentSql == clone) + sb.ParentSql = this; + }); + } + + public SqlQuery Clone() + { + return (SqlQuery)Clone(new Dictionary(), _ => true); + } + + public SqlQuery Clone(Predicate doClone) + { + return (SqlQuery)Clone(new Dictionary(), doClone); + } + + #endregion + + #region Helpers + + public TableSource GetTableSource(ISqlTableSource table) + { + var ts = From[table]; + return ts == null && ParentSql != null? ParentSql.GetTableSource(table) : ts; + } + + static TableSource CheckTableSource(TableSource ts, ISqlTableSource table, string alias) + { + if (ts.Source == table && (alias == null || ts.Alias == alias)) + return ts; + + var jt = ts[table, alias]; + + if (jt != null) + return jt; + + if (ts.Source is SqlQuery) + { + var s = ((SqlQuery)ts.Source).From[table, alias]; + + if (s != null) + return s; + } + + return null; + } + + #endregion + + #region Overrides + + public string SqlText { get { return ToString(); } } + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ISqlExpression Members + + public bool CanBeNull() + { + return true; + } + + public bool Equals(ISqlExpression other, Func comparer) + { + return this == other; + } + + public int Precedence + { + get { return Sql.Precedence.Unknown; } + } + + public Type SystemType + { + get + { + if (Select.Columns.Count == 1) + return Select.Columns[0].SystemType; + + if (From.Tables.Count == 1 && From.Tables[0].Joins.Count == 0) + return From.Tables[0].SystemType; + + return null; + } + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + clone = new SqlQuery(this, objectTree, doClone); + + return clone; + } + + #endregion + + #region ISqlExpressionWalkable Members + + [Obsolete] + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + if (_insert != null) ((ISqlExpressionWalkable)_insert).Walk(skipColumns, func); + if (_update != null) ((ISqlExpressionWalkable)_update).Walk(skipColumns, func); + if (_delete != null) ((ISqlExpressionWalkable)_delete).Walk(skipColumns, func); + + ((ISqlExpressionWalkable)Select) .Walk(skipColumns, func); + ((ISqlExpressionWalkable)From) .Walk(skipColumns, func); + ((ISqlExpressionWalkable)Where) .Walk(skipColumns, func); + ((ISqlExpressionWalkable)GroupBy).Walk(skipColumns, func); + ((ISqlExpressionWalkable)Having) .Walk(skipColumns, func); + ((ISqlExpressionWalkable)OrderBy).Walk(skipColumns, func); + + if (HasUnion) + foreach (var union in Unions) + ((ISqlExpressionWalkable)union.SqlQuery).Walk(skipColumns, func); + + return func(this); + } + + #endregion + + #region IEquatable Members + + bool IEquatable.Equals(ISqlExpression other) + { + return this == other; + } + + #endregion + + #region ISqlTableSource Members + + public static int SourceIDCounter; + + public int SourceID { get; private set; } + public SqlTableType SqlTableType { get { return SqlTableType.Table; } } + + private SqlField _all; + public SqlField All + { + get + { + if (_all == null) + { + _all = new SqlField(null, "*", "*", true, -1, null, null); + ((IChild)_all).Parent = this; + } + + return _all; + } + + internal set + { + _all = value; + + if (_all != null) + ((IChild)_all).Parent = this; + } + } + + List _keys; + + public IList GetKeys(bool allIfEmpty) + { + if (_keys == null && From.Tables.Count == 1 && From.Tables[0].Joins.Count == 0) + { + _keys = new List(); + + var q = + from key in ((ISqlTableSource)From.Tables[0]).GetKeys(allIfEmpty) + from col in Select.Columns + where col.Expression == key + select col as ISqlExpression; + + _keys = q.ToList(); + } + + return _keys; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.SqlQuery; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + if (dic.ContainsKey(this)) + return sb.Append("..."); + + dic.Add(this, this); + + sb + .Append("(") + .Append(SourceID) + .Append(") "); + + ((IQueryElement)Select). ToString(sb, dic); + ((IQueryElement)From). ToString(sb, dic); + ((IQueryElement)Where). ToString(sb, dic); + ((IQueryElement)GroupBy).ToString(sb, dic); + ((IQueryElement)Having). ToString(sb, dic); + ((IQueryElement)OrderBy).ToString(sb, dic); + + if (HasUnion) + foreach (IQueryElement u in Unions) + u.ToString(sb, dic); + + dic.Remove(this); + + return sb; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlTable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlTable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,430 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; + +namespace BLToolkit.Data.Sql +{ + using DataAccess; + using Mapping; + using Reflection.Extension; + using SqlProvider; + + public class SqlTable : ISqlTableSource + { + #region Init + + public SqlTable() + { + _sourceID = Interlocked.Increment(ref SqlQuery.SourceIDCounter); + _fields = new ChildContainer(this); + } + + internal SqlTable( + int id, string name, string alias, string database, string owner, string physicalName, Type objectType, + SequenceNameAttribute[] sequenceAttributes, + SqlField[] fields, + SqlTableType sqlTableType, ISqlExpression[] tableArguments) + { + _sourceID = id; + Name = name; + Alias = alias; + Database = database; + Owner = owner; + PhysicalName = physicalName; + ObjectType = objectType; + _sequenceAttributes = sequenceAttributes; + + _fields = new ChildContainer(this); + _fields.AddRange(fields); + + foreach (var field in fields) + { + if (field.Name == "*") + { + _all = field; + _fields.Remove("*"); + ((IChild)_all).Parent = this; + break; + } + } + + SqlTableType = sqlTableType; + TableArguments = tableArguments; + } + + #endregion + + #region Init from type + + public SqlTable([JetBrains.Annotations.NotNull] MappingSchema mappingSchema, Type objectType) : this() + { + if (mappingSchema == null) throw new ArgumentNullException("mappingSchema"); + + bool isSet; + Database = mappingSchema.MetadataProvider.GetDatabaseName(objectType, mappingSchema.Extensions, out isSet); + Owner = mappingSchema.MetadataProvider.GetOwnerName (objectType, mappingSchema.Extensions, out isSet); + Name = mappingSchema.MetadataProvider.GetTableName (objectType, mappingSchema.Extensions, out isSet); + ObjectType = objectType; + PhysicalName = Name; + + var typeExt = TypeExtension.GetTypeExtension(objectType, mappingSchema.Extensions); + + foreach (MemberMapper mm in mappingSchema.GetObjectMapper(objectType)) + if (mm.MapMemberInfo.SqlIgnore == false) + { + var ua = + mappingSchema.MetadataProvider.GetNonUpdatableAttribute(objectType, typeExt, mm.MapMemberInfo.MemberAccessor, out isSet); + + var order = mappingSchema.MetadataProvider.GetPrimaryKeyOrder(objectType, typeExt, mm.MapMemberInfo.MemberAccessor, out isSet); + + Fields.Add(new SqlField( + mm.Type, + mm.MemberName, + mm.Name, + mm.MapMemberInfo.Nullable, + isSet ? order : int.MinValue, + ua, + mm)); + } + + var identityField = GetIdentityField(); + + if (identityField != null) + { + var om = mappingSchema.GetObjectMapper(ObjectType); + var mm = om[identityField.Name, true]; + + _sequenceAttributes = mm.MapMemberInfo.MemberAccessor.GetAttributes(); + } + } + + public SqlTable(Type objectType) + : this(Map.DefaultSchema, objectType) + { + } + + #endregion + + #region Init from Table + + public SqlTable(SqlTable table) : this() + { + Alias = table.Alias; + Database = table.Database; + Owner = table.Owner; + Name = table.Name; + PhysicalName = table.PhysicalName; + ObjectType = table.ObjectType; + _sequenceAttributes = table._sequenceAttributes; + + foreach (var field in table.Fields.Values) + Fields.Add(new SqlField(field)); + + foreach (var join in table.Joins) + Joins.Add(join.Clone()); + + SqlTableType = table.SqlTableType; + TableArguments = table.TableArguments; + } + + public SqlTable(SqlTable table, IEnumerable fields, IEnumerable joins, ISqlExpression[] tableArguments) : this() + { + Alias = table.Alias; + Database = table.Database; + Owner = table.Owner; + Name = table.Name; + PhysicalName = table.PhysicalName; + ObjectType = table.ObjectType; + _sequenceAttributes = table._sequenceAttributes; + + Fields.AddRange(fields); + Joins. AddRange(joins); + + SqlTableType = table.SqlTableType; + TableArguments = tableArguments; + } + + #endregion + + #region Init from XML + + public SqlTable(ExtensionList extensions, string name) + : this(Map.DefaultSchema, extensions, name) + { + } + + public SqlTable([JetBrains.Annotations.NotNull] MappingSchema mappingSchema, ExtensionList extensions, string name) : this() + { + if (mappingSchema == null) throw new ArgumentNullException("mappingSchema"); + if (extensions == null) throw new ArgumentNullException("extensions"); + if (name == null) throw new ArgumentNullException("name"); + + var te = extensions[name]; + + if (te == TypeExtension.Null) + throw new ArgumentException(string.Format("Table '{0}' not found.", name)); + + Name = te.Name; + Alias = (string)te.Attributes["Alias"]. Value; + Database = (string)te.Attributes["Database"]. Value; + Owner = (string)te.Attributes["Owner"]. Value; + PhysicalName = (string)te.Attributes["PhysicalName"].Value ?? te.Name; + + foreach (var me in te.Members.Values) + Fields.Add(new SqlField( + (Type)me["Type"].Value, + me.Name, + (string)me["MapField"].Value ?? (string)me["PhysicalName"].Value, + (bool?)me["Nullable"].Value ?? false, + -1, + (bool?)me["Identity"].Value == true ? new IdentityAttribute() : null, + null)); + + foreach (var ae in te.Attributes["Join"]) + Joins.Add(new Join(ae)); + + var baseExtension = (string)te.Attributes["BaseExtension"].Value; + + if (!string.IsNullOrEmpty(baseExtension)) + InitFromBase(new SqlTable(mappingSchema, extensions, baseExtension)); + + var baseTypeName = (string)te.Attributes["BaseType"].Value; + + if (!string.IsNullOrEmpty(baseTypeName)) + InitFromBase(new SqlTable(mappingSchema, Type.GetType(baseTypeName, true, true))); + } + + void InitFromBase(SqlTable baseTable) + { + if (Alias == null) Alias = baseTable.Alias; + if (Database == null) Database = baseTable.Database; + if (Owner == null) Owner = baseTable.Owner; + if (PhysicalName == null) PhysicalName = baseTable.PhysicalName; + + foreach (var field in baseTable.Fields.Values) + if (!Fields.ContainsKey(field.Name)) + Fields.Add(new SqlField(field)); + + foreach (var join in baseTable.Joins) + if (Joins.FirstOrDefault(j => j.TableName == join.TableName) == null) + Joins.Add(join); + } + + #endregion + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region Public Members + + public SqlField this[string fieldName] + { + get + { + SqlField field; + Fields.TryGetValue(fieldName, out field); + return field; + } + } + + public string Name { get; set; } + public string Alias { get; set; } + public string Database { get; set; } + public string Owner { get; set; } + public Type ObjectType { get; set; } + public string PhysicalName { get; set; } + + private SqlTableType _sqlTableType = SqlTableType.Table; + public SqlTableType SqlTableType { get { return _sqlTableType; } set { _sqlTableType = value; } } + + public ISqlExpression[] TableArguments { get; set; } + + readonly ChildContainer _fields; + public ChildContainer Fields { get { return _fields; } } + + readonly List _joins = new List(); + public List Joins { get { return _joins; } } + + private SequenceNameAttribute[] _sequenceAttributes; + public SequenceNameAttribute[] SequenceAttributes + { + get { return _sequenceAttributes; } + } + + private SqlField _all; + public SqlField All + { + get + { + if (_all == null) + { + _all = new SqlField(null, "*", "*", true, -1, null, null); + ((IChild)_all).Parent = this; + } + + return _all; + } + } + + public SqlField GetIdentityField() + { + foreach (var field in Fields) + if (field.Value.IsIdentity) + return field.Value; + + var keys = GetKeys(true); + + if (keys != null && keys.Count == 1) + return (SqlField)keys[0]; + + return null; + } + + #endregion + + #region ISqlTableSource Members + + readonly int _sourceID; + public int SourceID { get { return _sourceID; } } + + List _keyFields; + + public IList GetKeys(bool allIfEmpty) + { + if (_keyFields == null) + { + _keyFields = ( + from f in Fields.Values + where f.IsPrimaryKey + orderby f.PrimaryKeyOrder + select f as ISqlExpression + ).ToList(); + } + + if (_keyFields.Count == 0 && allIfEmpty) + return Fields.Values.Select(f => f as ISqlExpression).ToList(); + + return _keyFields; + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + { + var table = new SqlTable + { + Name = Name, + Alias = Alias, + Database = Database, + Owner = Owner, + PhysicalName = PhysicalName, + ObjectType = ObjectType, + SqlTableType = SqlTableType, + _sequenceAttributes = _sequenceAttributes, + }; + + table._fields.Clear(); + + foreach (var field in _fields) + { + var fc = new SqlField(field.Value); + + objectTree. Add(field.Value, fc); + table._fields.Add(field.Key, fc); + } + + table._joins.AddRange(_joins.ConvertAll(j => j.Clone())); + + if (TableArguments != null) + TableArguments = TableArguments.Select(e => (ISqlExpression)e.Clone(objectTree, doClone)).ToArray(); + + objectTree.Add(this, table); + objectTree.Add(All, table.All); + + clone = table; + } + + return clone; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.SqlTable; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + return sb.Append(Name); + } + + #endregion + + #region ISqlExpression Members + + bool ISqlExpression.CanBeNull() + { + return true; + } + + public bool Equals(ISqlExpression other, Func comparer) + { + return this == other; + } + + int ISqlExpression.Precedence + { + get { return Precedence.Unknown; } + } + + Type ISqlExpression.SystemType + { + get { return ObjectType; } + } + + #endregion + + #region IEquatable Members + + bool IEquatable.Equals(ISqlExpression other) + { + return this == other; + } + + #endregion + + #region ISqlExpressionWalkable Members + + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + if (TableArguments != null) + for (var i = 0; i < TableArguments.Length; i++) + TableArguments[i] = TableArguments[i].Walk(skipColumns, func); + + return func(this); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlTableT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlTableT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; + +using BLToolkit.Mapping; + +namespace BLToolkit.Data.Sql +{ + public class SqlTable : SqlTable + { + public SqlTable() + : base(typeof(T)) + { + } + + public SqlTable(MappingSchema mappingSchema) + : base(mappingSchema, typeof(T)) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlTableType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlTableType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +using System; + +namespace BLToolkit.Data.Sql +{ + public enum SqlTableType + { + Table, + Function, + Expression + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlValue.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlValue.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BLToolkit.Data.Sql +{ + public class SqlValue : SqlValueBase, ISqlExpression + { + public SqlValue(Type systemType, object value) + { + _systemType = systemType; + _value = value; + } + + public SqlValue(object value) + { + _value = value; + + if (value != null) + _systemType = value.GetType(); + } + + public override object Value + { + get + { + var rv = base.Value; + + if (rv != null && rv.GetType() != _systemType) + { + _systemType = rv.GetType(); + } + + return rv; + } + } + + Type _systemType; public Type SystemType { get { return _systemType; } } + + #region Overrides + +#if OVERRIDETOSTRING + + public override string ToString() + { + return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary()).ToString(); + } + +#endif + + #endregion + + #region ISqlExpression Members + + public int Precedence + { + get { return Sql.Precedence.Primary; } + } + + #endregion + + #region ISqlExpressionWalkable Members + + ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func func) + { + return func(this); + } + + #endregion + + #region IEquatable Members + + bool IEquatable.Equals(ISqlExpression other) + { + if (this == other) + return true; + + var value = other as SqlValue; + return + value != null && + _systemType == value._systemType && + (_value == null && value._value == null || _value != null && _value.Equals(value._value)); + } + + #endregion + + #region ISqlExpression Members + + public bool CanBeNull() + { + return Value == null; + } + + public bool Equals(ISqlExpression other, Func comparer) + { + return ((ISqlExpression)this).Equals(other) && comparer(this, other); + } + + #endregion + + #region ICloneableElement Members + + public ICloneableElement Clone(Dictionary objectTree, Predicate doClone) + { + if (!doClone(this)) + return this; + + ICloneableElement clone; + + if (!objectTree.TryGetValue(this, out clone)) + objectTree.Add(this, clone = new SqlValue(_systemType, _value)); + + return clone; + } + + #endregion + + #region IQueryElement Members + + public QueryElementType ElementType { get { return QueryElementType.SqlValue; } } + + StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary dic) + { + return + Value == null ? + sb.Append("NULL") : + Value is string ? + sb + .Append('\'') + .Append(Value.ToString().Replace("\'", "''")) + .Append('\'') + : + sb.Append(Value); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Data/Sql/SqlValueBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlValueBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,179 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using BLToolkit.Mapping; +using BLToolkit.Reflection; + +namespace BLToolkit.Data.Sql +{ + public abstract class SqlValueBase: IValueContainer + { + [CLSCompliant(false)] + protected object _value; + public virtual object Value + { + get + { + var valueConverter = ValueConverter; + return valueConverter == null ? _value : valueConverter(_value); + } + + set { _value = value; } + } + + #region Value Converter + + internal List EnumTypes; + internal List TakeValues; + internal string LikeStart, LikeEnd; + + private Converter _valueConverter; + public Converter ValueConverter + { + get + { + if (_valueConverter == null) + { + if (EnumTypes != null) + foreach (var type in EnumTypes.ToArray()) + SetEnumConverter(type, Map.DefaultSchema); + else if (TakeValues != null) + foreach (var take in TakeValues.ToArray()) + SetTakeConverter(take); + else if (LikeStart != null) + SetLikeConverter(LikeStart, LikeEnd); + } + + return _valueConverter; + } + + set { _valueConverter = value; } + } + + bool _isEnumConverterSet; + + internal void SetEnumConverter(Type type, MappingSchema ms) + { + if (!_isEnumConverterSet) + { + _isEnumConverterSet = true; + + if (EnumTypes == null) + EnumTypes = new List(); + + EnumTypes.Add(type); + + SetEnumConverterInternal(type, ms); + } + } + + internal void SetEnumConverter(MemberAccessor ma, MappingSchema ms) + { + if (!_isEnumConverterSet) + { + _isEnumConverterSet = true; + + if (EnumTypes == null) + EnumTypes = new List(); + + EnumTypes.Add(ma.Type); + + SetEnumConverterInternal(ma, ms); + } + } + + void SetEnumConverterInternal(MemberAccessor ma, MappingSchema ms) + { + if (_valueConverter == null) + { + _valueConverter = o => ms.MapEnumToValue(o, ma, true); + } + else + { + var converter = _valueConverter; + _valueConverter = o => ms.MapEnumToValue(converter(o), ma, true); + } + // update system type in SqlValue :-/ + var tmp = Value; + } + + void SetEnumConverterInternal(Type type, MappingSchema ms) + { + if (_valueConverter == null) + { + _valueConverter = o => ms.MapEnumToValue(o, type, true); + } + else + { + var converter = _valueConverter; + _valueConverter = o => ms.MapEnumToValue(converter(o), type, true); + } + // update system type in SqlValue :-/ + var tmp = Value; + } + + internal void SetTakeConverter(int take) + { + if (TakeValues == null) + TakeValues = new List(); + + TakeValues.Add(take); + + SetTakeConverterInternal(take); + } + + void SetTakeConverterInternal(int take) + { + var conv = _valueConverter; + + if (conv == null) + _valueConverter = v => v == null ? null : (object)((int)v + take); + else + _valueConverter = v => v == null ? null : (object)((int)conv(v) + take); + } + + internal void SetLikeConverter(string start, string end) + { + LikeStart = start; + LikeEnd = end; + _valueConverter = GetLikeEscaper(start, end); + } + + static Converter GetLikeEscaper(string start, string end) + { + return value => + { + if (value == null) + #if DEBUG + value = ""; + #else + throw new SqlException("NULL cannot be used as a LIKE predicate parameter."); + #endif + + var text = value.ToString(); + + if (text.IndexOfAny(new[] { '%', '_', '[' }) < 0) + return start + text + end; + + var sb = new StringBuilder(start, text.Length + start.Length + end.Length); + + foreach (var c in text) + { + if (c == '%' || c == '_' || c == '[') + { + sb.Append('['); + sb.Append(c); + sb.Append(']'); + } + else + sb.Append(c); + } + + return sb.ToString(); + }; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ActionNameAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ActionNameAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Method)] + public class ActionNameAttribute : Attribute + { + public ActionNameAttribute(string name) + { + _name = name; + } + + private readonly string _name; + public string Name + { + get { return _name; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ActionSprocNameAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ActionSprocNameAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] + public class ActionSprocNameAttribute : Attribute + { + public ActionSprocNameAttribute(string actionName, string procedureName) + { + _actionName = actionName; + _procedureName = procedureName; + } + + private readonly string _actionName; + public string ActionName + { + get { return _actionName; } + } + + private readonly string _procedureName; + public string ProcedureName + { + get { return _procedureName; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ActualTypeAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ActualTypeAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,27 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [JetBrains.Annotations.BaseTypeRequired(typeof(DataAccessor))] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true)] + public class ActualTypeAttribute : Attribute + { + public ActualTypeAttribute(Type baseType, Type actualType) + { + _baseType = baseType; + _actualType = actualType; + } + + private readonly Type _baseType; + public Type BaseType + { + get { return _baseType; } + } + + private readonly Type _actualType; + public Type ActualType + { + get { return _actualType; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/CommandBehaviorAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/CommandBehaviorAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; +using System.Data; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Method)] + public class CommandBehaviorAttribute : Attribute + { + public CommandBehaviorAttribute() + { + _commandBehavior = CommandBehavior.Default; + } + + public CommandBehaviorAttribute(CommandBehavior commandBehavior) + { + _commandBehavior = commandBehavior; + } + + private CommandBehavior _commandBehavior; + public CommandBehavior CommandBehavior + { + get { return _commandBehavior; } + set { _commandBehavior = value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DataAccess.xsd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DataAccess.xsd Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ + + + + + + + diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DataAccess.xsx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DataAccess.xsx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DataAccessException.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DataAccessException.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,83 @@ +using System; +using System.Runtime.Serialization; + +namespace BLToolkit.DataAccess +{ + /// + /// Defines the base class for the namespace exceptions. + /// + /// + /// This class is the base class for exceptions that may occur during + /// execution of the namespace members. + /// + [Serializable] + public class DataAccessException : Exception + { + /// + /// Initializes a new instance of the class. + /// + /// + /// This constructor initializes the + /// property of the new instance + /// to a system-supplied message that describes the error, + /// such as "BLToolkit Data Access error has occurred." + /// + public DataAccessException() + : base("A Data Access exception has occurred.") + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message. + /// + /// The message to display to the client when the + /// exception is thrown. + /// + public DataAccessException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message and InnerException property. + /// + /// The message to display to the client when the + /// exception is thrown. + /// The InnerException, if any, that threw + /// the current exception. + /// + /// + public DataAccessException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class + /// with the InnerException property. + /// + /// The InnerException, if any, that threw + /// the current exception. + /// + public DataAccessException(Exception innerException) + : base(innerException.Message, innerException) + { + } + + /// + /// Initializes a new instance of the class + /// with serialized data. + /// + /// The object that holds the serialized object data. + /// The contextual information about the source or + /// destination. + /// This constructor is called during deserialization to + /// reconstitute the exception object transmitted over a stream. + protected DataAccessException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DataAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DataAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,711 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlTypes; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Xml; +#if !SILVERLIGHT +using System.Xml.Linq; +#endif + +namespace BLToolkit.DataAccess +{ + using Aspects; + using Common; + using Data; + using Data.DataProvider; + using Mapping; + using Patterns; + using Properties; + using Reflection; + using TypeBuilder; + + [DataAccessor, DebuggerStepThrough] + public abstract class DataAccessor : DataAccessorBase + { + #region Constructors + + protected DataAccessor() + { + } + + protected DataAccessor(DbManager dbManager) + : base(dbManager) + { + } + + protected DataAccessor(DbManager dbManager, bool dispose) + : base(dbManager, dispose) + { + } + + #endregion + + #region CreateInstance + + public static DataAccessor CreateInstance(Type type) + { + return (DataAccessor)Activator.CreateInstance(TypeFactory.GetType(type)); + } + + public static DataAccessor CreateInstance(Type type, InitContext context) + { + return (DataAccessor)Activator.CreateInstance(TypeFactory.GetType(type), context); + } + + public static DataAccessor CreateInstance(Type type, DbManager dbManager) + { + return CreateInstance(type, dbManager, false); + } + + public static DataAccessor CreateInstance( + Type type, + InitContext context, + DbManager dbManager) + { + return CreateInstance(type, context, dbManager, false); + } + + public static DataAccessor CreateInstance(Type type, DbManager dbManager, bool dispose) + { + var da = CreateInstance(type); + + da.SetDbManager(dbManager, dispose); + + return da; + } + + public static DataAccessor CreateInstance( + Type type, + InitContext context, + DbManager dbManager, + bool dispose) + { + var da = CreateInstance(type, context); + + da.SetDbManager(dbManager, dispose); + + return da; + } + + public static T CreateInstance() where T : DataAccessor + { + return TypeFactory.CreateInstance(); + } + + public static T CreateInstance(DbManager dbManager) + where T : DataAccessor + { + return CreateInstance(dbManager, false); + } + + public static T CreateInstance(DbManager dbManager, bool dispose) + where T : DataAccessor + { + var da = TypeFactory.CreateInstance(); + + da.SetDbManager(dbManager, dispose); + + return da; + } + + #endregion + + #region Protected Members + + #region Parameters + + [NoInterception] + protected virtual string GetQueryParameterName(DbManager db, string paramName) + { + return (string)db.DataProvider.Convert(paramName, ConvertType.NameToQueryParameter); + } + + [NoInterception] + protected virtual string GetSpParameterName(DbManager db, string paramName) + { + return (string)db.DataProvider.Convert(paramName, db.GetConvertTypeToParameter()); + } + + [NoInterception] + protected virtual IDbDataParameter[] PrepareParameters(DbManager db, object[] parameters) + { + return db.PrepareParameters(parameters); + } + + [NoInterception] + protected virtual IDbDataParameter GetParameter(DbManager db, string paramName) + { + var p = db.Parameter(paramName); + + if (p == null) + { + // This usually means that the parameter name is incorrect. + // + throw new DataAccessException(string.Format( + Resources.DataAccessot_ParameterNotFound, paramName)); + } + + // Input parameter mapping make no sence. + // + Debug.WriteLineIf(p.Direction == ParameterDirection.Input, + string.Format("'{0}.{1}' is an input parameter.", + db.Command.CommandText, paramName)); + + return p; + } + + [NoInterception] + protected virtual IDbDataParameter[] CreateParameters( + DbManager db, + object obj, + string[] outputParameters, + string[] inputOutputParameters, + string[] ignoreParameters, + params IDbDataParameter[] commandParameters) + { + return db.CreateParameters(obj, outputParameters, + inputOutputParameters, ignoreParameters, commandParameters); + } + + [NoInterception] + protected virtual IDbDataParameter[] CreateParameters( + DbManager db, + DataRow dataRow, + string[] outputParameters, + string[] inputOutputParameters, + string[] ignoreParameters, + params IDbDataParameter[] commandParameters) + { + return db.CreateParameters(dataRow, outputParameters, + inputOutputParameters, ignoreParameters, commandParameters); + } + + [NoInterception] + protected virtual string PrepareSqlQuery(DbManager db, int queryID, int uniqueID, string sqlQuery) + { + return sqlQuery; + } + + #endregion + + #region ExecuteDictionary + + protected void ExecuteDictionary( + DbManager db, + IDictionary dictionary, + Type objectType, + Type keyType, + string methodName) + { + var isIndex = TypeHelper.IsSameOrParent(typeof(CompoundValue), keyType); + var mms = new SqlQuery(Extensions).GetKeyFieldList(db, objectType); + + if (mms.Length == 0) + throw new DataAccessException(string.Format( + Resources.DataAccessor_UnknownIndex, + GetType().Name, methodName)); + + if (mms.Length > 1 && keyType != typeof(object) && !isIndex) + throw new DataAccessException(string.Format( + Resources.DataAccessor_InvalidKeyType, + GetType().Name, methodName)); + + if (isIndex || mms.Length > 1) + { + var fields = new string[mms.Length]; + + for (var i = 0; i < mms.Length; i++) + fields[i] = mms[i].MemberName; + + db.ExecuteDictionary(dictionary, new MapIndex(fields), objectType, null); + } + else + { + db.ExecuteDictionary(dictionary, mms[0].MemberName, objectType, null); + } + } + + protected void ExecuteDictionary( + DbManager db, + IDictionary dictionary, + Type objectType, + string methodName) + { + var mms = new SqlQuery(Extensions).GetKeyFieldList(db, objectType); + + if (mms.Length == 0) + throw new DataAccessException(string.Format( + Resources.DataAccessor_UnknownIndex, + GetType().Name, methodName)); + + var fields = new string[mms.Length]; + + for (var i = 0; i < mms.Length; i++) + fields[i] = mms[i].MemberName; + + db.ExecuteDictionary(dictionary, new MapIndex(fields), objectType, null); + } + + protected void ExecuteDictionary( + DbManager db, + IDictionary dictionary, + Type objectType, + string methodName) + { + var mms = new SqlQuery(Extensions).GetKeyFieldList(db, objectType); + + if (mms.Length == 0) + throw new DataAccessException(string.Format( + Resources.DataAccessor_UnknownIndex, + GetType().Name, methodName)); + + if (mms.Length != 1) + throw new DataAccessException(string.Format( + Resources.DataAccessor_IndexIsComplex, + GetType().Name, methodName)); + + db.ExecuteDictionary(dictionary, mms[0].MemberName, objectType, null); + } + + protected void ExecuteScalarDictionary( + DbManager db, + IDictionary dictionary, + Type objectType, + Type keyType, + string methodName, + NameOrIndexParameter scalarField, + Type elementType) + { + var isIndex = TypeHelper.IsSameOrParent(typeof(CompoundValue), keyType); + var mms = new SqlQuery(Extensions).GetKeyFieldList(db, objectType); + + if (mms.Length == 0) + throw new DataAccessException(string.Format( + Resources.DataAccessor_UnknownIndex, + GetType().Name, methodName)); + + if (mms.Length > 1 && keyType != typeof(object) && !isIndex) + throw new DataAccessException(string.Format( + Resources.DataAccessor_InvalidKeyType, + GetType().Name, methodName)); + + if (isIndex || mms.Length > 1) + { + var fields = new string[mms.Length]; + + for (var i = 0; i < mms.Length; i++) + fields[i] = mms[i].Name; + + db.ExecuteScalarDictionary(dictionary, new MapIndex(fields), scalarField, elementType); + } + else + { + db.ExecuteScalarDictionary( + dictionary, + mms[0].Name, + keyType, + scalarField, + elementType); + } + } + + #endregion + + #region ExecuteEnumerable + + protected IEnumerable ExecuteEnumerable(DbManager db, Type objectType, bool disposeDbManager) + { + try + { + using (var rd = db.ExecuteReader()) + { + if (rd.Read()) + { + var dest = MappingSchema.GetObjectMapper(objectType); + var source = MappingSchema.CreateDataReaderMapper(rd); + + var ctx = new InitContext + { + MappingSchema = MappingSchema, + ObjectMapper = dest, + DataSource = source, + SourceObject = rd + }; + + var index = MappingSchema.GetIndex(source, dest); + var mappers = ctx.MappingSchema.GetValueMappers(source, dest, index); + + do + { + var destObject = (T)dest.CreateInstance(ctx); + + if (ctx.StopMapping) + yield return destObject; + + var smDest = destObject as ISupportMapping; + + if (smDest != null) + { + smDest.BeginMapping(ctx); + + if (ctx.StopMapping) + yield return destObject; + } + + MappingSchema.MapInternal(source, rd, dest, destObject, index, mappers); + + if (smDest != null) + smDest.EndMapping(ctx); + + yield return destObject; + } while (rd.Read()); + } + } + } + finally + { + if (disposeDbManager) + db.Dispose(); + } + } + + protected IEnumerable ExecuteEnumerable(DbManager db, Type objectType, bool disposeDbManager) + { + var ms = db.MappingSchema; + + if (disposeDbManager) + { + using (db) + using (var rd = db.ExecuteReader()) + while (rd.Read()) + yield return ms.MapDataReaderToObject(rd, objectType); + } + else + { + using (var rd = db.ExecuteReader()) + while (rd.Read()) + yield return ms.MapDataReaderToObject(rd, objectType); + } + } + + #endregion + + #region Convert + + #region Primitive Types + + [CLSCompliant(false)] + [NoInterception] + protected virtual SByte ConvertToSByte(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSByte(value); + } + + [NoInterception] + protected virtual Int16 ConvertToInt16(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToInt16(value); + } + + [NoInterception] + protected virtual Int32 ConvertToInt32(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToInt32(value); + } + + [NoInterception] + protected virtual Int64 ConvertToInt64(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToInt64(value); + } + + [NoInterception] + protected virtual Byte ConvertToByte(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToByte(value); + } + + [CLSCompliant(false)] + [NoInterception] + protected virtual UInt16 ConvertToUInt16(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToUInt16(value); + } + + [CLSCompliant(false)] + [NoInterception] + protected virtual UInt32 ConvertToUInt32(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToUInt32(value); + } + + [CLSCompliant(false)] + [NoInterception] + protected virtual UInt64 ConvertToUInt64(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToUInt64(value); + } + + [NoInterception] + protected virtual Char ConvertToChar(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToChar(value); + } + + [NoInterception] + protected virtual Single ConvertToSingle(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSingle(value); + } + + [NoInterception] + protected virtual Double ConvertToDouble(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToDouble(value); + } + + [NoInterception] + protected virtual Boolean ConvertToBoolean(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToBoolean(value); + } + + #endregion + + #region Simple Types + + [NoInterception] + protected virtual String ConvertToString(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToString(value); + } + + [NoInterception] + protected virtual DateTime ConvertToDateTime(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToDateTime(value); + } + + [NoInterception] + protected virtual DateTimeOffset ConvertToDateTimeOffset(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToDateTimeOffset(value); + } + + [NoInterception] + protected virtual System.Data.Linq.Binary ConvertToLinqBinary(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToLinqBinary(value); + } + + [NoInterception] + protected virtual Decimal ConvertToDecimal(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToDecimal(value); + } + + [NoInterception] + protected virtual Guid ConvertToGuid(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToGuid(value); + } + + [NoInterception] + protected virtual Stream ConvertToStream(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToStream(value); + } + + [NoInterception] + protected virtual XmlReader ConvertToXmlReader(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToXmlReader(value); + } + + [NoInterception] + protected virtual XmlDocument ConvertToXmlDocument(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToXmlDocument(value); + } + +#if !SILVERLIGHT + [NoInterception] + protected virtual XElement ConvertToXElement(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToXElement(value); + } +#endif + + [NoInterception] + protected virtual Byte[] ConvertToByteArray(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToByteArray(value); + } + + [NoInterception] + protected virtual Char[] ConvertToCharArray(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToCharArray(value); + } + + #endregion + + #region SqlTypes + + [NoInterception] + protected virtual SqlByte ConvertToSqlByte(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSqlByte(value); + } + + [NoInterception] + protected virtual SqlInt16 ConvertToSqlInt16(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSqlInt16(value); + } + + [NoInterception] + protected virtual SqlInt32 ConvertToSqlInt32(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSqlInt32(value); + } + + [NoInterception] + protected virtual SqlInt64 ConvertToSqlInt64(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSqlInt64(value); + } + + [NoInterception] + protected virtual SqlSingle ConvertToSqlSingle(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSqlSingle(value); + } + + [NoInterception] + protected virtual SqlBoolean ConvertToSqlBoolean(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSqlBoolean(value); + } + + [NoInterception] + protected virtual SqlDouble ConvertToSqlDouble(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSqlDouble(value); + } + + [NoInterception] + protected virtual SqlDateTime ConvertToSqlDateTime(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSqlDateTime(value); + } + + [NoInterception] + protected virtual SqlDecimal ConvertToSqlDecimal(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSqlDecimal(value); + } + + [NoInterception] + protected virtual SqlMoney ConvertToSqlMoney(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSqlMoney(value); + } + + [NoInterception] + protected virtual SqlGuid ConvertToSqlGuid(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSqlGuid(value); + } + + [NoInterception] + protected virtual SqlString ConvertToSqlString(DbManager db, object value, object parameter) + { + return db.MappingSchema.ConvertToSqlString(value); + } + + #endregion + + #region General case + + [NoInterception] + protected virtual object ConvertChangeType( + DbManager db, + object value, + Type conversionType, + object parameter) + { + return db.MappingSchema.ConvertChangeType(value, conversionType); + } + + #endregion + + #endregion + + #region IsNull + + /// + /// Reserved for internal BLToolkit use. + /// + public interface INullableInternal + { + bool IsNull { [MustImplement(false, false)] get; } + } + + [NoInterception] + protected virtual bool IsNull( + DbManager db, + object value, + object parameter) + { + // Speed up for scalar and nullable types. + // + switch (System.Convert.GetTypeCode(value)) + { + // null, DBNull.Value, Nullable without a value. + // + case TypeCode.Empty: + case TypeCode.DBNull: + return true; + + case TypeCode.Object: + break; + + // int, byte, string, DateTime and other primitives except Guid. + // Also Nullable with a value. + // + default: + return false; + } + + // Speed up for SqlTypes. + // + var nullable = value as INullable; + if (nullable != null) + return nullable.IsNull; + + // All other types which have 'IsNull' property but does not implement 'INullable' interface. + // For example: 'Oracle.DataAccess.Types.OracleDecimal'. + // + // For types without 'IsNull' property the return value is always false. + // + var nullableInternal = (INullableInternal)DuckTyping.Implement(typeof(INullableInternal), value); + + return nullableInternal.IsNull; + } + + #endregion + + protected virtual SqlQueryAttribute GetSqlQueryAttribute(MethodInfo methodInfo) + { + var attrs = methodInfo.GetCustomAttributes(typeof(SqlQueryAttribute), true); + return (SqlQueryAttribute)attrs[0]; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DataAccessorAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DataAccessorAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +using System; + +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Class)] + class DataAccessorAttribute : AbstractTypeBuilderAttribute + { + public override IAbstractTypeBuilder TypeBuilder + { + get { return new DataAccessorBuilder(); } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DataAccessorBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DataAccessorBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,195 @@ +using System; +using System.Collections; +using System.Data; + +using BLToolkit.Aspects; +using BLToolkit.Data; +using BLToolkit.Mapping; +using BLToolkit.Properties; +using BLToolkit.Reflection.Extension; + +namespace BLToolkit.DataAccess +{ + public abstract class DataAccessorBase + { + #region Constructors + + [System.Diagnostics.DebuggerStepThrough] + protected DataAccessorBase() + { + } + + [System.Diagnostics.DebuggerStepThrough] + protected DataAccessorBase(DbManager dbManager) + { + SetDbManager(dbManager, false); + } + + [System.Diagnostics.DebuggerStepThrough] + protected DataAccessorBase(DbManager dbManager, bool dispose) + { + SetDbManager(dbManager, dispose); + } + + #endregion + + #region Public Members + + [NoInterception, System.Diagnostics.DebuggerStepThrough] + public virtual DbManager GetDbManager() + { + return _dbManager ?? CreateDbManager(); + } + + [NoInterception] + protected virtual DbManager CreateDbManager() + { + return new DbManager(); + } + + [NoInterception] + public virtual void BeginTransaction() + { + if (_dbManager == null) + throw new InvalidOperationException(Resources.DataAccessorBase_NoDbManager); + + _dbManager.BeginTransaction(); + } + + [NoInterception] + public virtual void BeginTransaction(IsolationLevel il) + { + if (_dbManager == null) + throw new InvalidOperationException(Resources.DataAccessorBase_NoDbManager); + + _dbManager.BeginTransaction(il); + } + + [NoInterception] + public virtual void CommitTransaction() + { + if (_dbManager == null) + throw new InvalidOperationException(Resources.DataAccessorBase_NoDbManager); + + _dbManager.CommitTransaction(); + } + + [NoInterception] + public virtual void RollbackTransaction() + { + if (_dbManager == null) + throw new InvalidOperationException(Resources.DataAccessorBase_NoDbManager); + + _dbManager.RollbackTransaction(); + } + + private ExtensionList _extensions; + public ExtensionList Extensions + { + get { return _extensions ?? (_extensions = MappingSchema.Extensions); } + set { _extensions = value; } + } + + private bool _disposeDbManager = true; + [NoInterception] + public virtual bool DisposeDbManager + { + get { return _disposeDbManager; } + set { _disposeDbManager = value; } + } + + private MappingSchema _mappingSchema; + public MappingSchema MappingSchema + { + get { return _mappingSchema ?? (_mappingSchema = _dbManager != null? _dbManager.MappingSchema: Map.DefaultSchema); } + set { _mappingSchema = value; } + } + + #endregion + + #region Protected Members + + private DbManager _dbManager; + protected DbManager DbManager + { + get { return _dbManager; } + } + + protected internal void SetDbManager(DbManager dbManager, bool dispose) + { + _dbManager = dbManager; + _disposeDbManager = dispose; + } + + [NoInterception] + protected virtual string GetDefaultSpName(string typeName, string actionName) + { + return typeName == null? + actionName: + string.Format("{0}_{1}", typeName, actionName); + } + + private static readonly Hashtable _actionSproc = new Hashtable(); + + [NoInterception] + protected virtual string GetSpName(Type type, string actionName) + { + if (type == null) + return GetDefaultSpName(null, actionName); + + string key = type.FullName + "$" + actionName; + string sprocName = (string)_actionSproc[key]; + + if (sprocName == null) + { + object[] attrs = type.GetCustomAttributes(typeof(ActionSprocNameAttribute), true); + + foreach (ActionSprocNameAttribute attr in attrs) + { + if (attr.ActionName == actionName) + { + sprocName = attr.ProcedureName; + break; + } + } + + if (sprocName == null) + sprocName = GetDefaultSpName(GetTableName(type), actionName); + + _actionSproc[key] = sprocName; + } + + return sprocName; + } + + [NoInterception] + protected virtual string GetDatabaseName(Type type) + { + bool isSet; + return MappingSchema.MetadataProvider.GetDatabaseName(type, Extensions, out isSet); + } + + [NoInterception] + protected virtual string GetOwnerName(Type type) + { + bool isSet; + return MappingSchema.MetadataProvider.GetOwnerName(type, Extensions, out isSet); + } + + [NoInterception] + protected virtual string GetTableName(Type type) + { + bool isSet; + return MappingSchema.MetadataProvider.GetTableName(type, Extensions, out isSet); + } + + [NoInterception] + protected virtual void Dispose(DbManager dbManager) + { + if (dbManager != null && DisposeDbManager) + dbManager.Dispose(); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DataAccessorBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DataAccessorBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2107 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; + +using BLToolkit.Common; +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; +using BLToolkit.Mapping; +using BLToolkit.Properties; +using BLToolkit.Reflection; +using BLToolkit.Reflection.Emit; +using BLToolkit.TypeBuilder; +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.DataAccess +{ + public class DataAccessorBuilder : AbstractTypeBuilderBase + { + struct MapOutputParametersValue + { + public readonly string ReturnValueMember; + public readonly ParameterInfo ParameterInfo; + + public MapOutputParametersValue(string returnValueMember, ParameterInfo parameterInfo) + { + ReturnValueMember = returnValueMember; + ParameterInfo = parameterInfo; + } + } + + public override int GetPriority(BuildContext context) + { + return TypeBuilderConsts.Priority.DataAccessor; + } + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + if (context.IsBuildStep) + { + if (context.IsAbstractMethod) + { + // Give up if there is any builder that builds the method body. + // + if (builders.Count > 1) + foreach (IAbstractTypeBuilder builder in builders) + if (builder != this && builder.IsApplied(context, builders)) + return false; + + return true; + } + + // Treat an abstract getter/setter as a regular method + // when the property has [NoInstance] attribute + // + if (context.IsAbstractGetter || context.IsAbstractSetter) + return context.CurrentProperty.IsDefined(typeof(NoInstanceAttribute), true); + } + + return false; + } + + private Dictionary _actualTypes; + private Dictionary ActualTypes + { + get + { + if (_actualTypes == null) + { + _actualTypes = new Dictionary(); + + object[] attrs = Context.Type.GetAttributes(typeof(ActualTypeAttribute)); + + foreach (ActualTypeAttribute attr in attrs) + if (!_actualTypes.ContainsKey(attr.BaseType)) + _actualTypes.Add(attr.BaseType, attr.ActualType); + } + + return _actualTypes; + } + } + + enum ReturnType + { + DataReader, + DataSet, + DataTable, + List, + Dictionary, + Enumerable, + Void, + Scalar, + Object + } + + static ReturnType GetReturnType(Type returnType) + { + if (returnType == typeof(IDataReader)) + return ReturnType.DataReader; + + if (returnType == typeof(DataSet) || returnType.IsSubclassOf(typeof(DataSet))) + return ReturnType.DataSet; + + if (returnType == typeof(DataTable) || returnType.IsSubclassOf(typeof(DataTable))) + return ReturnType.DataTable; + + if (!returnType.IsArray && + (IsInterfaceOf(returnType, typeof(IList)) || + returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(IList<>))) + return ReturnType.List; + + if (IsInterfaceOf(returnType, typeof(IDictionary)) || + returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(IDictionary<,>)) + return ReturnType.Dictionary; + + if (returnType == typeof(IEnumerable) || + returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + return ReturnType.Enumerable; + + if (returnType == typeof(void)) + return ReturnType.Void; + + if (TypeHelper.IsScalar(returnType.IsByRef ? returnType.GetElementType() : returnType)) + return ReturnType.Scalar; + + return ReturnType.Object; + } + + void ThrowTypeBuilderException(string message) + { + throw new TypeBuilderException( + string.Format(message, Context.CurrentMethod.DeclaringType.Name, Context.CurrentMethod.Name)); + } + + const BindingFlags _bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + + readonly Type _baseType = typeof(DataAccessor); + Type _objectType; + bool _explicitObjectType; + ParameterInfo[] _parameters; + ArrayList _paramList; + ArrayList _refParamList; + bool _createManager; + LocalBuilder _locManager; + LocalBuilder _locObjType; + ArrayList _outputParameters; + SqlQueryAttribute _sqlQueryAttribute; + ArrayList _formatParamList; + ParameterInfo _destination; + ArrayList _mapOutputParameters; + + protected override void BuildAbstractMethod() + { + // Any class variable must be initialized before use + // as the same instance of the class is utilized to build abstract methods. + // + _paramList = new ArrayList(); + _refParamList = new ArrayList(); + _formatParamList = new ArrayList(); + _mapOutputParameters = new ArrayList(); + _destination = null; + _createManager = true; + _objectType = null; + _explicitObjectType = false; + _parameters = Context.CurrentMethod.GetParameters(); + _locManager = Context.MethodBuilder.Emitter.DeclareLocal(typeof(DbManager)); + _locObjType = Context.MethodBuilder.Emitter.DeclareLocal(typeof(Type)); + _outputParameters = null; + _sqlQueryAttribute = null; + + GetSqlQueryAttribute(); + ProcessParameters(); + + var returnType = MethodReturnType; + var rt = GetReturnType(returnType); + + CreateDbManager(rt != ReturnType.Enumerable); + SetObjectType(); + + // Define execution method type. + // + switch (rt) + { + case ReturnType.DataReader : ExecuteReader(); break; + case ReturnType.DataSet : ExecuteDataSet(returnType); break; + case ReturnType.DataTable : ExecuteDataTable(); break; + case ReturnType.Void : ExecuteNonQuery(); break; + case ReturnType.Scalar : ExecuteScalar(); break; + case ReturnType.Enumerable : ExecuteEnumerable(); break; + + case ReturnType.List: + + if (!_explicitObjectType) + { + Type elementType = TypeHelper.GetListItemType(returnType); + + if (elementType == typeof(object) && _destination != null) + elementType = TypeHelper.GetListItemType(Context.CurrentMethod.ReturnType); + + if (elementType != typeof(object)) + _objectType = elementType; + + if (ActualTypes.ContainsKey(_objectType)) + _objectType = ActualTypes[_objectType]; + } + + if (_objectType == null || _objectType == typeof(object)) + ThrowTypeBuilderException(Resources.DataAccessorBuilder_BadListItemType); + + if (TypeHelper.IsScalar(_objectType)) + ExecuteScalarList(); + else + ExecuteList(); + + break; + + case ReturnType.Dictionary: + { + Type elementType = null; + Type keyType = typeof(object); + Type[] gTypes = TypeHelper.GetGenericArguments(returnType, typeof(IDictionary)); + + if ((gTypes == null || gTypes.Length != 2) && _destination != null) + gTypes = TypeHelper.GetGenericArguments(_destination.ParameterType, typeof(IDictionary)); + + if (gTypes != null && gTypes.Length == 2) + { + keyType = gTypes[0]; + elementType = gTypes[1]; + } + + if (elementType == null || _explicitObjectType) + elementType = _objectType; + + if (elementType == null || elementType == typeof(object)) + ThrowTypeBuilderException(Resources.DataAccessorBuilder_BadListItemType); + + bool isIndex = TypeHelper.IsSameOrParent(typeof(CompoundValue), keyType); + + if (keyType != typeof(object) && !isIndex && !TypeHelper.IsScalar(keyType)) + ThrowTypeBuilderException( + Resources.DataAccessorBuilder_BadKeyType); + + MethodInfo mi = Context.CurrentMethod; + + object[] attrs = mi.GetCustomAttributes(typeof(IndexAttribute), true); + NameOrIndexParameter[] fields = new NameOrIndexParameter[0]; + + if (attrs.Length != 0) + fields = ((IndexAttribute)attrs[0]).Fields; + + if (fields.Length > 1 && keyType != typeof(object) && !isIndex) + ThrowTypeBuilderException( + Resources.DataAccessor_InvalidKeyType); + + if (TypeHelper.IsScalar(elementType)) + { + attrs = mi.GetCustomAttributes(typeof(ScalarFieldNameAttribute), true); + + if (attrs.Length == 0) + ThrowTypeBuilderException(Resources.DataAccessorBuilder_ScalarFieldNameMissing); + + NameOrIndexParameter scalarField = ((ScalarFieldNameAttribute)attrs[0]).NameOrIndex; + + if (fields.Length == 0) + ExecuteScalarDictionaryWithPK(keyType, scalarField, elementType); + else if (isIndex || fields.Length > 1) + ExecuteScalarDictionaryWithMapIndex(fields, scalarField, elementType); + else + ExecuteScalarDictionaryWithScalarKey(fields[0], keyType, scalarField, elementType); + } + else + { + if (!_explicitObjectType && ActualTypes.ContainsKey(elementType)) + elementType = ActualTypes[elementType]; + + if (fields.Length == 0) + ExecuteDictionaryWithPK(keyType, elementType); + else if (isIndex || fields.Length > 1) + ExecuteDictionaryWithMapIndex(fields, elementType); + else + ExecuteDictionaryWithScalarKey(fields[0], elementType); + } + } + + break; + + default: + + if (_objectType == null || !TypeHelper.IsSameOrParent(returnType, _objectType)) + _objectType = returnType; + + if (!_explicitObjectType && ActualTypes.ContainsKey(_objectType)) + _objectType = ActualTypes[_objectType]; + + ExecuteObject(); + + break; + } + + GetOutRefParameters(); + + if (rt != ReturnType.Enumerable) + Finally(); + } + + protected override void BuildAbstractGetter() + { + BuildAbstractMethod(); + } + + protected override void BuildAbstractSetter() + { + BuildAbstractMethod(); + } + + void GetSqlQueryAttribute() + { + object[] attrs = Context.CurrentMethod.GetCustomAttributes(typeof(SqlQueryAttribute), true); + + if (attrs.Length != 0) + _sqlQueryAttribute = (SqlQueryAttribute)attrs[0]; + } + + void AddParameter(ParameterInfo pi) + { + Type pType = pi.ParameterType; + + if (pType.IsByRef) + pType = pType.GetElementType(); + + if (TypeHelper.IsScalar(pType) +#if FW4 + || pi.IsRefCursor() +#endif + ) + _paramList.Add(pi); + else if (pType == typeof(DbManager) || pType.IsSubclassOf(typeof(DbManager))) + _createManager = false; + else + _refParamList.Add(pi); + } + + void ProcessParameters() + { + for (int i = 0; i < _parameters.Length; i++) + { + ParameterInfo pi = _parameters[i]; + NoMapAttribute[] attrs = (NoMapAttribute[])pi.GetCustomAttributes(typeof(NoMapAttribute), true); + + if (attrs.Length == 0) + AddParameter(pi); + else + { + for (int j = 0; j < attrs.Length; ++j) + { + if (!attrs[j].NoMap) + AddParameter(pi); + + if (attrs[j] is FormatAttribute) + { + int index = ((FormatAttribute)attrs[j]).Index; + + if (index < 0) + index = 0; + else if (index > _formatParamList.Count) + index = _formatParamList.Count; + + _formatParamList.Insert(index, pi); + } + else if (attrs[j] is DestinationAttribute) + { + if (_destination != null) + throw new TypeBuilderException(Resources.DataAccessorBuilderTooManyDestinations); + + _destination = pi; + } + } + } + } + } + + void CreateDbManager(bool beginException) + { + EmitHelper emit = Context.MethodBuilder.Emitter; + + if (_createManager) + { + emit + .ldarg_0 + .callvirt(_baseType, "GetDbManager") + .stloc(_locManager); + + if (beginException) + emit.BeginExceptionBlock(); + } + else + { + for (int i = 0; i < _parameters.Length; i++) + { + Type pType = _parameters[i].ParameterType; + + if (pType == typeof(DbManager) || pType.IsSubclassOf(typeof(DbManager))) + { + emit + .ldarg(_parameters[i]) + .stloc(_locManager) + ; + + break; + } + } + } + } + + void SetObjectType() + { + var mi = Context.CurrentMethod; + var attrs = mi.GetCustomAttributes(typeof(ObjectTypeAttribute), true); + + if (attrs.Length == 0) + attrs = mi.DeclaringType.GetCustomAttributes(typeof(ObjectTypeAttribute), true); + else + _explicitObjectType = true; + + if (attrs.Length != 0) + _objectType = ((ObjectTypeAttribute)attrs[0]).ObjectType; + + if (_objectType == null) + { + var types = TypeHelper.GetGenericArguments(mi.DeclaringType, typeof(DataAccessor)); + + if (types != null) + _objectType = types[0]; + } + } + + #region ExecuteReader + + void ExecuteReader() + { + InitObjectType(); + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + + var attrs = Context.CurrentMethod.GetCustomAttributes(typeof(CommandBehaviorAttribute), true); + + if (attrs.Length == 0) + { + Context.MethodBuilder.Emitter + .callvirt(typeof(DbManager).GetMethod("ExecuteReader", Type.EmptyTypes)) + .stloc(Context.ReturnValue) + ; + } + else + { + Context.MethodBuilder.Emitter + .ldc_i4_((int)((CommandBehaviorAttribute)attrs[0]).CommandBehavior) + .callvirt(typeof(DbManager), "ExecuteReader", typeof(CommandBehavior)) + .stloc(Context.ReturnValue) + ; + } + } + + #endregion + + #region ExecuteDataSet + + void ExecuteDataSet(Type returnType) + { + CreateReturnTypeInstance(); + InitObjectType(); + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + + var emit = Context.MethodBuilder.Emitter; + + if (returnType == typeof(DataSet)) + { + LoadDestinationOrReturnValue(); + + object[] attrs = Context.CurrentMethod.GetCustomAttributes(typeof(DataSetTableAttribute), true); + + if (attrs.Length == 0) + { + emit + .callvirt(typeof(DbManager), "ExecuteDataSet", typeof(DataSet)) + .pop + .end() + ; + } + else + { + emit + .ldNameOrIndex(((DataSetTableAttribute)attrs[0]).NameOrIndex) + .callvirt(typeof(DbManager), "ExecuteDataSet", typeof(DataSet), typeof(NameOrIndexParameter)) + .pop + .end() + ; + } + } + else + { + emit + .pop + .end() + ; + + LoadDestinationOrReturnValue(); + + Label l1 = emit.DefineLabel(); + Label l2 = emit.DefineLabel(); + + emit + .callvirt(typeof(DataSet).GetProperty("Tables").GetGetMethod()) + .callvirt(typeof(InternalDataCollectionBase).GetProperty("Count").GetGetMethod()) + .ldc_i4_0 + .ble_s(l1) + .ldloc(_locManager); + + LoadDestinationOrReturnValue(); + + object[] attrs = Context.CurrentMethod.GetCustomAttributes(typeof(DataSetTableAttribute), true); + + if (attrs.Length == 0) + { + LoadDestinationOrReturnValue(); + + emit + .callvirt(typeof(DataSet).GetProperty("Tables").GetGetMethod()) + .ldc_i4_0 + .callvirt(typeof(DataTableCollection), "get_Item", typeof(int)) + .callvirt(typeof(DataTable).GetProperty("TableName").GetGetMethod()) + .call(typeof(NameOrIndexParameter), "op_Implicit", typeof(string)) + ; + } + else + { + emit + .ldNameOrIndex(((DataSetTableAttribute)attrs[0]).NameOrIndex) + ; + } + + emit + .callvirt(typeof(DbManager), "ExecuteDataSet", typeof(DataSet), typeof(NameOrIndexParameter)) + .pop + .br_s(l2) + .MarkLabel(l1) + .ldloc(_locManager); + + LoadDestinationOrReturnValue(); + + emit + .callvirt(typeof(DbManager), "ExecuteDataSet", typeof(DataSet)) + .pop + .MarkLabel(l2) + ; + } + } + + #endregion + + #region ExecuteDataTable + + void ExecuteDataTable() + { + CreateReturnTypeInstance(); + InitObjectType(); + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + LoadDestinationOrReturnValue(); + + EmitHelper emit = Context.MethodBuilder.Emitter; + + emit + .callvirt(typeof(DbManager), "ExecuteDataTable", typeof(DataTable)) + .pop + .end() + ; + + // When DataSetTableAttribute is present, simply set table name to the name specified. + // + object[] attrs = Context.CurrentMethod.GetCustomAttributes(typeof(DataSetTableAttribute), true); + + if (attrs.Length != 0) + { + DataSetTableAttribute attr = (DataSetTableAttribute)attrs[0]; + + if (!attr.NameOrIndex.ByName) + throw new TypeBuilderException(string.Format( + Resources.DataAccessorBuilder_DataSetTableMustBeByName, + Context.CurrentMethod.DeclaringType.Name, Context.CurrentMethod.Name)); + + LoadDestinationOrReturnValue(); + + emit + .ldstr(attr.NameOrIndex.Name) + .callvirt(typeof(DataTable), "set_TableName", typeof(string)) + ; + } + } + + #endregion + + #region ExecuteScalarList + + void ExecuteScalarList() + { + CreateReturnTypeInstance(); + InitObjectType(); + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + LoadDestinationOrReturnValue(); + + object[] attrs = Context.CurrentMethod.GetCustomAttributes(typeof(ScalarFieldNameAttribute), true); + + if (attrs.Length == 0) + { + Context.MethodBuilder.Emitter + .ldloc(_locObjType) + .callvirt(typeof(DbManager), "ExecuteScalarList", typeof(IList), typeof(Type)) + .pop + .end() + ; + } + else + { + Context.MethodBuilder.Emitter + .ldloc(_locObjType) + .ldNameOrIndex(((ScalarFieldNameAttribute)attrs[0]).NameOrIndex) + .callvirt(typeof(DbManager), "ExecuteScalarList", typeof(IList), typeof(Type), typeof(NameOrIndexParameter)) + .pop + .end() + ; + } + } + + void ExecuteList() + { + CreateReturnTypeInstance(); + InitObjectType(); + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + LoadDestinationOrReturnValue(); + + Context.MethodBuilder.Emitter + .CastIfNecessary(typeof(IList), MethodReturnType) + .ldloc(_locObjType) + .callvirt(typeof(DbManager), "ExecuteList", typeof(IList), typeof(Type)) + .pop + .end() + ; + } + + #endregion + + #region ExecuteDictionary + + public FieldBuilder GetIndexField(NameOrIndexParameter[] namesOrIndexes) + { + var id = "index$" + string.Join("%", + Array.ConvertAll(namesOrIndexes, + delegate(NameOrIndexParameter nameOrIndex) + { + return nameOrIndex.ToString(); + })); + + var fieldBuilder = Context.GetField(id); + + if (fieldBuilder == null) + { + fieldBuilder = Context.CreatePrivateStaticField(id, typeof(MapIndex)); + + EmitHelper emit = Context.TypeBuilder.TypeInitializer.Emitter; + + emit + .ldc_i4_(namesOrIndexes.Length) + .newarr(typeof(NameOrIndexParameter)) + ; + + for (int i = 0; i < namesOrIndexes.Length; i++) + { + emit + .dup + .ldc_i4_(i) + .ldelema(typeof(NameOrIndexParameter)); + + if (namesOrIndexes[i].ByName) + { + emit + .ldstr(namesOrIndexes[i].Name) + .call(typeof(NameOrIndexParameter), "op_Implicit", typeof(string)); + } + else + { + emit + .ldc_i4_(namesOrIndexes[i].Index) + .call(typeof(NameOrIndexParameter), "op_Implicit", typeof(int)); + } + + emit + .stobj(typeof(NameOrIndexParameter)) + .end() + ; + } + + emit + .newobj(typeof(MapIndex), typeof(NameOrIndexParameter[])) + .stsfld(fieldBuilder) + ; + } + + return fieldBuilder; + } + + /// + /// Maps primary keys(s) to a scalar field. + /// + void ExecuteScalarDictionaryWithPK( + Type keyType, + NameOrIndexParameter scalarField, + Type elementType) + { + CreateReturnTypeInstance(); + InitObjectType(); + + Context.MethodBuilder.Emitter + .ldarg_0 + .end() + ; + + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + LoadDestinationOrReturnValue(); + + Context.MethodBuilder.Emitter + .ldloc(_locObjType) + .LoadType(keyType) + .ldstr(Context.CurrentMethod.Name) + .ldNameOrIndex(scalarField) + .LoadType(elementType) + .callvirt(_baseType, "ExecuteScalarDictionary", _bindingFlags, + typeof(DbManager), typeof(IDictionary), typeof(Type), + typeof(Type), typeof(string), typeof(NameOrIndexParameter), typeof(Type)) + ; + } + + /// + /// Maps a complex index to a scalar field. + /// + void ExecuteScalarDictionaryWithMapIndex( + NameOrIndexParameter[] index, + NameOrIndexParameter scalarField, + Type elementType) + { + _objectType = elementType; + + CreateReturnTypeInstance(); + InitObjectType(); + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + LoadDestinationOrReturnValue(); + + Context.MethodBuilder.Emitter + .ldsfld(GetIndexField(index)) + .ldNameOrIndex(scalarField) + .ldloc(_locObjType) + .callvirt(typeof(DbManager), "ExecuteScalarDictionary", + typeof(IDictionary), typeof(MapIndex), + typeof(NameOrIndexParameter), typeof(Type)) + .pop + .end() + ; + } + + /// + /// Maps any single field to any (other) single field. + /// + void ExecuteScalarDictionaryWithScalarKey( + NameOrIndexParameter keyField, Type keyType, + NameOrIndexParameter scalarField, Type elementType) + { + _objectType = elementType; + + CreateReturnTypeInstance(); + InitObjectType(); + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + LoadDestinationOrReturnValue(); + + Context.MethodBuilder.Emitter + .ldNameOrIndex(keyField) + .LoadType(keyType) + .ldNameOrIndex(scalarField) + .ldloc(_locObjType) + .callvirt(typeof(DbManager), "ExecuteScalarDictionary", + typeof(IDictionary), typeof(NameOrIndexParameter), typeof(Type), + typeof(NameOrIndexParameter), typeof(Type)) + .pop + .end() + ; + } + + /// + /// Maps primary keys(s) to an object of the specified type. + /// + void ExecuteDictionaryWithPK( + Type keyType, + Type elementType) + { + EmitHelper emit = Context.MethodBuilder.Emitter; + + _objectType = elementType; + + CreateReturnTypeInstance(); + InitObjectType(); + + emit + .ldarg_0 + .end() + ; + + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + LoadDestinationOrReturnValue(); + + if (IsGenericDestinationOrReturnValue()) + { + Type[] genericArgs = Context.ReturnValue.LocalType.GetGenericArguments(); + Type[] types = new Type[] + { + typeof(DbManager), + typeof(IDictionary<,>).MakeGenericType(genericArgs), + typeof(Type), + typeof(string), + }; + MethodInfo method = _baseType.GetMethod("ExecuteDictionary", + _bindingFlags, GenericBinder.Generic, types, null); + + if (TypeHelper.IsSameOrParent(typeof(CompoundValue), genericArgs[0])) + method = method.MakeGenericMethod(genericArgs[1]); + else + method = method.MakeGenericMethod(genericArgs); + + emit + .ldloc(_locObjType) + .ldstr(Context.CurrentMethod.Name) + .callvirt(method) + ; + } + else + + emit + .ldloc(_locObjType) + .LoadType(keyType) + .ldstr(Context.CurrentMethod.Name) + .callvirt(_baseType, "ExecuteDictionary", _bindingFlags, + typeof(DbManager), typeof(IDictionary), typeof(Type), + typeof(Type), typeof(string)) + ; + } + + /// + /// Maps a complex index to an object of the specified type. + /// + void ExecuteDictionaryWithMapIndex( + NameOrIndexParameter[] index, + Type elementType) + { + _objectType = elementType; + + CreateReturnTypeInstance(); + InitObjectType(); + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + LoadDestinationOrReturnValue(); + + Context.MethodBuilder.Emitter + .ldsfld(GetIndexField(index)) + .ldloc(_locObjType) + .ldnull + .callvirt(typeof(DbManager), "ExecuteDictionary", + typeof(IDictionary), typeof(MapIndex), typeof(Type), typeof(object[])) + .pop + .end() + ; + } + + /// + /// Maps any single field to object type. + /// + void ExecuteDictionaryWithScalarKey( + NameOrIndexParameter keyField, + Type elementType) + { + EmitHelper emit = Context.MethodBuilder.Emitter; + + _objectType = elementType; + + CreateReturnTypeInstance(); + InitObjectType(); + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + LoadDestinationOrReturnValue(); + + if (IsGenericDestinationOrReturnValue()) + { + Type[] genericArgs = Context.ReturnValue.LocalType.GetGenericArguments(); + Type[] types = new Type[] + { + typeof(IDictionary<,>).MakeGenericType(genericArgs), + typeof(NameOrIndexParameter), + typeof(Type), + typeof(object[]), + }; + MethodInfo method = typeof(DbManager).GetMethod("ExecuteDictionary", _bindingFlags, GenericBinder.Generic, types, null) + .MakeGenericMethod(genericArgs); + + emit + .ldNameOrIndex(keyField) + .ldloc(_locObjType) + .ldnull + .callvirt(method) + .pop + .end() + ; + } + else + { + emit + .ldNameOrIndex(keyField) + .ldloc(_locObjType) + .ldnull + .callvirt(typeof(DbManager), "ExecuteDictionary", typeof(IDictionary), typeof(NameOrIndexParameter), typeof(Type), typeof(object[])) + .pop + .end() + ; + } + } + + #endregion + + #region ExecuteEnumerable + + public void ExecuteEnumerable() + { + EmitHelper emit = Context.MethodBuilder.Emitter; + Type returnType = Context.CurrentMethod.ReturnType; + + if (_objectType == null && returnType.IsGenericType) + _objectType = returnType.GetGenericArguments()[0]; + + if (_objectType == null || _objectType == typeof(object)) + ThrowTypeBuilderException(Resources.DataAccessorBuilder_BadListItemType); + + Type returnObjectType = returnType.IsGenericType ? returnType.GetGenericArguments()[0] : _objectType; + + InitObjectType(); + + Context.MethodBuilder.Emitter + .ldarg_0 + .end() + ; + + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + + Type[] genericArgs = new Type[] { returnObjectType }; + Type[] types = new Type[] { typeof(DbManager), typeof(Type), typeof(bool), }; + MethodInfo method = _baseType + .GetMethod("ExecuteEnumerable", _bindingFlags, GenericBinder.Generic, types, null) + .MakeGenericMethod(genericArgs); + + emit + .LoadType(_objectType) + .ldc_i4_1 + .callvirt(method) + .stloc(Context.ReturnValue) + ; + } + + #endregion + + #region ExecuteNonQuery + + public void ExecuteNonQuery() + { + if (_destination != null) + throw new TypeBuilderException(Resources.DataAccessorBuilder_CantExecuteNonQueryToDestination); + + InitObjectType(); + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + + MethodInfo mi = typeof(DbManager).GetMethod("ExecuteNonQuery", Type.EmptyTypes); + LocalBuilder locExec = Context.MethodBuilder.Emitter.DeclareLocal(mi.ReturnType); + + Context.MethodBuilder.Emitter + .callvirt(mi) + .stloc(locExec) + ; + + if (Context.ReturnValue != null) + { + Context.MethodBuilder.Emitter + .ldloc(locExec) + .stloc(Context.ReturnValue) + ; + } + } + + #endregion + + #region ExecuteScalar + + public void ExecuteScalar() + { + EmitHelper emit = Context.MethodBuilder.Emitter; + Type returnType = Context.CurrentMethod.ReturnType; + Type scalarType; + + if (_destination != null) + { + if (_destination.ParameterType.IsByRef) + scalarType = _destination.ParameterType.GetElementType(); + else + throw new TypeBuilderException(Resources.DataAccessorBuilder_ScalarDestinationIsNotByRef); + + if (returnType != typeof(void) && !TypeHelper.IsSameOrParent(returnType, scalarType)) + { + // object Foo(out int num) is valid, + // IConvertible Foo(ref int num) is also ok, + // but string Bar(out DateTime dt) is not + // + throw new TypeBuilderException(string.Format( + Resources.DataAccessorBuilder_IncompatibleDestinationType, + returnType.FullName, Context.CurrentMethod.Name, scalarType.FullName)); + } + } + else + scalarType = returnType; + + if (_destination != null) + emit + .ldarg(_destination) + ; + + emit + .ldarg_0 + .ldloc(_locManager) + ; + + InitObjectType(); + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + + object[] attrs = Context.CurrentMethod.GetCustomAttributes(typeof(ScalarSourceAttribute), true); + + if (attrs.Length == 0) + { + emit + .callvirtNoGenerics(typeof(DbManager), "ExecuteScalar") + ; + } + else + { + ScalarSourceAttribute attr = (ScalarSourceAttribute)attrs[0]; + + emit + .ldc_i4_((int)attr.ScalarType) + .ldNameOrIndex(attr.NameOrIndex) + .callvirtNoGenerics(typeof(DbManager), "ExecuteScalar", typeof(ScalarSourceType), typeof(NameOrIndexParameter)); + } + + MethodInfo converter = GetConverterMethod(scalarType); + + if (converter == null) + { + emit + .LoadType(scalarType) + .ldnull + .callvirt(_baseType, "ConvertChangeType", _bindingFlags, typeof(DbManager), typeof(object), typeof(Type), typeof(object)) + .unboxIfValueType(scalarType) + ; + + } + else + { + emit + .ldnull + .callvirt(converter) + ; + } + + if (_destination != null) + { + emit + .stind(scalarType) + ; + + // The return value and a destination both are present + // + if (Context.ReturnValue != null) + { + emit + .ldargEx(_destination, false) + ; + + if (scalarType != returnType) + emit + .boxIfValueType(scalarType) + .CastFromObject(returnType) + ; + + emit.stloc(Context.ReturnValue) + ; + } + } + else + emit + .stloc(Context.ReturnValue) + ; + } + + #endregion + + #region ExecuteObject + + public void ExecuteObject() + { + InitObjectType(); + GetSprocNameOrSqlQueryTest(); + CallSetCommand(); + + EmitHelper emit = Context.MethodBuilder.Emitter; + + if (_destination != null) + { + emit + .ldarg(_destination) + .callvirt(typeof(DbManager), "ExecuteObject", typeof(Object)) + ; + } + else + { + emit + .ldloc(_locObjType) + .callvirt(typeof(DbManager), "ExecuteObject", typeof(Type)) + ; + } + + if (null != Context.ReturnValue) + { + emit + .castclass(_objectType) + .stloc(Context.ReturnValue) + ; + } + else + { + emit + .pop + .end() + ; + } + } + + #endregion + + void Finally() + { + if (_createManager) + { + Context.MethodBuilder.Emitter + .BeginFinallyBlock() + .ldarg_0 + .ldloc(_locManager) + .callvirt(_baseType, "Dispose", _bindingFlags, typeof(DbManager)) + .EndExceptionBlock() + ; + } + } + + void CreateReturnTypeInstance() + { + if (null == Context.ReturnValue) + return; + + if (null != _destination) + { + Context.MethodBuilder.Emitter + .ldarg(_destination) + .CastIfNecessary(Context.ReturnValue.LocalType, _destination.ParameterType) + .stloc(Context.ReturnValue) + ; + } + else + { + Type returnType = Context.CurrentMethod.ReturnType; + + if (returnType.IsInterface) + { + if (IsInterfaceOf(returnType, typeof(IList))) + returnType = typeof(ArrayList); + else if (IsInterfaceOf(returnType, typeof(IDictionary))) + returnType = typeof(Hashtable); + else if (returnType.GetGenericTypeDefinition() == typeof(IList<>)) + returnType = typeof(List<>).MakeGenericType(returnType.GetGenericArguments()); + else if (returnType.GetGenericTypeDefinition() == typeof(IDictionary<,>)) + returnType = typeof(Dictionary<,>).MakeGenericType(returnType.GetGenericArguments()); + } + + ConstructorInfo ci = TypeHelper.GetDefaultConstructor(returnType); + + if (ci == null) + throw new TypeBuilderException(string.Format(Resources.DataAccessorBuilder_CantCreateTypeInstance, + Context.CurrentMethod.ReturnType.FullName)); + + Context.MethodBuilder.Emitter + .newobj(ci) + .stloc(Context.ReturnValue) + ; + } + } + + Type MethodReturnType + { + get + { + return _destination != null ? + _destination.ParameterType : + Context.CurrentMethod.ReturnType; + } + } + + void LoadDestinationOrReturnValue() + { + if (_destination != null) + Context.MethodBuilder.Emitter.ldarg(_destination); + else + Context.MethodBuilder.Emitter.ldloc(Context.ReturnValue); + } + + bool IsGenericDestinationOrReturnValue() + { + return _destination == null ? + Context.ReturnValue.LocalType.IsGenericType : + _destination.ParameterType.IsGenericType; + } + + void InitObjectType() + { + Context.MethodBuilder.Emitter + .LoadType(_objectType) + .stloc(_locObjType) + ; + } + + static int _nameCounter; + static int _uniqueQueryID; + + void GetSprocNameOrSqlQueryTest() + { + EmitHelper emit = Context.MethodBuilder.Emitter; + + if (_sqlQueryAttribute != null) + { + emit + .ldloc(_locManager) + ; + + if (_sqlQueryAttribute.ID != int.MinValue) + { + emit + .ldarg_0 + .ldloc(_locManager) + .ldc_i4_(_sqlQueryAttribute.ID) + .ldc_i4_(++_uniqueQueryID) + ; + } + + if (_sqlQueryAttribute.IsDynamic) + { + Type attrType = typeof(SqlQueryAttribute); + FieldBuilder field = Context.CreatePrivateStaticField(attrType + "$" + ++_nameCounter, attrType); + Label isNull = emit.DefineLabel(); + + emit + .ldsfld(field) + .brtrue_s(isNull) + + .ldarg_0 + .call(typeof(MethodBase), "GetCurrentMethod") + .castclass(typeof(MethodInfo)) + .callvirt(_baseType, "GetSqlQueryAttribute", _bindingFlags, typeof(MethodInfo)) + + .stsfld(field) + .MarkLabel(isNull) + + .ldsfld(field) + .ldarg_0 + .ldloc(_locManager) + .callvirt(attrType, "GetSqlText", _bindingFlags, typeof(DataAccessor), typeof(DbManager)) + ; + } + else + { + emit + .ldstr(_sqlQueryAttribute.SqlText) + ; + } + + if (_sqlQueryAttribute.ID != int.MinValue) + { + emit + .callvirt(_baseType, "PrepareSqlQuery", _bindingFlags, + typeof(DbManager), typeof(int), typeof(int), typeof(string)) + ; + } + } + else + { + object[] attrs = Context.CurrentMethod.GetCustomAttributes(typeof(SprocNameAttribute), true); + + if (attrs.Length == 0) + { + attrs = Context.CurrentMethod.GetCustomAttributes(typeof(ActionNameAttribute), true); + + string actionName = attrs.Length == 0 ? + Context.CurrentMethod.Name : ((ActionNameAttribute)attrs[0]).Name; + + // Call GetSpName. + // + emit + .ldloc(_locManager) + .ldarg_0 + .ldloc(_locObjType) + .ldstr(actionName) + .callvirt(_baseType, "GetSpName", _bindingFlags, typeof(Type), typeof(string)) + ; + } + else + { + emit + .ldloc(_locManager) + .ldstr(((SprocNameAttribute)attrs[0]).Name) + ; + } + } + + // string.Format + // + if (_formatParamList.Count > 0) + { + emit + .ldc_i4_(_formatParamList.Count) + .newarr(typeof(object)) + ; + + for (int i = 0; i < _formatParamList.Count; i++) + { + ParameterInfo pi = (ParameterInfo)_formatParamList[i]; + + emit + .dup + .ldc_i4_(i) + .ldarg(pi) + .boxIfValueType(pi.ParameterType) + .stelem_ref + .end() + ; + } + + emit + .call(typeof(string), "Format", typeof(string), typeof(object[])) + ; + } + } + + void CallSetCommand() + { + EmitHelper emit = Context.MethodBuilder.Emitter; + + // Get DiscoverParametersAttribute. + // + object[] attrs = + Context.CurrentMethod.DeclaringType.GetCustomAttributes(typeof(DiscoverParametersAttribute), true); + + bool discoverParams = false; + + if (_sqlQueryAttribute == null) + { + discoverParams = attrs.Length == 0 ? + false : ((DiscoverParametersAttribute)attrs[0]).Discover; + + attrs = Context.CurrentMethod.GetCustomAttributes(typeof(DiscoverParametersAttribute), true); + + if (attrs.Length != 0) + discoverParams = ((DiscoverParametersAttribute)attrs[0]).Discover; + } + + LocalBuilder locParams = discoverParams ? + BuildParametersWithDiscoverParameters() : + BuildParameters(); + + // Call SetSpCommand. + // + string methodName = _sqlQueryAttribute == null ? "SetSpCommand" : "SetCommand"; + Type paramType = _sqlQueryAttribute == null ? typeof(object[]) : typeof(IDbDataParameter[]); + + emit + .ldloc(locParams) + .callvirt(typeof(DbManager), methodName, _bindingFlags, typeof(string), paramType) + ; + } + + LocalBuilder BuildParameters() + { + EmitHelper emit = Context.MethodBuilder.Emitter; + + LocalBuilder retParams = emit + .DeclareLocal(typeof(IDbDataParameter[])); + + LocalBuilder locParams = _refParamList.Count > 0 ? + BuildRefParameters() : + BuildSimpleParameters(); + + emit + .ldarg_0 + .ldloc(_locManager) + .ldloc(locParams) + .callvirt(_baseType, "PrepareParameters", _bindingFlags, typeof(DbManager), typeof(object[])) + .stloc(retParams) + ; + + return retParams; + } + + LocalBuilder BuildSimpleParameters() + { + EmitHelper emit = Context.MethodBuilder.Emitter; + + // Parameters. + // + LocalBuilder locParams = emit.DeclareLocal( + _sqlQueryAttribute == null ? typeof(object[]) : typeof(IDbDataParameter[])); + + emit + .ldc_i4_(_paramList.Count) + .newarr(_sqlQueryAttribute == null ? typeof(object) : typeof(IDbDataParameter)) + ; + + for (int i = 0; i < _paramList.Count; i++) + { + ParameterInfo pi = (ParameterInfo)_paramList[i]; + + emit + .dup + .ldc_i4_(i) + ; + + BuildParameter(pi); + + emit + .stelem_ref + .end() + ; + } + + emit.stloc(locParams); + return locParams; + } + + FieldBuilder CreateStringArrayField(object[] attrs) + { + if (attrs.Length == 0) + return null; + + List list = new List(); + + foreach (Direction attr in attrs) + if (attr.Members != null) + list.AddRange(attr.Members); + + if (list.Count == 0) + return null; + + list.Sort(string.CompareOrdinal); + + string[] strings = list.ToArray(); + + // There a no limit for a field name length, but Visual Studio Debugger + // may crash on fields with name longer then 256 symbols. + // + string key = "_string_array$" + string.Join("%", strings); + FieldBuilder fieldBuilder = Context.GetField(key); + + if (null == fieldBuilder) + { + fieldBuilder = Context.CreatePrivateStaticField(key, typeof(string[])); + + EmitHelper emit = Context.TypeBuilder.TypeInitializer.Emitter; + + emit + .ldc_i4_(strings.Length) + .newarr(typeof(string)) + ; + + for (int i = 0; i < strings.Length; i++) + { + emit + .dup + .ldc_i4_(i) + .ldstr(strings[i]) + .stelem_ref + .end() + ; + } + + emit + .stsfld(fieldBuilder) + ; + } + + return fieldBuilder; + } + + FieldBuilder CreateNullValueField(Type type, string value) + { + string key = "_null_value$" + type.FullName + "%" + value; + FieldBuilder fieldBuilder = Context.GetField(key); + + if (null == fieldBuilder) + { + fieldBuilder = Context.CreatePrivateStaticField(key, type); + + EmitHelper emit = Context.TypeBuilder.TypeInitializer.Emitter; + + emit + .LoadType(type) + .call(typeof(TypeDescriptor), "GetConverter", typeof(Type)) + .ldstr(value) + .callvirt(typeof(TypeConverter), "ConvertFromInvariantString", typeof(string)) + .unbox_any(type) + .stsfld(fieldBuilder) + ; + } + + return fieldBuilder; + } + + LocalBuilder BuildRefParameters() + { + EmitHelper emit = Context.MethodBuilder.Emitter; + + // Parameters. + // + LocalBuilder locParams = emit.DeclareLocal(typeof(object[])); + + emit + .ldc_i4_(_parameters.Length) + .newarr(typeof(object)) + ; + + for (int i = 0; i < _parameters.Length; i++) + { + ParameterInfo pi = _parameters[i]; + + emit + .dup + .ldc_i4_(i) + ; + + if (_paramList.Contains(pi)) + { + BuildParameter(pi); + } + else if (_refParamList.Contains(pi)) + { + var mapOutputParameters = false; + string returnValueMember = null; + FieldBuilder fieldBuilder; + var type = + pi.ParameterType == typeof(DataRow) || pi.ParameterType.IsSubclassOf(typeof(DataRow)) ? + typeof(DataRow) : typeof(object); + + emit + .ldarg_0 + .ldloc(_locManager) + .ldarg(pi) + ; + + fieldBuilder = CreateStringArrayField(pi.GetCustomAttributes(typeof(Direction.OutputAttribute), true)); + + if (fieldBuilder != null) + { + emit.ldsfld(fieldBuilder); + mapOutputParameters = true; + } + else + emit.ldnull.end(); + + fieldBuilder = CreateStringArrayField(pi.GetCustomAttributes(typeof(Direction.InputOutputAttribute), true)); + + if (fieldBuilder != null) + { + emit.ldsfld(fieldBuilder); + mapOutputParameters = true; + } + else + emit.ldnull.end(); + + fieldBuilder = CreateStringArrayField(pi.GetCustomAttributes(typeof(Direction.IgnoreAttribute), true)); + + if (fieldBuilder != null) + emit.ldsfld(fieldBuilder); + else + emit.ldnull.end(); + + emit + .ldnull + .callvirt(_baseType, "CreateParameters", _bindingFlags, + typeof(DbManager), type, typeof(string[]), typeof(string[]), typeof(string[]), typeof(IDbDataParameter[])) + ; + + object[] attrs = pi.GetCustomAttributes(typeof(Direction.ReturnValueAttribute), true); + + if (attrs.Length != 0) + returnValueMember = ((Direction.ReturnValueAttribute)attrs[0]).Member; + + if (null != returnValueMember || mapOutputParameters) + _mapOutputParameters.Add(new MapOutputParametersValue(returnValueMember, pi)); + } + else + { + emit + .ldnull + .end() + ; + } + + emit + .stelem_ref + .end() + ; + } + + emit.stloc(locParams); + return locParams; + } + + void LoadParameterOrNull(ParameterInfo pi, Type type) + { + EmitHelper emit = Context.MethodBuilder.Emitter; + object[] attrs = pi.GetCustomAttributes(typeof(ParamNullValueAttribute), true); + + object nullValue = attrs.Length == 0 ? + null : ((ParamNullValueAttribute)attrs[0]).Value; + + Label labelNull = emit.DefineLabel(); + Label labelEndIf = emit.DefineLabel(); + + if (pi.Attributes == ParameterAttributes.Out) + { + emit + .ldnull + .end() + ; + + return; + } + + if (nullValue != null) + { + Type nullValueType = type; + bool isNullable = TypeHelper.IsNullable(type); + + if (type.IsEnum) + { + nullValueType = Enum.GetUnderlyingType(type); + nullValue = System.Convert.ChangeType(nullValue, nullValueType); + } + else if (isNullable) + { + nullValueType = type.GetGenericArguments()[0]; + + emit + .ldarga(pi) + .call(type, "get_HasValue") + .brfalse(labelNull) + ; + } + + if (nullValueType == nullValue.GetType() && emit.LoadWellKnownValue(nullValue)) + { + if (nullValueType == typeof(string)) + emit + .ldargEx(pi, false) + .call(nullValueType, "Equals", nullValueType) + .brtrue(labelNull) + ; + else if (isNullable) + emit + .ldarga(pi) + .call(type, "get_Value") + .beq(labelNull) + ; + else + emit + .ldargEx(pi, false) + .beq(labelNull) + ; + } + else + { + string nullString = TypeDescriptor.GetConverter(nullValue).ConvertToInvariantString(nullValue); + FieldBuilder staticField = CreateNullValueField(nullValueType, nullString); + MethodInfo miEquals = new TypeHelper(nullValueType).GetPublicMethod("Equals", nullValueType); + + if (miEquals == null) + { + // Is it possible? + // + throw new TypeBuilderException(string.Format( + Resources.DataAccessorBuilder_EqualsMethodIsNotPublic, type.FullName)); + } + + if (isNullable) + emit + .ldsflda(staticField) + .ldarga(pi) + .call(pi.ParameterType, "get_Value") + ; + else + emit + .ldsflda(staticField) + .ldarg(pi) + ; + + if (miEquals.GetParameters()[0].ParameterType.IsClass) + emit + .boxIfValueType(nullValueType) + ; + + emit + .call(miEquals) + .brtrue(labelNull) + ; + } + } + + if (type.IsEnum) + emit + .ldloc(_locManager) + .callvirt(typeof(DbManager).GetProperty("MappingSchema").GetGetMethod()) + ; + + emit + .ldargEx(pi, true) + ; + + if (type.IsEnum) + emit + .ldc_i4_1 + .callvirt(typeof(MappingSchema), "MapEnumToValue", typeof(object), typeof(bool)) + ; + + if (nullValue != null) + { + emit + .br(labelEndIf) + .MarkLabel(labelNull) + .ldnull + .MarkLabel(labelEndIf) + ; + } + } + + void BuildParameter(ParameterInfo pi) + { + EmitHelper emit = Context.MethodBuilder.Emitter; + Type type = pi.ParameterType; + object[] attrs = pi.GetCustomAttributes(typeof(ParamNameAttribute), true); + string paramName = attrs.Length == 0 ? pi.Name : ((ParamNameAttribute)attrs[0]).Name; + + ParameterDirection direction = !type.IsByRef ? ParameterDirection.Input : + pi.IsOut ? ParameterDirection.Output : ParameterDirection.InputOutput; + + emit + .ldloc(_locManager) + .ldc_i4_((int)direction) + ; + + if (paramName[0] != '@') + { + string methodName = _sqlQueryAttribute == null ? "GetSpParameterName" : "GetQueryParameterName"; + emit + .ldarg_0 + .ldloc(_locManager) + .ldstr(paramName) + .callvirt(_baseType, methodName, _bindingFlags, typeof(DbManager), typeof(string)) + ; + } + else + emit.ldstr(paramName); + + if (type.IsByRef) + { + if (_outputParameters == null) + _outputParameters = new ArrayList(); + + _outputParameters.Add(pi); + + type = type.GetElementType(); + } + + LoadParameterOrNull(pi, type); + + // Special case for user-defined types. + // + attrs = pi.GetCustomAttributes(typeof(ParamTypeNameAttribute), true); + if (attrs.Length > 0) + { + emit + .ldstr(((ParamTypeNameAttribute)attrs[0]).TypeName) + .callvirt(typeof(DbManager), "Parameter", + typeof(ParameterDirection), typeof(string), typeof(object), typeof(string)) + ; + } + else + { + emit + .callvirt(typeof(DbManager), "Parameter", + typeof(ParameterDirection), typeof(string), typeof(object)) + ; + } + + // Check if parameter type/size is specified. + // + attrs = pi.GetCustomAttributes(typeof(ParamDbTypeAttribute), true); + if (attrs.Length > 0) + { + emit + .dup + .ldc_i4_((int)((ParamDbTypeAttribute)attrs[0]).DbType) + .callvirt(typeof(IDataParameter), "set_DbType", typeof(DbType)) + ; + } + + attrs = pi.GetCustomAttributes(typeof(ParamSizeAttribute), true); + if (attrs.Length > 0) + { + emit + .dup + .ldc_i4_(((ParamSizeAttribute)attrs[0]).Size) + .callvirt(typeof(IDbDataParameter), "set_Size", typeof(int)) + ; + } + } + + LocalBuilder BuildParametersWithDiscoverParameters() + { + EmitHelper emit = Context.MethodBuilder.Emitter; + LocalBuilder locParams = emit.DeclareLocal(typeof(object[])); + + emit + .ldc_i4_(_paramList.Count) + .newarr(typeof(object)) + ; + + for (int i = 0; i < _paramList.Count; i++) + { + ParameterInfo pi = (ParameterInfo)_paramList[i]; + + emit + .dup + .ldc_i4_(i) + ; + + LoadParameterOrNull(pi, pi.ParameterType); + + emit + .stelem_ref + .end() + ; + } + + emit.stloc(locParams); + return locParams; + } + + void StoreParameterValue(LocalBuilder param, ParameterInfo pi, Type type) + { + EmitHelper emit = Context.MethodBuilder.Emitter; + Label labelNull = emit.DefineLabel(); + Label labelEndIf = emit.DefineLabel(); + + object[] attrs = pi.GetCustomAttributes(typeof(ParamNullValueAttribute), true); + object nullValue = attrs.Length == 0 ? null : ((ParamNullValueAttribute)attrs[0]).Value; + + if (nullValue != null) + { + emit + .ldarg_0 + .ldloc(_locManager) + .ldloc(param) + .callvirt(typeof(IDataParameter).GetProperty("Value").GetGetMethod()) + .ldloc(param) + .callvirt(_baseType, "IsNull", _bindingFlags, typeof(DbManager), typeof(object), typeof(object)) + .brtrue(labelNull) + ; + } + + if (type.IsEnum) + { + emit + .ldloc(_locManager) + .callvirt(typeof(DbManager).GetProperty("MappingSchema").GetGetMethod()) + .ldloc(param) + .callvirt(typeof(IDataParameter).GetProperty("Value").GetGetMethod()) + .LoadType(type) + .callvirt(typeof(MappingSchema), "MapValueToEnum", typeof(object), typeof(Type)) + .CastFromObject(type) + ; + } +#if FW4 + else if (pi.IsRefCursor()) + { + // Make sure the parameter is a List + if (!type.GetInterfaces().Contains(typeof(IList))) + { + throw new Exception("The argument '" + pi.Name + "' must be of type 'IList'"); + } + //Get the generic type of the list + Type genericType = type.GetGenericArguments().First(); + + + // Get the data reader to the ref cursor + var dataReader = emit.DeclareLocal(typeof(IDataReader)); + emit + .ldloc(_locManager) + .callvirt(typeof(DbManager).GetProperty("DataProvider").GetGetMethod()) + .ldloc(param) + .callvirt(typeof(IDataParameter).GetProperty("Value").GetGetMethod()) + .callvirt(typeof(DataProviderBase), "GetRefCursorDataReader", typeof(object)) + .CastFromObject(typeof(IDataReader)) + .stloc(dataReader) + ; + + // Create the generic methos info to invoke + var mapDataReaderToListMethodInfo = typeof (MappingSchema).GetMethod("MapDataReaderToList", + new[] + { + typeof (IDataReader), + typeof (object[]) + }) + .MakeGenericMethod(genericType); + + // Run MapDataReaderToList + emit + .ldloc(_locManager) + .callvirt(typeof(DbManager).GetProperty("MappingSchema").GetGetMethod()) + .ldloc(dataReader) + .ldnull + .callvirt(mapDataReaderToListMethodInfo) + ; + } +#endif + else + { + emit + .ldarg_0 + .ldloc(_locManager) + .ldloc(param) + .callvirt(typeof(IDataParameter).GetProperty("Value").GetGetMethod()) + ; + + MethodInfo converter = GetConverterMethod(type); + + if (converter == null) + { + emit + .LoadType(type) + .ldloc(param) + .callvirt(_baseType, "ConvertChangeType", _bindingFlags, typeof(DbManager), typeof(object), typeof(Type), typeof(object)) + .unboxIfValueType(type) + ; + } + else + { + emit + .ldloc(param) + .callvirt(converter) + ; + } + } + + if (nullValue != null) + { + emit + .br(labelEndIf) + .MarkLabel(labelNull); + + if (nullValue.GetType() != type || !emit.LoadWellKnownValue(nullValue)) + { + string nullString = TypeDescriptor.GetConverter(type).ConvertToInvariantString(nullValue); + FieldBuilder staticField = CreateNullValueField(type, nullString); + + emit + .ldsfld(staticField) + ; + } + + emit + .MarkLabel(labelEndIf) + ; + } + + emit.stind(type); + } + + void GetOutRefParameters() + { + EmitHelper emit = Context.MethodBuilder.Emitter; + + if (_outputParameters != null) + { + LocalBuilder param = emit.DeclareLocal(typeof(IDataParameter)); + + foreach (ParameterInfo pi in _outputParameters) + { + Type type = pi.ParameterType.GetElementType(); + + emit + .ldarg(pi) + ; + + // Get parameter. + // + object[] attrs = pi.GetCustomAttributes(typeof(ParamNameAttribute), true); + + string paramName = attrs.Length == 0 ? + pi.Name : ((ParamNameAttribute)attrs[0]).Name; + + emit + .ldarg_0 + .ldloc(_locManager) + ; + + if (paramName[0] != '@') + { + string methodName = _sqlQueryAttribute == null ? "GetSpParameterName" : "GetQueryParameterName"; + + emit + .ldarg_0 + .ldloc(_locManager) + .ldstr(paramName) + .callvirt(_baseType, methodName, _bindingFlags, typeof(DbManager), typeof(string)) + ; + } + else + emit.ldstr(paramName); + + emit + .callvirt(_baseType, "GetParameter", _bindingFlags, typeof(DbManager), typeof(string)) + .stloc(param) + ; + + StoreParameterValue(param, pi, type); + } + } + + foreach (MapOutputParametersValue v in _mapOutputParameters) + { + emit + .ldloc(_locManager) + .ldstrEx(v.ReturnValueMember) + .ldarg(v.ParameterInfo) + .callvirt(typeof(DbManager), "MapOutputParameters", typeof(string), typeof(object)); + } + } + + static bool IsInterfaceOf(Type type, Type interfaceType) + { + Type[] types = type.GetInterfaces(); + + foreach (Type t in types) + if (t == interfaceType) + return true; + + return type == interfaceType; + } + + private MethodInfo GetConverterMethod(Type type) + { + if (type.IsEnum) + type = Enum.GetUnderlyingType(type); + + Type[] types = new Type[] { typeof(DbManager), typeof(object), typeof(object) }; + return _baseType.GetMethod("ConvertTo" + type.Name, _bindingFlags, null, types, null); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DataAccessorT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DataAccessorT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using BLToolkit.Data; + +namespace BLToolkit.DataAccess +{ + public abstract class DataAccessor : DataAccessor + { + #region Constructors + + [System.Diagnostics.DebuggerStepThrough] + protected DataAccessor() + { + } + + [System.Diagnostics.DebuggerStepThrough] + protected DataAccessor(DbManager dbManager) + : base(dbManager) + { + } + + [System.Diagnostics.DebuggerStepThrough] + protected DataAccessor(DbManager dbManager, bool dispose) + : base(dbManager, dispose) + { + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DataAccessorTA.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DataAccessorTA.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +using BLToolkit.Data; +using BLToolkit.TypeBuilder; + +namespace BLToolkit.DataAccess +{ + public abstract class DataAccessor : DataAccessor + where TA : DataAccessor + { + #region Constructors + + [System.Diagnostics.DebuggerStepThrough] + protected DataAccessor() + { + } + + [System.Diagnostics.DebuggerStepThrough] + protected DataAccessor(DbManager dbManager) + : base(dbManager) + { + } + + #endregion + + #region CreateInstance + + public static TA CreateInstance() + { + return TypeFactory.CreateInstance(); + } + + public static TA CreateInstance(DbManager dbManager) + { + return CreateInstance(dbManager, false); + } + + public static TA CreateInstance(DbManager dbManager, bool dispose) + { + TA da = TypeFactory.CreateInstance(); + + da.SetDbManager(dbManager, dispose); + + return da; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DataSetTableAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DataSetTableAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,31 @@ +using System; + +using BLToolkit.Common; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Method, AllowMultiple=false)] + public class DataSetTableAttribute : Attribute + { + public DataSetTableAttribute() + { + } + + public DataSetTableAttribute(string name) + { + _nameOrIndex = name; + } + + public DataSetTableAttribute(int index) + { + _nameOrIndex = index; + } + + private NameOrIndexParameter _nameOrIndex; + public NameOrIndexParameter NameOrIndex + { + get { return _nameOrIndex; } + set { _nameOrIndex = value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DbTypeAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DbTypeAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ +using System; +using System.Data; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false), CLSCompliant(false)] + public sealed class DbTypeAttribute : Attribute + { + public DbType DbType { get; set; } + public int? Size { get; set; } + + public DbTypeAttribute(DbType sqlDbType) + { + DbType = sqlDbType; + } + + public DbTypeAttribute(DbType sqlDbType, int size) + { + DbType = sqlDbType; + Size = size; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DestinationAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DestinationAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Parameter)] + public class DestinationAttribute : NoMapAttribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/Direction.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/Direction.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,54 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Parameter), CLSCompliant(false)] + public abstract class Direction : Attribute + { + protected string[] _members; + public string[] Members + { + get { return _members; } + set { _members = value; } + } + + public class OutputAttribute : Direction + { + public OutputAttribute(params string[] members) + { + _members = members; + } + } + + public class InputOutputAttribute : Direction + { + public InputOutputAttribute(params string[] members) + { + _members = members; + } + } + + public class IgnoreAttribute : Direction + { + public IgnoreAttribute(params string[] members) + { + _members = members; + } + } + + public class ReturnValueAttribute : Direction + { + protected string _member; + public string Member + { + get { return _member; } + set { _member = value; } + } + + public ReturnValueAttribute(string member) + { + _member = member; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/DiscoverParametersAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/DiscoverParametersAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] + public class DiscoverParametersAttribute : Attribute + { + public DiscoverParametersAttribute() + { + _discover = true; + } + + public DiscoverParametersAttribute(bool discover) + { + _discover = discover; + } + + private readonly bool _discover; + public bool Discover + { + get { return _discover; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/FormatAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/FormatAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Parameter)] + public class FormatAttribute : NoMapAttribute + { + public FormatAttribute() + { + _index = int.MaxValue; + } + + public FormatAttribute(int index) + { + _index = index; + } + + private readonly int _index; + public int Index + { + get { return _index; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ISqlQueryT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ISqlQueryT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using BLToolkit.Data; + +namespace BLToolkit.DataAccess +{ + public interface ISqlQueryT + { + T SelectByKey(DbManager db, params object[] keys); + T SelectByKey(params object[] keys); + List SelectAll(DbManager db); + + TL SelectAll(DbManager db, TL list) + where TL : IList; + + TL SelectAll(DbManager db) + where TL : IList, new(); + + List SelectAll(); + + TL SelectAll(TL list) + where TL : IList; + + TL SelectAll() + where TL : IList, new(); + + int Insert(DbManager db, T obj); + int Insert(T obj); + int Insert(DbManager db, int maxBatchSize, IEnumerable list); + int Insert(int maxBatchSize, IEnumerable list); + int Insert(DbManager db, IEnumerable list); + int Insert(IEnumerable list); + int Update(DbManager db, T obj); + int Update(T obj); + int Update(DbManager db, int maxBatchSize, IEnumerable list); + int Update(int maxBatchSize, IEnumerable list); + int Update(DbManager db, IEnumerable list); + int Update(IEnumerable list); + int DeleteByKey(DbManager db, params object[] key); + int DeleteByKey(params object[] key); + int Delete(DbManager db, T obj); + int Delete(T obj); + int Delete(DbManager db, int maxBatchSize, IEnumerable list); + int Delete(int maxBatchSize, IEnumerable list); + int Delete(DbManager db, IEnumerable list); + int Delete(IEnumerable list); + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/IdentityAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/IdentityAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [Serializable] + [AttributeUsage( + AttributeTargets.Field | AttributeTargets.Property | + AttributeTargets.Class | AttributeTargets.Interface, + AllowMultiple = true)] + public class IdentityAttribute : NonUpdatableAttribute + { + public IdentityAttribute() : base(true, true, true) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/IndexAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/IndexAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,50 @@ +using System; + +using BLToolkit.Common; +using BLToolkit.Properties; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Method), CLSCompliant(false)] + public class IndexAttribute : Attribute + { + public IndexAttribute(params string[] names) + { + if (null == names) + throw new ArgumentNullException("names"); + + if (names.Length == 0) + throw new ArgumentException(Resources.MapIndex_EmptyNames, "names"); + + _fields = NameOrIndexParameter.FromStringArray(names); + } + + public IndexAttribute(params int[] indices) + { + if (null == indices) + throw new ArgumentNullException("indices"); + + if (indices.Length == 0) + throw new ArgumentException(Resources.MapIndex_EmptyIndices, "indices"); + + _fields = NameOrIndexParameter.FromIndexArray(indices); + } + + public IndexAttribute(params NameOrIndexParameter[] fields) + { + if (null == fields) + throw new ArgumentNullException("fields"); + + if (fields.Length == 0) + throw new ArgumentException(Resources.MapIndex_EmptyFields, "fields"); + + _fields = fields; + } + + private readonly NameOrIndexParameter[] _fields; + public NameOrIndexParameter[] Fields + { + get { return _fields; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/NoMapAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/NoMapAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Parameter)] + public class NoMapAttribute : Attribute + { + public NoMapAttribute() + { + _noMap = true; + } + + public NoMapAttribute(bool noMap) + { + _noMap = noMap; + } + + private bool _noMap; + public bool NoMap + { + get { return _noMap; } + set { _noMap = value; } + } + } +} + diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/NonUpdatableAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/NonUpdatableAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,29 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [Serializable] + [AttributeUsage( + AttributeTargets.Field | AttributeTargets.Property | + AttributeTargets.Class | AttributeTargets.Interface, + AllowMultiple = true)] + public class NonUpdatableAttribute : Attribute + { + public NonUpdatableAttribute() + : this(true, true, false) + { + } + + public NonUpdatableAttribute(bool onInsert, bool onUpdate, bool isIdentity) + { + OnInsert = onInsert; + OnUpdate = onUpdate; + IsIdentity = isIdentity; + } + + public bool OnInsert { get; set; } + public bool OnUpdate { get; set; } + public bool IsIdentity { get; set; } + public string FieldName { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ObjectTypeAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ObjectTypeAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [JetBrains.Annotations.BaseTypeRequired(typeof(DataAccessor))] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] + public class ObjectTypeAttribute : Attribute + { + public ObjectTypeAttribute(Type objectType) + { + _objectType = objectType; + } + + private readonly Type _objectType; + public Type ObjectType + { + get { return _objectType; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ParamDbTypeAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ParamDbTypeAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; +using System.Data; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Parameter)] + public class ParamDbTypeAttribute : Attribute + { + public ParamDbTypeAttribute(DbType dbType) + { + _dbType = dbType; + } + + private readonly DbType _dbType; + public DbType DbType + { + get { return _dbType; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ParamNameAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ParamNameAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Parameter)] + public class ParamNameAttribute : Attribute + { + public ParamNameAttribute(string name) + { + _name = name; + } + + private readonly string _name; + public string Name + { + get { return _name; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ParamNullValue.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ParamNullValue.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +using System; +using System.ComponentModel; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Parameter)] + public class ParamNullValueAttribute : Attribute + { + public ParamNullValueAttribute(object value) + { + _value = value; + } + + public ParamNullValueAttribute(Type type, string value) + { + _value = TypeDescriptor.GetConverter(type).ConvertFromInvariantString(value); + } + + private readonly object _value; + public object Value + { + get { return _value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ParamSizeAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ParamSizeAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Parameter)] + public class ParamSizeAttribute : Attribute + { + public ParamSizeAttribute(int size) + { + _size = size; + } + + private readonly int _size; + public int Size + { + get { return _size; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ParamTypeNameAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ParamTypeNameAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Parameter)] + public class ParamTypeNameAttribute : Attribute + { + public ParamTypeNameAttribute(string typeName) + { + _typeName = typeName; + } + + private readonly string _typeName; + public string TypeName + { + get { return _typeName; } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/PrimaryKeyAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/PrimaryKeyAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public sealed class PrimaryKeyAttribute : Attribute + { + public PrimaryKeyAttribute() + { + _order = -1; + } + + public PrimaryKeyAttribute(int order) + { + _order = order; + } + + private readonly int _order; + public int Order + { + get { return _order; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/PrimaryKeyGeneratorType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/PrimaryKeyGeneratorType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ +namespace BLToolkit.DataAccess +{ + public enum PrimaryKeyGeneratorType + { + Sequence, + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ScalarAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ScalarAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,17 @@ +using System; + +namespace BLToolkit.DataAccess +{ + /// + /// This attribute is used to represent that a type is a UDT type linked to a UDT Type in the DB (Used most commanly in Oracle) + /// + /// Without this attribute if you try to use the code generation method to call a Stored Procedure in the DB and try to pass the UDT as a parm + /// BLToolkit will flaten the object and cause error's + /// + /// Another solution is to convert your UDT to a Struct which also causes BLToolkits 'IsScaler()' Method to return true. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] + public class ScalarAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ScalarFieldNameAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ScalarFieldNameAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,27 @@ +using System; + +using BLToolkit.Common; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Method)] + public class ScalarFieldNameAttribute : Attribute + { + public ScalarFieldNameAttribute(string name) + { + _nameOrIndex = name; + } + + public ScalarFieldNameAttribute(int index) + { + _nameOrIndex = index; + } + + private NameOrIndexParameter _nameOrIndex; + public NameOrIndexParameter NameOrIndex + { + get { return _nameOrIndex; } + set { _nameOrIndex = value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/ScalarSourceAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/ScalarSourceAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ +using System; + +using BLToolkit.Data; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Method)] + public class ScalarSourceAttribute : ScalarFieldNameAttribute + { + public ScalarSourceAttribute(ScalarSourceType scalarType) + : base(0) + { + _scalarType = scalarType; + } + + public ScalarSourceAttribute(ScalarSourceType scalarType, string name) + : base(name) + { + _scalarType = scalarType; + } + + public ScalarSourceAttribute(ScalarSourceType scalarType, int index) + : base(index) + { + _scalarType = scalarType; + } + + private ScalarSourceType _scalarType; + public ScalarSourceType ScalarType + { + get { return _scalarType; } + set { _scalarType = value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/SequenceKeyGenerator.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/SequenceKeyGenerator.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ +using System; + +namespace BLToolkit.DataAccess +{ + public class SequenceKeyGenerator : KeyGenerator + { + private readonly string _sequence; + + public SequenceKeyGenerator(string sequence) + { + _sequence = sequence; + } + + public string Sequence + { + get { return _sequence; } + } + } + + public class KeyGenerator + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/SprocNameAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/SprocNameAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Method)] + public class SprocNameAttribute : Attribute + { + public SprocNameAttribute(string name) + { + _name = name; + } + + private readonly string _name; + public string Name + { + get { return _name; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/SprocQuery.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/SprocQuery.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,282 @@ +using System; +using System.Collections; + +using BLToolkit.Data; + +namespace BLToolkit.DataAccess +{ + public class SprocQuery : DataAccessorBase + { + #region Constructors + + public SprocQuery() + { + } + + public SprocQuery(DbManager dbManager) + : base(dbManager) + { + } + + public SprocQuery(DbManager dbManager, bool dispose) + : base(dbManager, dispose) + { + } + + #endregion + + #region SelectByKey + + public virtual object SelectByKey(DbManager db, Type type, params object[] key) + { + return db + .SetSpCommand(GetSpName(type, "SelectByKey"), key) + .ExecuteObject(type); + } + + public virtual object SelectByKey(Type type, params object[] key) + { + DbManager db = GetDbManager(); + + try + { + return SelectByKey(db, type, key); + } + finally + { + Dispose(db); + } + } + + public virtual T SelectByKey(DbManager db, params object[] key) + { + return db + .SetSpCommand(GetSpName(typeof(T), "SelectByKey"), key) + .ExecuteObject(); + } + + public virtual T SelectByKey(params object[] key) + { + DbManager db = GetDbManager(); + + try + { + return SelectByKey(db, key); + } + finally + { + Dispose(db); + } + } + + #endregion + + #region SelectAll + + public virtual ArrayList SelectAll(DbManager db, Type type) + { + return db + .SetSpCommand(GetSpName(type, "SelectAll")) + .ExecuteList(type); + } + + public virtual IList SelectAll(DbManager db, IList list, Type type) + { + return db + .SetSpCommand(GetSpName(type, "SelectAll")) + .ExecuteList(list, type); + } + + public virtual ArrayList SelectAll(Type type) + { + DbManager db = GetDbManager(); + + try + { + return SelectAll(db, type); + } + finally + { + Dispose(db); + } + } + + public virtual IList SelectAll(IList list, Type type) + { + DbManager db = GetDbManager(); + + try + { + return SelectAll(db, list, type); + } + finally + { + Dispose(db); + } + } + + public virtual System.Collections.Generic.List SelectAll(DbManager db) + { + return db + .SetSpCommand(GetSpName(typeof(T), "SelectAll")) + .ExecuteList(); + } + + public virtual L SelectAll(DbManager db, L list) + where L : System.Collections.Generic.IList + { + return db + .SetSpCommand(GetSpName(typeof(T), "SelectAll")) + .ExecuteList(list); + } + + public virtual L SelectAll(DbManager db) + where L : System.Collections.Generic.IList, new() + { + return SelectAll(db, new L()); + } + + public virtual System.Collections.Generic.List SelectAll() + { + DbManager db = GetDbManager(); + + try + { + return SelectAll(db); + } + finally + { + Dispose(db); + } + } + + public virtual L SelectAll(L list) + where L : System.Collections.Generic.IList + { + DbManager db = GetDbManager(); + + try + { + return SelectAll(db, list); + } + finally + { + Dispose(db); + } + } + + public virtual L SelectAll() + where L : System.Collections.Generic.IList, new() + { + return SelectAll(new L()); + } + + #endregion + + #region Insert + + public virtual void Insert(DbManager db, object obj) + { + db + .SetSpCommand( + GetSpName(obj.GetType(), "Insert"), + db.CreateParameters(obj)) + .ExecuteNonQuery(); + } + + public virtual void Insert(object obj) + { + var db = GetDbManager(); + + try + { + Insert(db, obj); + } + finally + { + Dispose(db); + } + } + + #endregion + + #region Update + + public virtual int Update(DbManager db, object obj) + { + return db + .SetSpCommand( + GetSpName(obj.GetType(), "Update"), + db.CreateParameters(obj)) + .ExecuteNonQuery(); + } + + public virtual int Update(object obj) + { + DbManager db = GetDbManager(); + + try + { + return Update(db, obj); + } + finally + { + Dispose(db); + } + } + + #endregion + + #region DeleteByKey + + public virtual int DeleteByKey(DbManager db, Type type, params object[] key) + { + return db + .SetSpCommand(GetSpName(type, "Delete"), key) + .ExecuteNonQuery(); + } + + public virtual int DeleteByKey(Type type, params object[] key) + { + DbManager db = GetDbManager(); + + try + { + return DeleteByKey(db, type, key); + } + finally + { + Dispose(db); + } + } + + #endregion + + #region Delete + + public virtual int Delete(DbManager db, object obj) + { + return db + .SetSpCommand( + GetSpName(obj.GetType(), "Delete"), + db.CreateParameters(obj)) + .ExecuteNonQuery(); + } + + public virtual int Delete(object obj) + { + DbManager db = GetDbManager(); + + try + { + return Delete(db, obj); + } + finally + { + Dispose(db); + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/SprocQueryT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/SprocQueryT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,218 @@ +using System.Collections.Generic; + +using BLToolkit.Data; + +namespace BLToolkit.DataAccess +{ + public class SprocQuery : DataAccessorBase + { + #region Constructors + + public SprocQuery() + { + } + + public SprocQuery(DbManager dbManager) + : base(dbManager) + { + } + + public SprocQuery(DbManager dbManager, bool dispose) + : base(dbManager, dispose) + { + } + + #endregion + + #region SelectByKey + + public virtual T SelectByKey(DbManager db, params object[] key) + { + return db + .SetSpCommand(GetSpName(typeof(T), "SelectByKey"), key) + .ExecuteObject(); + } + + public virtual T SelectByKey(params object[] key) + { + DbManager db = GetDbManager(); + + try + { + return SelectByKey(db, key); + } + finally + { + Dispose(db); + } + } + + #endregion + + #region SelectAll + + public virtual List SelectAll(DbManager db) + { + return db + .SetSpCommand(GetSpName(typeof(T), "SelectAll")) + .ExecuteList(); + } + + public virtual L SelectAll(DbManager db, L list) + where L : IList + { + return db + .SetSpCommand(GetSpName(typeof(T), "SelectAll")) + .ExecuteList(list); + } + + public virtual L SelectAll(DbManager db) + where L : IList, new() + { + return SelectAll(db, new L()); + } + + public virtual List SelectAll() + { + DbManager db = GetDbManager(); + + try + { + return SelectAll(db); + } + finally + { + Dispose(db); + } + } + + public virtual L SelectAll(L list) + where L : IList + { + DbManager db = GetDbManager(); + + try + { + return SelectAll(db, list); + } + finally + { + Dispose(db); + } + } + + public virtual L SelectAll() + where L : IList, new() + { + return SelectAll(new L()); + } + + #endregion + + #region Insert + + public virtual void Insert(DbManager db, T obj) + { + db + .SetSpCommand( + GetSpName(obj.GetType(), "Insert"), + db.CreateParameters(obj)) + .ExecuteNonQuery(); + } + + public virtual void Insert(T obj) + { + var db = GetDbManager(); + + try + { + Insert(db, obj); + } + finally + { + Dispose(db); + } + } + + #endregion + + #region Update + + public virtual int Update(DbManager db, T obj) + { + return db + .SetSpCommand( + GetSpName(obj.GetType(), "Update"), + db.CreateParameters(obj)) + .ExecuteNonQuery(); + } + + public virtual int Update(T obj) + { + DbManager db = GetDbManager(); + + try + { + return Update(db, obj); + } + finally + { + Dispose(db); + } + } + + #endregion + + #region DeleteByKey + + public virtual int DeleteByKey(DbManager db, params object[] key) + { + return db + .SetSpCommand(GetSpName(typeof(T), "Delete"), key) + .ExecuteNonQuery(); + } + + public virtual int DeleteByKey(params object[] key) + { + DbManager db = GetDbManager(); + + try + { + return DeleteByKey(db, key); + } + finally + { + Dispose(db); + } + } + + #endregion + + #region Delete + + public virtual int Delete(DbManager db, T obj) + { + return db + .SetSpCommand( + GetSpName(obj.GetType(), "Delete"), + db.CreateParameters(obj)) + .ExecuteNonQuery(); + } + + public virtual int Delete(T obj) + { + DbManager db = GetDbManager(); + + try + { + return Delete(db, obj); + } + finally + { + Dispose(db); + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/SqlIgnoreAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/SqlIgnoreAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public class SqlIgnoreAttribute : Attribute + { + public SqlIgnoreAttribute() + { + _ignore = true; + } + + public SqlIgnoreAttribute(bool ignore) + { + _ignore = ignore; + } + + private bool _ignore; + public bool Ignore + { + get { return _ignore; } + set { _ignore = value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/SqlQuery.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/SqlQuery.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,336 @@ +using System; +using System.Collections; + +using BLToolkit.Data; +using BLToolkit.Reflection.Extension; + +namespace BLToolkit.DataAccess +{ + public class SqlQuery : SqlQueryBase + { + #region Constructors + + public SqlQuery() + { + } + + public SqlQuery(DbManager dbManager) + : base(dbManager) + { + } + + public SqlQuery(DbManager dbManager, bool dispose) + : base(dbManager, dispose) + { + } + + public SqlQuery(ExtensionList extensions) + { + Extensions = extensions; + } + + #endregion + + #region Overrides + + public SqlQueryInfo GetSqlQueryInfo(DbManager db, string actionName) + { + return base.GetSqlQueryInfo(db, typeof(T), actionName); + } + + #endregion + + #region SelectByKey + + public virtual object SelectByKey(DbManager db, Type type, params object[] keys) + { + var query = GetSqlQueryInfo(db, type, "SelectByKey"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, keys)) + .ExecuteObject(type); + } + + public virtual object SelectByKey(Type type, params object[] keys) + { + var db = GetDbManager(); + + try + { + return SelectByKey(db, type, keys); + } + finally + { + if (DisposeDbManager) + db.Dispose(); + } + } + + public virtual T SelectByKey(DbManager db, params object[] keys) + { + var query = GetSqlQueryInfo(db, typeof(T), "SelectByKey"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, keys)) + .ExecuteObject(); + } + + public virtual T SelectByKey(params object[] keys) + { + var db = GetDbManager(); + + try + { + return SelectByKey(db, keys); + } + finally + { + if (DisposeDbManager) + db.Dispose(); + } + } + + #endregion + + #region SelectAll + + public virtual ArrayList SelectAll(DbManager db, Type type) + { + var query = GetSqlQueryInfo(db, type, "SelectAll"); + + return db + .SetCommand(query.QueryText) + .ExecuteList(type); + } + + public virtual IList SelectAll(DbManager db, IList list, Type type) + { + var query = GetSqlQueryInfo(db, type, "SelectAll"); + + return db + .SetCommand(query.QueryText) + .ExecuteList(list, type); + } + + public virtual ArrayList SelectAll(Type type) + { + var db = GetDbManager(); + + try + { + return SelectAll(db, type); + } + finally + { + Dispose(db); + } + } + + public virtual IList SelectAll(IList list, Type type) + { + var db = GetDbManager(); + + try + { + return SelectAll(db, list, type); + } + finally + { + Dispose(db); + } + } + + public virtual System.Collections.Generic.List SelectAll(DbManager db) + { + var query = GetSqlQueryInfo(db, typeof(T), "SelectAll"); + + return db + .SetCommand(query.QueryText) + .ExecuteList(); + } + + public virtual TL SelectAll(DbManager db, TL list) + where TL : System.Collections.Generic.IList + { + var query = GetSqlQueryInfo(db, typeof(T), "SelectAll"); + + return db + .SetCommand(query.QueryText) + .ExecuteList(list); + } + + public virtual TL SelectAll(DbManager db) + where TL : System.Collections.Generic.IList, new() + { + return SelectAll(db, new TL()); + } + + public virtual System.Collections.Generic.List SelectAll() + { + var db = GetDbManager(); + + try + { + return SelectAll(db); + } + finally + { + Dispose(db); + } + } + + public virtual TL SelectAll(TL list) + where TL : System.Collections.Generic.IList + { + var db = GetDbManager(); + + try + { + return SelectAll(db, list); + } + finally + { + Dispose(db); + } + } + + public virtual TL SelectAll() + where TL : System.Collections.Generic.IList, new() + { + return SelectAll(new TL()); + } + + #endregion + + #region Insert + + public virtual int Insert(DbManager db, object obj) + { + var query = GetSqlQueryInfo(db, obj.GetType(), "Insert"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, obj)) + .ExecuteNonQuery(); + } + + public virtual int Insert(object obj) + { + var db = GetDbManager(); + + try + { + return Insert(db, obj); + } + finally + { + Dispose(db); + } + } + + #endregion + + #region Update + + public virtual int Update(DbManager db, object obj) + { + var query = GetSqlQueryInfo(db, obj.GetType(), "Update"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, obj)) + .ExecuteNonQuery(); + } + + public virtual int Update(object obj) + { + var db = GetDbManager(); + + try + { + return Update(db, obj); + } + finally + { + Dispose(db); + } + } + + #endregion + + #region DeleteByKey + + public virtual int DeleteByKey(DbManager db, Type type, params object[] key) + { + var query = GetSqlQueryInfo(db, type, "Delete"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, key)) + .ExecuteNonQuery(); + } + + public virtual int DeleteByKey(Type type, params object[] key) + { + var db = GetDbManager(); + + try + { + return DeleteByKey(db, type, key); + } + finally + { + Dispose(db); + } + } + + public virtual int DeleteByKey(DbManager db, params object[] key) + { + var query = GetSqlQueryInfo(db, typeof(T), "Delete"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, key)) + .ExecuteNonQuery(); + } + + public virtual int DeleteByKey(params object[] key) + { + var db = GetDbManager(); + + try + { + return DeleteByKey(db, key); + } + finally + { + Dispose(db); + } + } + + #endregion + + #region Delete + + public virtual int Delete(DbManager db, object obj) + { + var query = GetSqlQueryInfo(db, obj.GetType(), "Delete"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, obj)) + .ExecuteNonQuery(); + } + + public virtual int Delete(object obj) + { + var db = GetDbManager(); + + try + { + return Delete(db, obj); + } + finally + { + Dispose(db); + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/SqlQueryAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/SqlQueryAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,46 @@ +using System; + +using BLToolkit.Data; + +namespace BLToolkit.DataAccess +{ + [JetBrains.Annotations.BaseTypeRequired(typeof(DataAccessor))] + [AttributeUsage(AttributeTargets.Method)] + public class SqlQueryAttribute : Attribute + { + public SqlQueryAttribute() + { + } + + public SqlQueryAttribute(string sqlText) + { + _sqlText = sqlText; + } + + private string _sqlText; + public string SqlText + { + get { return _sqlText; } + set { _sqlText = value; } + } + + private bool _isDynamic; + public bool IsDynamic + { + get { return _isDynamic; } + set { _isDynamic = value; } + } + + private int _id = int.MinValue; + public int ID + { + get { return _id; } + set { _id = value; _isDynamic = value != int.MinValue; } + } + + public virtual string GetSqlText(DataAccessor accessor, DbManager dbManager) + { + return _sqlText; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/SqlQueryBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/SqlQueryBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,384 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +using BLToolkit.Aspects; +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; +using BLToolkit.Mapping; +using BLToolkit.Reflection; +using BLToolkit.Reflection.Extension; + +namespace BLToolkit.DataAccess +{ + public abstract class SqlQueryBase : DataAccessorBase + { + #region Constructors + + protected SqlQueryBase() + { + } + + protected SqlQueryBase(DbManager dbManager) + : base(dbManager) + { + } + + protected SqlQueryBase(DbManager dbManager, bool dispose) + : base(dbManager, dispose) + { + } + + #endregion + + #region Protected Members + + [NoInterception] + protected virtual MemberMapper[] GetFieldList(ObjectMapper om) + { + var list = new List(om.Count); + + foreach (MemberMapper mm in om) + if (mm.MapMemberInfo.SqlIgnore == false) + list.Add(mm); + + return list.ToArray(); + } + + [NoInterception] + protected virtual MemberMapper[] GetNonKeyFieldList(ObjectMapper om) + { + var typeExt = TypeExtension.GetTypeExtension(om.TypeAccessor.OriginalType, Extensions); + var list = new List(); + + foreach (MemberMapper mm in om) + { + if (mm.MapMemberInfo.SqlIgnore) + continue; + + var ma = mm.MapMemberInfo.MemberAccessor; + + bool isSet; + MappingSchema.MetadataProvider.GetPrimaryKeyOrder(om.TypeAccessor.OriginalType, typeExt, ma, out isSet); + + if (!isSet) + list.Add(mm); + } + + return list.ToArray(); + } + + struct MemberOrder + { + public MemberOrder(MemberMapper memberMapper, int order) + { + MemberMapper = memberMapper; + Order = order; + } + + public readonly MemberMapper MemberMapper; + public readonly int Order; + } + + private static readonly Hashtable _keyList = new Hashtable(); + + [NoInterception] + protected internal virtual MemberMapper[] GetKeyFieldList(DbManager db, Type type) + { + var key = type.FullName + "$" + db.DataProvider.UniqueName; + var mmList = (MemberMapper[])_keyList[key]; + + if (mmList == null) + { + var typeExt = TypeExtension.GetTypeExtension(type, Extensions); + var list = new List(); + + foreach (MemberMapper mm in db.MappingSchema.GetObjectMapper(type)) + { + if (mm.MapMemberInfo.SqlIgnore) + continue; + + var ma = mm.MapMemberInfo.MemberAccessor; + + if (TypeHelper.IsScalar(ma.Type)) + { + bool isSet; + var order = MappingSchema.MetadataProvider.GetPrimaryKeyOrder(type, typeExt, ma, out isSet); + + if (isSet) + list.Add(new MemberOrder(mm, order)); + } + } + + list.Sort((x, y) => x.Order - y.Order); + + _keyList[key] = mmList = new MemberMapper[list.Count]; + + for (var i = 0; i < list.Count; i++) + mmList[i] = list[i].MemberMapper; + } + + return mmList; + } + + [NoInterception] + protected virtual void AddWherePK(DbManager db, SqlQueryInfo query, StringBuilder sb, int nParameter) + { + sb.Append("WHERE\n"); + + var memberMappers = GetKeyFieldList(db, query.ObjectType); + + if (memberMappers.Length == 0) + throw new DataAccessException( + string.Format("No primary key field(s) in the type '{0}'.", query.ObjectType.FullName)); + + foreach (var mm in memberMappers) + { + var p = query.AddParameter( + db.DataProvider.Convert(mm.Name + "_W", ConvertType.NameToQueryParameter).ToString(), + mm.Name); + + sb.AppendFormat("\t{0} = ", db.DataProvider.Convert(p.FieldName, ConvertType.NameToQueryField)); + + if (nParameter < 0) + sb.AppendFormat("{0} AND\n", p.ParameterName); + else + sb.AppendFormat("{{{0}}} AND\n", nParameter++); + } + + sb.Remove(sb.Length - 5, 5); + } + + protected SqlQueryInfo CreateSelectByKeySqlText(DbManager db, Type type) + { + var om = db.MappingSchema.GetObjectMapper(type); + var sb = new StringBuilder(); + var query = new SqlQueryInfo(om); + + sb.Append("SELECT\n"); + + foreach (var mm in GetFieldList(om)) + sb.AppendFormat("\t{0},\n", + db.DataProvider.Convert(mm.Name, ConvertType.NameToQueryField)); + + sb.Remove(sb.Length - 2, 1); + + sb.Append("FROM\n\t"); + + AppendTableName(sb, db, type); + + AddWherePK(db, query, sb, -1); + + query.QueryText = sb.ToString(); + + return query; + } + + // NOTE changed to virtual + protected virtual void AppendTableName(StringBuilder sb, DbManager db, Type type) + { + var database = GetDatabaseName(type); + var owner = GetOwnerName (type); + var name = GetTableName (type); + + db.DataProvider.CreateSqlProvider().BuildTableName(sb, + database == null ? null : db.DataProvider.Convert(database, ConvertType.NameToDatabase). ToString(), + owner == null ? null : db.DataProvider.Convert(owner, ConvertType.NameToOwner). ToString(), + name == null ? null : db.DataProvider.Convert(name, ConvertType.NameToQueryTable).ToString()); + + sb.AppendLine(); + } + + protected SqlQueryInfo CreateSelectAllSqlText(DbManager db, Type type) + { + var om = db.MappingSchema.GetObjectMapper(type); + var sb = new StringBuilder(); + var query = new SqlQueryInfo(om); + + sb.Append("SELECT\n"); + + foreach (var mm in GetFieldList(om)) + sb.AppendFormat("\t{0},\n", + db.DataProvider.Convert(mm.Name, ConvertType.NameToQueryField)); + + sb.Remove(sb.Length - 2, 1); + + sb.Append("FROM\n\t"); + AppendTableName(sb, db, type); + + query.QueryText = sb.ToString(); + + return query; + } + + protected SqlQueryInfo CreateInsertSqlText(DbManager db, Type type, int nParameter) + { + var typeExt = TypeExtension.GetTypeExtension(type, Extensions); + var om = db.MappingSchema.GetObjectMapper(type); + var list = new List(); + var sb = new StringBuilder(); + var query = new SqlQueryInfo(om); + var mp = MappingSchema.MetadataProvider; + + sb.Append("INSERT INTO "); + AppendTableName(sb, db, type); + sb.Append(" (\n"); + + foreach (var mm in GetFieldList(om)) + { + // IT: This works incorrectly for complex mappers. + // + // [2009-03-24] ili: use mm.MemberAccessor instead of mm.ComplexMemberAccessor + // as in CreateUpdateSqlText + // + + bool isSet; + var nonUpdatableAttribute = mp.GetNonUpdatableAttribute(type, typeExt, mm.MapMemberInfo.MemberAccessor, out isSet); + + if (nonUpdatableAttribute == null || !isSet || nonUpdatableAttribute.OnInsert == false) + { + sb.AppendFormat("\t{0},\n", + db.DataProvider.Convert(mm.Name, ConvertType.NameToQueryField)); + list.Add(mm); + } + } + + sb.Remove(sb.Length - 2, 1); + + sb.Append(") VALUES (\n"); + + foreach (var mm in list) + { + var p = query.AddParameter( + db.DataProvider.Convert(mm.Name + "_P", ConvertType.NameToQueryParameter).ToString(), + mm.Name); + + if (nParameter < 0) + sb.AppendFormat("\t{0},\n", p.ParameterName); + //sb.AppendFormat("\t{0},\n", db.DataProvider.Convert(p.ParameterName, ConvertType.NameToQueryParameter)); + else + sb.AppendFormat("\t{{{0}}},\n", nParameter++); + } + + sb.Remove(sb.Length - 2, 1); + + sb.Append(")"); + + query.QueryText = sb.ToString(); + + return query; + } + + protected SqlQueryInfo CreateUpdateSqlText(DbManager db, Type type, int nParameter) + { + var typeExt = TypeExtension.GetTypeExtension(type, Extensions); + var om = db.MappingSchema.GetObjectMapper(type); + var sb = new StringBuilder(); + var query = new SqlQueryInfo(om); + var mp = MappingSchema.MetadataProvider; + + sb.Append("UPDATE\n\t"); + AppendTableName(sb, db, type); + sb.Append("\nSET\n"); + + var fields = GetFieldList(om); + var hasFields = false; + + foreach (var mm in fields) + { + bool isSet; + + var nonUpdatableAttribute = mp.GetNonUpdatableAttribute(type, typeExt, mm.MapMemberInfo.MemberAccessor, out isSet); + + if (nonUpdatableAttribute != null && isSet && nonUpdatableAttribute.OnUpdate == true) + continue; + + mp.GetPrimaryKeyOrder(type, typeExt, mm.MapMemberInfo.MemberAccessor, out isSet); + + if (isSet) + continue; + + hasFields = true; + + var p = query.AddParameter( + db.DataProvider.Convert(mm.Name + "_P", ConvertType.NameToQueryParameter).ToString(), + mm.Name); + + sb.AppendFormat("\t{0} = ", db.DataProvider.Convert(p.FieldName, ConvertType.NameToQueryField)); + + if (nParameter < 0) + sb.AppendFormat("{0},\n", p.ParameterName); + else + sb.AppendFormat("\t{{{0}}},\n", nParameter++); + } + + if (!hasFields) + throw new DataAccessException( + string.Format("There are no fields to update in the type '{0}'.", query.ObjectType.FullName)); + + sb.Remove(sb.Length - 2, 1); + + AddWherePK(db, query, sb, nParameter); + + query.QueryText = sb.ToString(); + + return query; + } + + protected SqlQueryInfo CreateDeleteSqlText(DbManager db, Type type, int nParameter) + { + var om = db.MappingSchema.GetObjectMapper(type); + var sb = new StringBuilder(); + var query = new SqlQueryInfo(om); + + sb.Append("DELETE FROM\n\t"); + AppendTableName(sb, db, type); + sb.AppendLine(); + + AddWherePK(db, query, sb, nParameter); + + query.QueryText = sb.ToString(); + + return query; + } + + [NoInterception] + protected virtual SqlQueryInfo CreateSqlText(DbManager db, Type type, string actionName) + { + switch (actionName) + { + case "SelectByKey": return CreateSelectByKeySqlText(db, type); + case "SelectAll": return CreateSelectAllSqlText (db, type); + case "Insert": return CreateInsertSqlText (db, type, -1); + case "InsertBatch": return CreateInsertSqlText (db, type, 0); + case "Update": return CreateUpdateSqlText (db, type, -1); + case "UpdateBatch": return CreateUpdateSqlText (db, type, 0); + case "Delete": return CreateDeleteSqlText (db, type, -1); + case "DeleteBatch": return CreateDeleteSqlText (db, type, 0); + default: + throw new DataAccessException( + string.Format("Unknown action '{0}'.", actionName)); + } + } + + private static readonly Hashtable _actionSqlQueryInfo = new Hashtable(); + + [NoInterception] + public virtual SqlQueryInfo GetSqlQueryInfo(DbManager db, Type type, string actionName) + { + var key = type.FullName + "$" + actionName + "$" + db.DataProvider.UniqueName + "$" + GetTableName(type); + var query = (SqlQueryInfo)_actionSqlQueryInfo[key]; + + if (query == null) + { + query = CreateSqlText(db, type, actionName); + _actionSqlQueryInfo[key] = query; + } + + return query; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/SqlQueryInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/SqlQueryInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Data; + +using BLToolkit.Data; +using BLToolkit.Mapping; + +namespace BLToolkit.DataAccess +{ + public class SqlQueryInfo + { + //NOTE Added empty constructor + public SqlQueryInfo() + { + } + + public SqlQueryInfo(ObjectMapper objectMapper) + { + ObjectMapper = objectMapper; + } + + public string QueryText { get; set; } + public ObjectMapper ObjectMapper { get; private set; } + + public Type ObjectType + { + get { return ObjectMapper.TypeAccessor.OriginalType; } + } + + //NOTE Changed from private to protected + protected readonly List Parameters = new List(); + + //NOTE Changed to virtual + public virtual SqlQueryParameterInfo AddParameter(string parameterName, string fieldName) + { + var parameter = new SqlQueryParameterInfo { ParameterName = parameterName, FieldName = fieldName }; + + parameter.SetMemberMapper(ObjectMapper); + + Parameters.Add(parameter); + + return parameter; + } + + public IDbDataParameter[] GetParameters(DbManager db, object[] key) + { + if (Parameters.Count != key.Length) + throw new DataAccessException("Parameter list does match key list."); + + var parameters = new IDbDataParameter[Parameters.Count]; + + for (var i = 0; i < Parameters.Count; i++) + { + var info = Parameters[i]; + + parameters[i] = db.Parameter(info.ParameterName, key[i]); + } + + return parameters; + } + + public IDbDataParameter[] GetParameters(DbManager db, object obj) + { + var parameters = new IDbDataParameter[Parameters.Count]; + + for (var i = 0; i < Parameters.Count; i++) + { + var info = Parameters[i]; + + //parameters[i] = db.Parameter(info.ParameterName, info.MemberMapper.GetValue(obj)); + + var mmi = info.MemberMapper.MapMemberInfo; + var val = info.MemberMapper.GetValue(obj); + + if (val == null && mmi.Nullable/* && mmi.NullValue == null*/) + { + //replace value with DbNull + val = DBNull.Value; + } + + if (mmi.IsDbTypeSet) + { + parameters[i] = mmi.IsDbSizeSet + ? db.Parameter(info.ParameterName, val, info.MemberMapper.DbType, mmi.DbSize) + : db.Parameter(info.ParameterName, val, info.MemberMapper.DbType); + } + else + { + parameters[i] = val != DBNull.Value + ? db.Parameter(info.ParameterName, val) + : db.Parameter(info.ParameterName, val, info.MemberMapper.GetDbType()); + } + } + + return parameters; + } + + public MemberMapper[] GetMemberMappers() + { + var members = new MemberMapper[Parameters.Count]; + + for (var i = 0; i < Parameters.Count; i++) + members[i] = Parameters[i].MemberMapper; + + return members; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/SqlQueryParameterInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/SqlQueryParameterInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,33 @@ +using BLToolkit.Mapping; + +namespace BLToolkit.DataAccess +{ + public class SqlQueryParameterInfo + { + private string _parameterName; + public string ParameterName + { + get { return _parameterName; } + set { _parameterName = value; } + } + + private string _fieldName; + public string FieldName + { + get { return _fieldName; } + set { _fieldName = value; } + } + + private MemberMapper _memberMapper; + public MemberMapper MemberMapper + { + get { return _memberMapper; } + } + + //NOTE Changed internal to public and added virtual + public virtual void SetMemberMapper(ObjectMapper objectMapper) + { + _memberMapper = objectMapper[_fieldName]; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/SqlQueryT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/SqlQueryT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,383 @@ +using System; +using System.Collections.Generic; + +namespace BLToolkit.DataAccess +{ + using Data; + using Mapping; + using Reflection.Extension; + + public class SqlQuery : SqlQueryBase + { + #region Constructors + + public SqlQuery() + { + } + + public SqlQuery(DbManager dbManager) + : base(dbManager) + { + } + + public SqlQuery(DbManager dbManager, bool dispose) + : base(dbManager, dispose) + { + } + + public SqlQuery(ExtensionList extensions) + { + Extensions = extensions; + } + + #endregion + + #region Overrides + + public SqlQueryInfo GetSqlQueryInfo(DbManager db, string actionName) + { + return base.GetSqlQueryInfo(db, typeof(T), actionName); + } + + #endregion + + #region SelectByKey + + public virtual T SelectByKey(DbManager db, params object[] keys) + { + var query = GetSqlQueryInfo(db, typeof(T), "SelectByKey"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, keys)) + .ExecuteObject(); + } + + public virtual T SelectByKey(params object[] keys) + { + var db = GetDbManager(); + + try + { + return SelectByKey(db, keys); + } + finally + { + if (DisposeDbManager) + db.Dispose(); + } + } + + #endregion + + #region SelectAll + + static SqlQueryInfo _selectAllQuery; + + public virtual List SelectAll(DbManager db) + { + if (_selectAllQuery == null) + _selectAllQuery = GetSqlQueryInfo(db, typeof(T), "SelectAll"); + + return db + .SetCommand(_selectAllQuery.QueryText) + .ExecuteList(); + } + + public virtual TL SelectAll(DbManager db, TL list) + where TL : IList + { + var query = GetSqlQueryInfo(db, typeof(T), "SelectAll"); + + return db + .SetCommand(query.QueryText) + .ExecuteList(list); + } + + public virtual TL SelectAll(DbManager db) + where TL : IList, new() + { + return SelectAll(db, new TL()); + } + + public virtual List SelectAll() + { + var db = GetDbManager(); + + try + { + return SelectAll(db); + } + finally + { + if (DisposeDbManager) + db.Dispose(); + } + } + + public virtual TL SelectAll(TL list) + where TL : IList + { + var db = GetDbManager(); + + try + { + return SelectAll(db, list); + } + finally + { + if (DisposeDbManager) + db.Dispose(); + } + } + + public virtual TL SelectAll() + where TL : IList, new() + { + return SelectAll(new TL()); + } + + #endregion + + #region Insert + + public virtual int Insert(DbManager db, T obj) + { + var query = GetSqlQueryInfo(db, obj.GetType(), "Insert"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, obj)) + .ExecuteNonQuery(); + } + + public virtual int Insert(T obj) + { + var db = GetDbManager(); + + try + { + return Insert(db, obj); + } + finally + { + if (DisposeDbManager) + db.Dispose(); + } + } + + public virtual int Insert(DbManager db, int maxBatchSize, IEnumerable list) + { + var query = GetSqlQueryInfo(db, typeof(T), "InsertBatch"); + + return db.DataProvider.InsertBatch( + db, + query.QueryText, + list, + query.GetMemberMappers(), + maxBatchSize, + obj => query.GetParameters(db, obj)); + } + + public virtual int Insert(int maxBatchSize, IEnumerable list) + { + var db = GetDbManager(); + + try + { + return Insert(db, maxBatchSize, list); + } + finally + { + if (DisposeDbManager) + db.Dispose(); + } + } + + public virtual int Insert(DbManager db, IEnumerable list) + { + return Insert(db, int.MaxValue, list); + } + + public virtual int Insert(IEnumerable list) + { + return Insert(int.MaxValue, list); + } + + #endregion + + #region Update + + public virtual int Update(DbManager db, T obj) + { + var query = GetSqlQueryInfo(db, obj.GetType(), "Update"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, obj)) + .ExecuteNonQuery(); + } + + public virtual int Update(T obj) + { + var db = GetDbManager(); + + try + { + return Update(db, obj); + } + finally + { + if (DisposeDbManager) + db.Dispose(); + } + } + + public virtual int Update(DbManager db, int maxBatchSize, IEnumerable list) + { + var query = GetSqlQueryInfo(db, typeof(T), "UpdateBatch"); + + db.SetCommand(query.QueryText); + + return ExecuteForEach( + db, + list, + query.GetMemberMappers(), + maxBatchSize, + obj => query.GetParameters(db, obj)); + } + + public virtual int Update(int maxBatchSize, IEnumerable list) + { + var db = GetDbManager(); + + try + { + return Update(db, maxBatchSize, list); + } + finally + { + if (DisposeDbManager) + db.Dispose(); + } + } + + public virtual int Update(DbManager db, IEnumerable list) + { + return Update(db, int.MaxValue, list); + } + + public virtual int Update(IEnumerable list) + { + return Update(int.MaxValue, list); + } + + #endregion + + #region DeleteByKey + + public virtual int DeleteByKey(DbManager db, params object[] key) + { + var query = GetSqlQueryInfo(db, typeof(T), "Delete"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, key)) + .ExecuteNonQuery(); + } + + public virtual int DeleteByKey(params object[] key) + { + var db = GetDbManager(); + + try + { + return DeleteByKey(db, key); + } + finally + { + if (DisposeDbManager) + db.Dispose(); + } + } + + #endregion + + #region Delete + + public virtual int Delete(DbManager db, T obj) + { + var query = GetSqlQueryInfo(db, obj.GetType(), "Delete"); + + return db + .SetCommand(query.QueryText, query.GetParameters(db, obj)) + .ExecuteNonQuery(); + } + + public virtual int Delete(T obj) + { + var db = GetDbManager(); + + try + { + return Delete(db, obj); + } + finally + { + if (DisposeDbManager) + db.Dispose(); + } + } + + public virtual int Delete(DbManager db, int maxBatchSize, IEnumerable list) + { + var query = GetSqlQueryInfo(db, typeof(T), "DeleteBatch"); + + db.SetCommand(query.QueryText); + + return ExecuteForEach( + db, + list, + query.GetMemberMappers(), + maxBatchSize, + obj => query.GetParameters(db, obj)); + } + + public virtual int Delete(int maxBatchSize, IEnumerable list) + { + var db = GetDbManager(); + + try + { + return Delete(db, list); + } + finally + { + if (DisposeDbManager) + db.Dispose(); + } + } + + public virtual int Delete(DbManager db, IEnumerable list) + { + return Delete(db, int.MaxValue, list); + } + + public virtual int Delete(IEnumerable list) + { + return Delete(int.MaxValue, list); + } + + #endregion + + #region Helpers + + protected int ExecuteForEach( + DbManager db, + IEnumerable collection, + MemberMapper[] members, + int maxBatchSize, + DbManager.ParameterProvider getParameters) + { + return db.ExecuteForEach(collection, members, maxBatchSize, getParameters); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/DataAccess/TableNameAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/DataAccess/TableNameAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,34 @@ +using System; + +namespace BLToolkit.DataAccess +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] + public class TableNameAttribute : Attribute + { + public TableNameAttribute() + { + } + + public TableNameAttribute(string name) + { + _name = name; + } + + public TableNameAttribute(string database, string name) + { + _database = database; + _name = name; + } + + public TableNameAttribute(string database, string owner, string name) + { + _database = database; + _owner = owner; + _name = name; + } + + private string _database; public virtual string Database { get { return _database; } set { _database = value; } } + private string _owner; public virtual string Owner { get { return _owner; } set { _owner = value; } } + private string _name; public virtual string Name { get { return _name; } set { _name = value; } } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Doc/BLToolkit.chm Binary file Source/Doc/BLToolkit.chm has changed diff -r 000000000000 -r f990fcb411a9 Source/Doc/ChangeLog.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Doc/ChangeLog.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,299 @@ +v 4.1 + +Enhancement + +- New Linq converter. +- New InsertOrUpdate method. + + +v 4.0 + +Enhancement + +- No more .NET Framework 2.0 support. +- T4 Templates for Sybase, MS SQL Server, MySql, and PostgreSQL. +- Linq over WCF. +- Silverlight support. +- New attributes TableFunction & TableExpression to support table-valued UDF, hints, + and other around table decorations. +- Linq DML support. + + +v 3.2 + +Demo (see the dev version of the project) + +- Linq.Demo. +- WebServices powered by BLToolkit. +- Partial.Trust demo. + +Bug fixes + +- Extension assemblies are ignored in TypeFactory.GetType(type). +- Default parameter values were ignored by OverloadAspectBuilder. +- [Parameter(null)] wasn't setting Nullable<> and EditableValue> values to null +- DefaultTypeBuilder throwing exception if [Parameter(value)] was used on + EditableValue> generated properties when Nullable<> did have appropriate + constructor accepting value type +- DateTimeOffset wasn't handled in DataReaderMapper correctly. + +Enhancement + +- Linq provider for supported databases. +- New Object to Object mapping. See ExpressionMapper. +- PostgreSQL Data Provider added. +- Informix Data Provider added. +- DB2 Data Provider added. +- New SqlIgnore attribute. +- New SqlBuilder class. +- Partial trust support. +- Mapping to/from private classes (FW 3.x only). +- New ParamTypeName attribute for SqlServer2008 table-type parameter support (FW 3.x only). +- EditableArrayList & BindingListImpl implements INotifyCollectionChanged interface. + + +v 3.1 + +Bug fixes + +- MapValueAttribute ignored for nullable enums. +- MappingSchema.ConvertChangeType does not handle nullable enums properly. +- EditableArrayList indexer add/remove bug. +- ParameterAttribute doesn't work with Nullabe and EditableValue + when 'T' constructor is not trivial. +- BindingListImpl.AddNew does not fire ListChanged event. +- Some inner types are missing in ObjectMappes, some included w/o reason. +- Setter for ObjectBinder.ItemType fires OnListChanged event before the list changes. +- Convert does not handle `Nullable' from scalar `From' case. +- EditableXmlDocument fires PropertyChanged event before an xml node changes. + +Enhancement + +- CHM help file provided. See the Doc folder. +- New InstanceCache attribute. +- DataAccessor support for IEnumerable. +- Multiple duck. See DuckTyping.Aggregate methods. +- New Overload aspect. +- Own configuration section. +- TypeFactory.GetType() is public now. +- Simplified GenerateAttributeAttribute usage. + + +v 3.0 + +Breaking changes + +- No more support for .Net 1.1 Framework. + +Bug fixes + +- EmitHelper.ldc_i4_ emits wrong opcode for numbers from 128 till 255 (bug in msdn) +- Some opcodes were not implemented. +- MappingSchema.MapResultSets fails with NullReferenceException when no data returned. +- Nullable enums were not handled properly. +- BindingList.GetItemSortedPosition() returns wrong index for an item at end of the list. +- Fixed AsyncAspect and other type builders compatibility. +- DbMananger.DiscoverSpParameters fires both OpenConnection and CloseConnection events. + +Enhancement + +- DateTimeOffset type support. +- MemberAccessor.CloneValue to avoid boxing. +- Named arguments support for GenerateAttributeTypeBuilder. +- Extended support for IsNull & Nullable types in MemberAccessor. +- Support for enum values in EmitHelper.LoadWellKnownValue/LoadInitValue and so on. +- Generic GetValue/SetValue methods for ValueHolders. +- Different projects to support FW 2.0 & FW 3.5. +- LinqMetadataProvider to support Linq To SQL attributes. +- Relocated MetadataProvider's to BLToolkit.Reflection namespace. +- New DbManager ctors to support manual/custom configuration. +- Ability to configure SqlQueryAttribute dynamically. +- Assembly is signed. +- New ActualTypeAttribute to associate DataAccessor's object type and its implementation. +- New AutoImplementInterfaceAttribute to automatically generate interface implementation. +- New TypeAccessor.AssociateType method and TypeAccessor.AssociatedTypeHandler event + to control interface/type implementation. +- DataException now has the 'Number' property. +- New ClearCache aspect. + + +v 2.0.7 + +Bug fixes + +- Oracle/Odp does not handle colon (':') in ConvertType.ParameterToName. +- Property change builder will use op_Inequality operation if it is available to compare + property values. +- DbManager.ExecuteList(params object[]) add an extra typeof(T) +- EditableObject.Clone does reference cloning of its inner objects. +- EditableObject.Clone does not track dirty state of its members. +- Generated assembly name ends with '.dll'. + As a result, System.Reflection.Assembly.Load() tries to load 'SomeAssembly.dll.DLL' + and fails. +- Oracle treat '\r' as an invalid character. +- DataAccessorBuilder calls DbProvider.Convert(NameToParameter) for text query + parameters. +- SqlQueryBase.GetKeyFieldList was incorrectly marked as public. +- TypeAccessorBuilder fails to build a getter/setter if base method is protected. +- EditableXmlDocument fails to reject changes if there was an attribute insertion or + deletion. + +Enhancement + +- FdpDataProvider.QuoteIdentifiers option for FB data provier. +- GenerateAtribute attribute to specify any custom attribute for a generated type or + member. +- SQLite data provider. +- DeriveParameters implemented for MsAccess data provider. +- XmlIncludeAbstractAttribute to simplify the xml serialization of a BLToolkit generated + type. +- Better support for internal types/members. The behavior is configurable via + Configuration.EditableObjectUsesMemberwiseEquals property. +- VS 2008 support. + + +v 2.0.6 + +Demo + +- MS PetShop 4.0 powered by BLToolkit (see the dev version of the project). + +Bug fixes + +- DbManager.OutputParameter lacks overload with 'size' parameters. +- CacheAspect hungs a desktop application on exit. +- ExecuteResultSet fails on many-to-one relations. +- TypeBuilder fails to override a method with generic parameters or generic return type. + +Enhancement + +- ParamSize & ParamDbType attributes to tweak DataAccessor parameters. Especially output + ones. +- All 'emit.stloc' immediately followed by 'emit.ldloc' were replaced with simple + 'emit.dup' command. + Lots of redundant local variables were removed. +- UnitTests for Oracle, Firebird & Access (Jet) +- DataSetTableAttribute is handled by all DataSet/DataTable related methods of + DataAccessBuilder. +- ClearCache method for CacheAspect. +- Metadata provider for mapping. +- Ability to specify global assembly version & strong name key pair. +- AsyncAspect to execute any method asynchronously. +- Added support for ConnectionStrings config settings. +- Editable XmlDocuments. +- Added support for IDictionary, IDictionary<,>, IList, and IList<> abstract data + accessor return types. + + +v 2.0.5 + +Breaking changes + +- DbManager.InitCommand renamed to OnInitCommand. + +Bug fixes + +- System.Reflection.Emit.AssemblyBuilder assemblies are processed properly. +- RegExAttribute - now properly returns valid==true only when whole value is equal to + match. +- EditableObject serialization issue +- StandardPropertyDescriptor.CheckNull was always returning DBNull.Value if _isNull + handler was returning null. Now configurable via Configuration.CheckNullReturnIfNull. +- PropertyChangedBuilder was crashing when property was not public +- ObjectBinder.IsNull was serialized to resources +- Oracle provider now handles arrays of nullable types correctly. +- DataAccessor.PrepareParameters was invoked only to ref parameters. +- DataAccessor.PrepareParameters lacks DbManager which may be external. +- DbManager.InitParameters did hot handle decimal type. +- MappingSchema.ValueToEnum fails with underlying type other then Int32. +- CounterAspect catches the OnCatch event now to count exceptions. +- DbManager.ExecuteForEach does not call InitParameters in the loop. + +Enhancement + +- Ability to specify RegexOptions for RegExAttribute. Regex not being created on every + call to IsValid +- Destination attribute works with scalar types. +- DataAccessorBuilder generates getters/setters for abstract properties & indexers. +- Ability to specify globaly whether strings should be trimed when mapping +- Ability to specify whether PropertyChange notification should only be fired when + underlying value is changed and not when setter is called +- XmlDocument type support. +- DbManager.SetParameters() accepts arrays of IDbDataParameter. +- DataSetTableAttribute for DataAccessorBuilder to explicitly specify DataSet table name. +- Default CacheAspect.IsWeak value changed to false. +- Cleanup thread for CacheAspect. +- MemberMapper type can be specified directly in the target type declaration. +- Events for DbManager.OnBeforeOperation, OnAfterOperation, OnOperationException & + OnInitCommand. + + +v 2.0.4 + +Bug fixes + +- By default, the mapper included const fields into map list (???). +- If enum does not have explicit mapping, data accessor builder + does not convert it to underlying type. +- MemberMapper fails to convert an object to its base type. +- BindingListImpl.RemoveSort was not firing ListChange event. +- TypeAccessor.CreateExtendedPropertyDescriptors did not work properly + with 3rd+ level nested properties. +- Object holder ignored NoInstanceAttribute. +- ValidatorContext caches NullValue. +- EditableObject.RejectChanges/RejectMemberChanges were not firing PropertyChanged event + for reverted fields. +- Fixed the generating IsValueType && !IsPrimitive ref/out parameters. + +Enhancement + +- Operator is extensible now. +- ObjectBinder can now control lifetime (Disposal) of underlying collection. +- DuckTyping. +- ParamNullValue attribute. +- Virtual method DataProviderBase.PrepareCommand to let a data provider modify SQL + statement befory query. +- Virtual method CacheAspect.GetCache. Can be used to provide a custom hashtable. + + +v 2.0.3 + +Bug fixes + +- Race condition in MappingSchema.GetObjectMapper. +- DbManager will not try to close the connection in the finalizer anymore. +- MinValue/MaxValue attributes now determine value type by object property/field instead + of test value. +- Fixed obscure case when object is removed from EditableArrayList/BindingListImpl while + ItemPropertyChanged delegate is in process of being executed and collection handler was + not yet invoked. + +Enhancement + +- HttpReader SOAP support. +- Convert uses type cast operators when available. +- Third party DataProvider registration via appsettings. +- More specification adherent sorting behavior implementation of + IBindingList/IBindingListView in BindingListImpl. +- EditableArrayList (potentially breaking changes) heavily relies on BindingListImpl for + IBindingList/IBindingListView and their base interfaces implementation. +- BindingListImpl is changed to be fully specification adherent binding wrapper for other + object lists/collection types. +- 2.0.1 version obsolete methods have been removed. + + +v 2.0.2 + +Bug fixes + +- Abstract class builder overrode virtual final methods. +- Append records to a log file. +- ObjectBinder's AllowNew, AllowEdit, AllowRemove properties serialization. + +Enhancement + +- New DataAccessor class. +- Direction.ReturnValueAttribute takes the Member parameter in '@fieldName' format. +- New property Object of the InterceptCallInfo class, which is an intercepted object + reference. + diff -r 000000000000 -r f990fcb411a9 Source/Doc/Development rules and regulations.doc Binary file Source/Doc/Development rules and regulations.doc has changed diff -r 000000000000 -r f990fcb411a9 Source/Doc/License.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Doc/License.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +Copyright (c) 2002-2011 www.bltoolkit.net + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff -r 000000000000 -r f990fcb411a9 Source/Doc/OnlineDoc.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Doc/OnlineDoc.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1 @@ +See online documentation at http://www.bltoolkit.net/Doc/index.htm diff -r 000000000000 -r f990fcb411a9 Source/EditableObjects/EditableArrayList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/EditableObjects/EditableArrayList.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1100 @@ +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Diagnostics; +using System.Reflection; + +namespace BLToolkit.EditableObjects +{ + using Reflection; + using Mapping; + using ComponentModel; + + [DebuggerDisplay("Count = {Count}, ItemType = {ItemType}")] + [Serializable] + public class EditableArrayList : ArrayList, IEditable, ISortable, ISupportMapping, + IDisposable, IPrintDebugState, ITypedList, IBindingListView, ICancelAddNew, INotifyCollectionChanged + { + #region Constructors + + public EditableArrayList() : this(typeof(object), new ArrayList(), true) + { + } + + public EditableArrayList([JetBrains.Annotations.NotNull] Type itemType, [JetBrains.Annotations.NotNull] ArrayList list, bool trackChanges) + { + if (itemType == null) throw new ArgumentNullException("itemType"); + if (list == null) throw new ArgumentNullException("list"); + + ItemType = itemType; + List = list; + + _noTrackingChangesCount++; + AddInternal(List); + _noTrackingChangesCount--; + + if (!trackChanges) + { + SetTrackingChanges(false); + _minTrackingChangesCount = 1; + } + } + + public EditableArrayList(Type itemType) + : this(itemType, new ArrayList(), true) + { + } + + public EditableArrayList(Type itemType, bool trackChanges) + : this(itemType, new ArrayList(), trackChanges) + { + } + + public EditableArrayList(Type itemType, int capacity) + : this(itemType, new ArrayList(capacity), true) + { + } + + public EditableArrayList(Type itemType, int capacity, bool trackChanges) + : this(itemType, new ArrayList(capacity), trackChanges) + { + } + + public EditableArrayList(Type itemType, ICollection c) + : this(itemType, new ArrayList(c), true) + { + } + + public EditableArrayList(Type itemType, ICollection c, bool trackChanges) + : this(itemType, new ArrayList(c), trackChanges) + { + } + + public EditableArrayList(Type itemType, ArrayList list) + : this(itemType, list, true) + { + } + + public EditableArrayList(EditableArrayList list) + : this(list.ItemType, new ArrayList(list), true) + { + } + + public EditableArrayList(EditableArrayList list, bool trackChanges) + : this(list.ItemType, new ArrayList(list), trackChanges) + { + } + + public EditableArrayList(Type itemType, EditableArrayList list) + : this(itemType, new ArrayList(list), true) + { + } + + public EditableArrayList(Type itemType, EditableArrayList list, bool trackChanges) + : this(itemType, new ArrayList(list), trackChanges) + { + } + + #endregion + + #region Public Members + + internal ArrayList List { get; private set; } + public Type ItemType { get; private set; } + + private ArrayList _newItems; + public ArrayList NewItems + { + get { return _newItems ?? (_newItems = new ArrayList()); } + } + + private ArrayList _delItems; + public ArrayList DelItems + { + get { return _delItems ?? (_delItems = new ArrayList()); } + } + + public void Sort(params string[] memberNames) + { + Sort(ListSortDirection.Ascending, memberNames); + } + + public void Sort(ListSortDirection direction, params string[] memberNames) + { + if (memberNames == null) throw new ArgumentNullException ("memberNames"); + if (memberNames.Length == 0) throw new ArgumentOutOfRangeException("memberNames"); + + Sort(new SortMemberComparer(TypeAccessor.GetAccessor(ItemType), direction, memberNames)); + } + + public void SortEx(string sortExpression) + { + var sorts = sortExpression.Split(','); + + for (var i = 0; i < sorts.Length; i++) + sorts[i] = sorts[i].Trim(); + + var last = sorts[sorts.Length - 1]; + var desc = last.ToLower().EndsWith(" desc"); + + if (desc) + sorts[sorts.Length - 1] = last.Substring(0, last.Length - " desc".Length); + + Sort(desc? ListSortDirection.Descending: ListSortDirection.Ascending, sorts); + } + + public void Move(int newIndex, int oldIndex) + { + BindingListImpl.Move(newIndex, oldIndex); + } + + public void Move(int newIndex, object item) + { + lock (SyncRoot) + { + var index = IndexOf(item); + + if (index >= 0) + Move(newIndex, index); + } + } + + #endregion + + #region Change Notification + + public bool NotifyChanges + { + get { return BindingListImpl.NotifyChanges; } + set { BindingListImpl.NotifyChanges = value; } + } + + protected virtual void OnListChanged(ListChangedEventArgs e) + { + if (!_supressEvent && NotifyChanges && ListChanged != null) + ListChanged(this, e); + } + + protected void OnListChanged(ListChangedType listChangedType, int index) + { + OnListChanged(new EditableListChangedEventArgs(listChangedType, index)); + } + + private void OnResetList() + { + OnListChanged(ListChangedType.Reset, -1); + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); + } + + private void OnAddItem(object newObject, int index) + { + OnListChanged(ListChangedType.ItemAdded, index); + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newObject, index)); + } + + #endregion + + #region Add/Remove Internal + + void AddInternal(object value) + { + if (IsTrackingChanges) + { + if (DelItems.Contains(value)) + DelItems.Remove(value); + else + NewItems.Add(value); + } + + OnAdd(value); + } + + private void RemoveInternal(object value) + { + if (IsTrackingChanges) + { + if (NewItems.Contains(value)) + NewItems.Remove(value); + else + DelItems.Add(value); + } + + OnRemove(value); + } + + private void AddInternal(IEnumerable e) + { + foreach (var o in e) + AddInternal(o); + } + + private void RemoveInternal(IEnumerable e) + { + foreach (var o in e) + RemoveInternal(o); + } + + protected virtual void OnAdd(object value) + { + } + + protected virtual void OnRemove(object value) + { + } + + #endregion + + #region Track Changes + + private int _noTrackingChangesCount; + private readonly int _minTrackingChangesCount; + + public bool IsTrackingChanges + { + get { return _noTrackingChangesCount == 0; } + } + + protected void SetTrackingChanges(bool trackChanges) + { + if (trackChanges) + { + _noTrackingChangesCount--; + + if (_noTrackingChangesCount < _minTrackingChangesCount) + { + _noTrackingChangesCount = _minTrackingChangesCount; + throw new InvalidOperationException("Tracking Changes Counter can not be negative."); + } + } + else + { + _noTrackingChangesCount++; + } + } + + #endregion + + #region ISupportMapping Members + + public virtual void BeginMapping(InitContext initContext) + { + if (initContext.IsDestination) + _noTrackingChangesCount++; + } + + public virtual void EndMapping(InitContext initContext) + { + if (initContext.IsDestination) + { + AcceptChanges(); + _noTrackingChangesCount--; + } + } + + #endregion + + #region IEditable Members + + public virtual void AcceptChanges() + { + foreach (var o in List) + { + if (o is EditableObject) + ((EditableObject)o).AcceptChanges(); + else if (o is IEditable) + ((IEditable)o).AcceptChanges(); + } + + _newItems = null; + _delItems = null; + } + + public virtual void RejectChanges() + { + _noTrackingChangesCount++; + + if (_delItems != null) + foreach (var o in _delItems) + Add(o); + + if (_newItems != null) + foreach (var o in _newItems) + Remove(o); + + foreach (var o in List) + { + if (o is EditableObject) + ((EditableObject)o).RejectChanges(); + else if (o is IEditable) + ((IEditable)o).RejectChanges(); + } + + _noTrackingChangesCount--; + + _newItems = null; + _delItems = null; + } + + public virtual bool IsDirty + { + get + { + if (_newItems != null && _newItems.Count > 0 || + _delItems != null && _delItems.Count > 0) + return true; + + foreach (var o in List) + { + if (o is EditableObject) + if (((EditableObject)o).IsDirty) + return true; + else if (o is IEditable) + if (((IEditable)o).IsDirty) + return true; + } + + return false; + } + } + + void IPrintDebugState.PrintDebugState(PropertyInfo propertyInfo, ref string str) + { + var original = List.Count + - (_newItems == null? 0: _newItems.Count) + + (_delItems == null? 0: _delItems.Count); + + str += string.Format("{0,-20} {1} {2,-40} {3,-40} \r\n", + propertyInfo.Name, IsDirty? "*": " ", original, List.Count); + } + + #endregion + + #region IList Members + + public override bool IsFixedSize + { + get { return BindingListImpl.IsFixedSize; } + } + + public override bool IsReadOnly + { + get { return BindingListImpl.IsReadOnly; } + } + + public override object this[int index] + { + get { return BindingListImpl[index]; } + set + { + var o = BindingListImpl[index]; + + if (o != value) + { + RemoveInternal(o); + AddInternal(value); + } + + BindingListImpl[index] = value; + } + } + + public override int Add(object value) + { + AddInternal(value); + + return BindingListImpl.Add(value); + } + + public override void Clear() + { + if (List.Count > 0) + RemoveInternal(List); + + BindingListImpl.Clear(); + } + + public override bool Contains(object item) + { + return BindingListImpl.Contains(item); + } + + public override int IndexOf(object value) + { + return BindingListImpl.IndexOf(value); + } + + public override void Insert(int index, object value) + { + AddInternal(value); + + BindingListImpl.Insert(index, value); + } + + public override void Remove(object value) + { + RemoveInternal(value); + + BindingListImpl.Remove(value); + } + + public override void RemoveAt(int index) + { + RemoveInternal(BindingListImpl[index]); + + BindingListImpl.RemoveAt(index); + } + + #endregion + + #region ICollection Members + + public override int Count + { + get { return BindingListImpl.Count; } + } + + public override bool IsSynchronized + { + get { return BindingListImpl.IsSynchronized; } + } + + public override object SyncRoot + { + get { return BindingListImpl.SyncRoot; } + } + + public override void CopyTo(Array array, int arrayIndex) + { + BindingListImpl.CopyTo(array, arrayIndex); + } + + #endregion + + #region IEnumerable Members + + public override IEnumerator GetEnumerator() + { + return BindingListImpl.GetEnumerator(); + } + + #endregion + + #region Overridden Methods + + public int Add(object value, bool trackChanges) + { + if (!trackChanges) _noTrackingChangesCount++; + var idx = Add(value); + if (!trackChanges) _noTrackingChangesCount--; + + return idx; + } + + public override void AddRange(ICollection c) + { + if (c.Count == 0) + return; + + AddInternal(c); + + BindingListImpl.AddRange(c); + } + + public void AddRange(ICollection c, bool trackChanges) + { + if (c.Count == 0) + return; + + if (!trackChanges) _noTrackingChangesCount++; + AddRange(c); + if (!trackChanges) _noTrackingChangesCount--; + } + + public override int BinarySearch(int index, int count, object value, IComparer comparer) + { + return List.BinarySearch(index, count, value, comparer); + } + + public override int BinarySearch(object value) + { + return List.BinarySearch(value); + } + + public override int BinarySearch(object value, IComparer comparer) + { + return List.BinarySearch(value, comparer); + } + + public override int Capacity + { + get { return List.Capacity; } + set { List.Capacity = value; } + } + + public void Clear(bool trackChanges) + { + if (!trackChanges) _noTrackingChangesCount++; + Clear(); + if (!trackChanges) _noTrackingChangesCount--; + } + + protected EditableArrayList Clone(EditableArrayList el) + { + if (_newItems != null) el._newItems = (ArrayList)_newItems.Clone(); + if (_delItems != null) el._delItems = (ArrayList)_delItems.Clone(); + + el.NotifyChanges = NotifyChanges; + el._noTrackingChangesCount = _noTrackingChangesCount; + + return el; + } + + public override object Clone() + { + return Clone(new EditableArrayList(ItemType, (ArrayList)List.Clone())); + } + + public override void CopyTo(int index, Array array, int arrayIndex, int count) + { + List.CopyTo(index, array, arrayIndex, count); + } + + public override void CopyTo(Array array) + { + List.CopyTo(array); + } + + public override bool Equals(object obj) + { + return List.Equals(obj); + } + + public override IEnumerator GetEnumerator(int index, int count) + { + return List.GetEnumerator(index, count); + } + + public override int GetHashCode() + { + return List.GetHashCode(); + } + + public override ArrayList GetRange(int index, int count) + { + return List.GetRange(index, count); + } + + public override int IndexOf(object value, int startIndex) + { + return List.IndexOf(value, startIndex); + } + + public override int IndexOf(object value, int startIndex, int count) + { + return List.IndexOf(value, startIndex, count); + } + + public void Insert(int index, object value, bool trackChanges) + { + if (!trackChanges) _noTrackingChangesCount++; + Insert(index, value); + if (!trackChanges) _noTrackingChangesCount--; + } + + public override void InsertRange(int index, ICollection c) + { + BindingListImpl.InsertRange(index, c); + } + + public void InsertRange(int index, ICollection c, bool trackChanges) + { + if (!trackChanges) _noTrackingChangesCount++; + InsertRange(index, c); + if (!trackChanges) _noTrackingChangesCount--; + } + + public override int LastIndexOf(object value) + { + return List.LastIndexOf(value); + } + + public override int LastIndexOf(object value, int startIndex) + { + return List.LastIndexOf(value, startIndex); + } + + public override int LastIndexOf(object value, int startIndex, int count) + { + return List.LastIndexOf(value, startIndex, count); + } + + public void Remove(object obj, bool trackChanges) + { + if (!trackChanges) _noTrackingChangesCount++; + Remove(obj); + if (!trackChanges) _noTrackingChangesCount--; + } + + public void RemoveAt(int index, bool trackChanges) + { + if (!trackChanges) _noTrackingChangesCount++; + RemoveAt(index); + if (!trackChanges) _noTrackingChangesCount--; + } + + public override void RemoveRange(int index, int count) + { + RemoveInternal(GetRange(index, count)); + + BindingListImpl.RemoveRange(index, count); + } + + public void RemoveRange(int index, int count, bool trackChanges) + { + if (!trackChanges) _noTrackingChangesCount++; + RemoveRange(index, count); + if (!trackChanges) _noTrackingChangesCount--; + } + + public override void Reverse() + { + BindingListImpl.EndNew(); + + if (!BindingListImpl.IsSorted) + List.Reverse(); + else + throw new InvalidOperationException("Reverse is not supported for already sorted arrays. Invoke IBindingList.RemoveSort() first or provide reverse sort direction."); + + if (List.Count > 1) + OnResetList(); + } + + public override void Reverse(int index, int count) + { + BindingListImpl.EndNew(); + + if (!BindingListImpl.IsSorted) + List.Reverse(index, count); + else + throw new InvalidOperationException("Range Reverse is not supported for already sorted arrays. Invoke IBindingList.RemoveSort() first."); + + if (count > 1) + OnResetList(); + } + + public override void SetRange(int index, ICollection c) + { + if (c.Count == 0) + return; + + AddInternal(c); + + BindingListImpl.SetRange(index, c); + } + + public override void Sort() + { + BindingListImpl.EndNew(); + + if (!BindingListImpl.IsSorted) + { + List.Sort(); + + if (List.Count > 1) + OnResetList(); + } + else + { + if (BindingListImpl.SortProperty != null) + BindingListImpl.ApplySort(BindingListImpl.SortProperty, BindingListImpl.SortDirection); + else if (BindingListImpl.SortDescriptions != null) + BindingListImpl.ApplySort(BindingListImpl.SortDescriptions); + else + throw new InvalidOperationException("Currently applied sort method is not recognized/supported by EditableArrayList."); + } + } + + public override void Sort(int index, int count, IComparer comparer) + { + BindingListImpl.EndNew(); + + if (!BindingListImpl.IsSorted) + List.Sort(index, count, comparer); + else + throw new InvalidOperationException("Custom sorting is not supported on already sorted arrays. Invoke IBindingList.RemoveSort first."); + + if (count > 1) + OnResetList(); + } + + public override void Sort(IComparer comparer) + { + BindingListImpl.EndNew(); + + if (!BindingListImpl.IsSorted) + List.Sort(comparer); + else + throw new InvalidOperationException("Custom sorting is not supported on already sorted arrays. Invoke IBindingList.RemoveSort first."); + + if (List.Count > 1) + OnResetList(); + } + + public override object[] ToArray() + { + return List.ToArray(); + } + + public override Array ToArray(Type type) + { + return List.ToArray(type); + } + + public override string ToString() + { + return List.ToString(); + } + + public override void TrimToSize() + { + List.TrimToSize(); + } + + #endregion + + #region Static Methods + + public static EditableArrayList Adapter(Type itemType, IList list) + { + if (list == null) throw new ArgumentNullException("list"); + + if (list.IsFixedSize) + return new EditableArrayList(itemType, new ArrayList(list)); + + return list is ArrayList? + new EditableArrayList(itemType, (ArrayList)list): + new EditableArrayList(itemType, ArrayList.Adapter(list)); + } + + public static new EditableArrayList Adapter(IList list) + { + return Adapter(TypeHelper.GetListItemType(list), list); + } + + #endregion + + #region IDisposable + + public void Dispose() + { + Clear(); + } + + #endregion + + #region SortMemberComparer + + class SortMemberComparer : IComparer + { + readonly ListSortDirection _direction; + readonly string[] _memberNames; + readonly TypeAccessor _typeAccessor; + readonly MemberAccessor[] _members; + readonly MemberAccessor _member; + + public SortMemberComparer(TypeAccessor typeAccessor, ListSortDirection direction, string[] memberNames) + { + _typeAccessor = typeAccessor; + _direction = direction; + _memberNames = memberNames; + _members = new MemberAccessor[memberNames.Length]; + + _member = _members[0] = _typeAccessor[memberNames[0]]; + + if (_member == null) + throw new InvalidOperationException( + string.Format("Field '{0}.{1}' not found.", + _typeAccessor.OriginalType.Name, _memberNames[0])); + } + + public int Compare(object x, object y) + { + var a = _member.GetValue(x); + var b = _member.GetValue(y); + var n = Comparer.Default.Compare(a, b); + + if (n == 0) for (var i = 1; n == 0 && i < _members.Length; i++) + { + var member = _members[i]; + + if (member == null) + { + member = _members[i] = _typeAccessor[_memberNames[i]]; + + if (member == null) + throw new InvalidOperationException( + string.Format("Field '{0}.{1}' not found.", + _typeAccessor.OriginalType.Name, _memberNames[i])); + } + + a = member.GetValue(x); + b = member.GetValue(y); + n = Comparer.Default.Compare(a, b); + } + + return _direction == ListSortDirection.Ascending? n: -n; + } + } + + #endregion + + #region ITypedList Members + + [NonSerialized] + private TypedListImpl _typedListImpl; + private TypedListImpl TypedListImpl + { + get { return _typedListImpl ?? (_typedListImpl = new TypedListImpl(ItemType)); } + } + + public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors) + { + return GetItemProperties(listAccessors, null, null, true); + } + + public PropertyDescriptorCollection GetItemProperties( + PropertyDescriptor[] listAccessors, + Type objectViewType, + IsNullHandler isNull, + bool cache) + { + return TypedListImpl.GetItemProperties(listAccessors, objectViewType, isNull, cache); + } + + public string GetListName(PropertyDescriptor[] listAccessors) + { + return TypedListImpl.GetListName(listAccessors); + } + + #endregion + + #region IBindingList Members + + sealed class BindingListImplInternal : BindingListImpl + { + readonly EditableArrayList _owner; + + public BindingListImplInternal(IList list, Type itemType, EditableArrayList owner) + : base(list, itemType) + { + _owner = owner; + } + + protected override void OnListChanged(EditableListChangedEventArgs e) + { + _owner.OnListChanged(e); + } + + protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs ea) + { + _owner.OnCollectionChanged(ea); + } + } + + [NonSerialized] + private BindingListImpl _bindingListImpl; + private BindingListImpl BindingListImpl + { + get { return _bindingListImpl ?? (_bindingListImpl = new BindingListImplInternal(List, ItemType, this)); } + } + + public void AddIndex(PropertyDescriptor property) + { + BindingListImpl.AddIndex(property); + } + + public object AddNew() + { + object newObject; + + try + { + BeginSuppressEvent(); + newObject = BindingListImpl.AddNew(); + } + finally + { + EndSuppressEvent(); + } + + AddInternal(newObject); + + var index = IndexOf(newObject); + + EndSuppressEvent(); + OnAddItem(newObject, index); + + return newObject; + } + + public bool AllowEdit + { + get { return BindingListImpl.AllowEdit; } + } + + public bool AllowNew + { + get { return BindingListImpl.AllowNew; } + } + + public bool AllowRemove + { + get { return BindingListImpl.AllowRemove; } + } + + public void ApplySort(PropertyDescriptor property, ListSortDirection direction) + { + BindingListImpl.ApplySort(property, direction); + } + + public int Find(PropertyDescriptor property, object key) + { + return BindingListImpl.Find(property, key); + } + + public bool IsSorted + { + get { return BindingListImpl.IsSorted; } + } + + public void RemoveIndex(PropertyDescriptor property) + { + BindingListImpl.RemoveIndex(property); + } + + public void RemoveSort() + { + BindingListImpl.RemoveSort(); + } + + public ListSortDirection SortDirection + { + get { return BindingListImpl.SortDirection; } + } + + public PropertyDescriptor SortProperty + { + get { return BindingListImpl.SortProperty; } + } + + public bool SupportsChangeNotification + { + get { return BindingListImpl.SupportsChangeNotification; } + } + + public event ListChangedEventHandler ListChanged; + + private bool _supressEvent; + + private void BeginSuppressEvent() + { + _supressEvent = true; + } + + private void EndSuppressEvent() + { + _supressEvent = false; + } + + public bool SupportsSearching + { + get { return BindingListImpl.SupportsSearching; } + } + + public bool SupportsSorting + { + get { return BindingListImpl.SupportsSorting; } + } + + #endregion + + #region Sorting Enhancement + + public void CreateSortSubstitution(string originalProperty, string substituteProperty) + { + BindingListImpl.CreateSortSubstitution(originalProperty, substituteProperty); + } + + public void RemoveSortSubstitution(string originalProperty) + { + BindingListImpl.RemoveSortSubstitution(originalProperty); + } + + #endregion + + #region IBindingListView Members + + public void ApplySort(ListSortDescriptionCollection sorts) + { + BindingListImpl.ApplySort(sorts); + } + + public string Filter + { + get { return BindingListImpl.Filter; } + set { BindingListImpl.Filter = value; } + } + + public void RemoveFilter() + { + BindingListImpl.RemoveFilter(); + } + + public ListSortDescriptionCollection SortDescriptions + { + get { return BindingListImpl.SortDescriptions; } + } + + public bool SupportsAdvancedSorting + { + get { return BindingListImpl.SupportsAdvancedSorting; } + } + + public bool SupportsFiltering + { + get { return BindingListImpl.SupportsFiltering; } + } + + #endregion + + #region ICancelAddNew Members + + public void CancelNew(int itemIndex) + { + if (itemIndex >= 0 && itemIndex < List.Count) + NewItems.Remove(List[itemIndex]); + + BindingListImpl.CancelNew(itemIndex); + } + + public void EndNew(int itemIndex) + { + BindingListImpl.EndNew(itemIndex); + } + + #endregion + + #region INotifyCollectionChanged Members + + public event NotifyCollectionChangedEventHandler CollectionChanged; + + protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) + { + if (!_supressEvent && NotifyChanges && CollectionChanged != null) + CollectionChanged(this, e); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/EditableObjects/EditableList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/EditableObjects/EditableList.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,369 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; + +namespace BLToolkit.EditableObjects +{ + [Serializable] + [DebuggerDisplay("Count = {Count}")] + public class EditableList : EditableArrayList, IList + { + #region Constructors + + public EditableList() + : base(typeof(T)) + { + } + + public EditableList(int capacity) + : base(typeof(T), capacity) + { + } + + public EditableList(ICollection c) + : base(typeof(T), c) + { + } + + public EditableList(bool trackChanges) + : base(typeof(T), trackChanges) + { + } + + public EditableList(int capacity, bool trackChanges) + : base(typeof(T), capacity, trackChanges) + { + } + + public EditableList(ICollection c, bool trackChanges) + : base(typeof(T), c, trackChanges) + { + } + + public EditableList(EditableList list) + : base(list, true) + { + } + + public EditableList(EditableList list, bool trackChanges) + : base(list, trackChanges) + { + } + + #endregion + + #region Typed Methods + + public override object Clone() + { + return Clone(new EditableList((ArrayList)List.Clone())); + } + + public new T this[int index] + { + get { return (T)base[index]; } + set { base[index] = value; } + } + + public new T[] ToArray() + { + return (T[])base.ToArray(typeof(T)); + } + + public new T AddNew() + { + return (T)base.AddNew(); + } + + public int RemoveAll(Predicate match) + { + var n = 0; + + for (var i = 0; i < Count; i++) + { + var item = this[i]; + + if (match(item)) + { + Remove((object)item); + i--; + n++; + } + } + + return n; + } + + #endregion + + #region Like List Methods + + public T Find(Predicate match) + { + if (match == null) throw new ArgumentNullException("match"); + + foreach (T t in List) + if (match(t)) + return t; + + return default(T); + } + + public EditableList FindAll(Predicate match) + { + if (match == null) throw new ArgumentNullException("match"); + + var list = new EditableList(); + + foreach (T t in List) + if (match(t)) + list.Add(t); + + return list; + } + + public int FindIndex(Predicate match) + { + return FindIndex(0, List.Count, match); + } + + public int FindIndex(int startIndex, Predicate match) + { + return FindIndex(startIndex, List.Count - startIndex, match); + } + + public int FindIndex(int startIndex, int count, Predicate match) + { + if (startIndex > List.Count) + throw new ArgumentOutOfRangeException("startIndex"); + + if (count < 0 || startIndex > List.Count - count) + throw new ArgumentOutOfRangeException("count"); + + if (match == null) + throw new ArgumentNullException("match"); + + for (var i = startIndex; i < startIndex + count; i++) + if (match((T)List[i])) + return i; + + return -1; + } + + public T FindLast(Predicate match) + { + if (match == null) throw new ArgumentNullException("match"); + + for (var i = List.Count - 1; i >= 0; i--) + { + var t = (T)List[i]; + + if (match(t)) + return t; + } + + return default(T); + } + + public int FindLastIndex(Predicate match) + { + return FindLastIndex(List.Count - 1, List.Count, match); + } + + public int FindLastIndex(int startIndex, Predicate match) + { + return FindLastIndex(startIndex, startIndex + 1, match); + } + + public int FindLastIndex(int startIndex, int count, Predicate match) + { + if (startIndex >= List.Count) + throw new ArgumentOutOfRangeException("startIndex"); + + if (count < 0 || startIndex - count + 1 < 0) + throw new ArgumentOutOfRangeException("count"); + + if (match == null) + throw new ArgumentNullException("match"); + + for (var i = startIndex; i > startIndex - count; i--) + { + var t = (T)List[i]; + + if (match(t)) + return i; + } + + return -1; + } + + public void ForEach(Action action) + { + if (action == null) throw new ArgumentNullException("action"); + + foreach (T t in List) + action(t); + } + + public void Sort(IComparer comparer) + { + Sort(0, List.Count, comparer); + } + + public void Sort(int index, int count, IComparer comparer) + { + if (List.Count > 1 && count > 1) + { + var items = new T[count]; + + List.CopyTo(index, items, 0, count); + Array.Sort(items, index, count, comparer); + + for (var i = 0; i < count; i++) + List[i + index] = items[i]; + + OnListChanged(ListChangedType.Reset, 0); + } + } + + public void Sort(Comparison comparison) + { + if (List.Count > 1) + { + var items = new T[List.Count]; + + List.CopyTo(items); + Array.Sort(items, comparison); + + for (var i = 0; i < List.Count; i++) + List[i] = items[i]; + + OnListChanged(ListChangedType.Reset, 0); + } + } + + #endregion + + #region Static Methods + + internal EditableList(ArrayList list) + : base(typeof(T), list) + { + } + + public static EditableList Adapter(List list) + { + return new EditableList(ArrayList.Adapter(list)); + } + + public static new EditableList Adapter(IList list) + { + return list is ArrayList? + new EditableList((ArrayList)list): + new EditableList(ArrayList.Adapter(list)); + } + + #endregion + + #region IList Members + + public int IndexOf(T item) + { + return IndexOf((object)item); + } + + public void Insert(int index, T item) + { + Insert(index, (object)item); + } + + #endregion + + #region ICollection Members + + public void Add(T item) + { + Add((object)item); + } + + public bool Contains(T item) + { + return Contains((object)item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + CopyTo((Array)array, arrayIndex); + } + + public bool Remove(T item) + { + if (Contains(item) == false) + return false; + + Remove((object)item); + + return true; + } + + #endregion + + #region IEnumerable Members + + public new IEnumerator GetEnumerator() + { + return new Enumerator(List.GetEnumerator()); + } + + class Enumerator : IEnumerator + { + public Enumerator(IEnumerator enumerator) + { + _enumerator = enumerator; + } + + private readonly IEnumerator _enumerator; + + #region IEnumerator Members + + T IEnumerator.Current + { + get { return (T)_enumerator.Current; } + } + + #endregion + + #region IEnumerator Members + + object IEnumerator.Current + { + get { return _enumerator.Current; } + } + + bool IEnumerator.MoveNext() + { + return _enumerator.MoveNext(); + } + + void IEnumerator.Reset() + { + _enumerator.Reset(); + } + + #endregion + + #region IDisposable Members + + void IDisposable.Dispose() + { + } + + #endregion + } + + #endregion + } +} + diff -r 000000000000 -r f990fcb411a9 Source/EditableObjects/EditableListChangedEventArgs.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/EditableObjects/EditableListChangedEventArgs.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,27 @@ +using System.ComponentModel; + +namespace BLToolkit.EditableObjects +{ + public class EditableListChangedEventArgs : ListChangedEventArgs + { + public EditableListChangedEventArgs(int newIndex, int oldIndex) + : base(ListChangedType.ItemMoved, newIndex, oldIndex) + { + } + + public EditableListChangedEventArgs(ListChangedType listChangedType, int index) + : base(listChangedType, index) + { + } + + public EditableListChangedEventArgs(ListChangedType listChangedType) + : base(listChangedType, -1) + { + } + + public EditableListChangedEventArgs(int index, PropertyDescriptor propDesc) + : base(ListChangedType.ItemChanged, index, propDesc) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/EditableObjects/EditableObject.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/EditableObjects/EditableObject.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,301 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data.SqlTypes; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Xml; +using System.Xml.Serialization; + +using BLToolkit.Common; +using BLToolkit.ComponentModel; +using BLToolkit.Mapping; +using BLToolkit.Reflection; +using BLToolkit.TypeBuilder; +using BLToolkit.Validation; + +namespace BLToolkit.EditableObjects +{ + #region Instance Types + [GlobalInstanceType(typeof(byte), typeof(EditableValue))] + [GlobalInstanceType(typeof(char), typeof(EditableValue))] + [GlobalInstanceType(typeof(ushort), typeof(EditableValue))] + [GlobalInstanceType(typeof(uint), typeof(EditableValue))] + [GlobalInstanceType(typeof(ulong), typeof(EditableValue))] + [GlobalInstanceType(typeof(bool), typeof(EditableValue))] + [GlobalInstanceType(typeof(sbyte), typeof(EditableValue))] + [GlobalInstanceType(typeof(short), typeof(EditableValue))] + [GlobalInstanceType(typeof(int), typeof(EditableValue))] + [GlobalInstanceType(typeof(long), typeof(EditableValue))] + [GlobalInstanceType(typeof(float), typeof(EditableValue))] + [GlobalInstanceType(typeof(double), typeof(EditableValue))] + [GlobalInstanceType(typeof(string), typeof(EditableValue), "")] + [GlobalInstanceType(typeof(DateTime), typeof(EditableValue))] + [GlobalInstanceType(typeof(decimal), typeof(EditableValue))] + [GlobalInstanceType(typeof(Guid), typeof(EditableValue))] + + [GlobalInstanceType(typeof(byte?), typeof(EditableValue))] + [GlobalInstanceType(typeof(char?), typeof(EditableValue))] + [GlobalInstanceType(typeof(ushort?), typeof(EditableValue))] + [GlobalInstanceType(typeof(uint?), typeof(EditableValue))] + [GlobalInstanceType(typeof(ulong?), typeof(EditableValue))] + [GlobalInstanceType(typeof(bool?), typeof(EditableValue))] + [GlobalInstanceType(typeof(sbyte?), typeof(EditableValue))] + [GlobalInstanceType(typeof(short?), typeof(EditableValue))] + [GlobalInstanceType(typeof(int?), typeof(EditableValue))] + [GlobalInstanceType(typeof(long?), typeof(EditableValue))] + [GlobalInstanceType(typeof(float?), typeof(EditableValue))] + [GlobalInstanceType(typeof(double?), typeof(EditableValue))] + [GlobalInstanceType(typeof(DateTime?), typeof(EditableValue))] + [GlobalInstanceType(typeof(decimal?), typeof(EditableValue))] + [GlobalInstanceType(typeof(Guid?), typeof(EditableValue))] + + [GlobalInstanceType(typeof(SqlBoolean), typeof(EditableValue))] + [GlobalInstanceType(typeof(SqlByte), typeof(EditableValue))] + [GlobalInstanceType(typeof(SqlDateTime), typeof(EditableValue))] + [GlobalInstanceType(typeof(SqlDecimal), typeof(EditableValue))] + [GlobalInstanceType(typeof(SqlDouble), typeof(EditableValue))] + [GlobalInstanceType(typeof(SqlGuid), typeof(EditableValue))] + [GlobalInstanceType(typeof(SqlInt16), typeof(EditableValue))] + [GlobalInstanceType(typeof(SqlInt32), typeof(EditableValue))] + [GlobalInstanceType(typeof(SqlInt64), typeof(EditableValue))] + [GlobalInstanceType(typeof(SqlMoney), typeof(EditableValue))] + [GlobalInstanceType(typeof(SqlSingle), typeof(EditableValue))] + [GlobalInstanceType(typeof(SqlString), typeof(EditableValue), "")] + + [GlobalInstanceType(typeof(XmlDocument), typeof(EditableXmlDocument))] + [GlobalInstanceType(typeof(EditableObject), typeof(EditableObjectHolder), IsObjectHolder=true)] + #endregion + [ImplementInterface(typeof(IEditable))] + [ImplementInterface(typeof(IMemberwiseEditable))] + [ImplementInterface(typeof(IPrintDebugState))] + [ImplementInterface(typeof(ISetParent))] + [ComVisible(true)] + [Serializable] + public abstract class EditableObject : EntityBase, + ICloneable, IEditableObject, INotifyPropertyChanged, + ISupportMapping, IValidatable, IPropertyChanged, INotifyObjectEdit + { + #region Constructor + + protected EditableObject() + { + ISetParent setParent = this as ISetParent; + + if (setParent != null) + setParent.SetParent(this, null); + } + + #endregion + + #region IEditable + + public virtual void AcceptChanges() + { + if (this is IEditable) + ((IEditable)this).AcceptChanges(); + } + + public virtual void RejectChanges() + { + var dirtyMembers = GetDirtyMembers(); + + if (this is IEditable) + ((IEditable)this).RejectChanges(); + + foreach (PropertyInfo dirtyMember in dirtyMembers) + OnPropertyChanged(dirtyMember.Name); + } + + [MapIgnore, Bindable(false)] + public virtual bool IsDirty + { + get { return this is IEditable? ((IEditable)this).IsDirty: false; } + } + + public virtual void AcceptMemberChanges(string memberName) + { + if (this is IMemberwiseEditable) + ((IMemberwiseEditable)this).AcceptMemberChanges(null, memberName); + } + + public virtual void RejectMemberChanges(string memberName) + { + bool notifyChange = IsDirtyMember(memberName); + + if (this is IMemberwiseEditable) + ((IMemberwiseEditable)this).RejectMemberChanges(null, memberName); + + if (notifyChange) + OnPropertyChanged(memberName); + } + + public virtual bool IsDirtyMember(string memberName) + { + bool isDirty = false; + + if (this is IMemberwiseEditable) + ((IMemberwiseEditable)this).IsDirtyMember(null, memberName, ref isDirty); + + return isDirty; + } + + public virtual PropertyInfo[] GetDirtyMembers() + { + ArrayList list = new ArrayList(); + + if (this is IMemberwiseEditable) + ((IMemberwiseEditable)this).GetDirtyMembers(null, list); + + return (PropertyInfo[])list.ToArray(typeof(PropertyInfo)); + } + + [MapIgnore, Bindable(false)] + public virtual string PrintDebugState + { + get + { +#if DEBUG + if (this is IPrintDebugState) + { + string s = string.Format( + "====== {0} ======\r\nIsDirty: {1}\r\n" + + "Property IsDirty Original Current\r\n" + + "==================== = ======================================== ========================================\r\n", + GetType().Name, IsDirty); + + ((IPrintDebugState)this).PrintDebugState(null, ref s); + + return s + "\r\n"; + } +#endif + return ""; + } + } + + #endregion + + #region ISupportMapping Members + + private bool _isInMapping; + [MapIgnore, Bindable(false)] + public bool IsInMapping + { + get { return _isInMapping; } + } + + protected void SetIsInMapping(bool isInMapping) + { + _isInMapping = isInMapping; + } + + public virtual void BeginMapping(InitContext initContext) + { + _isInMapping = true; + } + + public virtual void EndMapping(InitContext initContext) + { + if (initContext.IsDestination) + AcceptChanges(); + + _isInMapping = false; + + if (initContext.IsDestination) + OnPropertyChanged(""); + } + + #endregion + + #region Notify Changes + + protected internal virtual void OnPropertyChanged(string propertyName) + { + if (NotifyChanges && PropertyChanged != null) + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + + private int _notNotifyChangesCount = 0; + [MapIgnore, Bindable(false), XmlIgnore] + public bool NotifyChanges + { + get { return _notNotifyChangesCount == 0; } + set { _notNotifyChangesCount = value? 0: 1; } + } + + public void LockNotifyChanges() + { + _notNotifyChangesCount++; + } + + public void UnlockNotifyChanges() + { + _notNotifyChangesCount--; + + if (_notNotifyChangesCount < 0) + throw new InvalidOperationException(); + } + + #endregion + + #region IPropertyChanged Members + + void IPropertyChanged.OnPropertyChanged(PropertyInfo propertyInfo) + { + if (_isInMapping == false) + OnPropertyChanged(propertyInfo.Name); + } + + #endregion + + #region INotifyPropertyChanged Members + + [field : NonSerialized] + public virtual event PropertyChangedEventHandler PropertyChanged; + + #endregion + + #region IEditableObject Members + + public virtual void BeginEdit() + { + if (ObjectEdit != null) + ObjectEdit(this, new ObjectEditEventArgs(ObjectEditType.Begin)); + } + + public virtual void CancelEdit() + { + if (ObjectEdit != null) + ObjectEdit(this, new ObjectEditEventArgs(ObjectEditType.Cancel)); + } + + public virtual void EndEdit() + { + if (ObjectEdit != null) + ObjectEdit(this, new ObjectEditEventArgs(ObjectEditType.End)); + } + + #endregion + + #region INotifyObjectEdit Members + + public event ObjectEditEventHandler ObjectEdit; + + #endregion + + #region ICloneable Members + + /// + ///Creates a new object that is a copy of the current instance. + /// + /// + ///A new object that is a copy of this instance. + /// + object ICloneable.Clone() + { + return TypeAccessor.Copy(this); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/EditableObjects/EditableObjectHolder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/EditableObjects/EditableObjectHolder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,142 @@ +using System; +using System.Collections; +using System.Reflection; +using System.ComponentModel; + +using BLToolkit.TypeBuilder; + +namespace BLToolkit.EditableObjects +{ + [Serializable] + public class /*struct*/ EditableObjectHolder : IEditable, IMemberwiseEditable, ISetParent, IPrintDebugState + { + public EditableObjectHolder(EditableObject obj) + { + _original = obj; + _current = obj; + + if (_current != null) + _current.PropertyChanged += _current_PropertyChanged; + } + + void _current_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + EditableObject obj = _parent as EditableObject; + + if (obj != null) + obj.OnPropertyChanged(_propertyInfo.Name + "." + e.PropertyName); + } + + private EditableObject _original; + private EditableObject _current; + private object _parent; + private PropertyInfo _propertyInfo; + + [GetValue, SetValue] + public EditableObject Value + { + get { return _current; } + set + { + if (_current != null) + _current.PropertyChanged -= _current_PropertyChanged; + + _current = value; + + if (_current != null) + _current.PropertyChanged += _current_PropertyChanged; + } + } + + #region IEditable Members + + public void AcceptChanges() + { + _original = _current; + + if (_current != null) + _current.AcceptChanges(); + } + + public void RejectChanges() + { + _current = _original; + + if (_current != null) + _current.RejectChanges(); + } + + public bool IsDirty + { + get + { + if (_current == null) + return _original != null; + + return _current != _original || _current.IsDirty; + } + } + + #endregion + + #region IMemberwiseEditable Members + + public bool AcceptMemberChanges(PropertyInfo propertyInfo, string memberName) + { + if (memberName != propertyInfo.Name) + return false; + + AcceptChanges(); + + return true; + } + + public bool RejectMemberChanges(PropertyInfo propertyInfo, string memberName) + { + if (memberName != propertyInfo.Name) + return false; + + RejectChanges(); + + return true; + } + + public bool IsDirtyMember(PropertyInfo propertyInfo, string memberName, ref bool isDirty) + { + if (memberName != propertyInfo.Name) + return false; + + isDirty = IsDirty; + + return true; + } + + public void GetDirtyMembers(PropertyInfo propertyInfo, ArrayList list) + { + if (IsDirty) + list.Add(propertyInfo); + } + + #endregion + + #region IPrintDebugState Members + + public void PrintDebugState(PropertyInfo propertyInfo, ref string str) + { + str += string.Format("{0,-20} {1} {2,-40} {3,-40} \r\n", + propertyInfo.Name, IsDirty? "*": " ", _original, _current); + } + + #endregion + + #region ISetParent Members + + public void SetParent(object parent, PropertyInfo propertyInfo) + { + _parent = parent; + _propertyInfo = propertyInfo; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/EditableObjects/EditableObjectT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/EditableObjects/EditableObjectT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,38 @@ +using System; + +using BLToolkit.Reflection; + +namespace BLToolkit.EditableObjects +{ + [Serializable] + public abstract class EditableObject : EditableObject + where T : EditableObject + { + #region CreateInstance + + public static T CreateInstance() + { + return TypeAccessor.CreateInstanceEx(); + } + + #endregion + + #region Clone + + public virtual T Clone() + { + return (T)TypeAccessor.Copy(this); + } + + #endregion + + #region Copy + + public void CopyTo(T dest) + { + TypeAccessor.Copy(this, dest); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/EditableObjects/EditableValue.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/EditableObjects/EditableValue.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,103 @@ +using System; +using System.Collections; +using System.Reflection; + +using BLToolkit.TypeBuilder; + +namespace BLToolkit.EditableObjects +{ + [Serializable] + public struct EditableValue: IEditable, IMemberwiseEditable, IPrintDebugState + { + private T _original; + private T _current; + + public EditableValue(T value) + { + _original = value; + _current = value; + } + + [GetValue, SetValue] + public T Value + { + get { return _current; } + set { _current = value; } + } + + #region IEditable Members + + public void AcceptChanges() + { + _original = _current; + } + + public void RejectChanges() + { + _current = _original; + } + + public bool IsDirty + { + get + { + object o = _original; + object c = _current; + + return o == null? c != null: o.Equals(c) == false; + } + } + + #endregion + + #region IMemberwiseEditable Members + + public bool AcceptMemberChanges(PropertyInfo propertyInfo, string memberName) + { + if (memberName != propertyInfo.Name) + return false; + + AcceptChanges(); + + return true; + } + + public bool RejectMemberChanges(PropertyInfo propertyInfo, string memberName) + { + if (memberName != propertyInfo.Name) + return false; + + RejectChanges(); + + return true; + } + + public bool IsDirtyMember(PropertyInfo propertyInfo, string memberName, ref bool isDirty) + { + if (memberName != propertyInfo.Name) + return false; + + isDirty = IsDirty; + + return true; + } + + public void GetDirtyMembers(PropertyInfo propertyInfo, ArrayList list) + { + if (IsDirty) + list.Add(propertyInfo); + } + + #endregion + + #region IPrintDebugState Members + + public void PrintDebugState(PropertyInfo propertyInfo, ref string str) + { + str += string.Format("{0,-20} {1} {2,-40} {3,-40} \r\n", + propertyInfo.Name, IsDirty? "*": " ", _original, _current); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/EditableObjects/EditableXmlDocument.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/EditableObjects/EditableXmlDocument.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,267 @@ +using System; +using System.Collections; +using System.Reflection; +using System.Xml; + +using BLToolkit.TypeBuilder; + +namespace BLToolkit.EditableObjects +{ + [Serializable] + public class EditableXmlDocument: IEditable, ISetParent, IMemberwiseEditable, IPrintDebugState + { + private Stack _changedNodes; + private XmlDocument _original; + private XmlDocument _current; + private IPropertyChanged _parent; + private PropertyInfo _propertyInfo; + + public EditableXmlDocument() + : this(new XmlDocument()) + { + } + + public EditableXmlDocument(XmlDocument value) + { + _changedNodes = null; + _current = value; + _original = value; + + StartXmlDocTracking(); + } + + [GetValue, SetValue] + public XmlDocument Value + { + get { return _current; } + set + { + if (_current == value) + return; + + if (_current == _original) + StopXmlDocTracking(); + + // Drop changes, if any. + // + if (_changedNodes != null) + _changedNodes.Clear(); + + _current = value; + + if (_current == _original) + StartXmlDocTracking(); + } + } + + private void StartXmlDocTracking() + { + if (_current == null) + return; + + _current.NodeInserted += HandleNodeChanged; + _current.NodeRemoved += HandleNodeChanged; + _current.NodeChanged += HandleNodeChanged; + } + + private void StopXmlDocTracking() + { + if (_current == null) + return; + + _current.NodeInserted -= HandleNodeChanged; + _current.NodeRemoved -= HandleNodeChanged; + _current.NodeChanged -= HandleNodeChanged; + } + + private void HandleNodeChanged(object sender, XmlNodeChangedEventArgs ea) + { + if (ea.Action == XmlNodeChangedAction.Change && ea.NewValue == ea.OldValue) + { + // A void change can be ignored. + // + return; + } + + if (_changedNodes == null) + _changedNodes = new Stack(); + + _changedNodes.Push(new XmlNodeTrackBack(ea)); + + // Propagate changes to parent object, if set. + // + if (_parent != null) + _parent.OnPropertyChanged(_propertyInfo); + } + + #region IEditable Members + + public void AcceptChanges() + { + if (_original != _current) + { + _original = _current; + StartXmlDocTracking(); + } + else + { + // Let them go away. + // + if (_changedNodes != null) + _changedNodes.Clear(); + } + } + + public void RejectChanges() + { + if (_original != _current) + { + _current = _original; + StartXmlDocTracking(); + } + else if (_changedNodes != null && _changedNodes.Count > 0) + { + // Don't fall into an infinite loop. + // + StopXmlDocTracking(); + + // A Stack enumerates from back to front. + // + foreach (XmlNodeTrackBack nodeTrackBack in _changedNodes) + { + switch (nodeTrackBack.Action) + { + case XmlNodeChangedAction.Insert: + if (nodeTrackBack.Node.NodeType == XmlNodeType.Attribute) + ((XmlElement)nodeTrackBack.Value).Attributes.Remove((XmlAttribute)nodeTrackBack.Node); + else + ((XmlNode)nodeTrackBack.Value).RemoveChild(nodeTrackBack.Node); + break; + case XmlNodeChangedAction.Remove: + // NB: The order of children nodes may change. + // + if (nodeTrackBack.Node.NodeType == XmlNodeType.Attribute) + ((XmlElement)nodeTrackBack.Value).Attributes.Append((XmlAttribute)nodeTrackBack.Node); + else + ((XmlNode)nodeTrackBack.Value).AppendChild(nodeTrackBack.Node); + break; + case XmlNodeChangedAction.Change: + nodeTrackBack.Node.Value = (string)nodeTrackBack.Value; + break; + } + } + + _changedNodes.Clear(); + StartXmlDocTracking(); + } + } + + public bool IsDirty + { + get + { + if (_current == _original) + return _changedNodes != null && _changedNodes.Count > 0; + + if (_current == null || _original == null) + return true; + + return _current.InnerXml.TrimEnd() != _original.InnerXml.TrimEnd(); + } + } + + #endregion + + #region IMemberwiseEditable Members + + public bool AcceptMemberChanges(PropertyInfo propertyInfo, string memberName) + { + if (memberName != propertyInfo.Name) + return false; + + AcceptChanges(); + + return true; + } + + public bool RejectMemberChanges(PropertyInfo propertyInfo, string memberName) + { + if (memberName != propertyInfo.Name) + return false; + + RejectChanges(); + + return true; + } + + public bool IsDirtyMember(PropertyInfo propertyInfo, string memberName, ref bool isDirty) + { + if (memberName != propertyInfo.Name) + return false; + + isDirty = IsDirty; + + return true; + } + + public void GetDirtyMembers(PropertyInfo propertyInfo, ArrayList list) + { + if (IsDirty) + list.Add(propertyInfo); + } + + #endregion + + #region IPrintDebugState Members + + public void PrintDebugState(PropertyInfo propertyInfo, ref string str) + { + str += string.Format("{0,-20} {1} {2,-80}\r\n", + propertyInfo.Name, IsDirty? "*": " ", _current != null? _current.OuterXml: "(null)"); + } + + #endregion + + #region ISetParent Members + + public void SetParent(object parent, PropertyInfo propertyInfo) + { + _parent = parent as IPropertyChanged; + _propertyInfo = propertyInfo; + } + + #endregion + + #region Inner types + + private struct XmlNodeTrackBack + { + public readonly XmlNode Node; + public readonly XmlNodeChangedAction Action; + public readonly object Value; + + public XmlNodeTrackBack(XmlNodeChangedEventArgs ea) + { + Node = ea.Node; + Action = ea.Action; + switch(ea.Action) + { + case XmlNodeChangedAction.Insert: + Value = ea.NewParent; + break; + case XmlNodeChangedAction.Remove: + Value = ea.OldParent; + break; + case XmlNodeChangedAction.Change: + Value = ea.OldValue; + break; + default: + throw new ArgumentOutOfRangeException("ea", ea.Action, string.Format("Unknown XmlNodeChangedAction")); + } + } + } + + #endregion + + } +} diff -r 000000000000 -r f990fcb411a9 Source/EditableObjects/IEditable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/EditableObjects/IEditable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +using BLToolkit.TypeBuilder; + +namespace BLToolkit.EditableObjects +{ + public interface IEditable + { + void AcceptChanges(); + void RejectChanges(); + bool IsDirty { [return: ReturnIfTrue] get; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/EditableObjects/IMemberwiseEditable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/EditableObjects/IMemberwiseEditable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +using System.Reflection; +using System.Collections; + +using BLToolkit.TypeBuilder; + +namespace BLToolkit.EditableObjects +{ + public interface IMemberwiseEditable + { + [return: ReturnIfTrue] bool AcceptMemberChanges([PropertyInfo] PropertyInfo propertyInfo, string memberName); + [return: ReturnIfTrue] bool RejectMemberChanges([PropertyInfo] PropertyInfo propertyInfo, string memberName); + [return: ReturnIfTrue] bool IsDirtyMember ([PropertyInfo] PropertyInfo propertyInfo, string memberName, ref bool isDirty); + + void GetDirtyMembers([PropertyInfo] PropertyInfo propertyInfo, ArrayList list); + } +} diff -r 000000000000 -r f990fcb411a9 Source/EditableObjects/IPrintDebugState.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/EditableObjects/IPrintDebugState.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System.Reflection; +using System.Diagnostics.CodeAnalysis; + +using BLToolkit.TypeBuilder; + +namespace BLToolkit.EditableObjects +{ + public interface IPrintDebugState + { + [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "1#")] + void PrintDebugState([PropertyInfo] PropertyInfo propertyInfo, ref string str); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Linq/ExpressionHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Linq/ExpressionHelper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2298 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +using BLToolkit.Data.Linq.Builder; + +// ReSharper disable ConditionIsAlwaysTrueOrFalse +// ReSharper disable HeuristicUnreachableCode + +namespace BLToolkit.Linq +{ + using Data.Linq; + using Reflection; + + public static class ExpressionHelper + { + #region IsConstant + + public static bool IsConstant(Type type) + { + if (type.IsEnum) + return true; + + switch (Type.GetTypeCode(type)) + { + case TypeCode.Int16 : + case TypeCode.Int32 : + case TypeCode.Int64 : + case TypeCode.UInt16 : + case TypeCode.UInt32 : + case TypeCode.UInt64 : + case TypeCode.SByte : + case TypeCode.Byte : + case TypeCode.Decimal : + case TypeCode.Double : + case TypeCode.Single : + case TypeCode.Boolean : + case TypeCode.String : + case TypeCode.Char : return true; + } + + if (TypeHelper.IsNullableType(type)) + return IsConstant(type.GetGenericArguments()[0]); + + return false; + } + + #endregion + + #region Compare + + internal static bool Compare(Expression expr1, Expression expr2, Dictionary queryableAccessorDic) + { + return Compare(expr1, expr2, new HashSet(), queryableAccessorDic); + } + + static bool Compare( + Expression expr1, + Expression expr2, + HashSet visited, + Dictionary queryableAccessorDic) + { + if (expr1 == expr2) + return true; + + if (expr1 == null || expr2 == null || expr1.NodeType != expr2.NodeType || expr1.Type != expr2.Type) + return false; + + switch (expr1.NodeType) + { + case ExpressionType.Add: + case ExpressionType.AddChecked: + case ExpressionType.And: + case ExpressionType.AndAlso: + case ExpressionType.ArrayIndex: +#if FW4 || SILVERLIGHT + case ExpressionType.Assign: +#endif + case ExpressionType.Coalesce: + case ExpressionType.Divide: + case ExpressionType.Equal: + case ExpressionType.ExclusiveOr: + case ExpressionType.GreaterThan: + case ExpressionType.GreaterThanOrEqual: + case ExpressionType.LeftShift: + case ExpressionType.LessThan: + case ExpressionType.LessThanOrEqual: + case ExpressionType.Modulo: + case ExpressionType.Multiply: + case ExpressionType.MultiplyChecked: + case ExpressionType.NotEqual: + case ExpressionType.Or: + case ExpressionType.OrElse: + case ExpressionType.Power: + case ExpressionType.RightShift: + case ExpressionType.Subtract: + case ExpressionType.SubtractChecked: + { + var e1 = (BinaryExpression)expr1; + var e2 = (BinaryExpression)expr2; + return + e1.Method == e2.Method && + Compare(e1.Conversion, e2.Conversion, visited, queryableAccessorDic) && + Compare(e1.Left, e2.Left, visited, queryableAccessorDic) && + Compare(e1.Right, e2.Right, visited, queryableAccessorDic); + } + + case ExpressionType.ArrayLength: + case ExpressionType.Convert: + case ExpressionType.ConvertChecked: + case ExpressionType.Negate: + case ExpressionType.NegateChecked: + case ExpressionType.Not: + case ExpressionType.Quote: + case ExpressionType.TypeAs: + case ExpressionType.UnaryPlus: + { + var e1 = (UnaryExpression)expr1; + var e2 = (UnaryExpression)expr2; + return e1.Method == e2.Method && Compare(e1.Operand, e2.Operand, visited, queryableAccessorDic); + } + + case ExpressionType.Call: + { + var e1 = (MethodCallExpression)expr1; + var e2 = (MethodCallExpression)expr2; + + if (e1.Arguments.Count != e2.Arguments.Count || e1.Method != e2.Method) + return false; + + if (queryableAccessorDic.Count > 0) + { + QueryableAccessor qa; + + if (queryableAccessorDic.TryGetValue(expr1, out qa)) + return Compare(qa.Queryable.Expression, qa.Accessor(expr2).Expression, visited, queryableAccessorDic); + } + + if (!Compare(e1.Object, e2.Object, visited, queryableAccessorDic)) + return false; + + for (var i = 0; i < e1.Arguments.Count; i++) + if (!Compare(e1.Arguments[i], e2.Arguments[i], visited, queryableAccessorDic)) + return false; + + return true; + } + + case ExpressionType.Conditional: + { + var e1 = (ConditionalExpression)expr1; + var e2 = (ConditionalExpression)expr2; + return + Compare(e1.Test, e2.Test, visited, queryableAccessorDic) && + Compare(e1.IfTrue, e2.IfTrue, visited, queryableAccessorDic) && + Compare(e1.IfFalse, e2.IfFalse, visited, queryableAccessorDic); + } + + case ExpressionType.Constant: + { + var e1 = (ConstantExpression)expr1; + var e2 = (ConstantExpression)expr2; + + if (e1.Value == null && e2.Value == null) + return true; + + if (IsConstant(e1.Type)) + return Equals(e1.Value, e2.Value); + + if (e1.Value == null || e2.Value == null) + return false; + + if (e1.Value is IQueryable) + { + var eq1 = ((IQueryable)e1.Value).Expression; + var eq2 = ((IQueryable)e2.Value).Expression; + + if (visited.Add(eq1)) + return Compare(eq1, eq2, visited, queryableAccessorDic); + } + + return true; + } + + case ExpressionType.Invoke: + { + var e1 = (InvocationExpression)expr1; + var e2 = (InvocationExpression)expr2; + + if (e1.Arguments.Count != e2.Arguments.Count || !Compare(e1.Expression, e2.Expression, visited, queryableAccessorDic)) + return false; + + for (var i = 0; i < e1.Arguments.Count; i++) + if (!Compare(e1.Arguments[i], e2.Arguments[i], visited, queryableAccessorDic)) + return false; + + return true; + } + + case ExpressionType.Lambda: + { + var e1 = (LambdaExpression)expr1; + var e2 = (LambdaExpression)expr2; + + if (e1.Parameters.Count != e2.Parameters.Count || !Compare(e1.Body, e2.Body, visited, queryableAccessorDic)) + return false; + + for (var i = 0; i < e1.Parameters.Count; i++) + if (!Compare(e1.Parameters[i], e2.Parameters[i], visited, queryableAccessorDic)) + return false; + + return true; + } + + case ExpressionType.ListInit: + { + var e1 = (ListInitExpression)expr1; + var e2 = (ListInitExpression)expr2; + + if (e1.Initializers.Count != e2.Initializers.Count || !Compare(e1.NewExpression, e2.NewExpression, visited, queryableAccessorDic)) + return false; + + for (var i = 0; i < e1.Initializers.Count; i++) + { + var i1 = e1.Initializers[i]; + var i2 = e2.Initializers[i]; + + if (i1.Arguments.Count != i2.Arguments.Count || i1.AddMethod != i2.AddMethod) + return false; + + for (var j = 0; j < i1.Arguments.Count; j++) + if (!Compare(i1.Arguments[j], i2.Arguments[j], visited, queryableAccessorDic)) + return false; + } + + return true; + } + + case ExpressionType.MemberAccess: + { + var e1 = (MemberExpression)expr1; + var e2 = (MemberExpression)expr2; + + if (e1.Member == e2.Member) + { + if (e1.Expression == e2.Expression || e1.Expression.Type == e2.Expression.Type) + { + if (queryableAccessorDic.Count > 0) + { + QueryableAccessor qa; + + if (queryableAccessorDic.TryGetValue(expr1, out qa)) + return + Compare(e1.Expression, e2.Expression, visited, queryableAccessorDic) && + Compare(qa.Queryable.Expression, qa.Accessor(expr2).Expression, visited, queryableAccessorDic); + } + } + + return Compare(e1.Expression, e2.Expression, visited, queryableAccessorDic); + } + + return false; + } + + case ExpressionType.MemberInit: + { + var e1 = (MemberInitExpression)expr1; + var e2 = (MemberInitExpression)expr2; + + if (e1.Bindings.Count != e2.Bindings.Count || !Compare(e1.NewExpression, e2.NewExpression, visited, queryableAccessorDic)) + return false; + + Func compareBindings = null; compareBindings = (b1,b2) => + { + if (b1 == b2) + return true; + + if (b1 == null || b2 == null || b1.BindingType != b2.BindingType || b1.Member != b2.Member) + return false; + + switch (b1.BindingType) + { + case MemberBindingType.Assignment: + return Compare(((MemberAssignment)b1).Expression, ((MemberAssignment)b2).Expression, visited, queryableAccessorDic); + + case MemberBindingType.ListBinding: + var ml1 = (MemberListBinding)b1; + var ml2 = (MemberListBinding)b2; + + if (ml1.Initializers.Count != ml2.Initializers.Count) + return false; + + for (var i = 0; i < ml1.Initializers.Count; i++) + { + var ei1 = ml1.Initializers[i]; + var ei2 = ml2.Initializers[i]; + + if (ei1.AddMethod != ei2.AddMethod || ei1.Arguments.Count != ei2.Arguments.Count) + return false; + + for (var j = 0; j < ei1.Arguments.Count; j++) + if (!Compare(ei1.Arguments[j], ei2.Arguments[j], visited, queryableAccessorDic)) + return false; + } + + break; + + case MemberBindingType.MemberBinding: + var mm1 = (MemberMemberBinding)b1; + var mm2 = (MemberMemberBinding)b2; + + if (mm1.Bindings.Count != mm2.Bindings.Count) + return false; + + for (var i = 0; i < mm1.Bindings.Count; i++) + if (!compareBindings(mm1.Bindings[i], mm2.Bindings[i])) + return false; + + break; + } + + return true; + }; + + for (var i = 0; i < e1.Bindings.Count; i++) + { + var b1 = e1.Bindings[i]; + var b2 = e2.Bindings[i]; + + if (!compareBindings(b1, b2)) + return false; + } + + return true; + } + + case ExpressionType.New: + { + var e1 = (NewExpression)expr1; + var e2 = (NewExpression)expr2; + + if (e1.Arguments.Count != e2.Arguments.Count) + return false; + + if (e1.Members == null && e2.Members != null) + return false; + + if (e1.Members != null && e2.Members == null) + return false; + + if (e1.Constructor != e2.Constructor) + return false; + + if (e1.Members != null) + { + if (e1.Members.Count != e2.Members.Count) + return false; + + for (var i = 0; i < e1.Members.Count; i++) + if (e1.Members[i] != e2.Members[i]) + return false; + } + + for (var i = 0; i < e1.Arguments.Count; i++) + if (!Compare(e1.Arguments[i], e2.Arguments[i], visited, queryableAccessorDic)) + return false; + + return true; + } + + case ExpressionType.NewArrayBounds: + case ExpressionType.NewArrayInit: + { + var e1 = (NewArrayExpression)expr1; + var e2 = (NewArrayExpression)expr2; + + if (e1.Expressions.Count != e2.Expressions.Count) + return false; + + for (var i = 0; i < e1.Expressions.Count; i++) + if (!Compare(e1.Expressions[i], e2.Expressions[i], visited, queryableAccessorDic)) + return false; + + return true; + } + + case ExpressionType.Parameter: + { + var e1 = (ParameterExpression)expr1; + var e2 = (ParameterExpression)expr2; + return e1.Name == e2.Name; + } + + case ExpressionType.TypeIs: + { + var e1 = (TypeBinaryExpression)expr1; + var e2 = (TypeBinaryExpression)expr2; + return e1.TypeOperand == e2.TypeOperand && Compare(e1.Expression, e2.Expression, visited, queryableAccessorDic); + } + +#if FW4 || SILVERLIGHT + + case ExpressionType.Block: + { + var e1 = (BlockExpression)expr1; + var e2 = (BlockExpression)expr2; + + for (var i = 0; i < e1.Expressions.Count; i++) + if (!Compare(e1.Expressions[i], e2.Expressions[i], visited, queryableAccessorDic)) + return false; + + for (var i = 0; i < e1.Variables.Count; i++) + if (!Compare(e1.Variables[i], e2.Variables[i], visited, queryableAccessorDic)) + return false; + + return true; + } + +#endif + } + + throw new InvalidOperationException(); + } + + #endregion + + #region Path + + static Expression ConvertTo(Expression expr, Type type) + { + return Expression.Convert(expr, type); + } + + static void Path(IEnumerable source, HashSet visited, Expression path, MethodInfo property, Action func) + where T : class + { + var prop = Expression.Property(path, property); + var i = 0; + foreach (var item in source) + func(item, Expression.Call(prop, ReflectionHelper.IndexExpressor.Item, new Expression[] { Expression.Constant(i++) })); + } + + static void Path(IEnumerable source, HashSet visited, Expression path, MethodInfo property, Action func) + where T : Expression + { + var prop = Expression.Property(path, property); + var i = 0; + foreach (var item in source) + Path(item, visited, Expression.Call(prop, ReflectionHelper.IndexExpressor.Item, new Expression[] { Expression.Constant(i++) }), func); + } + + static void Path(Expression expr, HashSet visited, Expression path, MethodInfo property, Action func) + { + Path(expr, visited, Expression.Property(path, property), func); + } + + public static void Path(this Expression expr, Expression path, Action func) + { + Path(expr, new HashSet(), path, func); + } + + static void Path( + this Expression expr, + HashSet visited, + Expression path, + Action func) + { + if (expr == null) + return; + + switch (expr.NodeType) + { + case ExpressionType.Add: + case ExpressionType.AddChecked: + case ExpressionType.And: + case ExpressionType.AndAlso: + case ExpressionType.ArrayIndex: +#if FW4 || SILVERLIGHT + case ExpressionType.Assign: +#endif + case ExpressionType.Coalesce: + case ExpressionType.Divide: + case ExpressionType.Equal: + case ExpressionType.ExclusiveOr: + case ExpressionType.GreaterThan: + case ExpressionType.GreaterThanOrEqual: + case ExpressionType.LeftShift: + case ExpressionType.LessThan: + case ExpressionType.LessThanOrEqual: + case ExpressionType.Modulo: + case ExpressionType.Multiply: + case ExpressionType.MultiplyChecked: + case ExpressionType.NotEqual: + case ExpressionType.Or: + case ExpressionType.OrElse: + case ExpressionType.Power: + case ExpressionType.RightShift: + case ExpressionType.Subtract: + case ExpressionType.SubtractChecked: + { + path = ConvertTo(path, typeof(BinaryExpression)); + var e = (BinaryExpression)expr; + + Path(e.Conversion, visited, path, ReflectionHelper.Binary.Conversion, func); + Path(e.Left, visited, path, ReflectionHelper.Binary.Left, func); + Path(e.Right, visited, path, ReflectionHelper.Binary.Right, func); + + break; + } + + case ExpressionType.ArrayLength: + case ExpressionType.Convert: + case ExpressionType.ConvertChecked: + case ExpressionType.Negate: + case ExpressionType.NegateChecked: + case ExpressionType.Not: + case ExpressionType.Quote: + case ExpressionType.TypeAs: + case ExpressionType.UnaryPlus: + Path( + ((UnaryExpression)expr).Operand, + visited, + path = ConvertTo(path, typeof(UnaryExpression)), + ReflectionHelper.Unary.Operand, + func); + break; + + case ExpressionType.Call: + { + path = ConvertTo(path, typeof(MethodCallExpression)); + var e = (MethodCallExpression)expr; + + Path(e.Object, visited, path, ReflectionHelper.MethodCall.Object, func); + Path(e.Arguments, visited, path, ReflectionHelper.MethodCall.Arguments, func); + + break; + } + + case ExpressionType.Conditional: + { + path = ConvertTo(path, typeof(ConditionalExpression)); + var e = (ConditionalExpression)expr; + + Path(e.Test, visited, path, ReflectionHelper.Conditional.Test, func); + Path(e.IfTrue, visited, path, ReflectionHelper.Conditional.IfTrue, func); + Path(e.IfFalse, visited, path, ReflectionHelper.Conditional.IfFalse, func); + + break; + } + + case ExpressionType.Invoke: + { + path = ConvertTo(path, typeof(InvocationExpression)); + var e = (InvocationExpression)expr; + + Path(e.Expression, visited, path, ReflectionHelper.Invocation.Expression, func); + Path(e.Arguments, visited, path, ReflectionHelper.Invocation.Arguments, func); + + break; + } + + case ExpressionType.Lambda: + { + path = ConvertTo(path, typeof(LambdaExpression)); + var e = (LambdaExpression)expr; + + Path(e.Body, visited, path, ReflectionHelper.LambdaExpr.Body, func); + Path(e.Parameters, visited, path, ReflectionHelper.LambdaExpr.Parameters, func); + + break; + } + + case ExpressionType.ListInit: + { + path = ConvertTo(path, typeof(ListInitExpression)); + var e = (ListInitExpression)expr; + + Path(e.NewExpression, visited, path, ReflectionHelper.ListInit.NewExpression, func); + Path(e.Initializers, visited, path, ReflectionHelper.ListInit.Initializers, + (ex,p) => Path(ex.Arguments, visited, p, ReflectionHelper.ElementInit.Arguments, func)); + + break; + } + + case ExpressionType.MemberAccess: + Path( + ((MemberExpression)expr).Expression, + visited, + path = ConvertTo(path, typeof(MemberExpression)), + ReflectionHelper.Member.Expression, + func); + break; + + case ExpressionType.MemberInit: + { + Action modify = null; modify = (b,pinf) => + { + switch (b.BindingType) + { + case MemberBindingType.Assignment: + Path( + ((MemberAssignment)b).Expression, + visited, + ConvertTo(pinf, typeof(MemberAssignment)), + ReflectionHelper.MemberAssignmentBind.Expression, + func); + break; + + case MemberBindingType.ListBinding: + Path( + ((MemberListBinding)b).Initializers, + visited, + ConvertTo(pinf, typeof(MemberListBinding)), + ReflectionHelper.MemberListBind.Initializers, + (p,psi) => Path(p.Arguments, visited, psi, ReflectionHelper.ElementInit.Arguments, func)); + break; + + case MemberBindingType.MemberBinding: + Path( + ((MemberMemberBinding)b).Bindings, + visited, + ConvertTo(pinf, typeof(MemberMemberBinding)), + ReflectionHelper.MemberMemberBind.Bindings, + modify); + break; + } + }; + + path = ConvertTo(path, typeof(MemberInitExpression)); + var e = (MemberInitExpression)expr; + + Path(e.NewExpression, visited, path, ReflectionHelper.MemberInit.NewExpression, func); + Path(e.Bindings, visited, path, ReflectionHelper.MemberInit.Bindings, modify); + + break; + } + + case ExpressionType.New: + Path( + ((NewExpression)expr).Arguments, + visited, + path = ConvertTo(path, typeof(NewExpression)), + ReflectionHelper.New.Arguments, + func); + break; + + case ExpressionType.NewArrayBounds: + Path( + ((NewArrayExpression)expr).Expressions, + visited, + path = ConvertTo(path, typeof(NewArrayExpression)), + ReflectionHelper.NewArray.Expressions, + func); + break; + + case ExpressionType.NewArrayInit: + Path( + ((NewArrayExpression)expr).Expressions, + visited, + path = ConvertTo(path, typeof(NewArrayExpression)), + ReflectionHelper.NewArray.Expressions, + func); + break; + + case ExpressionType.TypeIs: + Path( + ((TypeBinaryExpression)expr).Expression, + visited, + path = ConvertTo(path, typeof(TypeBinaryExpression)), + ReflectionHelper.TypeBinary.Expression, + func); + break; + +#if FW4 || SILVERLIGHT + + case ExpressionType.Block: + { + path = ConvertTo(path, typeof(BlockExpression)); + var e = (BlockExpression)expr; + + Path(e.Expressions, visited, path, ReflectionHelper.Block.Expressions, func); + Path(e.Variables, visited, path, ReflectionHelper.Block.Variables, func); // ? + + break; + } + +#endif + + case ExpressionType.Constant : + { + path = ConvertTo(path, typeof(ConstantExpression)); + var e = (ConstantExpression)expr; + var iq = e.Value as IQueryable; + + if (iq != null && !visited.Contains(iq.Expression)) + { + visited.Add(iq.Expression); + + Expression p = Expression.Property(path, ReflectionHelper.Constant.Value); + p = ConvertTo(p, typeof(IQueryable)); + Path(iq.Expression, visited, p, ReflectionHelper.QueryableInt.Expression, func); + } + + break; + } + + case ExpressionType.Parameter: path = ConvertTo(path, typeof(ParameterExpression)); break; + } + + func(expr, path); + } + + #endregion + + #region Visit + + static void Visit(IEnumerable source, Action func) + { + foreach (var item in source) + func(item); + } + + static void Visit(IEnumerable source, Action func) + where T : Expression + { + foreach (var item in source) + Visit(item, func); + } + + public static void Visit(this Expression expr, Action func) + { + if (expr == null) + return; + + switch (expr.NodeType) + { + case ExpressionType.Add: + case ExpressionType.AddChecked: + case ExpressionType.And: + case ExpressionType.AndAlso: + case ExpressionType.ArrayIndex: +#if FW4 || SILVERLIGHT + case ExpressionType.Assign: +#endif + case ExpressionType.Coalesce: + case ExpressionType.Divide: + case ExpressionType.Equal: + case ExpressionType.ExclusiveOr: + case ExpressionType.GreaterThan: + case ExpressionType.GreaterThanOrEqual: + case ExpressionType.LeftShift: + case ExpressionType.LessThan: + case ExpressionType.LessThanOrEqual: + case ExpressionType.Modulo: + case ExpressionType.Multiply: + case ExpressionType.MultiplyChecked: + case ExpressionType.NotEqual: + case ExpressionType.Or: + case ExpressionType.OrElse: + case ExpressionType.Power: + case ExpressionType.RightShift: + case ExpressionType.Subtract: + case ExpressionType.SubtractChecked: + { + var e = (BinaryExpression)expr; + + Visit(e.Conversion, func); + Visit(e.Left, func); + Visit(e.Right, func); + + break; + } + + case ExpressionType.ArrayLength: + case ExpressionType.Convert: + case ExpressionType.ConvertChecked: + case ExpressionType.Negate: + case ExpressionType.NegateChecked: + case ExpressionType.Not: + case ExpressionType.Quote: + case ExpressionType.TypeAs: + case ExpressionType.UnaryPlus: + Visit(((UnaryExpression)expr).Operand, func); + break; + + case ExpressionType.Call: + { + var e = (MethodCallExpression)expr; + + Visit(e.Object, func); + Visit(e.Arguments, func); + + break; + } + + case ExpressionType.Conditional: + { + var e = (ConditionalExpression)expr; + + Visit(e.Test, func); + Visit(e.IfTrue, func); + Visit(e.IfFalse, func); + + break; + } + + case ExpressionType.Invoke: + { + var e = (InvocationExpression)expr; + + Visit(e.Expression, func); + Visit(e.Arguments, func); + + break; + } + + case ExpressionType.Lambda: + { + var e = (LambdaExpression)expr; + + Visit(e.Body, func); + Visit(e.Parameters, func); + + break; + } + + case ExpressionType.ListInit: + { + var e = (ListInitExpression)expr; + + Visit(e.NewExpression, func); + Visit(e.Initializers, ex => Visit(ex.Arguments, func)); + + break; + } + + case ExpressionType.MemberAccess: Visit(((MemberExpression)expr).Expression, func); break; + + case ExpressionType.MemberInit: + { + Action modify = null; modify = b => + { + switch (b.BindingType) + { + case MemberBindingType.Assignment : Visit(((MemberAssignment)b). Expression, func); break; + case MemberBindingType.ListBinding : Visit(((MemberListBinding)b).Initializers, p => Visit(p.Arguments, func)); break; + case MemberBindingType.MemberBinding : Visit(((MemberMemberBinding)b).Bindings, modify); break; + } + }; + + var e = (MemberInitExpression)expr; + + Visit(e.NewExpression, func); + Visit(e.Bindings, modify); + + break; + } + + case ExpressionType.New : Visit(((NewExpression) expr).Arguments, func); break; + case ExpressionType.NewArrayBounds : Visit(((NewArrayExpression) expr).Expressions, func); break; + case ExpressionType.NewArrayInit : Visit(((NewArrayExpression) expr).Expressions, func); break; + case ExpressionType.TypeIs : Visit(((TypeBinaryExpression)expr).Expression, func); break; + +#if FW4 || SILVERLIGHT + + case ExpressionType.Block: + { + var e = (BlockExpression)expr; + + Visit(e.Expressions, func); + Visit(e.Variables, func); + + break; + } + +#endif + + case (ExpressionType)ChangeTypeExpression.ChangeTypeType : + Visit(((ChangeTypeExpression)expr).Expression, func); break; + } + + func(expr); + } + + static void Visit(IEnumerable source, Func func) + { + foreach (var item in source) + func(item); + } + + static void Visit(IEnumerable source, Func func) + where T : Expression + { + foreach (var item in source) + Visit(item, func); + } + + public static void Visit(this Expression expr, Func func) + { + if (expr == null || !func(expr)) + return; + + switch (expr.NodeType) + { + case ExpressionType.Add: + case ExpressionType.AddChecked: + case ExpressionType.And: + case ExpressionType.AndAlso: + case ExpressionType.ArrayIndex: +#if FW4 || SILVERLIGHT + case ExpressionType.Assign: +#endif + case ExpressionType.Coalesce: + case ExpressionType.Divide: + case ExpressionType.Equal: + case ExpressionType.ExclusiveOr: + case ExpressionType.GreaterThan: + case ExpressionType.GreaterThanOrEqual: + case ExpressionType.LeftShift: + case ExpressionType.LessThan: + case ExpressionType.LessThanOrEqual: + case ExpressionType.Modulo: + case ExpressionType.Multiply: + case ExpressionType.MultiplyChecked: + case ExpressionType.NotEqual: + case ExpressionType.Or: + case ExpressionType.OrElse: + case ExpressionType.Power: + case ExpressionType.RightShift: + case ExpressionType.Subtract: + case ExpressionType.SubtractChecked: + { + var e = (BinaryExpression)expr; + + Visit(e.Conversion, func); + Visit(e.Left, func); + Visit(e.Right, func); + + break; + } + + case ExpressionType.ArrayLength: + case ExpressionType.Convert: + case ExpressionType.ConvertChecked: + case ExpressionType.Negate: + case ExpressionType.NegateChecked: + case ExpressionType.Not: + case ExpressionType.Quote: + case ExpressionType.TypeAs: + case ExpressionType.UnaryPlus: + Visit(((UnaryExpression)expr).Operand, func); + break; + + case ExpressionType.Call: + { + var e = (MethodCallExpression)expr; + + Visit(e.Object, func); + Visit(e.Arguments, func); + + break; + } + + case ExpressionType.Conditional: + { + var e = (ConditionalExpression)expr; + + Visit(e.Test, func); + Visit(e.IfTrue, func); + Visit(e.IfFalse, func); + + break; + } + + case ExpressionType.Invoke: + { + var e = (InvocationExpression)expr; + + Visit(e.Expression, func); + Visit(e.Arguments, func); + + break; + } + + case ExpressionType.Lambda: + { + var e = (LambdaExpression)expr; + + Visit(e.Body, func); + Visit(e.Parameters, func); + + break; + } + + case ExpressionType.ListInit: + { + var e = (ListInitExpression)expr; + + Visit(e.NewExpression, func); + Visit(e.Initializers, ex => Visit(ex.Arguments, func)); + + break; + } + + case ExpressionType.MemberAccess: Visit(((MemberExpression)expr).Expression, func); break; + + case ExpressionType.MemberInit: + { + Func modify = null; modify = b => + { + switch (b.BindingType) + { + case MemberBindingType.Assignment : Visit(((MemberAssignment)b). Expression, func); break; + case MemberBindingType.ListBinding : Visit(((MemberListBinding)b).Initializers, p => Visit(p.Arguments, func)); break; + case MemberBindingType.MemberBinding : Visit(((MemberMemberBinding)b).Bindings, modify); break; + } + + return true; + }; + + var e = (MemberInitExpression)expr; + + Visit(e.NewExpression, func); + Visit(e.Bindings, modify); + + break; + } + + case ExpressionType.New : Visit(((NewExpression) expr).Arguments, func); break; + case ExpressionType.NewArrayBounds : Visit(((NewArrayExpression) expr).Expressions, func); break; + case ExpressionType.NewArrayInit : Visit(((NewArrayExpression) expr).Expressions, func); break; + case ExpressionType.TypeIs : Visit(((TypeBinaryExpression)expr).Expression, func); break; + +#if FW4 || SILVERLIGHT + + case ExpressionType.Block: + { + var e = (BlockExpression)expr; + + Visit(e.Expressions, func); + Visit(e.Variables, func); + + break; + } + +#endif + + case (ExpressionType)ChangeTypeExpression.ChangeTypeType : + Visit(((ChangeTypeExpression)expr).Expression, func); + break; + } + } + + #endregion + + #region Find + + static Expression Find(IEnumerable source, Func func) + { + foreach (var item in source) + { + var ex = func(item); + if (ex != null) + return ex; + } + + return null; + } + + static Expression Find(IEnumerable source, Func func) + where T : Expression + { + foreach (var item in source) + { + var f = Find(item, func); + if (f != null) + return f; + } + + return null; + } + + public static Expression Find(this Expression expr, Func func) + { + if (expr == null || func(expr)) + return expr; + + switch (expr.NodeType) + { + case ExpressionType.Add: + case ExpressionType.AddChecked: + case ExpressionType.And: + case ExpressionType.AndAlso: + case ExpressionType.ArrayIndex: +#if FW4 || SILVERLIGHT + case ExpressionType.Assign: +#endif + case ExpressionType.Coalesce: + case ExpressionType.Divide: + case ExpressionType.Equal: + case ExpressionType.ExclusiveOr: + case ExpressionType.GreaterThan: + case ExpressionType.GreaterThanOrEqual: + case ExpressionType.LeftShift: + case ExpressionType.LessThan: + case ExpressionType.LessThanOrEqual: + case ExpressionType.Modulo: + case ExpressionType.Multiply: + case ExpressionType.MultiplyChecked: + case ExpressionType.NotEqual: + case ExpressionType.Or: + case ExpressionType.OrElse: + case ExpressionType.Power: + case ExpressionType.RightShift: + case ExpressionType.Subtract: + case ExpressionType.SubtractChecked: + { + var e = (BinaryExpression)expr; + + return + Find(e.Conversion, func) ?? + Find(e.Left, func) ?? + Find(e.Right, func); + } + + case ExpressionType.ArrayLength: + case ExpressionType.Convert: + case ExpressionType.ConvertChecked: + case ExpressionType.Negate: + case ExpressionType.NegateChecked: + case ExpressionType.Not: + case ExpressionType.Quote: + case ExpressionType.TypeAs: + case ExpressionType.UnaryPlus: + return Find(((UnaryExpression)expr).Operand, func); + + case ExpressionType.Call: + { + var e = (MethodCallExpression)expr; + + return + Find(e.Object, func) ?? + Find(e.Arguments, func); + } + + case ExpressionType.Conditional: + { + var e = (ConditionalExpression)expr; + + return + Find(e.Test, func) ?? + Find(e.IfTrue, func) ?? + Find(e.IfFalse, func); + } + + case ExpressionType.Invoke: + { + var e = (InvocationExpression)expr; + + return + Find(e.Expression, func) ?? + Find(e.Arguments, func); + } + + case ExpressionType.Lambda: + { + var e = (LambdaExpression)expr; + + return + Find(e.Body, func) ?? + Find(e.Parameters, func); + } + + case ExpressionType.ListInit: + { + var e = (ListInitExpression)expr; + + return + Find(e.NewExpression, func) ?? + Find(e.Initializers, ex => Find(ex.Arguments, func)); + } + + case ExpressionType.MemberAccess: + return Find(((MemberExpression)expr).Expression, func); + + case ExpressionType.MemberInit: + { + Func modify = null; modify = b => + { + switch (b.BindingType) + { + case MemberBindingType.Assignment : return Find(((MemberAssignment)b). Expression, func); + case MemberBindingType.ListBinding : return Find(((MemberListBinding)b). Initializers, p => Find(p.Arguments, func)); + case MemberBindingType.MemberBinding : return Find(((MemberMemberBinding)b).Bindings, modify); + } + + return null; + }; + + var e = (MemberInitExpression)expr; + + return + Find(e.NewExpression, func) ?? + Find(e.Bindings, modify); + } + + case ExpressionType.New : return Find(((NewExpression) expr).Arguments, func); + case ExpressionType.NewArrayBounds : return Find(((NewArrayExpression) expr).Expressions, func); + case ExpressionType.NewArrayInit : return Find(((NewArrayExpression) expr).Expressions, func); + case ExpressionType.TypeIs : return Find(((TypeBinaryExpression)expr).Expression, func); + +#if FW4 || SILVERLIGHT + + case ExpressionType.Block: + { + var e = (BlockExpression)expr; + + return + Find(e.Expressions, func) ?? + Find(e.Variables, func); + } + +#endif + + case (ExpressionType)ChangeTypeExpression.ChangeTypeType : + return Find(((ChangeTypeExpression)expr).Expression, func); + } + + return null; + } + + #endregion + + #region Convert + + static IEnumerable Convert(IEnumerable source, Func func) + where T : class + { + var modified = false; + var list = new List(); + + foreach (var item in source) + { + var e = func(item); + list.Add(e); + modified = modified || e != item; + } + + return modified ? list : source; + } + + static IEnumerable Convert(IEnumerable source, Func func) + where T : Expression + { + var modified = false; + var list = new List(); + + foreach (var item in source) + { + var e = Convert(item, func); + list.Add((T)e); + modified = modified || e != item; + } + + return modified? list: source; + } + + public static Expression Convert(this Expression expr, Func func) + { + if (expr == null) + return null; + + switch (expr.NodeType) + { + case ExpressionType.Add: + case ExpressionType.AddChecked: + case ExpressionType.And: + case ExpressionType.AndAlso: + case ExpressionType.ArrayIndex: +#if FW4 || SILVERLIGHT + case ExpressionType.Assign: +#endif + case ExpressionType.Coalesce: + case ExpressionType.Divide: + case ExpressionType.Equal: + case ExpressionType.ExclusiveOr: + case ExpressionType.GreaterThan: + case ExpressionType.GreaterThanOrEqual: + case ExpressionType.LeftShift: + case ExpressionType.LessThan: + case ExpressionType.LessThanOrEqual: + case ExpressionType.Modulo: + case ExpressionType.Multiply: + case ExpressionType.MultiplyChecked: + case ExpressionType.NotEqual: + case ExpressionType.Or: + case ExpressionType.OrElse: + case ExpressionType.Power: + case ExpressionType.RightShift: + case ExpressionType.Subtract: + case ExpressionType.SubtractChecked: + { + var ex = func(expr); + if (ex != expr) + return ex; + + var e = (BinaryExpression)expr; + var c = Convert(e.Conversion, func); + var l = Convert(e.Left, func); + var r = Convert(e.Right, func); + +#if FW3 + return c != e.Conversion || l != e.Left || r != e.Right ? + Expression.MakeBinary(expr.NodeType, l, r, e.IsLiftedToNull, e.Method, (LambdaExpression)c): + expr; +#else + return e.Update(l, (LambdaExpression)c, r); +#endif + } + + case ExpressionType.ArrayLength: + case ExpressionType.Convert: + case ExpressionType.ConvertChecked: + case ExpressionType.Negate: + case ExpressionType.NegateChecked: + case ExpressionType.Not: + case ExpressionType.Quote: + case ExpressionType.TypeAs: + case ExpressionType.UnaryPlus: + { + var ex = func(expr); + if (ex != expr) + return ex; + + var e = (UnaryExpression)expr; + var o = Convert(e.Operand, func); + +#if FW3 + return o != e.Operand ? + Expression.MakeUnary(expr.NodeType, o, e.Type, e.Method) : + expr; +#else + return e.Update(o); +#endif + } + + case ExpressionType.Call: + { + var ex = func(expr); + if (ex != expr) + return ex; + + var e = (MethodCallExpression)expr; + var o = Convert(e.Object, func); + var a = Convert(e.Arguments, func); + +#if FW3 + return o != e.Object || a != e.Arguments ? + Expression.Call(o, e.Method, a) : + expr; +#else + return e.Update(o, a); +#endif + } + + case ExpressionType.Conditional: + { + var ex = func(expr); + if (ex != expr) + return ex; + + var e = (ConditionalExpression)expr; + var s = Convert(e.Test, func); + var t = Convert(e.IfTrue, func); + var f = Convert(e.IfFalse, func); + +#if FW3 + return s != e.Test || t != e.IfTrue || f != e.IfFalse ? + Expression.Condition(s, t, f) : + expr; +#else + return e.Update(s, t, f); +#endif + } + + case ExpressionType.Invoke: + { + var exp = func(expr); + if (exp != expr) + return exp; + + var e = (InvocationExpression)expr; + var ex = Convert(e.Expression, func); + var a = Convert(e.Arguments, func); + +#if FW3 + return ex != e.Expression || a != e.Arguments ? Expression.Invoke(ex, a) : expr; +#else + return e.Update(ex, a); +#endif + } + + case ExpressionType.Lambda: + { + var ex = func(expr); + if (ex != expr) + return ex; + + var e = (LambdaExpression)expr; + var b = Convert(e.Body, func); + var p = Convert(e.Parameters, func); + + return b != e.Body || p != e.Parameters ? Expression.Lambda(ex.Type, b, p.ToArray()) : expr; + } + + case ExpressionType.ListInit: + { + var ex = func(expr); + if (ex != expr) + return ex; + + var e = (ListInitExpression)expr; + var n = Convert(e.NewExpression, func); + var i = Convert(e.Initializers, p => + { + var args = Convert(p.Arguments, func); + return args != p.Arguments? Expression.ElementInit(p.AddMethod, args): p; + }); + +#if FW3 + return n != e.NewExpression || i != e.Initializers ? + Expression.ListInit((NewExpression)n, i) : + expr; +#else + return e.Update((NewExpression)n, i); +#endif + } + + case ExpressionType.MemberAccess: + { + var exp = func(expr); + if (exp != expr) + return exp; + + var e = (MemberExpression)expr; + var ex = Convert(e.Expression, func); + +#if FW3 + return ex != e.Expression ? Expression.MakeMemberAccess(ex, e.Member) : expr; +#else + return e.Update(ex); +#endif + } + + case ExpressionType.MemberInit: + { + var exp = func(expr); + if (exp != expr) + return exp; + + Func modify = null; modify = b => + { + switch (b.BindingType) + { + case MemberBindingType.Assignment: + { + var ma = (MemberAssignment)b; + var ex = Convert(ma.Expression, func); + + if (ex != ma.Expression) + ma = Expression.Bind(ma.Member, ex); + + return ma; + } + + case MemberBindingType.ListBinding: + { + var ml = (MemberListBinding)b; + var i = Convert(ml.Initializers, p => + { + var args = Convert(p.Arguments, func); + return args != p.Arguments? Expression.ElementInit(p.AddMethod, args): p; + }); + + if (i != ml.Initializers) + ml = Expression.ListBind(ml.Member, i); + + return ml; + } + + case MemberBindingType.MemberBinding: + { + var mm = (MemberMemberBinding)b; + var bs = Convert(mm.Bindings, modify); + + if (bs != mm.Bindings) + mm = Expression.MemberBind(mm.Member); + + return mm; + } + } + + return b; + }; + + var e = (MemberInitExpression)expr; + var ne = Convert(e.NewExpression, func); + var bb = Convert(e.Bindings, modify); + +#if FW3 + return ne != e.NewExpression || bb != e.Bindings ? + Expression.MemberInit((NewExpression)ne, bb) : + expr; +#else + return e.Update((NewExpression)ne, bb); +#endif + } + + case ExpressionType.New: + { + var ex = func(expr); + if (ex != expr) + return ex; + + var e = (NewExpression)expr; + var a = Convert(e.Arguments, func); + +#if FW3 + return a != e.Arguments ? + e.Members == null ? + Expression.New(e.Constructor, a) : + Expression.New(e.Constructor, a, e.Members) : + expr; +#else + return e.Update(a); +#endif + } + + case ExpressionType.NewArrayBounds: + { + var exp = func(expr); + if (exp != expr) + return exp; + + var e = (NewArrayExpression)expr; + var ex = Convert(e.Expressions, func); + +#if FW3 + return ex != e.Expressions ? Expression.NewArrayBounds(e.Type, ex) : expr; +#else + return e.Update(ex); +#endif + } + + case ExpressionType.NewArrayInit: + { + var exp = func(expr); + if (exp != expr) + return exp; + + var e = (NewArrayExpression)expr; + var ex = Convert(e.Expressions, func); + +#if FW3 + return ex != e.Expressions ? + Expression.NewArrayInit(e.Type.GetElementType(), ex) : + expr; +#else + return e.Update(ex); + +#endif + } + + case ExpressionType.TypeIs: + { + var exp = func(expr); + if (exp != expr) + return exp; + + var e = (TypeBinaryExpression)expr; + var ex = Convert(e.Expression, func); + +#if FW3 + return ex != e.Expression ? Expression.TypeIs(ex, e.Type) : expr; +#else + return e.Update(ex); +#endif + } + +#if FW4 || SILVERLIGHT + + case ExpressionType.Block: + { + var exp = func(expr); + if (exp != expr) + return exp; + + var e = (BlockExpression)expr; + var ex = Convert(e.Expressions, func); + var v = Convert(e.Variables, func); + + return e.Update(v, ex); + } + +#endif + + case ExpressionType.Constant : return func(expr); + case ExpressionType.Parameter: return func(expr); + + case (ExpressionType)ChangeTypeExpression.ChangeTypeType : + { + var exp = func(expr); + if (exp != expr) + return exp; + + var e = expr as ChangeTypeExpression; + var ex = Convert(e.Expression, func); + + if (ex == e.Expression) + return expr; + + if (ex.Type == e.Type) + return ex; + + return new ChangeTypeExpression(ex, e.Type); + } + } + + throw new InvalidOperationException(); + } + + #endregion + + #region Convert2 + + public struct ConvertInfo + { + public ConvertInfo(Expression expression, bool stop) + { + Expression = expression; + Stop = stop; + } + + public ConvertInfo(Expression expression) + { + Expression = expression; + Stop = false; + } + + public Expression Expression; + public bool Stop; + } + + static IEnumerable Convert2(IEnumerable source, Func func) + where T : class + { + var modified = false; + var list = new List(); + + foreach (var item in source) + { + var e = func(item); + list.Add(e); + modified = modified || e != item; + } + + return modified ? list : source; + } + + static IEnumerable Convert2(IEnumerable source, Func func) + where T : Expression + { + var modified = false; + var list = new List(); + + foreach (var item in source) + { + var e = Convert2(item, func); + list.Add((T)e); + modified = modified || e != item; + } + + return modified ? list : source; + } + +#if FW3 + static IEnumerable ConvertMethodArguments(IEnumerable source, MethodBase method) + { + return ConvertMethodArguments(source, method, null); + } + + static IEnumerable ConvertMethodArguments(IEnumerable source, MethodBase method, IList initMembers) +#else + static IEnumerable ConvertMethodArguments(IEnumerable source, MethodBase method, IList initMembers = null) +#endif + { + var list = new List(); + + var targetTypes = new List(); + foreach (var param in method.GetParameters()) + { + targetTypes.Add(param.ParameterType); + } + if (initMembers != null) + { + foreach (var mi in initMembers) + { + if (mi is PropertyInfo) + { + targetTypes.Add(((PropertyInfo)mi).PropertyType); + } + else if (mi is FieldInfo) + { + targetTypes.Add(((FieldInfo)mi).FieldType); + } + } + } + + var idx = 0; + foreach (var item in source) + { + var targetType = targetTypes[idx]; + if (item.Type != targetType) + { + list.Add(Expression.Convert(item, targetType)); + } + else + { + list.Add(item); + } + idx++; + } + + return list; + } + + public static Expression Convert2(this Expression expr, Func func) + { + if (expr == null) + return null; + + ConvertInfo ci; + + switch (expr.NodeType) + { + case ExpressionType.Add: + case ExpressionType.AddChecked: + case ExpressionType.And: + case ExpressionType.AndAlso: + case ExpressionType.ArrayIndex: +#if FW4 || SILVERLIGHT + case ExpressionType.Assign: +#endif + case ExpressionType.Coalesce: + case ExpressionType.Divide: + case ExpressionType.Equal: + case ExpressionType.ExclusiveOr: + case ExpressionType.GreaterThan: + case ExpressionType.GreaterThanOrEqual: + case ExpressionType.LeftShift: + case ExpressionType.LessThan: + case ExpressionType.LessThanOrEqual: + case ExpressionType.Modulo: + case ExpressionType.Multiply: + case ExpressionType.MultiplyChecked: + case ExpressionType.NotEqual: + case ExpressionType.Or: + case ExpressionType.OrElse: + case ExpressionType.Power: + case ExpressionType.RightShift: + case ExpressionType.Subtract: + case ExpressionType.SubtractChecked: + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as BinaryExpression; + var c = Convert2(e.Conversion, func); + var l = Convert2(e.Left, func); + var r = Convert2(e.Right, func); + + return c != e.Conversion || l != e.Left || r != e.Right ? + Expression.MakeBinary(expr.NodeType, l, r, e.IsLiftedToNull, e.Method, (LambdaExpression)c): + expr; + } + + case ExpressionType.ArrayLength: + case ExpressionType.Convert: + case ExpressionType.ConvertChecked: + case ExpressionType.Negate: + case ExpressionType.NegateChecked: + case ExpressionType.Not: + case ExpressionType.Quote: + case ExpressionType.TypeAs: + case ExpressionType.UnaryPlus: + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as UnaryExpression; + var o = Convert2(e.Operand, func); + + return o != e.Operand ? + Expression.MakeUnary(expr.NodeType, o, e.Type, e.Method) : + expr; + } + + case ExpressionType.Call: + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as MethodCallExpression; + var o = Convert2(e.Object, func); + var a = Convert2(e.Arguments, func); + + return o != e.Object || a != e.Arguments ? + Expression.Call(o, e.Method, ConvertMethodArguments(a, e.Method)) : + expr; + } + + case ExpressionType.Conditional: + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as ConditionalExpression; + var s = Convert2(e.Test, func); + var t = Convert2(e.IfTrue, func); + var f = Convert2(e.IfFalse, func); + + return s != e.Test || t != e.IfTrue || f != e.IfFalse ? + Expression.Condition(s, t, f) : + expr; + } + + case ExpressionType.Invoke: + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as InvocationExpression; + var ex = Convert2(e.Expression, func); + var a = Convert2(e.Arguments, func); + + return ex != e.Expression || a != e.Arguments ? Expression.Invoke(ex, a) : expr; + } + + case ExpressionType.Lambda: + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as LambdaExpression; + var b = Convert2(e.Body, func); + var p = Convert2(e.Parameters, func); + + return b != e.Body || p != e.Parameters ? Expression.Lambda(ci.Expression.Type, b, p.ToArray()) : expr; + } + + case ExpressionType.ListInit: + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as ListInitExpression; + var n = Convert2(e.NewExpression, func); + var i = Convert2(e.Initializers, p => + { + var args = Convert2(p.Arguments, func); + return args != p.Arguments? Expression.ElementInit(p.AddMethod, args): p; + }); + + return n != e.NewExpression || i != e.Initializers ? + Expression.ListInit((NewExpression)n, i) : + expr; + } + + case ExpressionType.MemberAccess: + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as MemberExpression; + var ex = Convert2(e.Expression, func); + + return ex != e.Expression ? Expression.MakeMemberAccess(ex, e.Member) : expr; + } + + case ExpressionType.MemberInit: + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + Func modify = null; modify = b => + { + switch (b.BindingType) + { + case MemberBindingType.Assignment: + { + var ma = (MemberAssignment)b; + var ex = Convert2(ma.Expression, func); + + if (ex != ma.Expression) + { + if (ex.Type != ma.Expression.Type) + { + ex = Expression.Convert(ex, ma.Expression.Type); + } + ma = Expression.Bind(ma.Member, ex); + } + + return ma; + } + + case MemberBindingType.ListBinding: + { + var ml = (MemberListBinding)b; + var i = Convert(ml.Initializers, p => + { + var args = Convert2(p.Arguments, func); + return args != p.Arguments? Expression.ElementInit(p.AddMethod, args): p; + }); + + if (i != ml.Initializers) + ml = Expression.ListBind(ml.Member, i); + + return ml; + } + + case MemberBindingType.MemberBinding: + { + var mm = (MemberMemberBinding)b; + var bs = Convert(mm.Bindings, modify); + + if (bs != mm.Bindings) + mm = Expression.MemberBind(mm.Member); + + return mm; + } + } + + return b; + }; + + var e = expr as MemberInitExpression; + var ne = Convert2(e.NewExpression, func); + var bb = Convert2(e.Bindings, modify); + + return ne != e.NewExpression || bb != e.Bindings ? + Expression.MemberInit((NewExpression)ne, bb) : + expr; + } + + case ExpressionType.New: + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as NewExpression; + var a = Convert2(e.Arguments, func); + + return a != e.Arguments ? + e.Members == null ? + Expression.New(e.Constructor, ConvertMethodArguments(a, e.Constructor)) : + Expression.New(e.Constructor, ConvertMethodArguments(a, e.Constructor, e.Members), e.Members) : + expr; + } + + case ExpressionType.NewArrayBounds: + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as NewArrayExpression; + var ex = Convert2(e.Expressions, func); + + return ex != e.Expressions ? Expression.NewArrayBounds(e.Type, ex) : expr; + } + + case ExpressionType.NewArrayInit: + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as NewArrayExpression; + var et = e.Type.GetElementType(); + var ex = Convert2(e.Expressions, func) + .Select(ee => et == typeof(object) && ee.Type.IsValueType ? + Expression.Convert(ee, typeof(object)) : + ee); + + return ex != e.Expressions ? + Expression.NewArrayInit(et, ex) : + expr; + } + + case ExpressionType.TypeIs : + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as TypeBinaryExpression; + var ex = Convert2(e.Expression, func); + + return ex != e.Expression ? Expression.TypeIs(ex, e.Type) : expr; + } + +#if FW4 || SILVERLIGHT + + case ExpressionType.Block : + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as BlockExpression; + var ex = Convert2(e.Expressions, func); + var v = Convert2(e.Variables, func); + + return ex != e.Expressions || v != e.Variables ? Expression.Block(e.Type, v, ex) : expr; + } + +#endif + + case ExpressionType.Constant : return func(expr).Expression; + case ExpressionType.Parameter: return func(expr).Expression; + + case (ExpressionType)ChangeTypeExpression.ChangeTypeType : + { + ci = func(expr); + if (ci.Stop || ci.Expression != expr) + return ci.Expression; + + var e = expr as ChangeTypeExpression; + var ex = Convert2(e.Expression, func); + + if (ex == e.Expression) + return expr; + + if (ex.Type == e.Type) + return ex; + + return new ChangeTypeExpression(ex, e.Type); + } + } + + throw new InvalidOperationException(); + } + + #endregion + + #region Helpers + + static public Expression Unwrap(this Expression ex) + { + if (ex == null) + return null; + + switch (ex.NodeType) + { + case ExpressionType.Quote : return ((UnaryExpression)ex).Operand.Unwrap(); + case ExpressionType.ConvertChecked : + case ExpressionType.Convert : + { + var ue = (UnaryExpression)ex; + + if (!ue.Operand.Type.IsEnum) + return ue.Operand.Unwrap(); + + break; + } + } + + return ex; + } + + static public Dictionary GetExpressionAccessors(this Expression expression, Expression path) + { + var accessors = new Dictionary(); + + expression.Path(path, (e,p) => + { + switch (e.NodeType) + { + case ExpressionType.Call : + case ExpressionType.MemberAccess : + case ExpressionType.New : + if (!accessors.ContainsKey(e)) + accessors.Add(e, p); + break; + + case ExpressionType.Constant : + if (!accessors.ContainsKey(e)) + accessors.Add(e, Expression.Property(p, ReflectionHelper.Constant.Value)); + break; + + case ExpressionType.ConvertChecked : + case ExpressionType.Convert : + if (!accessors.ContainsKey(e)) + { + var ue = (UnaryExpression)e; + + switch (ue.Operand.NodeType) + { + case ExpressionType.Call : + case ExpressionType.MemberAccess : + case ExpressionType.New : + case ExpressionType.Constant : + + accessors.Add(e, p); + break; + } + } + + break; + } + }); + + return accessors; + } + + static public Expression GetRootObject(this Expression expr) + { + if (expr == null) + return null; + + switch (expr.NodeType) + { + case ExpressionType.Call : + { + var e = (MethodCallExpression)expr; + + if (e.Object != null) + return GetRootObject(e.Object); + + if (e.Arguments != null && e.Arguments.Count > 0 && e.IsQueryable()) + return GetRootObject(e.Arguments[0]); + + break; + } + + case ExpressionType.MemberAccess : + { + var e = (MemberExpression)expr; + + if (e.Expression != null) + return GetRootObject(e.Expression.Unwrap()); + + break; + } + } + + return expr; + } + + static public List GetMembers(this Expression expr) + { + if (expr == null) + return new List(); + + List list; + + switch (expr.NodeType) + { + case ExpressionType.Call : + { + var e = (MethodCallExpression)expr; + + if (e.Object != null) + list = GetMembers(e.Object); + else if (e.Arguments != null && e.Arguments.Count > 0 && e.IsQueryable()) + list = GetMembers(e.Arguments[0]); + else + list = new List(); + + break; + } + + case ExpressionType.MemberAccess : + { + var e = (MemberExpression)expr; + + if (e.Expression != null) + list = GetMembers(e.Expression.Unwrap()); + else + list = new List(); + + break; + } + + default : + list = new List(); + break; + } + + list.Add(expr); + + return list; + } + + static public bool IsQueryable(this MethodCallExpression method) + { + var type = method.Method.DeclaringType; + + return type == typeof(Queryable) || type == typeof(Enumerable) || type == typeof(LinqExtensions); + } + + static public bool IsQueryable(this MethodCallExpression method, string name) + { + return method.Method.Name == name && method.IsQueryable(); + } + + static public bool IsQueryable(this MethodCallExpression method, params string[] names) + { + if (method.IsQueryable()) + foreach (var name in names) + if (method.Method.Name == name) + return true; + + return false; + } + + static Expression FindLevel(Expression expression, int level, ref int current) + { + switch (expression.NodeType) + { + case ExpressionType.Call : + { + var call = (MethodCallExpression)expression; + var expr = call.Object; + + if (expr == null && call.IsQueryable() && call.Arguments.Count > 0) + expr = call.Arguments[0]; + + if (expr != null) + { + var ex = FindLevel(expr, level, ref current); + + if (level == current) + return ex; + + current++; + } + + break; + } + + case ExpressionType.MemberAccess: + { + var e = ((MemberExpression)expression); + + if (e.Expression != null) + { + var expr = FindLevel(e.Expression.Unwrap(), level, ref current); + + if (level == current) + return expr; + + current++; + } + + break; + } + } + + return expression; + } + + static public Expression GetLevelExpression(this Expression expression, int level) + { + var current = 0; + var expr = FindLevel(expression, level, ref current); + + if (expr == null || current != level) + throw new InvalidOperationException(); + + return expr; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Linq/Extensions.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Linq/Extensions.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; + +using JetBrains.Annotations; + +namespace BLToolkit.Linq +{ + public static class Extensions + { + public static IEnumerable Zip( + [NotNull] this IEnumerable first, + [NotNull] IEnumerable second, + [NotNull] Func resultSelector) + { + if (first == null) throw new ArgumentNullException("first"); + if (second == null) throw new ArgumentNullException("second"); + if (resultSelector == null) throw new ArgumentNullException("resultSelector"); + + using (var e1 = first.GetEnumerator()) + using (var e2 = second.GetEnumerator()) + while (e1.MoveNext() && e2.MoveNext()) + yield return resultSelector(e1.Current, e2.Current); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Association.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Association.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,52 @@ +using System; + +using JNotNull = JetBrains.Annotations.NotNullAttribute; + +namespace BLToolkit.Mapping +{ + using Common; + using Reflection; + + public class Association + { + public Association( + [JNotNull] MemberAccessor memberAccessor, + [JNotNull] string[] thisKey, + [JNotNull] string[] otherKey, + string storage, + bool canBeNull) + { + if (memberAccessor == null) throw new ArgumentNullException("memberAccessor"); + if (thisKey == null) throw new ArgumentNullException("thisKey"); + if (otherKey == null) throw new ArgumentNullException("otherKey"); + + if (thisKey.Length == 0) + throw new ArgumentOutOfRangeException( + "thisKey", + string.Format("Association '{0}.{1}' does not define keys.", memberAccessor.TypeAccessor.Type.Name, memberAccessor.Name)); + + if (thisKey.Length != otherKey.Length) + throw new ArgumentException( + string.Format( + "Association '{0}.{1}' has different number of keys for parent and child objects.", + memberAccessor.TypeAccessor.Type.Name, memberAccessor.Name)); + + MemberAccessor = memberAccessor; + ThisKey = thisKey; + OtherKey = otherKey; + Storage = storage; + CanBeNull = canBeNull; + } + + public MemberAccessor MemberAccessor { get; set; } + public string[] ThisKey { get; set; } + public string[] OtherKey { get; set; } + public string Storage { get; set; } + public bool CanBeNull { get; set; } + + public static string[] ParseKeys(string keys) + { + return keys == null ? Array.Empty : keys.Replace(" ", "").Split(','); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/AssociationAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/AssociationAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +using System; + +namespace BLToolkit.Mapping +{ + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple=false)] + public class AssociationAttribute : Attribute + { + private string _thisKey; public string ThisKey { get { return _thisKey; } set { _thisKey = value; } } + private string _otherKey; public string OtherKey { get { return _otherKey; } set { _otherKey = value; } } + private string _storage; public string Storage { get { return _storage; } set { _storage = value; } } + private bool _canBeNull = true; public bool CanBeNull { get { return _canBeNull; } set { _canBeNull = value; } } + + public string[] GetThisKeys () { return Association.ParseKeys(_thisKey); } + public string[] GetOtherKeys() { return Association.ParseKeys(_otherKey); } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/DataReaderListMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/DataReaderListMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,29 @@ +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public class DataReaderListMapper : IMapDataSourceList + { + public DataReaderListMapper(DataReaderMapper mapper) + { + _mapper = mapper; + } + + private readonly DataReaderMapper _mapper; + + public virtual void InitMapping(InitContext initContext) + { + initContext.DataSource = _mapper; + initContext.SourceObject = _mapper.DataReader; + } + + public virtual bool SetNextDataSource(InitContext initContext) + { + return _mapper.DataReader.Read(); + } + + public virtual void EndMapping(InitContext initContext) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/DataReaderMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/DataReaderMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,151 @@ +using System; +using System.Data; +using System.Data.SqlTypes; + +namespace BLToolkit.Mapping +{ + using Data; + + public class DataReaderMapper : IMapDataSource + { + public DataReaderMapper(MappingSchema mappingSchema, IDataReader dataReader) + { + _mappingSchema = mappingSchema; + _dataReader = dataReader; + _dataReaderEx = dataReader as IDataReaderEx; + } + + readonly IDataReaderEx _dataReaderEx; + + readonly IDataReader _dataReader; + public IDataReader DataReader + { + get { return _dataReader; } + } + + readonly MappingSchema _mappingSchema; + public MappingSchema MappingSchema + { + get { return _mappingSchema; } + } + + #region IMapDataSource Members + + public virtual int Count + { + get { return _dataReader.FieldCount; } + } + + public virtual Type GetFieldType(int index) + { + return _dataReader.GetFieldType(index); + } + + public virtual string GetName(int index) + { + return _dataReader.GetName(index); + } + + public virtual int GetOrdinal(string name) + { + return _dataReader.GetOrdinal(name); + } + + public virtual object GetValue(object o, int index) + { + var value = _dataReader.GetValue(index); + return value is DBNull? null: value; + } + + public virtual object GetValue(object o, string name) + { + var value = _dataReader[name]; + return value is DBNull? null: value; + } + + public virtual bool IsNull (object o, int index) { return _dataReader.IsDBNull(index); } + public virtual bool SupportsTypedValues(int index) { return true; } + + // Simple type getters. + // + [CLSCompliant(false)] + public virtual SByte GetSByte (object o, int index) { return _mappingSchema.ConvertToSByte(GetValue(o, index)); } + public virtual Int16 GetInt16 (object o, int index) { return _dataReader.GetInt16 (index); } + public virtual Int32 GetInt32 (object o, int index) { return _dataReader.GetInt32 (index); } + public virtual Int64 GetInt64 (object o, int index) { return _dataReader.GetInt64 (index); } + + public virtual Byte GetByte (object o, int index) { return _dataReader.GetByte (index); } + [CLSCompliant(false)] + public virtual UInt16 GetUInt16 (object o, int index) { return _mappingSchema.ConvertToUInt16(GetValue(o, index)); } + [CLSCompliant(false)] + public virtual UInt32 GetUInt32 (object o, int index) { return _mappingSchema.ConvertToUInt32(GetValue(o, index)); } + [CLSCompliant(false)] + public virtual UInt64 GetUInt64 (object o, int index) { return _mappingSchema.ConvertToUInt64(GetValue(o, index)); } + + public virtual Boolean GetBoolean (object o, int index) { return _dataReader.GetBoolean (index); } + public virtual Char GetChar (object o, int index) { return _dataReader.GetChar (index); } + public virtual Single GetSingle (object o, int index) { return _dataReader.GetFloat (index); } + public virtual Double GetDouble (object o, int index) { return _dataReader.GetDouble (index); } + public virtual Decimal GetDecimal (object o, int index) { return _dataReader.GetDecimal (index); } + public virtual Guid GetGuid (object o, int index) { return _dataReader.GetGuid (index); } + public virtual DateTime GetDateTime(object o, int index) { return _dataReader.GetDateTime(index); } + + public virtual DateTimeOffset GetDateTimeOffset(object o, int index) + { + return _dataReaderEx != null? + _dataReaderEx.GetDateTimeOffset(index): + _mappingSchema.ConvertToDateTimeOffset(_dataReader.GetValue(index)); + } + + // Nullable type getters. + // + [CLSCompliant(false)] + public virtual SByte? GetNullableSByte (object o, int index) { return _dataReader.IsDBNull(index)? null: _mappingSchema.ConvertToNullableSByte(GetValue(o, index)); } + public virtual Int16? GetNullableInt16 (object o, int index) { return _dataReader.IsDBNull(index)? null: (Int16?)_dataReader.GetInt16 (index); } + public virtual Int32? GetNullableInt32 (object o, int index) { return _dataReader.IsDBNull(index)? null: (Int32?)_dataReader.GetInt32 (index); } + public virtual Int64? GetNullableInt64 (object o, int index) { return _dataReader.IsDBNull(index)? null: (Int64?)_dataReader.GetInt64 (index); } + + public virtual Byte? GetNullableByte (object o, int index) { return _dataReader.IsDBNull(index)? null: (Byte?) _dataReader.GetByte (index); } + [CLSCompliant(false)] + public virtual UInt16? GetNullableUInt16 (object o, int index) { return _dataReader.IsDBNull(index)? null: _mappingSchema.ConvertToNullableUInt16(GetValue(o, index)); } + [CLSCompliant(false)] + public virtual UInt32? GetNullableUInt32 (object o, int index) { return _dataReader.IsDBNull(index)? null: _mappingSchema.ConvertToNullableUInt32(GetValue(o, index)); } + [CLSCompliant(false)] + public virtual UInt64? GetNullableUInt64 (object o, int index) { return _dataReader.IsDBNull(index)? null: _mappingSchema.ConvertToNullableUInt64(GetValue(o, index)); } + + public virtual Boolean? GetNullableBoolean (object o, int index) { return _dataReader.IsDBNull(index)? null: (Boolean?) _dataReader.GetBoolean (index); } + public virtual Char? GetNullableChar (object o, int index) { return _dataReader.IsDBNull(index)? null: (Char?) _dataReader.GetChar (index); } + public virtual Single? GetNullableSingle (object o, int index) { return _dataReader.IsDBNull(index)? null: (Single?) _dataReader.GetFloat (index); } + public virtual Double? GetNullableDouble (object o, int index) { return _dataReader.IsDBNull(index)? null: (Double?) _dataReader.GetDouble (index); } + public virtual Decimal? GetNullableDecimal (object o, int index) { return _dataReader.IsDBNull(index)? null: (Decimal?) _dataReader.GetDecimal (index); } + public virtual Guid? GetNullableGuid (object o, int index) { return _dataReader.IsDBNull(index)? null: (Guid?) _dataReader.GetGuid (index); } + public virtual DateTime? GetNullableDateTime(object o, int index) { return _dataReader.IsDBNull(index)? null: (DateTime?)_dataReader.GetDateTime(index); } + public virtual DateTimeOffset? GetNullableDateTimeOffset(object o, int index) + { + return _dataReader.IsDBNull(index)? null: + _dataReaderEx != null? _dataReaderEx.GetDateTimeOffset(index): + _mappingSchema.ConvertToNullableDateTimeOffset(_dataReader.GetValue(index)); + } + +#if !SILVERLIGHT + + // SQL type getters. + // + public virtual SqlByte GetSqlByte (object o, int index) { return _dataReader.IsDBNull(index)? SqlByte. Null: _dataReader.GetByte (index); } + public virtual SqlInt16 GetSqlInt16 (object o, int index) { return _dataReader.IsDBNull(index)? SqlInt16. Null: _dataReader.GetInt16 (index); } + public virtual SqlInt32 GetSqlInt32 (object o, int index) { return _dataReader.IsDBNull(index)? SqlInt32. Null: _dataReader.GetInt32 (index); } + public virtual SqlInt64 GetSqlInt64 (object o, int index) { return _dataReader.IsDBNull(index)? SqlInt64. Null: _dataReader.GetInt64 (index); } + public virtual SqlSingle GetSqlSingle (object o, int index) { return _dataReader.IsDBNull(index)? SqlSingle. Null: _dataReader.GetFloat (index); } + public virtual SqlBoolean GetSqlBoolean (object o, int index) { return _dataReader.IsDBNull(index)? SqlBoolean. Null: _dataReader.GetBoolean (index); } + public virtual SqlDouble GetSqlDouble (object o, int index) { return _dataReader.IsDBNull(index)? SqlDouble. Null: _dataReader.GetDouble (index); } + public virtual SqlDateTime GetSqlDateTime(object o, int index) { return _dataReader.IsDBNull(index)? SqlDateTime.Null: _dataReader.GetDateTime(index); } + public virtual SqlDecimal GetSqlDecimal (object o, int index) { return _dataReader.IsDBNull(index)? SqlDecimal. Null: _dataReader.GetDecimal (index); } + public virtual SqlMoney GetSqlMoney (object o, int index) { return _dataReader.IsDBNull(index)? SqlMoney. Null: _dataReader.GetDecimal (index); } + public virtual SqlGuid GetSqlGuid (object o, int index) { return _dataReader.IsDBNull(index)? SqlGuid. Null: _dataReader.GetGuid (index); } + public virtual SqlString GetSqlString (object o, int index) { return _dataReader.IsDBNull(index)? SqlString. Null: _dataReader.GetString (index); } + +#endif + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/DataRowMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/DataRowMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,188 @@ +using System; +using System.Data; +using System.Collections; + +namespace BLToolkit.Mapping +{ + public class DataRowMapper : MapDataSourceDestinationBase + { + bool _createColumns; + readonly DataRowVersion _version; + + public DataRowMapper(DataRow dataRow) + : this(dataRow, DataRowVersion.Default) + { + } + + public DataRowMapper(DataRowView view) + : this(view.Row, view.RowVersion) + { + } + + public DataRowMapper(DataRow dataRow, DataRowVersion version) + { + _version = version; + + Init(dataRow); + } + + private void Init(DataRow dataRow) + { + if (_dataRow == null && dataRow != null) + _createColumns = dataRow.Table.Columns.Count == 0; + + _dataRow = dataRow; + } + + private DataRow _dataRow; + public DataRow DataRow + { + get { return _dataRow; } + set { Init(value); } + } + + #region IMapDataSource Members + + public override int Count + { + get { return _dataRow.Table.Columns.Count; } + } + + public override Type GetFieldType(int index) + { + return index < _dataRow.Table.Columns.Count? + _dataRow.Table.Columns[index].DataType: null; + } + + public override string GetName(int index) + { + return _dataRow.Table.Columns[index].ColumnName; + } + + public override object GetValue(object o, int index) + { + object value = _version == DataRowVersion.Default ? _dataRow[index] : _dataRow[index, _version]; + return value is DBNull? null: value; + } + + public override object GetValue(object o, string name) + { + object value = _version == DataRowVersion.Default ? _dataRow[name] : _dataRow[name, _version]; + return value is DBNull? null: value; + } + + public override bool IsNull(object o, int index) + { + if (_version == DataRowVersion.Default) + return _dataRow.IsNull(index); + + DataColumn col = _dataRow.Table.Columns[index]; + + return _dataRow.IsNull(col, _version); + } + + #endregion + + #region IMapDataDestination Members + + private ArrayList _nameList; + + public override int GetOrdinal(string name) + { + if (_createColumns) + { + if (_nameList == null) + _nameList = new ArrayList(); + + for (int i = 0; i < _nameList.Count; i++) + if (name == _nameList[i].ToString()) + return i; + + return _nameList.Add(name); + } + + return _dataRow.Table.Columns.IndexOf(name); + } + + private void CreateColumn(int index, object value) + { + if (_dataRow.Table.Rows.Count > 1) + { + _createColumns = false; + } + else + { + DataColumnCollection cc = _dataRow.Table.Columns; + string name = _nameList[index].ToString(); + + DataColumn column = + value == null || value is DBNull? cc.Add(name): cc.Add(name, value.GetType()); + + if (cc.IndexOf(column) != index) + throw new MappingException(string.Format("Cant create data column '{0}'.", name)); + } + } + + public override void SetValue(object o, int index, object value) + { + if (_createColumns) + CreateColumn(index, value); + + if (value == null || value is DBNull) + { + _dataRow[index] = DBNull.Value; + } + else + { + DataColumn column = _dataRow.Table.Columns[index]; + + if (column.DataType != value.GetType()) + { + if (column.DataType == typeof(Guid)) + { + value = new Guid(value.ToString()); + } + else + { + if (column.DataType != typeof(string)) + value = Convert.ChangeType(value, column.DataType); + } + } + + _dataRow[index] = value; + } + } + + public override void SetValue(object o, string name, object value) + { + if (_createColumns) + CreateColumn(GetOrdinal(name), value); + + if (value == null || value is DBNull) + { + _dataRow[name] = DBNull.Value; + } + else + { + DataColumn dc = _dataRow.Table.Columns[name]; + + if (dc.DataType != value.GetType()) + { + if (dc.DataType == typeof(Guid)) + { + value = new Guid(value.ToString()); + } + else + { + if (dc.DataType != typeof(string)) + value = Convert.ChangeType(value, dc.DataType); + } + } + + _dataRow[name] = value; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/DataTableMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/DataTableMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,75 @@ +using System.Data; + +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public class DataTableMapper : IMapDataSourceList, IMapDataDestinationList + { + public DataTableMapper(DataTable dataTable, DataRowMapper mapper) + { + _table = dataTable; + _mapper = mapper; + } + + private readonly DataTable _table; + private readonly DataRowMapper _mapper; + private int _currentRow; + + #region IMapDataSourceList Members + + void IMapDataSourceList.InitMapping(InitContext initContext) + { + initContext.DataSource = _mapper; + } + + bool IMapDataSourceList.SetNextDataSource(InitContext initContext) + { + if (_currentRow >= _table.Rows.Count) + return false; + + DataRow row = _table.Rows[_currentRow++]; + + if (row.RowState == DataRowState.Deleted) + return ((IMapDataSourceList)this).SetNextDataSource(initContext); + + _mapper.DataRow = row; + initContext.SourceObject = row; + + return true; + } + + void IMapDataSourceList.EndMapping(InitContext initContext) + { + } + + #endregion + + #region IMapDataDestinationList Members + + void IMapDataDestinationList.InitMapping(InitContext initContext) + { + } + + IMapDataDestination IMapDataDestinationList.GetDataDestination(InitContext initContext) + { + return _mapper; + } + + object IMapDataDestinationList.GetNextObject(InitContext initContext) + { + DataRow row = _table.NewRow(); + + _mapper.DataRow = row; + _table.Rows.Add(row); + + return row; + } + + void IMapDataDestinationList.EndMapping(InitContext initContext) + { + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/DefaultMappingSchema.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/DefaultMappingSchema.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ +namespace BLToolkit.Mapping +{ + public sealed class DefaultMappingSchema : MappingSchema + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/DefaultMemberMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/DefaultMemberMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +namespace BLToolkit.Mapping +{ + class DefaultMemberMapper : MemberMapper + { + public override bool SupportsValue + { + get { return false; } + } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/DefaultValueAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/DefaultValueAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,41 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace BLToolkit.Mapping +{ + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")] + [AttributeUsage( + AttributeTargets.Class | AttributeTargets.Interface | + AttributeTargets.Property | AttributeTargets.Field | + AttributeTargets.Enum, + AllowMultiple=true)] + public class DefaultValueAttribute : Attribute + { + public DefaultValueAttribute() + { + } + + public DefaultValueAttribute(object value) + { + _value = value; + } + + public DefaultValueAttribute(Type type, object value) + { + _type = type; + _value = value; + } + + private readonly object _value; + public object Value + { + get { return _value; } + } + + private readonly Type _type; + public Type Type + { + get { return _type; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/DictionaryIndexListMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/DictionaryIndexListMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,104 @@ +using System; +using System.Collections; + +using BLToolkit.Common; +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public class DictionaryIndexListMapper : IMapDataDestinationList + { + public DictionaryIndexListMapper( + IDictionary dic, + MapIndex index, + ObjectMapper objectMapper) + { + _dic = dic; + _mapper = objectMapper; + + _fields = new NameOrIndexParameter[index.Fields.Length]; + _fromSource = new bool[index.Fields.Length]; + + for (int i = 0; i < _fields.Length; i++) + { + bool fromSource = index.Fields[i].ByName && index.Fields[i].Name[0] == '@'; + + _fields[i] = fromSource? index.Fields[i].Name.Substring(1): index.Fields[i]; + _fromSource[i] = fromSource; + _isFromSource = _isFromSource || fromSource; + _isFromDest = _isFromDest || !fromSource; + } + } + + private readonly NameOrIndexParameter[] _fields; + private readonly IDictionary _dic; + private readonly bool[] _fromSource; + private readonly bool _isFromSource; + private readonly bool _isFromDest; + private ObjectMapper _mapper; + private object _newObject; + private object[] _indexValue; + + #region IMapDataDestinationList Members + + private void AddObject() + { + if (_newObject != null) + { + if (_isFromDest) + for (int i = 0; i < _fields.Length; i++) + if (!_fromSource[i]) + _indexValue[i] = _mapper.TypeAccessor[_fields[i]].GetValue(_newObject); + + _dic[new CompoundValue(_indexValue)] = _newObject; + } + } + + public virtual void InitMapping(InitContext initContext) + { + var sm = _dic as ISupportMapping; + + if (sm != null) + { + sm.BeginMapping(initContext); + + if (_mapper != initContext.ObjectMapper) + _mapper = initContext.ObjectMapper; + } + } + + [CLSCompliant(false)] + public virtual IMapDataDestination GetDataDestination(InitContext initContext) + { + return _mapper; + } + + public virtual object GetNextObject(InitContext initContext) + { + AddObject(); + + _indexValue = new object[_fields.Length]; + + if (_isFromSource) + for (int i = 0; i < _fields.Length; i++) + if (_fromSource[i]) + _indexValue[i] = _fields[i].ByName ? + initContext.DataSource.GetValue( initContext.SourceObject, _fields[i].Name) : + initContext.DataSource.GetValue( initContext.SourceObject, _fields[i].Index); + + return _newObject = _mapper.CreateInstance(initContext); + } + + public virtual void EndMapping(InitContext initContext) + { + AddObject(); + + ISupportMapping sm = _dic as ISupportMapping; + + if (sm != null) + sm.EndMapping(initContext); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/DictionaryIndexListMapperT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/DictionaryIndexListMapperT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; + +using BLToolkit.Common; +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public class DictionaryIndexListMapper : IMapDataDestinationList + { + public DictionaryIndexListMapper( + IDictionary dic, + MapIndex index, + ObjectMapper objectMapper) + { + _dic = dic; + _mapper = objectMapper; + + _fields = new NameOrIndexParameter[index.Fields.Length]; + _fromSource = new bool[index.Fields.Length]; + + for (int i = 0; i < _fields.Length; i++) + { + bool fromSource = index.Fields[i].ByName && index.Fields[i].Name[0] == '@'; + + _fields[i] = fromSource ? index.Fields[i].Name.Substring(1) : index.Fields[i]; + _fromSource[i] = fromSource; + _isFromSource = _isFromSource || fromSource; + _isFromDest = _isFromDest || !fromSource; + } + } + + private readonly NameOrIndexParameter[] _fields; + private readonly IDictionary _dic; + private readonly bool[] _fromSource; + private readonly bool _isFromSource; + private readonly bool _isFromDest; + private ObjectMapper _mapper; + private object _newObject; + private object[] _indexValue; + + #region IMapDataDestinationList Members + + private void AddObject() + { + if (_newObject != null) + { + if (_isFromDest) + for (int i = 0; i < _fields.Length; i++) + if (!_fromSource[i]) + _indexValue[i] = _mapper.TypeAccessor[_fields[i]].GetValue(_newObject); + + _dic[new CompoundValue(_indexValue)] = (T)_newObject; + } + } + + public virtual void InitMapping(InitContext initContext) + { + ISupportMapping sm = _dic as ISupportMapping; + + if (sm != null) + { + sm.BeginMapping(initContext); + + if (_mapper != initContext.ObjectMapper) + _mapper = initContext.ObjectMapper; + } + } + + [CLSCompliant(false)] + public virtual IMapDataDestination GetDataDestination(InitContext initContext) + { + return _mapper; + } + + public virtual object GetNextObject(InitContext initContext) + { + AddObject(); + + _indexValue = new object[_fields.Length]; + + if (_isFromSource) + for (int i = 0; i < _fields.Length; i++) + if (_fromSource[i]) + _indexValue[i] = _fields[i].ByName ? + initContext.DataSource.GetValue(initContext.SourceObject, _fields[i].Name) : + initContext.DataSource.GetValue(initContext.SourceObject, _fields[i].Index); + + return _newObject = _mapper.CreateInstance(initContext); + } + + public virtual void EndMapping(InitContext initContext) + { + AddObject(); + + ISupportMapping sm = _dic as ISupportMapping; + + if (sm != null) + sm.EndMapping(initContext); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/DictionaryListMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/DictionaryListMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,92 @@ +using System; +using System.Collections; + +using BLToolkit.Common; +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public class DictionaryListMapper : IMapDataDestinationList + { + public DictionaryListMapper( + IDictionary dic, + NameOrIndexParameter keyField, + ObjectMapper objectMapper) + { + _dic = dic; + _mapper = objectMapper; + _fromSource = keyField.ByName && keyField.Name[0] == '@'; + _keyField = _fromSource? keyField.Name.Substring(1): keyField; + } + + private readonly IDictionary _dic; + private readonly bool _fromSource; + private NameOrIndexParameter _keyField; + private ObjectMapper _mapper; + private object _newObject; + private object _keyValue; + + #region IMapDataDestinationList Members + + private void AddObject() + { + if (_newObject != null) + { + if (!_fromSource) + _keyValue = _mapper.TypeAccessor[_keyField].GetValue(_newObject); + + _dic[_keyValue] = _newObject; + } + } + + public virtual void InitMapping(InitContext initContext) + { + ISupportMapping sm = _dic as ISupportMapping; + + if (sm != null) + { + sm.BeginMapping(initContext); + + if (_mapper != initContext.ObjectMapper) + _mapper = initContext.ObjectMapper; + } + } + + [CLSCompliant(false)] + public virtual IMapDataDestination GetDataDestination(InitContext initContext) + { + return _mapper; + } + + static readonly char[] _trim = { ' ' }; + + public virtual object GetNextObject(InitContext initContext) + { + AddObject(); + + if (_fromSource) + { + _keyValue = _keyField.ByName ? + initContext.DataSource.GetValue(initContext.SourceObject, _keyField.Name) : + initContext.DataSource.GetValue(initContext.SourceObject, _keyField.Index); + + if (Common.Configuration.TrimDictionaryKey && _keyValue is string) + _keyValue = _keyValue.ToString().TrimEnd(_trim); + } + + return _newObject = _mapper.CreateInstance(initContext); + } + + public virtual void EndMapping(InitContext initContext) + { + AddObject(); + + ISupportMapping sm = _dic as ISupportMapping; + + if (sm != null) + sm.EndMapping(initContext); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/DictionaryListMapperT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/DictionaryListMapperT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using BLToolkit.Common; +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public class DictionaryListMapper : IMapDataDestinationList + { + public DictionaryListMapper( + IDictionary dic, + NameOrIndexParameter keyField, + ObjectMapper objectMapper) + { + _dic = dic; + _mapper = objectMapper; + _keyGetter = MapGetData.I; + _fromSource = keyField.ByName && keyField.Name[0] == '@'; + _keyField = _fromSource? keyField.Name.Substring(1): keyField; + } + + private readonly IDictionary _dic; + private readonly bool _fromSource; + private readonly MapGetData.MB _keyGetter; + private NameOrIndexParameter _keyField; + private int _index; + private ObjectMapper _mapper; + private object _newObject; + private bool _typeMismatch; + private K _keyValue; + + #region IMapDataDestinationList Members + + private void AddObject() + { + if (_newObject != null) + { + if (_typeMismatch) + _keyValue = _mapper.MappingSchema.ConvertTo(_mapper[_index].GetValue(_newObject)); + else if (!_fromSource) + _keyValue = _keyGetter.From(_mapper, _newObject, _index); + + _dic[_keyValue] = (T)_newObject; + } + } + + public virtual void InitMapping(InitContext initContext) + { + var sm = _dic as ISupportMapping; + + if (sm != null) + { + sm.BeginMapping(initContext); + + if (_mapper != initContext.ObjectMapper) + _mapper = initContext.ObjectMapper; + } + + if (_fromSource) + _index = _keyField.ByName? initContext.DataSource.GetOrdinal(_keyField.Name): _keyField.Index; + else + { + _index = _keyField.ByName? _mapper.GetOrdinal(_keyField.Name, true): _keyField.Index; + + if (_index < 0) + throw new MappingException( + _keyField.ByName? + string.Format("Field '{0}' not found.", _keyField.Name): + string.Format("Index '{0}' is invalid.", _keyField.Index)); + + var mm = _mapper[_index]; + _typeMismatch = !TypeHelper.IsSameOrParent(typeof(K), mm.Type); + +#if !SILVERLIGHT + + Debug.WriteLineIf(_typeMismatch, string.Format( + "Member {0} type '{1}' does not match dictionary key type '{2}'.", + mm.Name, mm.Type.Name, (typeof(K).Name))); + +#endif + } + } + + [CLSCompliant(false)] + public virtual IMapDataDestination GetDataDestination(InitContext initContext) + { + return _mapper; + } + + static readonly char[] _trim = { ' ' }; + + public virtual object GetNextObject(InitContext initContext) + { + AddObject(); + + if (_fromSource) + { + _keyValue = _keyGetter.From(initContext.DataSource, initContext.SourceObject, _index); + + if (Common.Configuration.TrimDictionaryKey && _keyValue is string) + _keyValue = (K)(object)_keyValue.ToString().TrimEnd(_trim); + } + + return _newObject = _mapper.CreateInstance(initContext); + } + + public virtual void EndMapping(InitContext initContext) + { + AddObject(); + + ISupportMapping sm = _dic as ISupportMapping; + + if (sm != null) + sm.EndMapping(initContext); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/DictionaryMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/DictionaryMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,115 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace BLToolkit.Mapping +{ + public class DictionaryMapper : MapDataSourceDestinationBase + { + public DictionaryMapper(IDictionary dictionary) + { + if (dictionary == null) throw new ArgumentNullException("dictionary"); + + _dictionary = dictionary; + } + + private readonly IDictionary _dictionary; + public IDictionary Dictionary + { + get { return _dictionary; } + } + + private int _currentIndex; + private IDictionaryEnumerator _enumerator; + + private void SetEnumerator(int i) + { + if (_enumerator == null) + { + _enumerator = _dictionary.GetEnumerator(); + _enumerator.MoveNext(); + } + + if (_currentIndex > i) + { + _currentIndex = 0; + _enumerator.Reset(); + _enumerator.MoveNext(); + } + + for (; _currentIndex < i; _currentIndex++) + _enumerator.MoveNext(); + } + + #region IMapDataSource Members + + public override int Count + { + get { return _dictionary.Count; } + } + + public override Type GetFieldType(int index) + { + SetEnumerator(index); + return _enumerator.Value == null? typeof(object): _enumerator.Value.GetType(); + } + + public override string GetName(int index) + { + SetEnumerator(index); + return _enumerator.Key.ToString(); + } + + public override bool SupportsTypedValues(int index) + { + return index < _dictionary.Count; + } + + public override object GetValue(object o, int index) + { + SetEnumerator(index); + return _enumerator.Value; + } + + public override object GetValue(object o, string name) + { + return _dictionary.Contains(name) ? _dictionary[name] : null; + } + + #endregion + + #region IMapDataDestination Members + + private List _nameList; + + public override int GetOrdinal(string name) + { + if (_nameList == null) + _nameList = new List(); + + var idx = _nameList.IndexOf(name); + + if (idx >= 0) + return idx; + + _nameList.Add(name); + + return _nameList.Count - 1; + } + + public override void SetValue(object o, int index, object value) + { + SetValue(o, _nameList[index], value); + } + + public override void SetValue(object o, string name, object value) + { + if (_dictionary.Contains(name)) + _dictionary[name] = value; + else + _dictionary.Add(name, value); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/EnumeratorMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/EnumeratorMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,51 @@ +using System; +using System.Collections; + +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public class EnumeratorMapper : IMapDataSourceList + { + public EnumeratorMapper(IEnumerator enumerator) + { + _enumerator = enumerator; + } + + private readonly IEnumerator _enumerator; + private Type _objectType; + + #region IMapDataSourceList Members + + public virtual void InitMapping(InitContext initContext) + { + _enumerator.Reset(); + } + + public virtual bool SetNextDataSource(InitContext initContext) + { + if (initContext == null) throw new ArgumentNullException("initContext"); + + if (_enumerator.MoveNext() == false) + return false; + + object sourceObject = _enumerator.Current; + + if (_objectType != sourceObject.GetType()) + { + _objectType = sourceObject.GetType(); + initContext.DataSource = initContext.MappingSchema.GetObjectMapper(_objectType); + } + + initContext.SourceObject = sourceObject; + + return true; + } + + public virtual void EndMapping(InitContext initContext) + { + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/ExpressionMapIgnoreAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/ExpressionMapIgnoreAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +using System; + +namespace BLToolkit.Mapping +{ + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public sealed class ExpressionMapIgnoreAttribute : Attribute + { + public ExpressionMapIgnoreAttribute() + { + Ignore = true; + } + + public ExpressionMapIgnoreAttribute(bool ignore) + { + Ignore = ignore; + } + + public bool Ignore { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/ExpressionMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/ExpressionMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,785 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +using BLToolkit.Common; +using BLToolkit.Data.Linq; +using BLToolkit.Reflection; + +using JetBrains.Annotations; + +namespace BLToolkit.Mapping +{ + class Mapper + { + public Func Map; + } + + class MappingContext + { + public Dictionary Objects; + public Func GetParent; + public List> CrossActions; + public Dictionary>> Crosses; + } + + class MappingParameters + { + public MappingSchema MappingSchema; + public bool DeepCopy = true; + public bool HandleCrossReferences = true; + public bool IncludeComplexMapping; + + public Dictionary MapperList = new Dictionary(); + + public bool UseContext; + public bool ContextParameterUsed; + + readonly ParameterExpression _mappingContext = Expression.Parameter(typeof(MappingContext), "ctx"); + public ParameterExpression MappingContext + { + get + { + ContextParameterUsed = true; + return _mappingContext; + } + } + } + + public class ExpressionMapper + { + readonly MappingParameters _parameters; + private Func _getCurrent; + private Action _setCurrent; + + public bool DeepCopy { get { return _parameters.DeepCopy; } set { _parameters.DeepCopy = value; } } + public bool HandleBackReferences { get { return _parameters.HandleCrossReferences; } set { _parameters.HandleCrossReferences = value; } } + public bool IncludeComplexMapping { get { return _parameters.IncludeComplexMapping; } set { _parameters.IncludeComplexMapping = value; } } + + public ExpressionMapper() + : this(Map.DefaultSchema) + { + } + + public ExpressionMapper(MappingSchema mappingSchema) + { + _parameters = new MappingParameters { MappingSchema = mappingSchema }; + } + + ExpressionMapper(MappingParameters parameters) + { + _parameters = parameters; + } + + #region Value Converter + + interface IValueConvertHelper + { + Expression GetConverter (Expression source); + Expression CheckNull (ExpressionMapper mapper, Expression source, object nullValue, MapValue[] mapValues, object defaultValue, MapValue[] srcMapValues); + Expression SourceMapValues(ExpressionMapper mapper, Expression source, object nullValue, object defaultValue, MapValue[] srcMapValues); + Expression DestMapValues (ExpressionMapper mapper, Expression source, object nullValue, MapValue[] mapValues, object defaultValue); + } + + class ValueConvertHelper : IValueConvertHelper + { + public Expression GetConverter(Expression source) + { + return Expression.Invoke(Expression.Constant(Convert.From), source); + } + + public Expression CheckNull( + ExpressionMapper mapper, + Expression source, + object nullValue, + MapValue[] mapValues, + object defaultValue, + MapValue[] srcMapValues) + { + var param = + source.NodeType != ExpressionType.MemberAccess && + source.NodeType != ExpressionType.Parameter && + source.NodeType != ExpressionType.Constant? + Expression.Parameter(typeof(TS), "p") : + null; + + var nexpr = Expression.Constant(nullValue ?? default(TD)); + + var expr = + source.NodeType == ExpressionType.Constant && ((ConstantExpression)source).Value == null ? + nexpr as Expression: + Expression.Condition( + Expression.Equal(param ?? source, Expression.Constant(null)), + nexpr.Value == null ? Expression.Convert(nexpr, typeof(TD)) : nexpr as Expression, + mapper.GetValueMapper(param ?? source, typeof(TD), false, null, mapValues, defaultValue, srcMapValues)); + + return param == null ? expr : Expression.Invoke(Expression.Lambda>(expr, param), source); + } + + public Expression SourceMapValues( + ExpressionMapper mapper, + Expression source, + object nullValue, + object defaultValue, + MapValue[] srcMapValues) + { + var param = + //source.NodeType != ExpressionType.MemberAccess && + source.NodeType != ExpressionType.Parameter && + source.NodeType != ExpressionType.Constant? + Expression.Parameter(typeof(TS), "p") : + null; + + var expr = mapper.GetValueMapper(Expression.Constant(defaultValue), typeof(TD), true, nullValue, null, null, null); + + for (var i = srcMapValues.Length - 1; i >= 0; i--) + { + var value = srcMapValues[i]; + + expr = Expression.Condition( + Expression.Equal(param ?? source, mapper.GetValueMapper(Expression.Constant(value.OrigValue), typeof(TS), false, null, null, null, null)), + mapper.GetValueMapper(Expression.Constant(value.MapValues[0]), typeof(TD), true, nullValue, null, null, null), + expr); + } + + return param == null ? expr : Expression.Invoke(Expression.Lambda>(expr, param), source); + } + + public Expression DestMapValues( + ExpressionMapper mapper, + Expression source, + object nullValue, + MapValue[] mapValues, + object defaultValue) + { + var param = + //source.NodeType != ExpressionType.MemberAccess && + source.NodeType != ExpressionType.Parameter && + source.NodeType != ExpressionType.Constant? + Expression.Parameter(typeof(TS), "p") : + null; + + var expr = mapper.GetValueMapper(Expression.Constant(defaultValue), typeof(TD), true, nullValue, null, null, null); + + for (var i = mapValues.Length - 1; i >= 0; i--) + { + var value = mapValues[i]; + var orex = null as Expression; + + foreach (var mapValue in value.MapValues) + { + var ex = Expression.Equal(param ?? source, mapper.GetValueMapper(Expression.Constant(mapValue), typeof (TS), false, null, null, null, null)); + orex = orex == null ? ex : Expression.OrElse(orex, ex); + } + + if (orex != null) + expr = Expression.Condition( + orex, + mapper.GetValueMapper(Expression.Constant(value.OrigValue), typeof(TD), true, nullValue, null, null, null), + expr); + } + + return param == null ? expr : Expression.Invoke(Expression.Lambda>(expr, param), source); + } + } + + static IValueConvertHelper GetValueHelper(Type stype, Type dtype) + { + var type = typeof(ValueConvertHelper<,>).MakeGenericType(typeof(TSource), typeof(TDest), stype, dtype); + return ((IValueConvertHelper)Activator.CreateInstance(type)); + } + + #endregion + + #region Object Converter + + interface IConvertHelper + { + Expression MapObjects(ExpressionMapper mapper, Expression source); + Expression MapLists (ExpressionMapper mapper, Expression source); + } + + class ConvertHelper : IConvertHelper + where TS : class + where TD : class + { + static TD MapCrossReferences( + MappingContext ctx, + TS source, + Func func, + Func getCurrent, + Action setCurrent) + { + if (source == null) + return null; + + object dest; + List> list; + + if (ctx.Objects.TryGetValue(source, out dest)) + { + if (dest == null) + { + if (ctx.Crosses == null) + ctx.Crosses = new Dictionary>>(); + + if (!ctx.Crosses.TryGetValue(source, out list)) + ctx.Crosses[source] = list = new List>(); + + var getParent = ctx.GetParent; + + Action setter = (obj,value) => setCurrent(getParent(obj), value); + + list.Add(setter); + } + + return (TD)dest; + } + + var currParent = ctx.GetParent; + + ctx.GetParent = p => getCurrent(currParent(p)); + ctx.Objects.Add(source, null); + ctx.Objects[source] = dest = func(source); + ctx.GetParent = currParent; + + if (ctx.Crosses != null && ctx.Crosses.TryGetValue(source, out list)) + { + if (ctx.CrossActions == null) + ctx.CrossActions = new List>(); + + foreach (var action in list) + { + var setValue = action; + + Action f = parent => setValue(parent, dest); + ctx.CrossActions.Add(f); + } + + ctx.Crosses.Remove(source); + } + + return (TD)dest; + } + + static TD MapObjects(TS source, Func func) + { + return source == null ? null : func(source); + } + + public Expression MapObjects(ExpressionMapper mapper, Expression source) + { + var param = mapper._getCurrent == null ? (ParameterExpression)source : Expression.Parameter(source.Type, "source"); + + Expression expr; + object m; + + if (mapper._parameters.MapperList.TryGetValue(new { S = typeof(TS), D = typeof(TD) }, out m)) + { + var map = (Mapper)m; + + if (map.Map == null) + { + expr = Expression.Invoke( + Expression.PropertyOrField(Expression.Constant(map), "Map"), + source, mapper._parameters.MappingContext); + } + else + { + expr = Expression.Invoke(Expression.Constant(map.Map), source, mapper._parameters.MappingContext); + } + } + else + { + var exmap = new ExpressionMapper(mapper._parameters); + expr = exmap.GetMemberInit(param); + } + + if (mapper._getCurrent == null) + return expr; + + if (!mapper.HandleBackReferences) + { + Expression> func = () => MapObjects((TS)null, null); + return Expression.Call((MethodInfo)ReflectionHelper.MemeberInfo(func), source, Expression.Lambda>(expr, param)); + } + else + { + mapper._parameters.UseContext = true; + + Expression> func = () => MapCrossReferences(null, null, null, null, null); + + return Expression.Call( + (MethodInfo)ReflectionHelper.MemeberInfo(func), + mapper._parameters.MappingContext, + source, + Expression.Lambda>(expr, param), + Expression.Constant(mapper._getCurrent), + Expression.Constant(mapper._setCurrent)); + } + } + + interface IItemHelper + { + Expression MapLists(ExpressionMapper mapper, Expression source); + } + + interface IClassItemHelper + { + MethodInfo GetObjectArrayInfo(); + MethodInfo GetObjectListInfo(bool isList); + } + + class ClassItemHelper : IClassItemHelper + where TSourceItem : class + where TDestItem : class + { + static TDestItem[] MapObjectArray(MappingContext ctx, IEnumerable source, Func itemMapper) + { + if (source == null) + return null; + + if (source is ICollection) + { + var col = (ICollection)source; + var dest = new TDestItem[col.Count]; + var n = 0; + + foreach (var item in source) + { + var current = n; + dest[n++] = ConvertHelper.MapCrossReferences( + ctx, item, itemMapper, + _ => dest[current], + (_,v) => { dest[current] = (TDestItem)v; }); + } + + return dest; + } + else + { + TDestItem[] dest = null; + + var list = new List(); + var n = 0; + + foreach (var item in source) + { + var current = n; + list.Add(null); + list[n++] = ConvertHelper.MapCrossReferences( + ctx, item, itemMapper, + _ => dest == null ? list[current] : dest[current], + (_,v) => { if (dest == null) list[current] = (TDestItem)v; else dest[current] = (TDestItem)v; }); + } + + return dest = list.ToArray(); + } + } + + [UsedImplicitly] + static TList MapObjectList(MappingContext ctx, IEnumerable source, Func itemMapper) + where TList : class, IList, new() + { + if (source == null) + return null; + + var n = 0; + var dest = source is ICollection && typeof(TList) == typeof(List) ? + (TList)(IList)new List(((ICollection)source).Count) : new TList(); + + foreach (var item in source) + { + var current = n; + dest.Add(null); + dest[n++] = ConvertHelper.MapCrossReferences( + ctx, item, itemMapper, + _ => dest[current], + (_,v) => { dest[current] = (TDestItem)v; }); + } + + return dest; + } + + public MethodInfo GetObjectArrayInfo() + { + Expression> arrMapper = () => MapObjectArray(null, null, null); + return (MethodInfo)ReflectionHelper.MemeberInfo(arrMapper); + } + + public MethodInfo GetObjectListInfo(bool isList) + { + var method = typeof(ClassItemHelper).GetMethod("MapObjectList", BindingFlags.NonPublic | BindingFlags.Static); + return method.MakeGenericMethod(isList ? typeof (List) : typeof (TD)); + } + } + + class ItemHelper : IItemHelper + { + static TDestItem[] MapScalarArray(IEnumerable source, Func itemMapper) + { + if (source == null) + return null; + + if (source is ICollection) + { + var col = (ICollection)source; + var dest = new TDestItem[col.Count]; + var n = 0; + + foreach (var item in source) + dest[n++] = itemMapper(item); + + return dest; + } + + return source.Select(itemMapper).ToArray(); + } + + [UsedImplicitly] + static TList MapScalarList(IEnumerable source, Func itemMapper) + where TList : class, IList, new() + { + if (source == null) + return null; + + var dest = new TList(); + var list = dest as List; + + if (list != null) + list.AddRange(source.Select(itemMapper)); + else + foreach (var item in source) + dest.Add(itemMapper(item)); + + return dest; + } + + public Expression MapLists(ExpressionMapper mapper, Expression source) + { + var itemMapper = + new ExpressionMapper(mapper._parameters); + + var itemParam = Expression.Parameter(typeof(TSourceItem), "item"); + var itemExpr = itemMapper.GetValueMapper( + itemParam, + typeof(TDestItem), + true, + mapper._parameters.MappingSchema.GetNullValue (typeof(TDestItem)), + mapper._parameters.MappingSchema.GetMapValues (typeof(TDestItem)), + mapper._parameters.MappingSchema.GetDefaultValue(typeof(TDestItem)), + mapper._parameters.MappingSchema.GetMapValues (typeof(TSourceItem))); + + var itemLambda = Expression.Lambda>(itemExpr, itemParam); + + var isSourceScalar = !typeof(TSourceItem).IsArray && TypeHelper.IsScalar(typeof(TSourceItem)); + var isDestScalar = !typeof(TDestItem). IsArray && TypeHelper.IsScalar(typeof(TDestItem)); + + if (!mapper.HandleBackReferences || isSourceScalar || isDestScalar) + { + if (typeof (TD).IsArray) + { + Expression> arrMapper = () => MapScalarArray(null, null); + return Expression.Call((MethodInfo)ReflectionHelper.MemeberInfo(arrMapper), source, itemLambda); + } + + var isList = + typeof (TD) == typeof (IEnumerable) || typeof (TD) == typeof (ICollection) || + typeof (TD) == typeof (IList) || typeof (TD) == typeof (List); + + var method = typeof (ItemHelper).GetMethod("MapScalarList", BindingFlags.NonPublic | BindingFlags.Static); + + method = method.MakeGenericMethod(isList ? typeof (List) : typeof (TD)); + + return Expression.Call(method, source, itemLambda); + } + else + { + mapper._parameters.UseContext = true; + + var type = typeof (ClassItemHelper<,>).MakeGenericType( + typeof (TSource), typeof (TDest), + typeof (TS), typeof (TD), + typeof (TSourceItem), typeof (TDestItem)); + + var helper = ((IClassItemHelper)Activator.CreateInstance(type)); + + if (typeof (TD).IsArray) + return Expression.Call(helper.GetObjectArrayInfo(), mapper._parameters.MappingContext, source, itemLambda); + + var isList = + typeof (TD) == typeof (IEnumerable) || typeof (TD) == typeof (ICollection) || + typeof (TD) == typeof (IList) || typeof (TD) == typeof (List); + + return Expression.Call(helper.GetObjectListInfo(isList), mapper._parameters.MappingContext, source, itemLambda); + } + } + } + + public Expression MapLists(ExpressionMapper mapper, Expression source) + { + var ts = TypeHelper.GetGenericType(typeof(IEnumerable<>), typeof(TS)).GetGenericArguments()[0]; + var td = TypeHelper.GetGenericType(typeof(IEnumerable<>), typeof(TD)).GetGenericArguments()[0]; + + var type = typeof(ItemHelper<,>).MakeGenericType(typeof(TSource), typeof(TDest), typeof(TS), typeof(TD), ts, td); + return ((IItemHelper)Activator.CreateInstance(type)).MapLists(mapper, source); + } + } + + static IConvertHelper GetHelper(Type stype, Type dtype) + { + var type = typeof(ConvertHelper<,>).MakeGenericType(typeof(TSource), typeof(TDest), stype, dtype); + return ((IConvertHelper)Activator.CreateInstance(type)); + } + + #endregion + + Expression GetValueMapper( + Expression source, + Type dtype, + bool checkNull, + object nullValue, + MapValue[] destMapValues, + object defaultValue, + MapValue[] srcMapValues) + { + var stype = source.Type; + + var isSourceScalar = !stype.IsArray && TypeHelper.IsScalar(stype); + var isDestScalar = !dtype.IsArray && TypeHelper.IsScalar(dtype); + + if (dtype == typeof(object) || dtype == stype && (!DeepCopy || isSourceScalar)) + return source; + + var isSourceNullable = TypeHelper.IsNullableType(stype) || stype.IsClass; + + if (checkNull && isSourceNullable && !TypeHelper.IsNullableType(dtype) && (isDestScalar || isSourceScalar)) + return GetValueHelper(stype, dtype).CheckNull(this, source, nullValue, destMapValues, defaultValue, srcMapValues); + + if (srcMapValues != null) + return GetValueHelper(stype, dtype).SourceMapValues(this, source, nullValue, defaultValue, srcMapValues); + + if (destMapValues != null) + return GetValueHelper(stype, dtype).DestMapValues(this, source, nullValue, destMapValues, defaultValue); + + if (dtype == typeof (string)) + return + isSourceNullable + ? + Expression.Condition( + Expression.Equal(source, Expression.Constant(null)), + Expression.Constant(null), + Expression.Call(source, "ToString", Array.Empty)) as Expression + : + Expression.Call(source, "ToString", Array.Empty); + + if (!isDestScalar && !isSourceScalar) + { + if (TypeHelper.GetGenericType(typeof(IEnumerable<>), dtype) != null && + TypeHelper.GetGenericType(typeof(IEnumerable<>), stype) != null) + return GetHelper(stype, dtype).MapLists(this, source); + + return GetHelper(stype, dtype).MapObjects(this, source); + } + + try + { + return Expression.Convert(source, dtype); + } + catch (InvalidOperationException) + { + } + + return GetValueHelper(stype, dtype).GetConverter(source); + } + + IEnumerable GetBindings(Expression source) + { + var dest = _parameters.MappingSchema.GetObjectMapper(typeof(TDest)); + var src = _parameters.MappingSchema.GetObjectMapper(typeof(TSource)); + + foreach (MemberMapper dmm in dest) + { + if (!IncludeComplexMapping && dmm is MemberMapper.ComplexMapper) + continue; + + var dma = dmm.MemberAccessor; + + if (!dma.HasSetter) + continue; + + var attr = dma.GetAttribute(); + + if (attr != null && attr.Ignore) + continue; + + var smm = src[dmm.Name]; + + if (smm == null) + continue; + + if (!IncludeComplexMapping && smm is MemberMapper.ComplexMapper) + continue; + + var sma = smm.MemberAccessor; + + if (!sma.HasGetter) + continue; + + attr = sma.GetAttribute(); + + if (attr != null && attr.Ignore) + continue; + + _getCurrent = dma.GetValue; + _setCurrent = dma.SetValue; + + var bind = Expression.Bind( + dma.MemberInfo, + GetValueMapper( + Expression.PropertyOrField(source, sma.Name), + dma.Type, + true, + dmm.MapMemberInfo.NullValue, + dmm.MapMemberInfo.MapValues, + dmm.MapMemberInfo.DefaultValue, + smm.MapMemberInfo.MapValues)); + + yield return bind; + } + + var destMembers = from m in ((IEnumerable)dest.TypeAccessor) select m; + + destMembers = destMembers.Except(dest.Select(mm => mm.MemberAccessor)).ToList(); + + var srcMembers = + (from m in ((IEnumerable)src.TypeAccessor) select m) + .Except(src.Select(mm => mm.MemberAccessor)) + .ToList(); + + foreach (var dma in destMembers) + { + if (!dma.HasSetter) + continue; + + var sma = srcMembers.FirstOrDefault(mi => mi.Name == dma.Name); + + if (sma == null || !sma.HasGetter) + continue; + + _getCurrent = dma.GetValue; + _setCurrent = dma.SetValue; + + var bind = Expression.Bind( + dma.MemberInfo, + GetValueMapper( + Expression.MakeMemberAccess(source, sma.MemberInfo), + dma.Type, + true, + _parameters.MappingSchema.GetNullValue (dma.Type), + _parameters.MappingSchema.GetMapValues (dma.Type), + _parameters.MappingSchema.GetDefaultValue(dma.Type), + _parameters.MappingSchema.GetMapValues (sma.Type))); + + yield return bind; + } + } + + Expression GetMemberInit(ParameterExpression source) + { + var mapper = new Mapper(); + + _parameters.MapperList.Add(new { S = typeof(TSource), D = typeof(TDest) }, mapper); + + var dest = TypeAccessor.Instance; + var expr = Expression.MemberInit(Expression.New(dest.Type), GetBindings(source)); + + mapper.Map = Expression.Lambda>(expr, source, _parameters.MappingContext).Compile(); + + return expr; + } + + interface IAbstractHelper + { + Func GetMapper(MappingParameters ps); + } + + class AbstractHelper : IAbstractHelper + { + public Func GetMapper(MappingParameters ps) + { + var em = new ExpressionMapper(ps); + var mapper = em.GetMapper(); + + return source => (TDest)(object)mapper((TS)(object)source); + } + } + + public Func GetMapper() + { + if (typeof(TSource) == typeof(TDest) && !DeepCopy) + return s => (TDest)(object)s; + + if (TypeHelper.IsAbstractClass(typeof(TSource)) || TypeHelper.IsAbstractClass(typeof(TDest))) + { + var st = TypeHelper.IsAbstractClass(typeof(TSource)) ? TypeAccessor.Instance.Type : typeof(TSource); + var dt = TypeHelper.IsAbstractClass(typeof(TDest)) ? TypeAccessor. Instance.Type : typeof(TDest); + + var type = typeof(AbstractHelper<,>).MakeGenericType(typeof(TSource), typeof(TDest), st, dt); + return ((IAbstractHelper)Activator.CreateInstance(type)).GetMapper(_parameters); + } + + var parm = Expression.Parameter(typeof(TSource), "src"); + var expr = GetValueMapper( + parm, + typeof(TDest), + true, + _parameters.MappingSchema.GetNullValue (typeof(TDest)), + _parameters.MappingSchema.GetMapValues (typeof(TDest)), + _parameters.MappingSchema.GetDefaultValue(typeof(TDest)), + _parameters.MappingSchema.GetMapValues (typeof(TSource))); + + if (_parameters.ContextParameterUsed) + { + var l = Expression.Lambda>(expr, parm, _parameters.MappingContext); + var f = l.Compile(); + + if (!_parameters.UseContext) + return s => f(s, null); + + return s => + { + var ctx = new MappingContext + { + Objects = new Dictionary(10) { { s, null } }, + GetParent = p => p, + }; + + var dest = f(s, ctx); + + if (ctx.CrossActions != null) + foreach (var circle in ctx.CrossActions) + circle(dest); + + if (ctx.Crosses != null) + { + List> list; + + if (ctx.Crosses.TryGetValue(s, out list)) + foreach (var action in list) + action(dest, dest); + } + + return dest; + }; + } + + var lambda = Expression.Lambda>(expr, parm); + + return lambda.Compile(); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Fluent/AssociationMap.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Fluent/AssociationMap.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; + +namespace BLToolkit.Mapping.Fluent +{ + public partial class MapFieldMap + { + public class AssociationMap + { + private readonly MapFieldMap _owner; + private readonly bool _canBeNull; + private readonly List>> _thisKeys; + + public AssociationMap(MapFieldMap owner, bool canBeNull, List>> thisKeys) + { + this._owner = owner; + this._canBeNull = canBeNull; + this._thisKeys = thisKeys; + } + + public MapFieldMap ToMany(Expression> otherKey, params Expression>[] otherKeys) + { + var keys = new List>>(otherKeys); + keys.Insert(0, otherKey); + return this._owner.Association(this._canBeNull, this._thisKeys, keys); + } + + public MapFieldMap ToOne(Expression> otherKey, params Expression>[] otherKeys) + { + var keys = new List>>(otherKeys); + keys.Insert(0, otherKey); + return this._owner.Association(this._canBeNull, this._thisKeys, keys); + } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Fluent/Attributes.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Fluent/Attributes.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,107 @@ +namespace BLToolkit.Mapping.Fluent +{ + /// + /// Used Attribute Names + /// + /// + public partial class FluentMap + { + protected static class Attributes + { + public static class TableName + { + public const string Name = "TableName"; + + public const string Database = "DatabaseName"; + + public const string Owner = "OwnerName"; + } + + public static class MapField + { + public const string Name = "MapField"; + + public const string Storage = "FieldStorage"; + + public const string IsInheritanceDiscriminator = "IsInheritanceDiscriminator"; + + public const string OrigName = "OrigName"; + + public const string MapName = "MapName"; + } + + public static class PrimaryKey + { + public const string Order = "PrimaryKey"; + } + + public static class SqlIgnore + { + public const string Ignore = "SqlIgnore"; + } + + public static class MapIgnore + { + public const string Ignore = "MapIgnore"; + } + + public static class MapValue + { + public const string Name = "MapValue"; + + public const string OrigValue = "OrigValue"; + } + + public static class Nullable + { + public const string IsNullable = "Nullable"; + } + + public static class LazyInstance + { + public const string IsLazyInstance = "LazyInstance"; + } + + public static class InheritanceMapping + { + public const string Name = "InheritanceMapping"; + + public const string Code = "Code"; + + public const string IsDefault = "IsDefault"; + + public const string Type = "Type"; + } + + public static class Association + { + public const string ThisKey = "ThisKey"; + + public const string OtherKey = "OtherKey"; + + public const string Storage = "Storage"; + } + + public const string NonUpdatable = "NonUpdatable"; + + public const string Identity = "Identity"; + + public const string Trimmable = "Trimmable"; + + public const string DefaultValue = "DefaultValue"; + + public const string DbType = "DbType"; + + public static class MemberMapper + { + public const string Name = "MemberMapper"; + + public const string MemberType = "MemberType"; + + public const string MemberMapperType = "MemberMapperType"; + } + + public const string NullValue = "NullValue"; + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Fluent/FluentConfig.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Fluent/FluentConfig.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,133 @@ +using System; +using System.CodeDom; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; +using BLToolkit.Reflection.Extension; + +namespace BLToolkit.Mapping.Fluent +{ + /// + /// Configure BLToolkit in fluent style + /// + public static class FluentConfig + { + private static Dictionary _hash = new Dictionary(); + + /// + /// Configure DbManager + /// + /// + public static MappingConfigurator Configure(DbManager dbManager) + { + MappingSchema mappingSchema = dbManager.MappingSchema ?? (dbManager.MappingSchema = Map.DefaultSchema); + return Configure(mappingSchema); + } + + /// + /// Configure DataProvider + /// + /// + public static MappingConfigurator Configure(DataProviderBase dataProvider) + { + MappingSchema mappingSchema = dataProvider.MappingSchema ?? (dataProvider.MappingSchema = Map.DefaultSchema); + return Configure(mappingSchema); + } + + /// + /// Configure MappingSchema + /// + /// + public static MappingConfigurator Configure(MappingSchema mappingSchema) + { + ExtensionList extensionList = mappingSchema.Extensions ?? (mappingSchema.Extensions = new ExtensionList()); + return Configure(extensionList); + } + + /// + /// Configure ExtensionList + /// + /// + public static MappingConfigurator Configure(ExtensionList extensionList) + { + return new MappingConfigurator(extensionList); + } + + public class MappingConfigurator + { + private ExtensionList _extensions; + + public MappingConfigurator(ExtensionList extensions) + { + this._extensions = extensions; + } + + /// + /// Mapping IFluentMap-Type + /// + /// + /// + public void MapingFromType() where T : IFluentMap + { + MapingFromType(typeof(T)); + } + + public void MapingFromType(Type T) + { + var res = new ExtensionList(); + var map = (IFluentMap)Activator.CreateInstance(T); + + map.MapTo(res); + + FluentMapHelper.MergeExtensions(res, ref this._extensions); + } + /// + /// Mapping from assembly contains type + /// + /// + /// + public void MapingFromAssemblyOf() + { + this.MapingFromAssembly(typeof(T).Assembly); + } + + /// + /// Mapping from assembly + /// + /// + /// + public void MapingFromAssembly(Assembly assembly) + { + ExtensionList res; + if (!_hash.TryGetValue(assembly, out res)) + { + res = new ExtensionList(); + _hash.Add(assembly, res); + + string fluentType = typeof(IFluentMap).FullName; + var mapTypes = from type in assembly.GetTypes() + where type.IsClass && !type.IsAbstract && !type.IsGenericType + && (null != type.GetInterface(fluentType)) // Is IFluentMap + && (null != type.GetConstructor(new Type[0])) // Is defaut ctor + select type; + foreach (var fluentMapType in mapTypes) + { + MapingFromType(fluentMapType); + } + } + //FluentMapHelper.MergeExtensions(res, ref this._extensions); + } + + #region Conventions + + public static Func GetTableName; + public static Func GetColumnName; + //public static Func GetManyToManyTableName; + + #endregion + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Fluent/FluentMap.Interface.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Fluent/FluentMap.Interface.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,348 @@ +using System; +using System.Collections; +using System.Data; +using System.Linq; + +using BLToolkit.Reflection; +using BLToolkit.Reflection.Extension; + +namespace BLToolkit.Mapping.Fluent +{ + public partial class FluentMap : IFluentMap + { + /// + /// Get mapping + /// + /// + ExtensionList IFluentMap.Map() + { + return this.Map(); + } + + /// + /// TableNameAttribute + /// + /// + /// + /// + /// + void IFluentMap.TableName(string database, string owner, string name) + { + if (null != database) + { + this._typeExtension.Attributes.Add(Attributes.TableName.Database, database); + } + if (null != owner) + { + this._typeExtension.Attributes.Add(Attributes.TableName.Owner, owner); + } + if (null != name) + { + this._typeExtension.Attributes.Add(Attributes.TableName.Name, name); + } + this.EachChilds(m => m.TableName(database, owner, name)); + } + + /// + /// Map to ExtensionList + /// + /// + void IFluentMap.MapTo(ExtensionList extensions) + { + this.MapTo(extensions); + } + + /// + /// Maps the field. + /// + /// Name of the prop. + /// Name of the map. + /// The storage. + /// The is inheritance discriminator. + /// + void IFluentMap.MapField(string propName, string mapName, string storage, bool? isInheritanceDiscriminator) + { + if (propName.Contains(MemberNameSeparator)) + { + this.MapFieldOnType(propName, mapName); + } + else + { + this.MapFieldOnField(propName, mapName, storage, isInheritanceDiscriminator); + } + this.EachChilds(m => m.MapField(propName, mapName, storage, isInheritanceDiscriminator)); + } + + /// + /// Primaries the key. + /// + /// Name of the prop. + /// The order. + void IFluentMap.PrimaryKey(string propName, int order) + { + var member = this.GetMemberExtension(propName); + member.Attributes.Add(Attributes.PrimaryKey.Order, Convert.ToString(order)); + this.EachChilds(m => m.PrimaryKey(propName, order)); + } + + /// + /// Nons the updatable. + /// + /// Name of the prop. + void IFluentMap.NonUpdatable(string propName) + { + var member = this.GetMemberExtension(propName); + member.Attributes.Add(Attributes.NonUpdatable, this.ToString(true)); + this.EachChilds(m => m.NonUpdatable(propName)); + } + + /// + /// Identities the specified prop name. + /// + /// Name of the prop. + void IFluentMap.Identity(string propName) + { + var member = this.GetMemberExtension(propName); + member.Attributes.Add(Attributes.Identity, this.ToString(true)); + this.EachChilds(m => m.Identity(propName)); + } + + /// + /// SQLs the ignore. + /// + /// Name of the prop. + /// if set to true [ignore]. + void IFluentMap.SqlIgnore(string propName, bool ignore) + { + var member = this.GetMemberExtension(propName); + member.Attributes.Add(Attributes.SqlIgnore.Ignore, this.ToString(ignore)); + this.EachChilds(m => m.SqlIgnore(propName, ignore)); + } + + /// + /// Maps the ignore. + /// + /// Name of the prop. + /// if set to true [ignore]. + void IFluentMap.MapIgnore(string propName, bool ignore) + { + var member = this.GetMemberExtension(propName); + member.Attributes.Add(Attributes.MapIgnore.Ignore, this.ToString(ignore)); + this.EachChilds(m => m.MapIgnore(propName, ignore)); + } + + /// + /// Trimmables the specified prop name. + /// + /// Name of the prop. + void IFluentMap.Trimmable(string propName) + { + var member = this.GetMemberExtension(propName); + member.Attributes.Add(Attributes.Trimmable, this.ToString(true)); + this.EachChilds(m => m.Trimmable(propName)); + } + + /// + /// Maps the value. + /// + /// The type of the R. + /// The type of the V. + /// Name of the prop. + /// The orig value. + /// The value. + /// The values. + void IFluentMap.MapValue(string propName, TR origValue, TV value, TV[] values) + { + var member = this.GetMemberExtension(propName); + this.FillMapValueExtension(member.Attributes, origValue, value, values); + this.EachChilds(m => m.MapValue(propName, origValue, value, values)); + } + + /// + /// Maps the value. + /// + /// The type of the V. + /// The orig value. + /// The value. + /// The values. + void IFluentMap.MapValue(Enum origValue, TV value, TV[] values) + { + MemberExtension member; + var name = Enum.GetName(origValue.GetType(), origValue); + if (!this._typeExtension.Members.TryGetValue(name, out member)) + { + member = new MemberExtension { Name = name }; + this._typeExtension.Members.Add(member); + } + this.FillMapValueExtension(member.Attributes, origValue, value, values); + this.EachChilds(m => m.MapValue(origValue, value, values)); + } + + /// + /// Maps the value. + /// + /// The type of the V. + /// The orig value. + /// The value. + /// The values. + void IFluentMap.MapValue(object origValue, TV value, TV[] values) + { + this.FillMapValueExtension(this._typeExtension.Attributes, origValue, value, values); + this.EachChilds(m => m.MapValue(origValue, value, values)); + } + + /// + /// Defauls the value. + /// + /// The type of the R. + /// Name of the prop. + /// The value. + void IFluentMap.DefaulValue(string propName, TR value) + { + var member = this.GetMemberExtension(propName); + member.Attributes.Add(Attributes.DefaultValue, Convert.ToString(value)); + this.EachChilds(m => m.DefaulValue(propName, value)); + } + + /// + /// DB-Type of the value. + /// + /// The type of the R. + /// Name of the prop. + /// The value. + void IFluentMap.DbType(string propName, DbType dbType) + { + var member = this.GetMemberExtension(propName); + member.Attributes.Add(Attributes.DbType, Convert.ToString(dbType)); + this.EachChilds(m => m.DefaulValue(propName, dbType)); + } + + /// + /// MemberMapper + /// + /// The type of the R. + /// Name of the prop. + /// The value. + void IFluentMap.MemberMapper(string propName, Type memberType, Type memberMapperType) + { + var member = this.GetMemberExtension(propName); + this.FillMemberMapperExtension(member.Attributes, memberType, memberMapperType); + this.EachChilds(m => m.MemberMapper(propName, memberType, memberMapperType)); + } + + /// + /// Nullables the specified prop name. + /// + /// Name of the prop. + /// if set to true [is nullable]. + void IFluentMap.Nullable(string propName, bool isNullable) + { + var member = this.GetMemberExtension(propName); + member.Attributes.Add(Attributes.Nullable.IsNullable, this.ToString(isNullable)); + this.EachChilds(m => m.Nullable(propName, isNullable)); + } + + void IFluentMap.LazyInstance(string propName, bool isLazy) + { + var member = this.GetMemberExtension(propName); + member.Attributes.Add(Attributes.LazyInstance.IsLazyInstance, this.ToString(isLazy)); + this.EachChilds(m => m.LazyInstance(propName, isLazy)); + } + + /// + /// Nulls the value. + /// + /// The type of the R. + /// Name of the prop. + /// The value. + void IFluentMap.NullValue(string propName, TR value) + { + var member = this.GetMemberExtension(propName); + member.Attributes.Add(Attributes.NullValue, Equals(value, null) ? null : Convert.ToString(value)); + this.EachChilds(m => m.NullValue(propName, value)); + } + + /// + /// Associations the specified prop name. + /// + /// Name of the prop. + /// if set to true [can be null]. + /// The this keys. + /// The other keys. + void IFluentMap.Association(string propName, bool canBeNull, string thisKeys, string otherKeys) + { + var member = this.GetMemberExtension(propName); + AttributeExtensionCollection attrs; + if (!member.Attributes.TryGetValue(TypeExtension.NodeName.Association, out attrs)) + { + attrs = new AttributeExtensionCollection(); + member.Attributes.Add(TypeExtension.NodeName.Association, attrs); + } + attrs.Clear(); + var attributeExtension = new AttributeExtension(); + attributeExtension.Values.Add(Attributes.Association.ThisKey, thisKeys); + attributeExtension.Values.Add(Attributes.Association.OtherKey, otherKeys); + attributeExtension.Values.Add(Attributes.Association.Storage, this.ToString(canBeNull)); + attrs.Add(attributeExtension); + this.EachChilds(m => m.Association(propName, canBeNull, thisKeys, otherKeys)); + } + + /// + /// Relations the specified prop name. + /// + /// Name of the prop. + /// Type of the destination. + /// Index of the slave. + /// Index of the master. + void IFluentMap.Relation(string propName, Type destinationType, string[] slaveIndex, string[] masterIndex) + { + if (TypeHelper.IsSameOrParent(typeof(IEnumerable), destinationType)) + { + destinationType = destinationType.GetGenericArguments().Single(); + } + var member = this.GetMemberExtension(propName); + AttributeExtensionCollection attrs; + if (!member.Attributes.TryGetValue(TypeExtension.NodeName.Relation, out attrs)) + { + attrs = new AttributeExtensionCollection(); + member.Attributes.Add(TypeExtension.NodeName.Relation, attrs); + } + attrs.Clear(); + var attributeExtension = new AttributeExtension(); + attributeExtension.Values.Add(TypeExtension.AttrName.DestinationType, destinationType.AssemblyQualifiedName); + attrs.Add(attributeExtension); + + FillRelationIndex(slaveIndex, attributeExtension, TypeExtension.NodeName.SlaveIndex); + FillRelationIndex(masterIndex, attributeExtension, TypeExtension.NodeName.MasterIndex); + this.EachChilds(m => m.Relation(propName, destinationType, slaveIndex, masterIndex)); + } + + /// + /// Inheritances the mapping. + /// + /// The type. + /// The code. + /// The is default. + void IFluentMap.InheritanceMapping(Type type, object code, bool? isDefault) + { + AttributeExtensionCollection extList; + if (!this._typeExtension.Attributes.TryGetValue(Attributes.InheritanceMapping.Name, out extList)) + { + extList = new AttributeExtensionCollection(); + this._typeExtension.Attributes.Add(Attributes.InheritanceMapping.Name, extList); + } + var attr = new AttributeExtension(); + attr.Values.Add(Attributes.InheritanceMapping.Type, type.AssemblyQualifiedName); + if (null != code) + { + attr.Values.Add(Attributes.InheritanceMapping.Code, code); + } + if (null != isDefault) + { + attr.Values.Add(Attributes.InheritanceMapping.IsDefault, isDefault.Value); + } + extList.Add(attr); + this.EachChilds(m => m.InheritanceMapping(type,code,isDefault)); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Fluent/FluentMap.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Fluent/FluentMap.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,686 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; +using BLToolkit.Reflection.Extension; + +namespace BLToolkit.Mapping.Fluent +{ + /// + /// FluentSettings + /// + /// + public partial class FluentMap + { + private readonly TypeExtension _typeExtension; + private List _childs; + private const string MemberNameSeparator = "."; + + /// + /// ctor + /// + public FluentMap() + : this(new TypeExtension { Name = typeof(T).FullName }, null) + { } + + /// + /// ctor + /// + /// + /// + protected FluentMap(TypeExtension typeExtension, List childs) + { + this._typeExtension = typeExtension; + this._childs = childs; + + if (FluentConfig.MappingConfigurator.GetTableName != null) + { + this.TableName(null, null, FluentConfig.MappingConfigurator.GetTableName(typeof(T))); + } + } + + /// + /// TableNameAttribute + /// + /// + /// + public FluentMap TableName(string name) + { + return this.TableName(null, null, name); + } + + /// + /// TableNameAttribute + /// + /// + /// + /// + public FluentMap TableName(string database, string name) + { + return this.TableName(database, null, name); + } + + /// + /// TableNameAttribute + /// + /// + /// + /// + /// + public FluentMap TableName(string database, string owner, string name) + { + ((IFluentMap)this).TableName(database, owner, name); + return this; + } + + /// + /// MapFieldAttribute + /// + /// + /// + /// + /// + public MapFieldMap MapField(Expression> prop, bool isInheritanceDiscriminator) + { + return this.MapField(prop, null, null, isInheritanceDiscriminator); + } + + /// + /// MapFieldAttribute + /// + /// + /// + /// + /// + /// + /// + public MapFieldMap MapField(Expression> prop, string mapName = null, string storage = null, bool? isInheritanceDiscriminator = null) + { + string name = this.GetExprName(prop); + + if (mapName == null && FluentConfig.MappingConfigurator.GetColumnName != null) + { + mapName = FluentConfig.MappingConfigurator.GetColumnName(new MappedProperty { Name = name, Type = typeof(TR), ParentType = typeof(T) }); + } + + ((IFluentMap)this).MapField(name, mapName, storage, isInheritanceDiscriminator); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + private void MapFieldOnType(string origName, string mapName) + { + AttributeExtensionCollection attrs; + if (!this._typeExtension.Attributes.TryGetValue(Attributes.MapField.Name, out attrs)) + { + attrs = new AttributeExtensionCollection(); + this._typeExtension.Attributes.Add(Attributes.MapField.Name, attrs); + } + var attributeExtension = new AttributeExtension(); + attributeExtension.Values.Add(Attributes.MapField.OrigName, origName); + attributeExtension.Values.Add(Attributes.MapField.MapName, mapName); + attrs.Add(attributeExtension); + } + + private void MapFieldOnField(string origName, string mapName, string storage, bool? isInheritanceDiscriminator) + { + var member = this.GetMemberExtension(origName); + if (!string.IsNullOrEmpty(mapName)) + { + member.Attributes.Add(Attributes.MapField.Name, mapName); + } + if (null != storage) + { + member.Attributes.Add(Attributes.MapField.Storage, storage); + } + if (null != isInheritanceDiscriminator) + { + member.Attributes.Add(Attributes.MapField.IsInheritanceDiscriminator, this.ToString(isInheritanceDiscriminator.Value)); + } + } + + /// + /// PrimaryKeyAttribute + /// + /// + /// + /// + /// + public MapFieldMap PrimaryKey(Expression> prop, int order = -1) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).PrimaryKey(name, order); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// NonUpdatableAttribute + /// + /// + public MapFieldMap NonUpdatable(Expression> prop) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).NonUpdatable(name); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// IdentityAttribute + /// + /// + /// + public MapFieldMap Identity(Expression> prop) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).Identity(name); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// SqlIgnoreAttribute + /// + /// + /// + /// + public MapFieldMap SqlIgnore(Expression> prop, bool ignore = true) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).SqlIgnore(name, ignore); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// MapIgnoreAttribute + /// + /// + /// + /// + public MapFieldMap MapIgnore(Expression> prop, bool ignore = true) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).MapIgnore(name, ignore); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// TrimmableAttribute + /// + /// + public MapFieldMap Trimmable(Expression> prop) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).Trimmable(name); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// MapValueAttribute + /// + /// + /// + /// + /// + /// + /// + /// + public MapFieldMap MapValue(Expression> prop, TR origValue, TV value, params TV[] values) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).MapValue(name, origValue, value, values); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// DefaultValueAttribute + /// + /// + /// + /// + public MapFieldMap DefaultValue(Expression> prop, TR value) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).DefaulValue(name, value); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// DbTypeAttribute + /// + /// + /// + /// + public MapFieldMap DbType(Expression> prop, DbType dbType) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).DbType(name, dbType); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// MemberMapperAttribute + /// + /// + /// + /// + public MapFieldMap MemberMapper(Expression> prop, Type memberMapperType) + { + return this.MemberMapper(prop, null, memberMapperType); + } + + /// + /// MemberMapperAttribute + /// + /// + /// + /// + /// + public MapFieldMap MemberMapper(Expression> prop, Type memberType, Type memberMapperType) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).MemberMapper(name, memberType, memberMapperType); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// NullableAttribute + /// + /// + /// + /// + public MapFieldMap Nullable(Expression> prop, bool isNullable = true) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).Nullable(name, isNullable); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// LazyInstanceAttribute + /// + /// + /// + /// + public MapFieldMap LazyInstance(Expression> prop, bool isLazy = true) + { + string name = this.GetExprName(prop); + if (!GetIsVirtual(prop)) + throw new Exception("Property wich uses LazyInstance needs to be virtual!"); + ((IFluentMap)this).LazyInstance(name, isLazy); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// NullValueAttribute + /// + /// + /// + /// + public MapFieldMap NullValue(Expression> prop, TR value) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).NullValue(name, value); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// AssociationAttribute + /// + /// + /// + /// + /// + /// + /// + /// + public MapFieldMap.AssociationMap Association(Expression> prop, bool canBeNull, Expression> thisKey, params Expression>[] thisKeys) + { + var keys = new List>>(thisKeys); + keys.Insert(0, thisKey); + return new MapFieldMap.AssociationMap(new MapFieldMap(this._typeExtension, this.Childs, prop), canBeNull, keys); + } + + /// + /// AssociationAttribute + /// + /// + /// + /// + /// + /// + /// + public MapFieldMap.AssociationMap Association(Expression> prop, Expression> thisKey, params Expression>[] thisKeys) + { + return this.Association(prop, true, thisKey, thisKeys); + } + + protected MapFieldMap Association(Expression> prop, bool canBeNull + , IEnumerable>> thisKeys, IEnumerable>> otherKeys) + { + string name = this.GetExprName(prop); + ((IFluentMap)this).Association(name, canBeNull, this.KeysToString(thisKeys.ToArray()), this.KeysToString(otherKeys.ToArray())); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + /// + /// Reverse on BLToolkit.Mapping.Association.ParseKeys() + /// + /// + /// + /// + /// + private string KeysToString(IEnumerable>> keys) + { + return keys.Select(this.GetExprName).Aggregate((s1, s2) => s1 + ", " + s2); + } + + /// + /// RelationAttribute + /// + /// + /// + /// + /// + /// + public MapFieldMap Relation(Expression> prop, string slaveIndex = null, string masterIndex = null) + { + return this.Relation(prop, new[] { slaveIndex }, new[] { masterIndex }); + } + + /// + /// RelationAttribute + /// + /// + /// + /// + /// + /// + public MapFieldMap Relation(Expression> prop, string[] slaveIndex, string[] masterIndex) + { + string name = this.GetExprName(prop); + + slaveIndex = (slaveIndex ?? new string[0]).Where(i => !string.IsNullOrEmpty(i)).ToArray(); + masterIndex = (masterIndex ?? new string[0]).Where(i => !string.IsNullOrEmpty(i)).ToArray(); + + Type destinationType = typeof(TR); + + ((IFluentMap)this).Relation(name, destinationType, slaveIndex, masterIndex); + return new MapFieldMap(this._typeExtension, this.Childs, prop); + } + + static void FillRelationIndex(string[] index, AttributeExtension attributeExtension, string indexName) + { + if (index.Any()) + { + var collection = new AttributeExtensionCollection(); + foreach (var s in index) + { + var ae = new AttributeExtension(); + ae.Values.Add(TypeExtension.AttrName.Name, s); + collection.Add(ae); + } + attributeExtension.Attributes.Add(indexName, collection); + } + } + + /// + /// MapValueAttribute + /// + /// + /// + /// + /// + /// + public FluentMap MapValue(Enum origValue, TV value, params TV[] values) + { + ((IFluentMap)this).MapValue(origValue, value, values); + return this; + } + + /// + /// MapValueAttribute + /// + /// + /// + /// + /// + /// + public FluentMap MapValue(object origValue, TV value, params TV[] values) + { + ((IFluentMap)this).MapValue(origValue, value, values); + return this; + } + + /// + /// MapFieldAttribute(isInheritanceDescriminator = true) + /// + /// + /// + /// + public FluentMap InheritanceField(Expression> prop) + { + return this.MapField(prop, true); + } + + /// + /// InheritanceMappingAttribute + /// + /// + /// + /// + public FluentMap InheritanceMapping(object code) + { + return this.InheritanceMapping(code, null); + } + + /// + /// InheritanceMappingAttribute + /// + /// + /// + /// + public FluentMap InheritanceMapping(bool isDefault) + { + return this.InheritanceMapping(null, isDefault); + } + + /// + /// InheritanceMappingAttribute + /// + /// + /// + /// + /// + public FluentMap InheritanceMapping(object code, bool? isDefault) + { + ((IFluentMap)this).InheritanceMapping(typeof(TC), code, isDefault); + return this; + } + + protected void FillMapValueExtension(AttributeNameCollection attributeCollection, TR origValue, TV value, TV[] values) + { + AttributeExtensionCollection list; + if (!attributeCollection.TryGetValue(Attributes.MapValue.Name, out list)) + { + list = new AttributeExtensionCollection(); + attributeCollection.Add(Attributes.MapValue.Name, list); + } + + var allValues = new List(values); + allValues.Insert(0, value); + var tvFullName = typeof(TV).FullName; + + foreach (var val in allValues) + { + var attributeExtension = new AttributeExtension(); + attributeExtension.Values.Add(Attributes.MapValue.OrigValue, origValue); + attributeExtension.Values.Add(TypeExtension.ValueName.Value, Convert.ToString(val)); + attributeExtension.Values.Add(TypeExtension.ValueName.Value + TypeExtension.ValueName.TypePostfix, tvFullName); + list.Add(attributeExtension); + } + } + + protected void FillMemberMapperExtension(AttributeNameCollection attributeCollection, Type memberType, Type memberMapperType) + { + AttributeExtensionCollection attrs; + if (!attributeCollection.TryGetValue(Attributes.MemberMapper.Name, out attrs)) + { + attrs = new AttributeExtensionCollection(); + attributeCollection.Add(Attributes.MemberMapper.Name, attrs); + } + var attributeExtension = new AttributeExtension(); + attributeExtension.Values.Add(Attributes.MemberMapper.MemberType, memberType); + attributeExtension.Values.Add(Attributes.MemberMapper.MemberMapperType, memberMapperType); + attrs.Add(attributeExtension); + } + + /// + /// Fluent settings result + /// + /// + public ExtensionList Map() + { + var result = new ExtensionList(); + this.MapTo(result); + return result; + } + + /// + /// Apply fluent settings to DbManager + /// + /// + public void MapTo(DbManager dbManager) + { + var ms = dbManager.MappingSchema ?? (dbManager.MappingSchema = Mapping.Map.DefaultSchema); + this.MapTo(ms); + } + + /// + /// Apply fluent settings to DataProviderBase + /// + /// + public void MapTo(DataProviderBase dataProvider) + { + var ms = dataProvider.MappingSchema ?? (dataProvider.MappingSchema = Mapping.Map.DefaultSchema); + this.MapTo(ms); + } + + /// + /// Apply fluent settings to MappingSchema + /// + /// + public void MapTo(MappingSchema mappingSchema) + { + var extensions = mappingSchema.Extensions ?? (mappingSchema.Extensions = new ExtensionList()); + this.MapTo(extensions); + } + + /// + /// Apply fluent settings to ExtensionList + /// + /// + public void MapTo(ExtensionList extensions) + { + var ext = this._typeExtension; + TypeExtension oldExt; + if (extensions.TryGetValue(ext.Name, out oldExt)) + { + FluentMapHelper.MergeExtensions(ext, ref oldExt); + } + else + { + extensions.Add(ext); + } + this.EachChilds(m => m.MapTo(extensions)); + } + + protected MemberExtension GetMemberExtension(Expression> prop) + { + string name = this.GetExprName(prop); + return this.GetMemberExtension(name); + } + + protected MemberExtension GetMemberExtension(string name) + { + MemberExtension member; + if (!this._typeExtension.Members.TryGetValue(name, out member)) + { + member = new MemberExtension { Name = name }; + this._typeExtension.Members.Add(member); + } + return member; + } + + private string GetExprName(Expression> prop) + { + string result = null; + var memberExpression = prop.Body as MemberExpression; + while (null != memberExpression) + { + result = null == result ? "" : MemberNameSeparator + result; + result = memberExpression.Member.Name + result; + memberExpression = memberExpression.Expression as MemberExpression; + } + if (null == result) + { + throw new ArgumentException("Fail member access expression."); + } + return result; + } + + static bool GetIsVirtual(Expression> prop) + { + var memberExpression = prop.Body as MemberExpression; + if (memberExpression != null) + { + var prpInfo = memberExpression.Member as PropertyInfo; + if (prpInfo != null && !prpInfo.GetGetMethod().IsVirtual) + { + return false; + } + } + + return true; + } + + /// + /// Invert for BLToolkit.Reflection.Extension.TypeExtension.ToBoolean() + /// + /// + /// + protected string ToString(bool value) + { + return Convert.ToString(value); + } + + private void EachChilds(Action action) + { + foreach (var childMap in this.Childs) + { + action(childMap); + } + } + + private List Childs + { + get + { + if (null == this._childs) + { + this._childs = new List(); + var thisType = typeof(T); + var fmType = typeof(FluentMap<>); + // Find child only first generation ... other generation find recursive + foreach (var childType in thisType.Assembly.GetTypes().Where(t => t.BaseType == thisType)) + { + this._childs.Add((IFluentMap)Activator.CreateInstance(fmType.MakeGenericType(childType))); + } + } + return this._childs; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Fluent/FluentMapHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Fluent/FluentMapHelper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,72 @@ +using BLToolkit.Reflection.Extension; + +namespace BLToolkit.Mapping.Fluent +{ + public static class FluentMapHelper + { + public static void MergeExtensions(ExtensionList fromExt, ref ExtensionList toExt) + { + foreach (var kv in fromExt) + { + TypeExtension toType; + if (toExt.TryGetValue(kv.Key, out toType)) + { + MergeExtensions(kv.Value, ref toType); + } + else + { + toExt.Add(kv.Key, kv.Value); + } + } + } + + public static void MergeExtensions(TypeExtension fromExt, ref TypeExtension toExt) + { + if (ReferenceEquals(fromExt, toExt)) + { + return; + } + foreach (var attribute in fromExt.Attributes) + { + AttributeExtensionCollection attrs; + if (toExt.Attributes.TryGetValue(attribute.Key, out attrs)) + { + MergeExtensions(attribute.Value, ref attrs); + } + else + { + toExt.Attributes.Add(attribute.Key, attribute.Value); + } + } + foreach (var member in fromExt.Members) + { + MemberExtension value; + if (toExt.Members.TryGetValue(member.Key, out value)) + { + MergeExtensions(member.Value, ref value); + } + else + { + toExt.Members.Add(member.Key, member.Value); + } + } + } + + private static void MergeExtensions(MemberExtension fromExt, ref MemberExtension toExt) + { + foreach (var attribute in fromExt.Attributes) + { + if (toExt.Attributes.ContainsKey(attribute.Key)) + { + toExt.Attributes.Remove(attribute.Key); + } + toExt.Attributes.Add(attribute.Key, attribute.Value); + } + } + + private static void MergeExtensions(AttributeExtensionCollection fromExt, ref AttributeExtensionCollection toExt) + { + toExt.AddRange(fromExt); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Fluent/IFluentMap.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Fluent/IFluentMap.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,179 @@ +using System; +using System.Data; + +using BLToolkit.Reflection.Extension; + +namespace BLToolkit.Mapping.Fluent +{ + /// + /// Interface fluent mapping + /// + public interface IFluentMap + { + /// + /// Get mapping + /// + /// + ExtensionList Map(); + + /// + /// TableNameAttribute + /// + /// + /// + /// + /// + void TableName(string database, string owner, string name); + + /// + /// Map to ExtensionList + /// + /// + void MapTo(ExtensionList extensions); + + /// + /// Maps the field. + /// + /// Name of the prop. + /// Name of the map. + /// The storage. + /// The is inheritance discriminator. + /// + void MapField(string propName, string mapName, string storage, bool? isInheritanceDiscriminator); + + /// + /// Primaries the key. + /// + /// Name of the prop. + /// The order. + void PrimaryKey(string propName, int order); + + /// + /// Nons the updatable. + /// + /// Name of the prop. + void NonUpdatable(string propName); + + /// + /// Identities the specified prop name. + /// + /// Name of the prop. + void Identity(string propName); + + /// + /// SQLs the ignore. + /// + /// Name of the prop. + /// if set to true [ignore]. + void SqlIgnore(string propName, bool ignore); + + /// + /// Maps the ignore. + /// + /// Name of the prop. + /// if set to true [ignore]. + void MapIgnore(string propName, bool ignore); + + /// + /// Trimmables the specified prop name. + /// + /// Name of the prop. + void Trimmable(string propName); + + /// + /// Maps the value. + /// + /// The type of the R. + /// The type of the V. + /// Name of the prop. + /// The orig value. + /// The value. + /// The values. + void MapValue(string propName, TR origValue, TV value, TV[] values); + + /// + /// Maps the value. + /// + /// The type of the V. + /// The orig value. + /// The value. + /// The values. + void MapValue(Enum origValue, TV value, TV[] values); + + /// + /// Maps the value. + /// + /// The type of the V. + /// The orig value. + /// The value. + /// The values. + void MapValue(object origValue, TV value, TV[] values); + + /// + /// Defauls the value. + /// + /// The type of the R. + /// Name of the prop. + /// The value. + void DefaulValue(string propName, TR value); + + /// + /// Defauls the value. + /// + /// The type of the R. + /// Name of the prop. + /// The value. + void DbType(string propName, DbType value); + + /// + /// MemberMapper + /// + /// The type of the R. + /// Name of the prop. + /// The value. + void MemberMapper(string propName, Type memberType, Type memberMapperType); + + /// + /// Nullables the specified prop name. + /// + /// Name of the prop. + /// if set to true [is nullable]. + void Nullable(string propName, bool isNullable); + + void LazyInstance(string propName, bool isLazy); + + /// + /// Nulls the value. + /// + /// The type of the R. + /// Name of the prop. + /// The value. + void NullValue(string propName, TR value); + + /// + /// Associations the specified prop name. + /// + /// Name of the prop. + /// if set to true [can be null]. + /// The this keys. + /// The other keys. + void Association(string propName, bool canBeNull, string thisKeys, string otherKeys); + + /// + /// Relations the specified prop name. + /// + /// Name of the prop. + /// Type of the destination. + /// Index of the slave. + /// Index of the master. + void Relation(string propName, Type destinationType, string[] slaveIndex, string[] masterIndex); + + /// + /// Inheritances the mapping. + /// + /// The type. + /// The code. + /// The is default. + void InheritanceMapping(Type type, object code, bool? isDefault); + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Fluent/MapFieldMap.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Fluent/MapFieldMap.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,218 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq.Expressions; + +using BLToolkit.Reflection.Extension; + +namespace BLToolkit.Mapping.Fluent +{ + /// + /// Fluent settings for field + /// + /// + /// + public partial class MapFieldMap : FluentMap + { + private readonly Expression> _prop; + + public MapFieldMap(TypeExtension owner, List childs, Expression> prop) + : base(owner, childs) + { + this._prop = prop; + } + + /// + /// PrimaryKeyAttribute + /// + /// + /// + /// + public MapFieldMap PrimaryKey(int order = -1) + { + return this.PrimaryKey(this._prop, order); + } + + public MapFieldMap LazyInstance(bool isLazy = true) + { + return this.LazyInstance(this._prop, isLazy); + } + + + /// + /// NonUpdatableAttribute + /// + /// + public MapFieldMap NonUpdatable() + { + return this.NonUpdatable(this._prop); + } + + /// + /// IdentityAttribute + /// + /// + /// + public MapFieldMap Identity() + { + return this.Identity(this._prop); + } + + /// + /// SqlIgnoreAttribute + /// + /// + /// + public MapFieldMap SqlIgnore(bool ignore = true) + { + return this.SqlIgnore(this._prop, ignore); + } + + /// + /// MapIgnoreAttribute + /// + /// + /// + public MapFieldMap MapIgnore(bool ignore = true) + { + return this.MapIgnore(this._prop, ignore); + } + + /// + /// TrimmableAttribute + /// + /// + public MapFieldMap Trimmable() + { + return this.Trimmable(this._prop); + } + + /// + /// MapValueAttribute + /// + /// + /// + /// + /// + /// + public MapFieldMap MapValue(TR origValue, TV value, params TV[] values) + { + return this.MapValue(this._prop, origValue, value, values); + } + + /// + /// DefaultValueAttribute + /// + /// + /// + public MapFieldMap DefaultValue(TR value) + { + return this.DefaultValue(this._prop, value); + } + + /// + /// DbTypeAttribute + /// + /// + /// + public MapFieldMap DbType(DbType dbType) + { + return this.DbType(this._prop, dbType); + } + + /// + /// MemberMapperAttribute + /// at the Moment you also have to specify MapIgnore(false) when using Complex types with Member Mapper. + /// + /// + /// + public MapFieldMap MemberMapper(Type memberMapperType) + { + return this.MemberMapper(this._prop, memberMapperType); + } + + /// + /// MemberMapperAttribute + /// at the Moment you also have to specify MapIgnore(false) when using Complex types with Member Mapper. + /// + /// + /// + public MapFieldMap MemberMapper(Type memberType, Type memberMapperType) + { + return this.MemberMapper(this._prop, memberType, memberMapperType); + } + + /// + /// NullableAttribute + /// + /// + /// + public MapFieldMap Nullable(bool isNullable = true) + { + return this.Nullable(this._prop, isNullable); + } + + /// + /// NullValueAttribute + /// + /// + /// + public MapFieldMap NullValue(TR value) + { + return this.NullValue(this._prop, value); + } + + /// + /// AssociationAttribute + /// + /// + /// + /// + /// + /// + public AssociationMap Association(bool canBeNull, Expression> thisKey, params Expression>[] thisKeys) + { + return this.Association(this._prop, canBeNull, thisKey, thisKeys); + } + + /// + /// AssociationAttribute + /// + /// + /// + /// + /// + public AssociationMap Association(Expression> thisKey, params Expression>[] thisKeys) + { + return this.Association(this._prop, thisKey, thisKeys); + } + + private MapFieldMap Association(bool canBeNull + , IEnumerable>> thisKeys, IEnumerable>> otherKeys) + { + return this.Association(this._prop, canBeNull, thisKeys, otherKeys); + } + + /// + /// RelationAttribute + /// + /// + /// + /// + public MapFieldMap Relation(string slaveIndex = null, string masterIndex = null) + { + return this.Relation(this._prop, slaveIndex, masterIndex); + } + + /// + /// RelationAttribute + /// + /// + /// + /// + public MapFieldMap Relation(string[] slaveIndex, string[] masterIndex) + { + return this.Relation(this._prop, slaveIndex, masterIndex); + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Fluent/MappedProperty.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Fluent/MappedProperty.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BLToolkit.Mapping.Fluent +{ + public class MappedProperty + { + public string Name { get; internal set; } + public Type Type { get; internal set; } + public Type ParentType { get; internal set; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/IMapDataDestination.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/IMapDataDestination.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,87 @@ +using System; +using System.Data.SqlTypes; + +namespace BLToolkit.Mapping +{ + [CLSCompliant(false)] + public interface IMapDataDestination + { + Type GetFieldType (int index); + int GetOrdinal (string name); + void SetValue (object o, int index, object value); + void SetValue (object o, string name, object value); + + void SetNull (object o, int index); + + bool SupportsTypedValues(int index); + + // Simple type setters. + // + [CLSCompliant(false)] + void SetSByte (object o, int index, SByte value); + void SetInt16 (object o, int index, Int16 value); + void SetInt32 (object o, int index, Int32 value); + void SetInt64 (object o, int index, Int64 value); + + void SetByte (object o, int index, Byte value); + [CLSCompliant(false)] + void SetUInt16 (object o, int index, UInt16 value); + [CLSCompliant(false)] + void SetUInt32 (object o, int index, UInt32 value); + [CLSCompliant(false)] + void SetUInt64 (object o, int index, UInt64 value); + + void SetBoolean (object o, int index, Boolean value); + void SetChar (object o, int index, Char value); + void SetSingle (object o, int index, Single value); + void SetDouble (object o, int index, Double value); + void SetDecimal (object o, int index, Decimal value); + void SetGuid (object o, int index, Guid value); + void SetDateTime (object o, int index, DateTime value); + void SetDateTimeOffset(object o, int index, DateTimeOffset value); + + // Simple type setters. + // + [CLSCompliant(false)] + void SetNullableSByte (object o, int index, SByte? value); + void SetNullableInt16 (object o, int index, Int16? value); + void SetNullableInt32 (object o, int index, Int32? value); + void SetNullableInt64 (object o, int index, Int64? value); + + void SetNullableByte (object o, int index, Byte? value); + [CLSCompliant(false)] + void SetNullableUInt16 (object o, int index, UInt16? value); + [CLSCompliant(false)] + void SetNullableUInt32 (object o, int index, UInt32? value); + [CLSCompliant(false)] + void SetNullableUInt64 (object o, int index, UInt64? value); + + void SetNullableBoolean (object o, int index, Boolean? value); + void SetNullableChar (object o, int index, Char? value); + void SetNullableSingle (object o, int index, Single? value); + void SetNullableDouble (object o, int index, Double? value); + void SetNullableDecimal (object o, int index, Decimal? value); + void SetNullableGuid (object o, int index, Guid? value); + void SetNullableDateTime (object o, int index, DateTime? value); + void SetNullableDateTimeOffset(object o, int index, DateTimeOffset? value); + +#if !SILVERLIGHT + + // SQL type setters. + // + void SetSqlByte (object o, int index, SqlByte value); + void SetSqlInt16 (object o, int index, SqlInt16 value); + void SetSqlInt32 (object o, int index, SqlInt32 value); + void SetSqlInt64 (object o, int index, SqlInt64 value); + void SetSqlSingle (object o, int index, SqlSingle value); + void SetSqlBoolean (object o, int index, SqlBoolean value); + void SetSqlDouble (object o, int index, SqlDouble value); + void SetSqlDateTime(object o, int index, SqlDateTime value); + void SetSqlDecimal (object o, int index, SqlDecimal value); + void SetSqlMoney (object o, int index, SqlMoney value); + void SetSqlGuid (object o, int index, SqlGuid value); + void SetSqlString (object o, int index, SqlString value); + +#endif + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/IMapDataDestinationList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/IMapDataDestinationList.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +using System; + +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + [CLSCompliant(false)] + public interface IMapDataDestinationList + { + void InitMapping (InitContext initContext); + [CLSCompliant(false)] + IMapDataDestination GetDataDestination(InitContext initContext); + object GetNextObject (InitContext initContext); + void EndMapping (InitContext initContext); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/IMapDataSource.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/IMapDataSource.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,93 @@ +using System; + +#if !SILVERLIGHT +using System.Data.SqlTypes; +#endif + +namespace BLToolkit.Mapping +{ + [CLSCompliant(false)] + public interface IMapDataSource + { + int Count { get; } + + Type GetFieldType (int index); + string GetName (int index); + int GetOrdinal (string name); + object GetValue (object o, int index); + object GetValue (object o, string name); + + bool IsNull (object o, int index); + + bool SupportsTypedValues(int index); + + // Simple type getters. + // + [CLSCompliant(false)] + SByte GetSByte (object o, int index); + Int16 GetInt16 (object o, int index); + Int32 GetInt32 (object o, int index); + Int64 GetInt64 (object o, int index); + + Byte GetByte (object o, int index); + [CLSCompliant(false)] + UInt16 GetUInt16 (object o, int index); + [CLSCompliant(false)] + UInt32 GetUInt32 (object o, int index); + [CLSCompliant(false)] + UInt64 GetUInt64 (object o, int index); + + Boolean GetBoolean (object o, int index); + Char GetChar (object o, int index); + Single GetSingle (object o, int index); + Double GetDouble (object o, int index); + Decimal GetDecimal (object o, int index); + DateTime GetDateTime (object o, int index); + DateTimeOffset GetDateTimeOffset(object o, int index); + Guid GetGuid (object o, int index); + + // Simple type getters. + // + [CLSCompliant(false)] + SByte? GetNullableSByte (object o, int index); + Int16? GetNullableInt16 (object o, int index); + Int32? GetNullableInt32 (object o, int index); + Int64? GetNullableInt64 (object o, int index); + + Byte? GetNullableByte (object o, int index); + [CLSCompliant(false)] + UInt16? GetNullableUInt16 (object o, int index); + [CLSCompliant(false)] + UInt32? GetNullableUInt32 (object o, int index); + [CLSCompliant(false)] + UInt64? GetNullableUInt64 (object o, int index); + + Boolean? GetNullableBoolean (object o, int index); + Char? GetNullableChar (object o, int index); + Single? GetNullableSingle (object o, int index); + Double? GetNullableDouble (object o, int index); + Decimal? GetNullableDecimal (object o, int index); + DateTime? GetNullableDateTime(object o, int index); + DateTimeOffset? GetNullableDateTimeOffset(object o, int index); + Guid? GetNullableGuid (object o, int index); + +#if !SILVERLIGHT + + // SQL type getters. + // + SqlByte GetSqlByte (object o, int index); + SqlInt16 GetSqlInt16 (object o, int index); + SqlInt32 GetSqlInt32 (object o, int index); + SqlInt64 GetSqlInt64 (object o, int index); + SqlSingle GetSqlSingle (object o, int index); + SqlBoolean GetSqlBoolean (object o, int index); + SqlDouble GetSqlDouble (object o, int index); + SqlDateTime GetSqlDateTime (object o, int index); + SqlDecimal GetSqlDecimal (object o, int index); + SqlMoney GetSqlMoney (object o, int index); + SqlGuid GetSqlGuid (object o, int index); + SqlString GetSqlString (object o, int index); + +#endif + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/IMapDataSourceList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/IMapDataSourceList.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public interface IMapDataSourceList + { + void InitMapping (InitContext initContext); + bool SetNextDataSource(InitContext initContext); + void EndMapping (InitContext initContext); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/IMappingSchemaProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/IMappingSchemaProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.Mapping +{ + public interface IMappingSchemaProvider + { + MappingSchema MappingSchema { get; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/ISupportMapping.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/ISupportMapping.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public interface ISupportMapping + { + void BeginMapping(InitContext initContext); + void EndMapping (InitContext initContext); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/IValueMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/IValueMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using System; + +namespace BLToolkit.Mapping +{ + [CLSCompliant(false)] + public interface IValueMapper + { + void Map( + IMapDataSource source, object sourceObject, int sourceIndex, + IMapDataDestination dest, object destObject, int destIndex); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/InheritanceMappingAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/InheritanceMappingAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using System; + +namespace BLToolkit.Mapping +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple=true)] + public class InheritanceMappingAttribute : Attribute + { + object _code; public object Code { get { return _code; } set { _code = value; } } + bool _isDefault; public bool IsDefault { get { return _isDefault; } set { _isDefault = value; } } + Type _type; public Type Type { get { return _type; } set { _type = value; } } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Map.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Map.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1021 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; + +namespace BLToolkit.Mapping +{ + using Common; + using Reflection; + using Reflection.Extension; + + public class Map + { + #region Public Members + + private static MappingSchema _defaultSchema = new DefaultMappingSchema(); + public static MappingSchema DefaultSchema + { + [System.Diagnostics.DebuggerStepThrough] + get { return _defaultSchema; } + set { _defaultSchema = value; } + } + + public static ExtensionList Extensions + { + [System.Diagnostics.DebuggerStepThrough] + get { return _defaultSchema.Extensions; } + set { _defaultSchema.Extensions = value; } + } + + public static ObjectMapper GetObjectMapper(Type type) + { + return _defaultSchema.GetObjectMapper(type); + } + + #endregion + + #region GetNullValue + + public static object GetNullValue(Type type) + { + return _defaultSchema.GetNullValue(type); + } + + public static bool IsNull(object value) + { + return _defaultSchema.IsNull(value); + } + + #endregion + + #region Base Mapping + + public static void SourceToDestination(object sourceObject, object destObject, params object[] parameters) + { + _defaultSchema.MapSourceToDestination(sourceObject, destObject, parameters); + } + + [CLSCompliant(false)] + public static void MapSourceToDestination( + IMapDataSource source, object sourceObject, + IMapDataDestination dest, object destObject, + params object[] parameters) + { + _defaultSchema.MapSourceToDestination(source, sourceObject, dest, destObject, parameters); + } + + [CLSCompliant(false)] + public static void SourceListToDestinationList( + IMapDataSourceList dataSourceList, + IMapDataDestinationList dataDestinationList, + params object[] parameters) + { + _defaultSchema.MapSourceListToDestinationList(dataSourceList, dataDestinationList, parameters); + } + + #endregion + + #region ValueToEnum, EnumToValue + + public static object ValueToEnum(object value, Type type) + { + return _defaultSchema.MapValueToEnum(value, type); + } + + public static object EnumToValue(object value) + { + return _defaultSchema.MapEnumToValue(value); + } + + public static object EnumToValue(object value, bool convertToUnderlyingType) + { + return _defaultSchema.MapEnumToValue(value, convertToUnderlyingType); + } + + public static T ToEnum(object value) + { + return (T)_defaultSchema.MapValueToEnum(value, typeof(T)); + } + + #endregion + + #region Object + + #region ObjectToObject + + public static object ObjectToObject(object sourceObject, object destObject, params object[] parameters) + { + return _defaultSchema.MapObjectToObject(sourceObject, destObject, parameters); + } + + public static object ObjectToObject(object sourceObject, Type destObjectType, params object[] parameters) + { + return _defaultSchema.MapObjectToObject(sourceObject, destObjectType, parameters); + } + + public static T ObjectToObject(object sourceObject, params object[] parameters) + { + return (T)_defaultSchema.MapObjectToObject(sourceObject, typeof(T), parameters); + } + + #endregion + + #region ObjectToDataRow + +#if !SILVERLIGHT + + public static DataRow ObjectToDataRow(object sourceObject, DataRow destRow) + { + return _defaultSchema.MapObjectToDataRow(sourceObject, destRow); + } + + public static DataRow ObjectToDataRow(object sourceObject, DataTable destTable) + { + return _defaultSchema.MapObjectToDataRow(sourceObject, destTable); + } + +#endif + + #endregion + + #region ObjectToDictionary + + public static IDictionary ObjectToDictionary(object sourceObject, IDictionary destDictionary) + { + return _defaultSchema.MapObjectToDictionary(sourceObject, destDictionary); + } + + public static IDictionary ObjectToDictionary(object sourceObject) + { + return _defaultSchema.MapObjectToDictionary(sourceObject); + } + + #endregion + + #endregion + + #region DataRow + + #region DataRowToObject + +#if !SILVERLIGHT + + public static object DataRowToObject(DataRow dataRow, object destObject, params object[] parameters) + { + return _defaultSchema.MapDataRowToObject(dataRow, destObject, parameters); + } + + public static object DataRowToObject( + DataRow dataRow, DataRowVersion version, object destObject, params object[] parameters) + { + return _defaultSchema.MapDataRowToObject(dataRow, version, destObject, parameters); + } + + public static object DataRowToObject(DataRow dataRow, Type destObjectType, params object[] parameters) + { + return _defaultSchema.MapDataRowToObject(dataRow, destObjectType, parameters); + } + + public static object DataRowToObject( + DataRow dataRow, DataRowVersion version, Type destObjectType, params object[] parameters) + { + return _defaultSchema.MapDataRowToObject(dataRow, version, destObjectType, parameters); + } + + public static T DataRowToObject(DataRow dataRow, params object[] parameters) + { + return (T)_defaultSchema.MapDataRowToObject(dataRow, typeof(T), parameters); + } + + public static T DataRowToObject(DataRow dataRow, DataRowVersion version, params object[] parameters) + { + return (T)_defaultSchema.MapDataRowToObject(dataRow, version, typeof(T), parameters); + } + +#endif + + #endregion + + #region DataRowToDataRow + +#if !SILVERLIGHT + + public static DataRow DataRowToDataRow(DataRow sourceRow, DataRow destRow) + { + return _defaultSchema.MapDataRowToDataRow(sourceRow, destRow); + } + + public static DataRow DataRowToDataRow(DataRow sourceRow, DataRowVersion version, DataRow destRow) + { + return _defaultSchema.MapDataRowToDataRow(sourceRow, version, destRow); + } + + public static DataRow DataRowToDataRow(DataRow sourceRow, DataTable destTable) + { + return _defaultSchema.MapDataRowToDataRow(sourceRow, destTable); + } + + public static DataRow DataRowToDataRow(DataRow sourceRow, DataRowVersion version, DataTable destTable) + { + return _defaultSchema.MapDataRowToDataRow(sourceRow, version, destTable); + } + +#endif + + #endregion + + #region DataRowToDictionary + +#if !SILVERLIGHT + + public static IDictionary DataRowToDictionary(DataRow sourceRow, IDictionary destDictionary) + { + return _defaultSchema.MapDataRowToDictionary(sourceRow, destDictionary); + } + + public static Hashtable DataRowToDictionary(DataRow sourceRow) + { + return _defaultSchema.MapDataRowToDictionary(sourceRow); + } + + public static IDictionary DataRowToDictionary( + DataRow sourceRow, DataRowVersion version, IDictionary destDictionary) + { + return _defaultSchema.MapDataRowToDictionary(sourceRow, version, destDictionary); + } + + public static Hashtable DataRowToDictionary(DataRow sourceRow, DataRowVersion version) + { + return _defaultSchema.MapDataRowToDictionary(sourceRow, version); + } + +#endif + + #endregion + + #endregion + + #region DataReader + + #region DataReaderToObject + + public static object DataReaderToObject(IDataReader dataReader, object destObject, params object[] parameters) + { + return _defaultSchema.MapDataReaderToObject(dataReader, destObject, parameters); + } + + public static object DataReaderToObject(IDataReader dataReader, Type destObjectType, params object[] parameters) + { + return _defaultSchema.MapDataReaderToObject(dataReader, destObjectType, parameters); + } + + public static T DataReaderToObject(IDataReader dataReader, params object[] parameters) + { + return (T)_defaultSchema.MapDataReaderToObject(dataReader, typeof(T), parameters); + } + + #endregion + + #region DataReaderToDataRow + +#if !SILVERLIGHT + + public static DataRow DataReaderToDataRow(IDataReader dataReader, DataRow destRow) + { + return _defaultSchema.MapDataReaderToDataRow(dataReader, destRow); + } + + public static DataRow DataReaderToDataRow(IDataReader dataReader, DataTable destTable) + { + return _defaultSchema.MapDataReaderToDataRow(dataReader, destTable); + } + +#endif + + #endregion + + #region DataReaderToDictionary + + public static IDictionary DataReaderToDictionary(IDataReader dataReader, IDictionary destDictionary) + { + return _defaultSchema.MapDataReaderToDictionary(dataReader, destDictionary); + } + + public static IDictionary DataReaderToDictionary(IDataReader dataReader) + { + return _defaultSchema.MapDataReaderToDictionary(dataReader); + } + + #endregion + + #endregion + + #region Dictionary + + #region DictionaryToObject + + public static object DictionaryToObject( + IDictionary sourceDictionary, object destObject, params object[] parameters) + { + return _defaultSchema.MapDictionaryToObject(sourceDictionary, destObject, parameters); + } + + public static object DictionaryToObject( + IDictionary sourceDictionary, Type destObjectType, params object[] parameters) + { + return _defaultSchema.MapDictionaryToObject(sourceDictionary, destObjectType, parameters); + } + + public static T DictionaryToObject(IDictionary sourceDictionary, params object[] parameters) + { + return (T)_defaultSchema.MapDictionaryToObject(sourceDictionary, typeof(T), parameters); + } + + #endregion + + #region DictionaryToDataRow + +#if !SILVERLIGHT + + public static DataRow DictionaryToDataRow(IDictionary sourceDictionary, DataRow destRow) + { + return _defaultSchema.MapDictionaryToDataRow(sourceDictionary, destRow); + } + + public static DataRow DictionaryToDataRow(IDictionary sourceDictionary, DataTable destTable) + { + return _defaultSchema.MapDictionaryToDataRow(sourceDictionary, destTable); + } + +#endif + + #endregion + + #endregion + + #region List + + #region ListToList + + public static IList ListToList( + ICollection sourceList, + IList destList, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapListToList(sourceList, destList, destObjectType, parameters); + } + + public static IList ListToList(ICollection sourceList, Type destObjectType, params object[] parameters) + { + return _defaultSchema.MapListToList(sourceList, destObjectType, parameters); + } + + public static List ListToList(ICollection sourceList, List destList, params object[] parameters) + { + return _defaultSchema.MapListToList(sourceList, destList, parameters); + } + + public static List ListToList(ICollection sourceList, params object[] parameters) + { + return _defaultSchema.MapListToList(sourceList, parameters); + } + + #endregion + + #region ListToDataTable + +#if !SILVERLIGHT + + public static DataTable ListToDataTable(ICollection sourceList, DataTable destTable) + { + return _defaultSchema.MapListToDataTable(sourceList, destTable); + } + + public static DataTable ListToDataTable(ICollection sourceList) + { + return _defaultSchema.MapListToDataTable(sourceList); + } + +#endif + + #endregion + + #region MapListToDictionary + + public static IDictionary ListToDictionary( + ICollection sourceList, + IDictionary destDictionary, + NameOrIndexParameter keyField, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapListToDictionary( + sourceList, destDictionary, keyField, destObjectType, parameters); + } + + public static IDictionary ListToDictionary( + ICollection sourceList, + NameOrIndexParameter keyField, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapListToDictionary(sourceList, keyField, destObjectType, parameters); + } + + public static IDictionary ListToDictionary( + ICollection sourceList, + IDictionary destDictionary, + NameOrIndexParameter keyField, + params object[] parameters) + { + return _defaultSchema.MapListToDictionary(sourceList, destDictionary, keyField, parameters); + } + + public static Dictionary ListToDictionary( + ICollection sourceList, + NameOrIndexParameter keyField, + params object[] parameters) + { + return _defaultSchema.MapListToDictionary(sourceList, keyField, parameters); + } + + #endregion + + #region MapListToDictionary (Index) + + public static IDictionary ListToDictionary( + ICollection sourceList, + IDictionary destDictionary, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapListToDictionary( + sourceList, destDictionary, index, destObjectType, parameters); + } + + public static IDictionary ListToDictionary( + ICollection sourceList, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapListToDictionary(sourceList, index, destObjectType, parameters); + } + + public static IDictionary ListToDictionary( + ICollection sourceList, + IDictionary destDictionary, + MapIndex index, + params object[] parameters) + { + return _defaultSchema.MapListToDictionary(sourceList, destDictionary, index, parameters); + } + + public static Dictionary ListToDictionary( + ICollection sourceList, + MapIndex index, + params object[] parameters) + { + return _defaultSchema.MapListToDictionary(sourceList, index, parameters); + } + + #endregion + + #endregion + + #region DataTable + + #region DataTableToDataTable + +#if !SILVERLIGHT + + public static DataTable DataTableToDataTable(DataTable sourceTable, DataTable destTable) + { + return _defaultSchema.MapDataTableToDataTable(sourceTable, destTable); + } + + public static DataTable DataTableToDataTable(DataTable sourceTable, DataRowVersion version, DataTable destTable) + { + return _defaultSchema.MapDataTableToDataTable(sourceTable, version, destTable); + } + + public static DataTable DataTableToDataTable(DataTable sourceTable) + { + return _defaultSchema.MapDataTableToDataTable(sourceTable); + } + + public static DataTable DataTableToDataTable(DataTable sourceTable, DataRowVersion version) + { + return _defaultSchema.MapDataTableToDataTable(sourceTable, version); + } + +#endif + + #endregion + + #region DataTableToList + +#if !SILVERLIGHT + + public static IList DataTableToList( + DataTable sourceTable, IList list, Type destObjectType, params object[] parameters) + { + return _defaultSchema.MapDataTableToList(sourceTable, list, destObjectType, parameters); + } + + public static IList DataTableToList( + DataTable sourceTable, + DataRowVersion version, + IList list, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDataTableToList(sourceTable, version, list, destObjectType, parameters); + } + + public static ArrayList DataTableToList(DataTable sourceTable, Type destObjectType, params object[] parameters) + { + return _defaultSchema.MapDataTableToList(sourceTable, destObjectType, parameters); + } + + public static ArrayList DataTableToList( + DataTable sourceTable, DataRowVersion version, Type destObjectType, params object[] parameters) + { + return _defaultSchema.MapDataTableToList(sourceTable, version, destObjectType, parameters); + } + + public static List DataTableToList(DataTable sourceTable, List list, params object[] parameters) + { + return _defaultSchema.MapDataTableToList(sourceTable, list, parameters); + } + + public static List DataTableToList( + DataTable sourceTable, + DataRowVersion version, + List list, + params object[] parameters) + { + return _defaultSchema.MapDataTableToList(sourceTable, version, list, parameters); + } + + public static List DataTableToList(DataTable sourceTable, params object[] parameters) + { + return _defaultSchema.MapDataTableToList(sourceTable, parameters); + } + + public static List DataTableToList(DataTable sourceTable, DataRowVersion version, params object[] parameters) + { + return _defaultSchema.MapDataTableToList(sourceTable, version, parameters); + } + +#endif + + #endregion + + #region DataTableToDictionary + +#if !SILVERLIGHT + + public static IDictionary DataTableToDictionary( + DataTable sourceTable, + IDictionary destDictionary, + NameOrIndexParameter keyField, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDataTableToDictionary( + sourceTable, destDictionary, keyField, destObjectType, parameters); + } + + public static Hashtable DataTableToDictionary( + DataTable sourceTable, + NameOrIndexParameter keyField, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDataTableToDictionary(sourceTable, keyField, destObjectType, parameters); + } + + public static IDictionary DataTableToDictionary( + DataTable sourceTable, + IDictionary destDictionary, + NameOrIndexParameter keyField, + params object[] parameters) + { + return _defaultSchema.MapDataTableToDictionary(sourceTable, destDictionary, keyField, parameters); + } + + public static Dictionary DataTableToDictionary( + DataTable sourceTable, + NameOrIndexParameter keyField, + params object[] parameters) + { + return _defaultSchema.MapDataTableToDictionary(sourceTable, keyField, parameters); + } + +#endif + + #endregion + + #region DataTableToDictionary (Index) + +#if !SILVERLIGHT + + public static IDictionary DataTableToDictionary( + DataTable sourceTable, + IDictionary destDictionary, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDataTableToDictionary( + sourceTable, destDictionary, index, destObjectType, parameters); + } + + public static Hashtable DataTableToDictionary( + DataTable sourceTable, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDataTableToDictionary(sourceTable, index, destObjectType, parameters); + } + + public static IDictionary DataTableToDictionary( + DataTable sourceTable, + IDictionary destDictionary, + MapIndex index, + params object[] parameters) + { + return _defaultSchema.MapDataTableToDictionary(sourceTable, destDictionary, index, parameters); + } + + public static Dictionary DataTableToDictionary( + DataTable sourceTable, + MapIndex index, + params object[] parameters) + { + return _defaultSchema.MapDataTableToDictionary(sourceTable, index, parameters); + } + +#endif + + #endregion + + #endregion + + #region DataReader + + #region DataReaderToList + + public static IList DataReaderToList( + IDataReader reader, + IList list, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDataReaderToList(reader, list, destObjectType, parameters); + } + + public static IList DataReaderToList(IDataReader reader, Type destObjectType, params object[] parameters) + { + return _defaultSchema.MapDataReaderToList(reader, destObjectType, parameters); + } + + public static IList DataReaderToList(IDataReader reader, IList list, params object[] parameters) + { + return _defaultSchema.MapDataReaderToList(reader, list, parameters); + } + + public static List DataReaderToList(IDataReader reader, params object[] parameters) + { + return _defaultSchema.MapDataReaderToList(reader, parameters); + } + + #endregion + + #region DataReaderToDataTable + +#if !SILVERLIGHT + + public static DataTable DataReaderToDataTable(IDataReader reader, DataTable destTable) + { + return _defaultSchema.MapDataReaderToDataTable(reader, destTable); + } + + public static DataTable DataReaderToDataTable(IDataReader reader) + { + return _defaultSchema.MapDataReaderToDataTable(reader); + } + +#endif + + #endregion + + #region DataReaderToDictionary + + public static IDictionary DataReaderToDictionary( + IDataReader dataReader, + IDictionary destDictionary, + NameOrIndexParameter keyField, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDataReaderToDictionary( + dataReader, destDictionary, keyField, destObjectType, parameters); + } + + public static IDictionary DataReaderToDictionary( + IDataReader dataReader, + NameOrIndexParameter keyField, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDataReaderToDictionary(dataReader, keyField, destObjectType, parameters); + } + + public static IDictionary DataReaderToDictionary( + IDataReader dataReader, + IDictionary destDictionary, + NameOrIndexParameter keyField, + params object[] parameters) + { + return _defaultSchema.MapDataReaderToDictionary( + dataReader, destDictionary, keyField, parameters); + } + + public static Dictionary DataReaderToDictionary( + IDataReader dataReader, + NameOrIndexParameter keyField, + params object[] parameters) + { + return _defaultSchema.MapDataReaderToDictionary(dataReader, keyField, parameters); + } + + #endregion + + #region DataReaderToDictionary (Index) + + public static IDictionary DataReaderToDictionary( + IDataReader dataReader, + IDictionary destDictionary, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDataReaderToDictionary( + dataReader, destDictionary, index, destObjectType, parameters); + } + + public static IDictionary DataReaderToDictionary( + IDataReader dataReader, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDataReaderToDictionary(dataReader, index, destObjectType, parameters); + } + + public static IDictionary DataReaderToDictionary( + IDataReader dataReader, + IDictionary destDictionary, + MapIndex index, + params object[] parameters) + { + return _defaultSchema.MapDataReaderToDictionary(dataReader, destDictionary, index, parameters); + } + + public static Dictionary DataReaderToDictionary( + IDataReader dataReader, + MapIndex index, + params object[] parameters) + { + return _defaultSchema.MapDataReaderToDictionary(dataReader, index, parameters); + } + + #endregion + + #endregion + + #region Dictionary + + #region DictionaryToList + + public static IList DictionaryToList( + IDictionary sourceDictionary, + IList destList, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDictionaryToList(sourceDictionary, destList, destObjectType, parameters); + } + + public static IList DictionaryToList( + IDictionary sourceDictionary, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDictionaryToList(sourceDictionary, destObjectType, parameters); + } + + public static List DictionaryToList( + IDictionary sourceDictionary, + List destList, + params object[] parameters) + { + return _defaultSchema.MapDictionaryToList(sourceDictionary, destList, parameters); + } + + public static List DictionaryToList(IDictionary sourceDictionary, params object[] parameters) + { + return _defaultSchema.MapDictionaryToList(sourceDictionary, parameters); + } + + #endregion + + #region DictionaryToDataTable + +#if !SILVERLIGHT + + public static DataTable DictionaryToDataTable(IDictionary sourceDictionary, DataTable destTable) + { + return _defaultSchema.MapDictionaryToDataTable(sourceDictionary, destTable); + } + + public static DataTable DictionaryToDataTable(IDictionary sourceDictionary) + { + return _defaultSchema.MapDictionaryToDataTable(sourceDictionary); + } + +#endif + + #endregion + + #region DictionaryToDictionary + + public static IDictionary DictionaryToDictionary( + IDictionary sourceDictionary, + IDictionary destDictionary, + NameOrIndexParameter keyField, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDictionaryToDictionary( + sourceDictionary, destDictionary, keyField, destObjectType, parameters); + } + + public static IDictionary DictionaryToDictionary( + IDictionary sourceDictionary, + NameOrIndexParameter keyField, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDictionaryToDictionary( + sourceDictionary, keyField, destObjectType, parameters); + } + + public static IDictionary DictionaryToDictionary( + IDictionary sourceDictionary, + IDictionary destDictionary, + NameOrIndexParameter keyField, + params object[] parameters) + { + return _defaultSchema.MapDictionaryToDictionary(sourceDictionary, destDictionary, keyField, parameters); + } + + public static Dictionary DictionaryToDictionary( + IDictionary sourceDictionary, + NameOrIndexParameter keyField, + params object[] parameters) + { + return _defaultSchema.MapDictionaryToDictionary(sourceDictionary, keyField, parameters); + } + + #endregion + + #region DictionaryToDictionary (Index) + + public static IDictionary DictionaryToDictionary( + IDictionary sourceDictionary, + IDictionary destDictionary, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDictionaryToDictionary( + sourceDictionary, destDictionary, index, destObjectType, parameters); + } + + public static IDictionary DictionaryToDictionary( + IDictionary sourceDictionary, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + return _defaultSchema.MapDictionaryToDictionary(sourceDictionary, index, destObjectType, parameters); + } + + public static IDictionary DictionaryToDictionary( + IDictionary sourceDictionary, + IDictionary destDictionary, + MapIndex index, + params object[] parameters) + { + return _defaultSchema.MapDictionaryToDictionary(sourceDictionary, destDictionary, index, parameters); + } + + public static Dictionary DictionaryToDictionary( + IDictionary sourceDictionary, + MapIndex index, + params object[] parameters) + { + return _defaultSchema.MapDictionaryToDictionary(sourceDictionary, index, parameters); + } + + #endregion + + #endregion + + #region ToResultSet + + public static void ResultSets(MapResultSet[] resultSets) + { + _defaultSchema.MapResultSets(resultSets);//, true); + } + + //public static void ResultSets(MapResultSet[] resultSets, bool throwException) + //{ + // _defaultSchema.MapResultSets(resultSets, throwException); + //} + + //public static void DataReaderToResultSet(IDataReader reader, MapResultSet[] resultSets) + //{ + // _defaultSchema.MapDataReaderToResultSet(reader, resultSets, true); + //} + + //public static void DataReaderToResultSet( + // IDataReader reader, MapResultSet[] resultSets, bool throwException) + //{ + // _defaultSchema.MapDataReaderToResultSet(reader, resultSets, throwException); + //} + + //public static void DataSetToResultSet(DataSet dataSet, MapResultSet[] resultSets) + //{ + // _defaultSchema.MapDataSetToResultSet(dataSet, resultSets, true); + //} + + //public static void DataSetToResultSet( + // DataSet dataSet, MapResultSet[] resultSets, bool throwException) + //{ + // _defaultSchema.MapDataSetToResultSet(dataSet, resultSets, throwException); + //} + + //public static MapResultSet[] Clone(MapResultSet[] resultSets) + //{ + // return _defaultSchema.Clone(resultSets); + //} + + //public static MapResultSet[] ConvertToResultSet(Type masterType, params MapNextResult[] nextResults) + //{ + // return _defaultSchema.ConvertToResultSet(masterType, nextResults); + //} + + #endregion + + #region CreateInstance + + public static object CreateInstance(Type type) + { + return TypeAccessor.CreateInstanceEx(type); + } + + public static T CreateInstance() + { + return TypeAccessor.CreateInstanceEx(); + } + + #endregion + + #region GetObjectMapper + + public static Func GetObjectMapper() + { + return _defaultSchema.GetObjectMapper(); + } + + public static Func GetObjectMapper(bool deepCopy) + { + return _defaultSchema.GetObjectMapper(deepCopy); + } + + public static Func GetObjectMapper(bool deepCopy, bool includeComplexMapping) + { + return _defaultSchema.GetObjectMapper(deepCopy, includeComplexMapping); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapDataDestinationBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapDataDestinationBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,91 @@ +using System; +using System.Data.SqlTypes; + +namespace BLToolkit.Mapping +{ + public abstract class MapDataDestinationBase : IMapDataDestination + { + #region IMapDataDestination Members + + public abstract Type GetFieldType(int index); + + public abstract int GetOrdinal (string name); + public abstract void SetValue (object o, int index, object value); + public abstract void SetValue (object o, string name, object value); + + public virtual void SetNull (object o, int index) { SetValue(o, index, null); } + + public virtual bool SupportsTypedValues(int index) { return true; } + + // Simple types setters. + // + [CLSCompliant(false)] + public virtual void SetSByte (object o, int index, SByte value) { SetValue(o, index, value); } + public virtual void SetInt16 (object o, int index, Int16 value) { SetValue(o, index, value); } + public virtual void SetInt32 (object o, int index, Int32 value) { SetValue(o, index, value); } + public virtual void SetInt64 (object o, int index, Int64 value) { SetValue(o, index, value); } + + public virtual void SetByte (object o, int index, Byte value) { SetValue(o, index, value); } + [CLSCompliant(false)] + public virtual void SetUInt16 (object o, int index, UInt16 value) { SetValue(o, index, value); } + [CLSCompliant(false)] + public virtual void SetUInt32 (object o, int index, UInt32 value) { SetValue(o, index, value); } + [CLSCompliant(false)] + public virtual void SetUInt64 (object o, int index, UInt64 value) { SetValue(o, index, value); } + + public virtual void SetBoolean (object o, int index, Boolean value) { SetValue(o, index, value); } + public virtual void SetChar (object o, int index, Char value) { SetValue(o, index, value); } + public virtual void SetSingle (object o, int index, Single value) { SetValue(o, index, value); } + public virtual void SetDouble (object o, int index, Double value) { SetValue(o, index, value); } + public virtual void SetDecimal (object o, int index, Decimal value) { SetValue(o, index, value); } + public virtual void SetGuid (object o, int index, Guid value) { SetValue(o, index, value); } + public virtual void SetDateTime (object o, int index, DateTime value) { SetValue(o, index, value); } + public virtual void SetDateTimeOffset(object o, int index, DateTimeOffset value) { SetValue(o, index, value); } + + // Nullable types setters. + // + [CLSCompliant(false)] + public virtual void SetNullableSByte (object o, int index, SByte? value) { SetValue(o, index, value); } + public virtual void SetNullableInt16 (object o, int index, Int16? value) { SetValue(o, index, value); } + public virtual void SetNullableInt32 (object o, int index, Int32? value) { SetValue(o, index, value); } + public virtual void SetNullableInt64 (object o, int index, Int64? value) { SetValue(o, index, value); } + + public virtual void SetNullableByte (object o, int index, Byte? value) { SetValue(o, index, value); } + [CLSCompliant(false)] + public virtual void SetNullableUInt16 (object o, int index, UInt16? value) { SetValue(o, index, value); } + [CLSCompliant(false)] + public virtual void SetNullableUInt32 (object o, int index, UInt32? value) { SetValue(o, index, value); } + [CLSCompliant(false)] + public virtual void SetNullableUInt64 (object o, int index, UInt64? value) { SetValue(o, index, value); } + + public virtual void SetNullableBoolean (object o, int index, Boolean? value) { SetValue(o, index, value); } + public virtual void SetNullableChar (object o, int index, Char? value) { SetValue(o, index, value); } + public virtual void SetNullableSingle (object o, int index, Single? value) { SetValue(o, index, value); } + public virtual void SetNullableDouble (object o, int index, Double? value) { SetValue(o, index, value); } + public virtual void SetNullableDecimal (object o, int index, Decimal? value) { SetValue(o, index, value); } + public virtual void SetNullableGuid (object o, int index, Guid? value) { SetValue(o, index, value); } + public virtual void SetNullableDateTime(object o, int index, DateTime? value) { SetValue(o, index, value); } + public virtual void SetNullableDateTimeOffset(object o, int index, DateTimeOffset? value) { SetValue(o, index, value); } + +#if !SILVERLIGHT + + // SQL type setters. + // + public virtual void SetSqlByte (object o, int index, SqlByte value) { SetValue(o, index, value); } + public virtual void SetSqlInt16 (object o, int index, SqlInt16 value) { SetValue(o, index, value); } + public virtual void SetSqlInt32 (object o, int index, SqlInt32 value) { SetValue(o, index, value); } + public virtual void SetSqlInt64 (object o, int index, SqlInt64 value) { SetValue(o, index, value); } + public virtual void SetSqlSingle (object o, int index, SqlSingle value) { SetValue(o, index, value); } + public virtual void SetSqlBoolean (object o, int index, SqlBoolean value) { SetValue(o, index, value); } + public virtual void SetSqlDouble (object o, int index, SqlDouble value) { SetValue(o, index, value); } + public virtual void SetSqlDateTime(object o, int index, SqlDateTime value) { SetValue(o, index, value); } + public virtual void SetSqlDecimal (object o, int index, SqlDecimal value) { SetValue(o, index, value); } + public virtual void SetSqlMoney (object o, int index, SqlMoney value) { SetValue(o, index, value); } + public virtual void SetSqlGuid (object o, int index, SqlGuid value) { SetValue(o, index, value); } + public virtual void SetSqlString (object o, int index, SqlString value) { SetValue(o, index, value); } + +#endif + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapDataSourceBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapDataSourceBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,92 @@ +using System; +using System.Data.SqlTypes; + +namespace BLToolkit.Mapping +{ + public abstract class MapDataSourceBase : IMapDataSource + { + #region IMapDataSource Members + + public abstract int Count { get; } + public abstract Type GetFieldType(int index); + public abstract string GetName (int index); + public abstract int GetOrdinal (string name); + public abstract object GetValue (object o, int index); + public abstract object GetValue (object o, string name); + + public virtual bool IsNull (object o, int index) { return GetValue(o, index) == null; } + + public virtual bool SupportsTypedValues(int index) { return true; } + + // Simple type getters. + // + [CLSCompliant(false)] + public virtual SByte GetSByte (object o, int index) { return Map.DefaultSchema.ConvertToSByte (GetValue(o, index)); } + public virtual Int16 GetInt16 (object o, int index) { return Map.DefaultSchema.ConvertToInt16 (GetValue(o, index)); } + public virtual Int32 GetInt32 (object o, int index) { return Map.DefaultSchema.ConvertToInt32 (GetValue(o, index)); } + public virtual Int64 GetInt64 (object o, int index) { return Map.DefaultSchema.ConvertToInt64 (GetValue(o, index)); } + + public virtual Byte GetByte (object o, int index) { return Map.DefaultSchema.ConvertToByte (GetValue(o, index)); } + [CLSCompliant(false)] + public virtual UInt16 GetUInt16 (object o, int index) { return Map.DefaultSchema.ConvertToUInt16 (GetValue(o, index)); } + [CLSCompliant(false)] + public virtual UInt32 GetUInt32 (object o, int index) { return Map.DefaultSchema.ConvertToUInt32 (GetValue(o, index)); } + [CLSCompliant(false)] + public virtual UInt64 GetUInt64 (object o, int index) { return Map.DefaultSchema.ConvertToUInt64 (GetValue(o, index)); } + + public virtual Boolean GetBoolean (object o, int index) { return Map.DefaultSchema.ConvertToBoolean (GetValue(o, index)); } + public virtual Char GetChar (object o, int index) { return Map.DefaultSchema.ConvertToChar (GetValue(o, index)); } + public virtual Single GetSingle (object o, int index) { return Map.DefaultSchema.ConvertToSingle (GetValue(o, index)); } + public virtual Double GetDouble (object o, int index) { return Map.DefaultSchema.ConvertToDouble (GetValue(o, index)); } + public virtual Decimal GetDecimal (object o, int index) { return Map.DefaultSchema.ConvertToDecimal (GetValue(o, index)); } + public virtual Guid GetGuid (object o, int index) { return Map.DefaultSchema.ConvertToGuid (GetValue(o, index)); } + public virtual DateTime GetDateTime (object o, int index) { return Map.DefaultSchema.ConvertToDateTime(GetValue(o, index)); } + public virtual DateTimeOffset GetDateTimeOffset(object o, int index) { return Map.DefaultSchema.ConvertToDateTimeOffset(GetValue(o, index)); } + + // Nullable type getters. + // + [CLSCompliant(false)] + public virtual SByte? GetNullableSByte (object o, int index) { return Map.DefaultSchema.ConvertToNullableSByte (GetValue(o, index)); } + public virtual Int16? GetNullableInt16 (object o, int index) { return Map.DefaultSchema.ConvertToNullableInt16 (GetValue(o, index)); } + public virtual Int32? GetNullableInt32 (object o, int index) { return Map.DefaultSchema.ConvertToNullableInt32 (GetValue(o, index)); } + public virtual Int64? GetNullableInt64 (object o, int index) { return Map.DefaultSchema.ConvertToNullableInt64 (GetValue(o, index)); } + + public virtual Byte? GetNullableByte (object o, int index) { return Map.DefaultSchema.ConvertToNullableByte (GetValue(o, index)); } + [CLSCompliant(false)] + public virtual UInt16? GetNullableUInt16 (object o, int index) { return Map.DefaultSchema.ConvertToNullableUInt16 (GetValue(o, index)); } + [CLSCompliant(false)] + public virtual UInt32? GetNullableUInt32 (object o, int index) { return Map.DefaultSchema.ConvertToNullableUInt32 (GetValue(o, index)); } + [CLSCompliant(false)] + public virtual UInt64? GetNullableUInt64 (object o, int index) { return Map.DefaultSchema.ConvertToNullableUInt64 (GetValue(o, index)); } + + public virtual Boolean? GetNullableBoolean (object o, int index) { return Map.DefaultSchema.ConvertToNullableBoolean (GetValue(o, index)); } + public virtual Char? GetNullableChar (object o, int index) { return Map.DefaultSchema.ConvertToNullableChar (GetValue(o, index)); } + public virtual Single? GetNullableSingle (object o, int index) { return Map.DefaultSchema.ConvertToNullableSingle (GetValue(o, index)); } + public virtual Double? GetNullableDouble (object o, int index) { return Map.DefaultSchema.ConvertToNullableDouble (GetValue(o, index)); } + public virtual Decimal? GetNullableDecimal (object o, int index) { return Map.DefaultSchema.ConvertToNullableDecimal (GetValue(o, index)); } + public virtual Guid? GetNullableGuid (object o, int index) { return Map.DefaultSchema.ConvertToNullableGuid (GetValue(o, index)); } + public virtual DateTime? GetNullableDateTime(object o, int index) { return Map.DefaultSchema.ConvertToNullableDateTime(GetValue(o, index)); } + public virtual DateTimeOffset? GetNullableDateTimeOffset(object o, int index) { return Map.DefaultSchema.ConvertToNullableDateTimeOffset(GetValue(o, index)); } + +#if !SILVERLIGHT + + // SQL type getters. + // + public virtual SqlByte GetSqlByte (object o, int index) { return Map.DefaultSchema.ConvertToSqlByte (GetValue(o, index)); } + public virtual SqlInt16 GetSqlInt16 (object o, int index) { return Map.DefaultSchema.ConvertToSqlInt16 (GetValue(o, index)); } + public virtual SqlInt32 GetSqlInt32 (object o, int index) { return Map.DefaultSchema.ConvertToSqlInt32 (GetValue(o, index)); } + public virtual SqlInt64 GetSqlInt64 (object o, int index) { return Map.DefaultSchema.ConvertToSqlInt64 (GetValue(o, index)); } + public virtual SqlSingle GetSqlSingle (object o, int index) { return Map.DefaultSchema.ConvertToSqlSingle (GetValue(o, index)); } + public virtual SqlBoolean GetSqlBoolean (object o, int index) { return Map.DefaultSchema.ConvertToSqlBoolean (GetValue(o, index)); } + public virtual SqlDouble GetSqlDouble (object o, int index) { return Map.DefaultSchema.ConvertToSqlDouble (GetValue(o, index)); } + public virtual SqlDateTime GetSqlDateTime (object o, int index) { return Map.DefaultSchema.ConvertToSqlDateTime(GetValue(o, index)); } + public virtual SqlDecimal GetSqlDecimal (object o, int index) { return Map.DefaultSchema.ConvertToSqlDecimal (GetValue(o, index)); } + public virtual SqlMoney GetSqlMoney (object o, int index) { return Map.DefaultSchema.ConvertToSqlMoney (GetValue(o, index)); } + public virtual SqlGuid GetSqlGuid (object o, int index) { return Map.DefaultSchema.ConvertToSqlGuid (GetValue(o, index)); } + public virtual SqlString GetSqlString (object o, int index) { return Map.DefaultSchema.ConvertToSqlString (GetValue(o, index)); } + +#endif + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapDataSourceDestinationBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapDataSourceDestinationBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,86 @@ +using System; +using System.Data.SqlTypes; + +namespace BLToolkit.Mapping +{ + public abstract class MapDataSourceDestinationBase : MapDataSourceBase, IMapDataDestination + { + #region IMapDataDestination Members + + public abstract void SetValue (object o, int index, object value); + public abstract void SetValue (object o, string name, object value); + + public virtual void SetNull (object o, int index) { SetValue(o, index, null); } + + // Simple types setters. + // + [CLSCompliant(false)] + public virtual void SetSByte (object o, int index, SByte value) { SetValue(o, index, value); } + public virtual void SetInt16 (object o, int index, Int16 value) { SetValue(o, index, value); } + public virtual void SetInt32 (object o, int index, Int32 value) { SetValue(o, index, value); } + public virtual void SetInt64 (object o, int index, Int64 value) { SetValue(o, index, value); } + + public virtual void SetByte (object o, int index, Byte value) { SetValue(o, index, value); } + [CLSCompliant(false)] + public virtual void SetUInt16 (object o, int index, UInt16 value) { SetValue(o, index, value); } + [CLSCompliant(false)] + public virtual void SetUInt32 (object o, int index, UInt32 value) { SetValue(o, index, value); } + [CLSCompliant(false)] + public virtual void SetUInt64 (object o, int index, UInt64 value) { SetValue(o, index, value); } + + public virtual void SetBoolean (object o, int index, Boolean value) { SetValue(o, index, value); } + public virtual void SetChar (object o, int index, Char value) { SetValue(o, index, value); } + public virtual void SetSingle (object o, int index, Single value) { SetValue(o, index, value); } + public virtual void SetDouble (object o, int index, Double value) { SetValue(o, index, value); } + public virtual void SetDecimal (object o, int index, Decimal value) { SetValue(o, index, value); } + public virtual void SetGuid (object o, int index, Guid value) { SetValue(o, index, value); } + public virtual void SetDateTime(object o, int index, DateTime value) { SetValue(o, index, value); } + public virtual void SetDateTimeOffset(object o, int index, DateTimeOffset value) { SetValue(o, index, value); } + + // Nullable types setters. + // + [CLSCompliant(false)] + public virtual void SetNullableSByte (object o, int index, SByte? value) { SetValue(o, index, value); } + public virtual void SetNullableInt16 (object o, int index, Int16? value) { SetValue(o, index, value); } + public virtual void SetNullableInt32 (object o, int index, Int32? value) { SetValue(o, index, value); } + public virtual void SetNullableInt64 (object o, int index, Int64? value) { SetValue(o, index, value); } + + public virtual void SetNullableByte (object o, int index, Byte? value) { SetValue(o, index, value); } + [CLSCompliant(false)] + public virtual void SetNullableUInt16 (object o, int index, UInt16? value) { SetValue(o, index, value); } + [CLSCompliant(false)] + public virtual void SetNullableUInt32 (object o, int index, UInt32? value) { SetValue(o, index, value); } + [CLSCompliant(false)] + public virtual void SetNullableUInt64 (object o, int index, UInt64? value) { SetValue(o, index, value); } + + public virtual void SetNullableBoolean (object o, int index, Boolean? value) { SetValue(o, index, value); } + public virtual void SetNullableChar (object o, int index, Char? value) { SetValue(o, index, value); } + public virtual void SetNullableSingle (object o, int index, Single? value) { SetValue(o, index, value); } + public virtual void SetNullableDouble (object o, int index, Double? value) { SetValue(o, index, value); } + public virtual void SetNullableDecimal (object o, int index, Decimal? value) { SetValue(o, index, value); } + public virtual void SetNullableGuid (object o, int index, Guid? value) { SetValue(o, index, value); } + public virtual void SetNullableDateTime(object o, int index, DateTime? value) { SetValue(o, index, value); } + public virtual void SetNullableDateTimeOffset(object o, int index, DateTimeOffset? value) { SetValue(o, index, value); } + +#if !SILVERLIGHT + + // SQL type setters. + // + public virtual void SetSqlByte (object o, int index, SqlByte value) { SetValue(o, index, value); } + public virtual void SetSqlInt16 (object o, int index, SqlInt16 value) { SetValue(o, index, value); } + public virtual void SetSqlInt32 (object o, int index, SqlInt32 value) { SetValue(o, index, value); } + public virtual void SetSqlInt64 (object o, int index, SqlInt64 value) { SetValue(o, index, value); } + public virtual void SetSqlSingle (object o, int index, SqlSingle value) { SetValue(o, index, value); } + public virtual void SetSqlBoolean (object o, int index, SqlBoolean value) { SetValue(o, index, value); } + public virtual void SetSqlDouble (object o, int index, SqlDouble value) { SetValue(o, index, value); } + public virtual void SetSqlDateTime(object o, int index, SqlDateTime value) { SetValue(o, index, value); } + public virtual void SetSqlDecimal (object o, int index, SqlDecimal value) { SetValue(o, index, value); } + public virtual void SetSqlMoney (object o, int index, SqlMoney value) { SetValue(o, index, value); } + public virtual void SetSqlGuid (object o, int index, SqlGuid value) { SetValue(o, index, value); } + public virtual void SetSqlString (object o, int index, SqlString value) { SetValue(o, index, value); } + +#endif + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapFieldAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapFieldAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,32 @@ +using System; + +namespace BLToolkit.Mapping +{ + [AttributeUsage( + AttributeTargets.Field | AttributeTargets.Property | + AttributeTargets.Class | AttributeTargets.Interface, + AllowMultiple=true)] + public class MapFieldAttribute : Attribute + { + public MapFieldAttribute() + { + } + + public MapFieldAttribute(string mapName) + { + MapName = mapName; + } + + public MapFieldAttribute(string mapName, string origName) + { + MapName = mapName; + OrigName = origName; + } + + public string MapName { get; set; } + public string OrigName { get; set; } + public string Format { get; set; } + public string Storage { get; set; } + public bool IsInheritanceDiscriminator { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapGetDataT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapGetDataT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,227 @@ +using System; +using System.Data.SqlTypes; + +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + [CLSCompliant(false)] + public static class MapGetData + { + public abstract class MB + { + public abstract V From(IMapDataSource s, object o, int i); + } + + public static T From(IMapDataSource s, object o, int i) + { + return I.From(s, o, i); + } + + public static MB I = GetGetter(); + private static MB GetGetter() + { + Type t = typeof(T); + + // Scalar Types. + // + if (t == typeof(SByte)) return (MB)(object)(new I8()); + if (t == typeof(Int16)) return (MB)(object)(new I16()); + if (t == typeof(Int32)) return (MB)(object)(new I32()); + if (t == typeof(Int64)) return (MB)(object)(new I64()); + + if (t == typeof(Byte)) return (MB)(object)(new U8()); + if (t == typeof(UInt16)) return (MB)(object)(new U16()); + if (t == typeof(UInt32)) return (MB)(object)(new U32()); + if (t == typeof(UInt64)) return (MB)(object)(new U64()); + + if (t == typeof(Single)) return (MB)(object)(new R4()); + if (t == typeof(Double)) return (MB)(object)(new R8()); + + if (t == typeof(Boolean)) return (MB)(object)(new B()); + if (t == typeof(Decimal)) return (MB)(object)(new D()); + + if (t == typeof(Char)) return (MB)(object)(new C()); + if (t == typeof(Guid)) return (MB)(object)(new G()); + if (t == typeof(DateTime)) return (MB)(object)(new DT()); + if (t == typeof(DateTimeOffset)) return (MB)(object)(new DTO()); + + // Enums. + // + if (t.IsEnum) + { + t = Enum.GetUnderlyingType(t); + + if (t == typeof(SByte)) return new EI8(); + if (t == typeof(Int16)) return new EI16(); + if (t == typeof(Int32)) return new EI32(); + if (t == typeof(Int64)) return new EI64(); + + if (t == typeof(Byte)) return new EU8(); + if (t == typeof(UInt16)) return new EU16(); + if (t == typeof(UInt32)) return new EU32(); + if (t == typeof(UInt64)) return new EU64(); + } + + // Nullable Types. + // + if (t == typeof(SByte?)) return (MB)(object)(new NI8()); + if (t == typeof(Int16?)) return (MB)(object)(new NI16()); + if (t == typeof(Int32?)) return (MB)(object)(new NI32()); + if (t == typeof(Int64?)) return (MB)(object)(new NI64()); + + if (t == typeof(Byte?)) return (MB)(object)(new NU8()); + if (t == typeof(UInt16?)) return (MB)(object)(new NU16()); + if (t == typeof(UInt32?)) return (MB)(object)(new NU32()); + if (t == typeof(UInt64?)) return (MB)(object)(new NU64()); + + if (t == typeof(Single?)) return (MB)(object)(new NR4()); + if (t == typeof(Double?)) return (MB)(object)(new NR8()); + + if (t == typeof(Boolean?)) return (MB)(object)(new NB()); + if (t == typeof(Decimal?)) return (MB)(object)(new ND()); + + if (t == typeof(Char?)) return (MB)(object)(new NC()); + if (t == typeof(Guid?)) return (MB)(object)(new NG()); + if (t == typeof(DateTime?)) return (MB)(object)(new NDT()); + if (t == typeof(DateTimeOffset?)) return (MB)(object)(new NDTO()); + + // Nullable Enums. + // + if (TypeHelper.IsNullable(t) && Nullable.GetUnderlyingType(t).IsEnum) + { + Type enumType = Nullable.GetUnderlyingType(t); + t = Enum.GetUnderlyingType(enumType); + + if (t == typeof(SByte)) return (MB)Activator.CreateInstance(typeof(NEI8<>).MakeGenericType(typeof(T), enumType)); + if (t == typeof(Int16)) return (MB)Activator.CreateInstance(typeof(NEI16<>).MakeGenericType(typeof(T), enumType)); + if (t == typeof(Int32)) return (MB)Activator.CreateInstance(typeof(NEI32<>).MakeGenericType(typeof(T), enumType)); + if (t == typeof(Int64)) return (MB)Activator.CreateInstance(typeof(NEI64<>).MakeGenericType(typeof(T), enumType)); + + if (t == typeof(Byte)) return (MB)Activator.CreateInstance(typeof(NEU8<>).MakeGenericType(typeof(T), enumType)); + if (t == typeof(UInt16)) return (MB)Activator.CreateInstance(typeof(NEU16<>).MakeGenericType(typeof(T), enumType)); + if (t == typeof(UInt32)) return (MB)Activator.CreateInstance(typeof(NEU32<>).MakeGenericType(typeof(T), enumType)); + if (t == typeof(UInt64)) return (MB)Activator.CreateInstance(typeof(NEU64<>).MakeGenericType(typeof(T), enumType)); + } + +#if !SILVERLIGHT + + // SqlTypes. + // + if (t == typeof(SqlString)) return (MB)(object)(new dbS()); + + if (t == typeof(SqlByte)) return (MB)(object)(new dbU8()); + if (t == typeof(SqlInt16)) return (MB)(object)(new dbI16()); + if (t == typeof(SqlInt32)) return (MB)(object)(new dbI32()); + if (t == typeof(SqlInt64)) return (MB)(object)(new dbI64()); + + if (t == typeof(SqlSingle)) return (MB)(object)(new dbR4()); + if (t == typeof(SqlDouble)) return (MB)(object)(new dbR8()); + if (t == typeof(SqlDecimal)) return (MB)(object)(new dbD()); + if (t == typeof(SqlMoney)) return (MB)(object)(new dbM()); + + if (t == typeof(SqlBoolean)) return (MB)(object)(new dbB()); + if (t == typeof(SqlGuid)) return (MB)(object)(new dbG()); + if (t == typeof(SqlDateTime)) return (MB)(object)(new dbDT()); + +#endif + + return new Default(); + } + + // Default setter. + // + public sealed class Default : MB { public override V From(IMapDataSource s, object o, int i) { return (V)s.GetValue (o, i); } } + + // Scalar Types. + // + sealed class I8 : MB { public override SByte From(IMapDataSource s, object o, int i) { return s.GetSByte (o, i); } } + sealed class I16 : MB { public override Int16 From(IMapDataSource s, object o, int i) { return s.GetInt16 (o, i); } } + sealed class I32 : MB { public override Int32 From(IMapDataSource s, object o, int i) { return s.GetInt32 (o, i); } } + sealed class I64 : MB { public override Int64 From(IMapDataSource s, object o, int i) { return s.GetInt64 (o, i); } } + + sealed class U8 : MB { public override Byte From(IMapDataSource s, object o, int i) { return s.GetByte (o, i); } } + sealed class U16 : MB { public override UInt16 From(IMapDataSource s, object o, int i) { return s.GetUInt16 (o, i); } } + sealed class U32 : MB { public override UInt32 From(IMapDataSource s, object o, int i) { return s.GetUInt32 (o, i); } } + sealed class U64 : MB { public override UInt64 From(IMapDataSource s, object o, int i) { return s.GetUInt64 (o, i); } } + + sealed class R4 : MB { public override Single From(IMapDataSource s, object o, int i) { return s.GetSingle (o, i); } } + sealed class R8 : MB { public override Double From(IMapDataSource s, object o, int i) { return s.GetDouble (o, i); } } + + sealed class B : MB { public override Boolean From(IMapDataSource s, object o, int i) { return s.GetBoolean (o, i); } } + sealed class D : MB { public override Decimal From(IMapDataSource s, object o, int i) { return s.GetDecimal (o, i); } } + + sealed class C : MB { public override Char From(IMapDataSource s, object o, int i) { return s.GetChar (o, i); } } + sealed class G : MB { public override Guid From(IMapDataSource s, object o, int i) { return s.GetGuid (o, i); } } + sealed class DT : MB { public override DateTime From(IMapDataSource s, object o, int i) { return s.GetDateTime (o, i); } } + sealed class DTO : MB { public override DateTimeOffset From(IMapDataSource s, object o, int i) { return s.GetDateTimeOffset (o, i); } } + // Enums. + // + sealed class EI8 : MB { public override E From(IMapDataSource s, object o, int i) { return (E)(object)s.GetSByte (o, i); } } + sealed class EI16 : MB { public override E From(IMapDataSource s, object o, int i) { return (E)(object)s.GetInt16 (o, i); } } + sealed class EI32 : MB { public override E From(IMapDataSource s, object o, int i) { return (E)(object)s.GetInt32 (o, i); } } + sealed class EI64 : MB { public override E From(IMapDataSource s, object o, int i) { return (E)(object)s.GetInt64 (o, i); } } + + sealed class EU8 : MB { public override E From(IMapDataSource s, object o, int i) { return (E)(object)s.GetByte (o, i); } } + sealed class EU16 : MB { public override E From(IMapDataSource s, object o, int i) { return (E)(object)s.GetUInt16 (o, i); } } + sealed class EU32 : MB { public override E From(IMapDataSource s, object o, int i) { return (E)(object)s.GetUInt32 (o, i); } } + sealed class EU64 : MB { public override E From(IMapDataSource s, object o, int i) { return (E)(object)s.GetUInt64 (o, i); } } + + // Nullable Types. + // + sealed class NI8 : MB { public override SByte? From(IMapDataSource s, object o, int i) { return s.GetNullableSByte (o, i); } } + sealed class NI16 : MB { public override Int16? From(IMapDataSource s, object o, int i) { return s.GetNullableInt16 (o, i); } } + sealed class NI32 : MB { public override Int32? From(IMapDataSource s, object o, int i) { return s.GetNullableInt32 (o, i); } } + sealed class NI64 : MB { public override Int64? From(IMapDataSource s, object o, int i) { return s.GetNullableInt64 (o, i); } } + + sealed class NU8 : MB { public override Byte? From(IMapDataSource s, object o, int i) { return s.GetNullableByte (o, i); } } + sealed class NU16 : MB { public override UInt16? From(IMapDataSource s, object o, int i) { return s.GetNullableUInt16 (o, i); } } + sealed class NU32 : MB { public override UInt32? From(IMapDataSource s, object o, int i) { return s.GetNullableUInt32 (o, i); } } + sealed class NU64 : MB { public override UInt64? From(IMapDataSource s, object o, int i) { return s.GetNullableUInt64 (o, i); } } + + sealed class NR4 : MB { public override Single? From(IMapDataSource s, object o, int i) { return s.GetNullableSingle (o, i); } } + sealed class NR8 : MB { public override Double? From(IMapDataSource s, object o, int i) { return s.GetNullableDouble (o, i); } } + + sealed class NB : MB { public override Boolean? From(IMapDataSource s, object o, int i) { return s.GetNullableBoolean (o, i); } } + sealed class ND : MB { public override Decimal? From(IMapDataSource s, object o, int i) { return s.GetNullableDecimal (o, i); } } + + sealed class NC : MB { public override Char? From(IMapDataSource s, object o, int i) { return s.GetNullableChar (o, i); } } + sealed class NG : MB { public override Guid? From(IMapDataSource s, object o, int i) { return s.GetNullableGuid (o, i); } } + sealed class NDT : MB { public override DateTime? From(IMapDataSource s, object o, int i) { return s.GetNullableDateTime (o, i); } } + sealed class NDTO : MB { public override DateTimeOffset? From(IMapDataSource s, object o, int i) { return s.GetNullableDateTimeOffset (o, i); } } + + // Nullable Enums. + // + sealed class NEI8 : MB where E : struct { public override E? From(IMapDataSource s, object o, int i) { return /*s.IsNull(o, i) ? (E?)null :*/ (E)(object)s.GetSByte (o, i); } } + sealed class NEI16 : MB where E : struct { public override E? From(IMapDataSource s, object o, int i) { return /*s.IsNull(o, i) ? (E?)null :*/ (E)(object)s.GetInt16 (o, i); } } + sealed class NEI32 : MB where E : struct { public override E? From(IMapDataSource s, object o, int i) { return /*s.IsNull(o, i) ? (E?)null :*/ (E)(object)s.GetInt32 (o, i); } } + sealed class NEI64 : MB where E : struct { public override E? From(IMapDataSource s, object o, int i) { return /*s.IsNull(o, i) ? (E?)null :*/ (E)(object)s.GetInt64 (o, i); } } + + sealed class NEU8 : MB where E : struct { public override E? From(IMapDataSource s, object o, int i) { return /*s.IsNull(o, i) ? (E?)null :*/ (E)(object)s.GetByte (o, i); } } + sealed class NEU16 : MB where E : struct { public override E? From(IMapDataSource s, object o, int i) { return /*s.IsNull(o, i) ? (E?)null :*/ (E)(object)s.GetUInt16(o, i); } } + sealed class NEU32 : MB where E : struct { public override E? From(IMapDataSource s, object o, int i) { return /*s.IsNull(o, i) ? (E?)null :*/ (E)(object)s.GetUInt32(o, i); } } + sealed class NEU64 : MB where E : struct { public override E? From(IMapDataSource s, object o, int i) { return /*s.IsNull(o, i) ? (E?)null :*/ (E)(object)s.GetUInt64(o, i); } } + +#if !SILVERLIGHT + + // SqlTypes. + // + sealed class dbS : MB { public override SqlString From(IMapDataSource s, object o, int i) { return s.GetSqlString (o, i); } } + + sealed class dbU8 : MB { public override SqlByte From(IMapDataSource s, object o, int i) { return s.GetSqlByte (o, i); } } + sealed class dbI16 : MB { public override SqlInt16 From(IMapDataSource s, object o, int i) { return s.GetSqlInt16 (o, i); } } + sealed class dbI32 : MB { public override SqlInt32 From(IMapDataSource s, object o, int i) { return s.GetSqlInt32 (o, i); } } + sealed class dbI64 : MB { public override SqlInt64 From(IMapDataSource s, object o, int i) { return s.GetSqlInt64 (o, i); } } + + sealed class dbR4 : MB { public override SqlSingle From(IMapDataSource s, object o, int i) { return s.GetSqlSingle (o, i); } } + sealed class dbR8 : MB { public override SqlDouble From(IMapDataSource s, object o, int i) { return s.GetSqlDouble (o, i); } } + sealed class dbD : MB { public override SqlDecimal From(IMapDataSource s, object o, int i) { return s.GetSqlDecimal (o, i); } } + sealed class dbM : MB { public override SqlMoney From(IMapDataSource s, object o, int i) { return s.GetSqlMoney (o, i); } } + + sealed class dbB : MB { public override SqlBoolean From(IMapDataSource s, object o, int i) { return s.GetSqlBoolean (o, i); } } + sealed class dbG : MB { public override SqlGuid From(IMapDataSource s, object o, int i) { return s.GetSqlGuid (o, i); } } + sealed class dbDT : MB { public override SqlDateTime From(IMapDataSource s, object o, int i) { return s.GetSqlDateTime (o, i); } } + +#endif + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapIgnoreAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapIgnoreAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +using System; + +namespace BLToolkit.Mapping +{ + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public sealed class MapIgnoreAttribute : Attribute + { + public MapIgnoreAttribute() + { + _ignore = true; + } + + public MapIgnoreAttribute(bool ignore) + { + _ignore = ignore; + } + + private bool _ignore; + public bool Ignore + { + get { return _ignore; } + set { _ignore = value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapImplicitAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapImplicitAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.Mapping +{ + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public abstract class MapImplicitAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapIndex.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapIndex.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,99 @@ +using System; +using System.Linq; +using BLToolkit.Common; +using BLToolkit.Properties; + +namespace BLToolkit.Mapping +{ + public class MapIndex + { + public MapIndex(string[] names) + { + if (null == names) + throw new ArgumentNullException("names"); + + if (names.Length == 0) + throw new ArgumentException(Resources.MapIndex_EmptyNames, "names"); + + Fields = NameOrIndexParameter.FromStringArray(names); + } + + public MapIndex(int[] indices) + { + if (null == indices) + throw new ArgumentNullException("indices"); + + if (indices.Length == 0) + throw new ArgumentException(Resources.MapIndex_EmptyIndices, "indices"); + + Fields = NameOrIndexParameter.FromIndexArray(indices); + } + + public MapIndex(params NameOrIndexParameter[] fields) + { + if (null == fields) + throw new ArgumentNullException("fields"); + + if (fields.Length == 0) + throw new ArgumentException(Resources.MapIndex_EmptyFields, "fields"); + + Fields = fields; + } + + public NameOrIndexParameter[] Fields { get; private set; } + + private string _id; + public string ID + { + get { return _id ?? (_id = string.Join(".", Fields.Select(_ => _.ToString()).ToArray())); } + } + + [CLSCompliant(false)] + public object GetValue(IMapDataSource source, object obj, int index) + { + if (source == null) + throw new ArgumentNullException("source"); + + var value = Fields[index].ByName? + source.GetValue(obj, Fields[index].Name): + source.GetValue(obj, Fields[index].Index); + + if (value == null) + { + var objectMapper = source as ObjectMapper; + + if (objectMapper != null) + { + var mm = Fields[index].ByName? + objectMapper[Fields[index].Name]: objectMapper[Fields[index].Index]; + + if (mm == null) + throw new MappingException(string.Format(Resources.MapIndex_BadField, + objectMapper.TypeAccessor.OriginalType.Name, Fields[index])); + } + } + + return value; + } + + [CLSCompliant(false)] + public object GetValueOrIndex(IMapDataSource source, object obj) + { + return Fields.Length == 1? + GetValue(source, obj, 0): + GetIndexValue(source, obj); + } + + [CLSCompliant(false)] + public CompoundValue GetIndexValue(IMapDataSource source, object obj) + { + var values = new object[Fields.Length]; + + for (var i = 0; i < values.Length; i++) + values[i] = GetValue(source, obj, i); + + return new CompoundValue(values); + } + } +} + diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapMemberInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapMemberInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Diagnostics; + +using BLToolkit.DataAccess; +using BLToolkit.Reflection; +using BLToolkit.Reflection.Extension; + +namespace BLToolkit.Mapping +{ + [DebuggerStepThrough] + public class MapMemberInfo + { + public MapMemberInfo() + { + DbType = DbType.Object; + } + + public MemberAccessor MemberAccessor { get; set; } + public MemberAccessor ComplexMemberAccessor { get; set; } + public string Name { get; set; } + public string MemberName { get; set; } + public string Storage { get; set; } + public bool IsInheritanceDiscriminator { get; set; } + public bool Trimmable { get; set; } + public bool SqlIgnore { get; set; } + public bool Nullable { get; set; } + public object NullValue { get; set; } + public object DefaultValue { get; set; } + public Type Type { get; set; } + public int DbSize { get; set; } + public bool IsDbTypeSet { get; set; } + public bool IsDbSizeSet { get; set; } + public MappingSchema MappingSchema { get; set; } + public MemberExtension MemberExtension { get; set; } + public DbType DbType { get; set; } + public KeyGenerator KeyGenerator { get; set; } + + private MapValue[] _mapValues; + public MapValue[] MapValues + { + get { return _mapValues; } + set + { + _mapValues = value; + if (value != null) + CacheMapValues(); + else + { + _mapValueCache = new Dictionary(); + _origValueCache = new Dictionary(); + } + } + } + + private Dictionary _mapValueCache; + + public bool TryGetOrigValue(object mapedValue, out object origValue) + { + return _mapValueCache.TryGetValue(mapedValue, out origValue); + } + + private Dictionary _origValueCache; + + public bool TryGetMapValue(object origValue, out object mapValue) + { + return _origValueCache.TryGetValue(origValue, out mapValue); + } + + private void CacheMapValues() + { + _mapValueCache = new Dictionary(); + + foreach (var mv in MapValues) + foreach (var mapValue in mv.MapValues) + { + _mapValueCache[mapValue] = mv.OrigValue; + + // this fixes spesial case for char + if (mapValue is char) + { + var str = new string(new[] { (char)mapValue }); + _mapValueCache[str] = mv.OrigValue; + } + } + + _origValueCache = new Dictionary(); + + foreach (var mv in MapValues) + { + // previous behaviour - first wins! + // yah, no... + // any wins - attributes order is not specified + // and memberInfo.GetCustomAttributes(...) order and can differ + if (!_origValueCache.ContainsKey(mv.OrigValue)) + _origValueCache[mv.OrigValue] = mv.MapValues[0]; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapNextResult.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapNextResult.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,61 @@ +using System; + +namespace BLToolkit.Mapping +{ + public class MapNextResult + { + public MapNextResult( + Type type, + MapIndex slaveIndex, + MapIndex masterIndex, + string containerName, + params MapNextResult[] nextResults) + { + _objectType = type; + _slaveIndex = slaveIndex; + _masterIndex = masterIndex; + _containerName = containerName; + _nextResults = nextResults; + } + + public MapNextResult( + Type type, + string slaveIndex, + string masterIndex, + string containerName, + params MapNextResult[] nextResults) + : this(type, new MapIndex(slaveIndex), new MapIndex(masterIndex), containerName, nextResults) + { + } + + private readonly Type _objectType; + internal Type ObjectType + { + get { return _objectType; } + } + + private readonly MapIndex _slaveIndex; + internal MapIndex SlaveIndex + { + get { return _slaveIndex; } + } + + private readonly MapIndex _masterIndex; + internal MapIndex MasterIndex + { + get { return _masterIndex; } + } + + private readonly string _containerName; + internal string ContainerName + { + get { return _containerName; } + } + + private readonly MapNextResult[] _nextResults; + internal MapNextResult[] NextResults + { + get { return _nextResults; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapRelation.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapRelation.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,27 @@ +using System; + +namespace BLToolkit.Mapping +{ + public class MapRelation : MapRelationBase + { + public MapRelation( + MapResultSet slaveResultSet, + MapIndex slaveIndex, + MapIndex masterIndex, + string containerName) + : base(slaveResultSet.ObjectType, slaveIndex, masterIndex, containerName) + { + _slaveResultSet = slaveResultSet; + } + + public MapRelation(MapResultSet slaveResultSet, MapRelationBase relation) + : this(slaveResultSet, relation.SlaveIndex, relation.MasterIndex, relation.ContainerName) + { } + + private readonly MapResultSet _slaveResultSet; + public MapResultSet SlaveResultSet + { + get { return _slaveResultSet; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapRelationBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapRelationBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,58 @@ +using System; + +namespace BLToolkit.Mapping +{ + public class MapRelationBase + { + public MapRelationBase( + Type slave, + MapIndex slaveIndex, + MapIndex masterIndex, + string containerName) + { + if (slave == null) + throw new ArgumentNullException("slave"); + + if (masterIndex.Fields.Length == 0) + throw new MappingException("Master index length can not be 0."); + + if ( slaveIndex.Fields.Length == 0) + throw new MappingException("Slave index length can not be 0."); + + if (masterIndex.Fields.Length != slaveIndex.Fields.Length) + throw new MappingException("Master and slave indexes do not match."); + + if (string.IsNullOrEmpty(containerName)) + throw new MappingException("Master container field name is wrong."); + + _slave = slave; + _masterIndex = masterIndex; + _slaveIndex = slaveIndex; + _containerName = containerName; + } + + private readonly MapIndex _masterIndex; + public MapIndex MasterIndex + { + get { return _masterIndex; } + } + + private readonly MapIndex _slaveIndex; + public MapIndex SlaveIndex + { + get { return _slaveIndex; } + } + + private readonly string _containerName; + public string ContainerName + { + get { return _containerName; } + } + + private readonly Type _slave; + public Type Slave + { + get { return _slave; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapResultSet.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapResultSet.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,146 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace BLToolkit.Mapping +{ + public class MapResultSet + { + public MapResultSet(Type objectType) + { + _objectType = objectType; + } + + public MapResultSet(Type objectType, IList list) + { + _objectType = objectType; + _list = list; + } + + public MapResultSet(Type objectType, object[] parameters) + { + _objectType = objectType; + _parameters = parameters; + } + + public MapResultSet(Type objectType, IList list, object[] parameters) + { + _objectType = objectType; + _parameters = parameters; + _list = list; + } + + internal MapResultSet(MapResultSet resultSet) + { + _objectType = resultSet._objectType; + _parameters = resultSet._parameters; + + if (resultSet._relationList != null) + { + _relationList = new List(resultSet._relationList.Count); + _relationList.AddRange(resultSet._relationList); + } + } + + private readonly Type _objectType; + internal Type ObjectType + { + get { return _objectType; } + } + + private object[] _parameters; + public object[] Parameters + { + get { return _parameters; } + set { _parameters = value; } + } + + private IList _list; + public IList List + { + get { return _list ?? (_list = new List()); } + set { _list = value; } + } + + private MapRelation[] _relations; + internal MapRelation[] Relations + { + get + { + if (_relationList != null && (_relations == null || _relations.Length != _relationList.Count)) + _relations = _relationList.ToArray(); + + return _relations; + } + + set { _relations = value; } + } + + private List _relationList; + + public void AddRelation( + MapResultSet slaveResultSet, + MapIndex slaveIndex, + MapIndex masterIndex, + string containerName) + { + if (_relationList == null) + _relationList = new List(); + + _relationList.Add(new MapRelation(slaveResultSet, slaveIndex, masterIndex, containerName)); + } + + public void AddRelation( + MapResultSet slaveResultSet, + string slaveIndex, + string masterIndex, + string containerName) + { + AddRelation( slaveResultSet, new MapIndex(slaveIndex), new MapIndex(masterIndex),containerName); + } + + public void AddRelation(MapResultSet slaveResultSet, MapRelationBase relation) + { + AddRelation(slaveResultSet, relation.SlaveIndex, relation.MasterIndex, relation.ContainerName); + } + + readonly Dictionary> _indexies = new Dictionary>(); + + public IDictionary GetIndex(MappingSchema ms, MapIndex masterIndex) + { + var indexId = masterIndex.ID; + + IDictionary indexHash; + + if (_indexies.TryGetValue(indexId, out indexHash)) + return indexHash; + + var masterMapper = ms.GetObjectMapper(ObjectType); + + indexHash = new Dictionary(); + + foreach (var o in List) + { + var key = masterIndex.GetValueOrIndex(masterMapper, o); + + if (ms.IsNull(key)) + continue; + + IList matches; + + if (!indexHash.TryGetValue(key, out matches)) + indexHash.Add(key, matches = new List()); + + matches.Add(o); + } + + return indexHash; + } + + public IDictionary GetIndex(MappingSchema ms, MapRelation relation) + { + return GetIndex(ms, relation.MasterIndex); + } + } +} + diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapSetDataT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapSetDataT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,228 @@ +using System; +using System.Data.SqlTypes; + +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + [CLSCompliant(false)] + public static class MapSetData + { + public abstract class MB + { + public abstract void To(IMapDataDestination d, object o, int i, V v); + } + + public static void To(IMapDataDestination d, object o, int i, T v) + { + I.To(d, o, i, v); + } + + public static MB I = GetSetter(); + private static MB GetSetter() + { + Type t = typeof(T); + + // Scalar Types. + // + if (t == typeof(SByte)) return (MB)(object)(new I8()); + if (t == typeof(Int16)) return (MB)(object)(new I16()); + if (t == typeof(Int32)) return (MB)(object)(new I32()); + if (t == typeof(Int64)) return (MB)(object)(new I64()); + + if (t == typeof(Byte)) return (MB)(object)(new U8()); + if (t == typeof(UInt16)) return (MB)(object)(new U16()); + if (t == typeof(UInt32)) return (MB)(object)(new U32()); + if (t == typeof(UInt64)) return (MB)(object)(new U64()); + + if (t == typeof(Single)) return (MB)(object)(new R4()); + if (t == typeof(Double)) return (MB)(object)(new R8()); + + if (t == typeof(Boolean)) return (MB)(object)(new B()); + if (t == typeof(Decimal)) return (MB)(object)(new D()); + + if (t == typeof(Char)) return (MB)(object)(new C()); + if (t == typeof(Guid)) return (MB)(object)(new G()); + if (t == typeof(DateTime)) return (MB)(object)(new DT()); + if (t == typeof(DateTimeOffset)) return (MB)(object)(new DTO()); + + // Enums. + // + if (t.IsEnum) + { + t = Enum.GetUnderlyingType(t); + + if (t == typeof(SByte)) return new EI8(); + if (t == typeof(Int16)) return new EI16(); + if (t == typeof(Int32)) return new EI32(); + if (t == typeof(Int64)) return new EI64(); + + if (t == typeof(Byte)) return new EU8(); + if (t == typeof(UInt16)) return new EU16(); + if (t == typeof(UInt32)) return new EU32(); + if (t == typeof(UInt64)) return new EU64(); + } + + // Nullable Types. + // + if (t == typeof(SByte?)) return (MB)(object)(new NI8()); + if (t == typeof(Int16?)) return (MB)(object)(new NI16()); + if (t == typeof(Int32?)) return (MB)(object)(new NI32()); + if (t == typeof(Int64?)) return (MB)(object)(new NI64()); + + if (t == typeof(Byte?)) return (MB)(object)(new NU8()); + if (t == typeof(UInt16?)) return (MB)(object)(new NU16()); + if (t == typeof(UInt32?)) return (MB)(object)(new NU32()); + if (t == typeof(UInt64?)) return (MB)(object)(new NU64()); + + if (t == typeof(Single?)) return (MB)(object)(new NR4()); + if (t == typeof(Double?)) return (MB)(object)(new NR8()); + + if (t == typeof(Boolean?)) return (MB)(object)(new NB()); + if (t == typeof(Decimal?)) return (MB)(object)(new ND()); + + if (t == typeof(Char?)) return (MB)(object)(new NC()); + if (t == typeof(Guid?)) return (MB)(object)(new NG()); + if (t == typeof(DateTime?)) return (MB)(object)(new NDT()); + if (t == typeof(DateTimeOffset?)) return (MB)(object)(new NDTO()); + + // Nullable Enums. + // + if (TypeHelper.IsNullable(t) && Nullable.GetUnderlyingType(t).IsEnum) + { + Type enumType = Nullable.GetUnderlyingType(t); + t = Enum.GetUnderlyingType(enumType); + + if (t == typeof(SByte)) return (MB)Activator.CreateInstance(typeof(NEI8<>).MakeGenericType(typeof(T), enumType)); + if (t == typeof(Int16)) return (MB)Activator.CreateInstance(typeof(NEI16<>).MakeGenericType(typeof(T), enumType)); + if (t == typeof(Int32)) return (MB)Activator.CreateInstance(typeof(NEI32<>).MakeGenericType(typeof(T), enumType)); + if (t == typeof(Int64)) return (MB)Activator.CreateInstance(typeof(NEI64<>).MakeGenericType(typeof(T), enumType)); + + if (t == typeof(Byte)) return (MB)Activator.CreateInstance(typeof(NEU8<>).MakeGenericType(typeof(T), enumType)); + if (t == typeof(UInt16)) return (MB)Activator.CreateInstance(typeof(NEU16<>).MakeGenericType(typeof(T), enumType)); + if (t == typeof(UInt32)) return (MB)Activator.CreateInstance(typeof(NEU32<>).MakeGenericType(typeof(T), enumType)); + if (t == typeof(UInt64)) return (MB)Activator.CreateInstance(typeof(NEU64<>).MakeGenericType(typeof(T), enumType)); + } + +#if !SILVERLIGHT + + // SqlTypes. + // + if (t == typeof(SqlString)) return (MB)(object)(new dbS()); + + if (t == typeof(SqlByte)) return (MB)(object)(new dbU8()); + if (t == typeof(SqlInt16)) return (MB)(object)(new dbI16()); + if (t == typeof(SqlInt32)) return (MB)(object)(new dbI32()); + if (t == typeof(SqlInt64)) return (MB)(object)(new dbI64()); + + if (t == typeof(SqlSingle)) return (MB)(object)(new dbR4()); + if (t == typeof(SqlDouble)) return (MB)(object)(new dbR8()); + if (t == typeof(SqlDecimal)) return (MB)(object)(new dbD()); + if (t == typeof(SqlMoney)) return (MB)(object)(new dbM()); + + if (t == typeof(SqlBoolean)) return (MB)(object)(new dbB()); + if (t == typeof(SqlGuid)) return (MB)(object)(new dbG()); + if (t == typeof(SqlDateTime)) return (MB)(object)(new dbDT()); + +#endif + + return new Default(); + } + + // Default setter. + // + public sealed class Default : MB { public override void To(IMapDataDestination d, object o, int i, V v) { d.SetValue (o, i, v); } } + + // Scalar Types. + // + sealed class I8 : MB { public override void To(IMapDataDestination d, object o, int i, SByte v) { d.SetSByte (o, i, v); } } + sealed class I16 : MB { public override void To(IMapDataDestination d, object o, int i, Int16 v) { d.SetInt16 (o, i, v); } } + sealed class I32 : MB { public override void To(IMapDataDestination d, object o, int i, Int32 v) { d.SetInt32 (o, i, v); } } + sealed class I64 : MB { public override void To(IMapDataDestination d, object o, int i, Int64 v) { d.SetInt64 (o, i, v); } } + + sealed class U8 : MB { public override void To(IMapDataDestination d, object o, int i, Byte v) { d.SetByte (o, i, v); } } + sealed class U16 : MB { public override void To(IMapDataDestination d, object o, int i, UInt16 v) { d.SetUInt16 (o, i, v); } } + sealed class U32 : MB { public override void To(IMapDataDestination d, object o, int i, UInt32 v) { d.SetUInt32 (o, i, v); } } + sealed class U64 : MB { public override void To(IMapDataDestination d, object o, int i, UInt64 v) { d.SetUInt64 (o, i, v); } } + + sealed class R4 : MB { public override void To(IMapDataDestination d, object o, int i, Single v) { d.SetSingle (o, i, v); } } + sealed class R8 : MB { public override void To(IMapDataDestination d, object o, int i, Double v) { d.SetDouble (o, i, v); } } + + sealed class B : MB { public override void To(IMapDataDestination d, object o, int i, Boolean v) { d.SetBoolean (o, i, v); } } + sealed class D : MB { public override void To(IMapDataDestination d, object o, int i, Decimal v) { d.SetDecimal (o, i, v); } } + + sealed class C : MB { public override void To(IMapDataDestination d, object o, int i, Char v) { d.SetChar (o, i, v); } } + sealed class G : MB { public override void To(IMapDataDestination d, object o, int i, Guid v) { d.SetGuid (o, i, v); } } + sealed class DT : MB { public override void To(IMapDataDestination d, object o, int i, DateTime v) { d.SetDateTime (o, i, v); } } + sealed class DTO : MB{ public override void To(IMapDataDestination d, object o, int i, DateTimeOffset v) { d.SetDateTimeOffset (o, i, v); } } + + // Enums. + // + sealed class EI8 : MB { public override void To(IMapDataDestination d, object o, int i, E v) { d.SetSByte (o, i, (SByte)(object)v); } } + sealed class EI16 : MB { public override void To(IMapDataDestination d, object o, int i, E v) { d.SetInt16 (o, i, (Int16)(object)v); } } + sealed class EI32 : MB { public override void To(IMapDataDestination d, object o, int i, E v) { d.SetInt32 (o, i, (Int32)(object)v); } } + sealed class EI64 : MB { public override void To(IMapDataDestination d, object o, int i, E v) { d.SetInt64 (o, i, (Int64)(object)v); } } + + sealed class EU8 : MB { public override void To(IMapDataDestination d, object o, int i, E v) { d.SetByte (o, i, (Byte)(object)v); } } + sealed class EU16 : MB { public override void To(IMapDataDestination d, object o, int i, E v) { d.SetUInt16 (o, i, (UInt16)(object)v); } } + sealed class EU32 : MB { public override void To(IMapDataDestination d, object o, int i, E v) { d.SetUInt32 (o, i, (UInt32)(object)v); } } + sealed class EU64 : MB { public override void To(IMapDataDestination d, object o, int i, E v) { d.SetUInt64 (o, i, (UInt64)(object)v); } } + + // Nullable Types. + // + sealed class NI8 : MB { public override void To(IMapDataDestination d, object o, int i, SByte? v) { d.SetNullableSByte (o, i, v); } } + sealed class NI16 : MB { public override void To(IMapDataDestination d, object o, int i, Int16? v) { d.SetNullableInt16 (o, i, v); } } + sealed class NI32 : MB { public override void To(IMapDataDestination d, object o, int i, Int32? v) { d.SetNullableInt32 (o, i, v); } } + sealed class NI64 : MB { public override void To(IMapDataDestination d, object o, int i, Int64? v) { d.SetNullableInt64 (o, i, v); } } + + sealed class NU8 : MB { public override void To(IMapDataDestination d, object o, int i, Byte? v) { d.SetNullableByte (o, i, v); } } + sealed class NU16 : MB { public override void To(IMapDataDestination d, object o, int i, UInt16? v) { d.SetNullableUInt16 (o, i, v); } } + sealed class NU32 : MB { public override void To(IMapDataDestination d, object o, int i, UInt32? v) { d.SetNullableUInt32 (o, i, v); } } + sealed class NU64 : MB { public override void To(IMapDataDestination d, object o, int i, UInt64? v) { d.SetNullableUInt64 (o, i, v); } } + + sealed class NR4 : MB { public override void To(IMapDataDestination d, object o, int i, Single? v) { d.SetNullableSingle (o, i, v); } } + sealed class NR8 : MB { public override void To(IMapDataDestination d, object o, int i, Double? v) { d.SetNullableDouble (o, i, v); } } + + sealed class NB : MB { public override void To(IMapDataDestination d, object o, int i, Boolean? v) { d.SetNullableBoolean (o, i, v); } } + sealed class ND : MB { public override void To(IMapDataDestination d, object o, int i, Decimal? v) { d.SetNullableDecimal (o, i, v); } } + + sealed class NC : MB { public override void To(IMapDataDestination d, object o, int i, Char? v) { d.SetNullableChar (o, i, v); } } + sealed class NG : MB { public override void To(IMapDataDestination d, object o, int i, Guid? v) { d.SetNullableGuid (o, i, v); } } + sealed class NDT : MB { public override void To(IMapDataDestination d, object o, int i, DateTime? v) { d.SetNullableDateTime (o, i, v); } } + sealed class NDTO : MB{ public override void To(IMapDataDestination d, object o, int i, DateTimeOffset? v) { d.SetNullableDateTimeOffset (o, i, v); } } + + // Nullable Enums. + // + sealed class NEI8 : MB where E : struct { public override void To(IMapDataDestination d, object o, int i, E? v) { /*if (null == v) d.SetNull(o, i); else*/ d.SetSByte (o, i, (SByte)(object)v.Value); } } + sealed class NEI16 : MB where E : struct { public override void To(IMapDataDestination d, object o, int i, E? v) { /*if (null == v) d.SetNull(o, i); else*/ d.SetInt16 (o, i, (Int16)(object)v.Value); } } + sealed class NEI32 : MB where E : struct { public override void To(IMapDataDestination d, object o, int i, E? v) { /*if (null == v) d.SetNull(o, i); else*/ d.SetInt32 (o, i, (Int32)(object)v.Value); } } + sealed class NEI64 : MB where E : struct { public override void To(IMapDataDestination d, object o, int i, E? v) { /*if (null == v) d.SetNull(o, i); else*/ d.SetInt64 (o, i, (Int64)(object)v.Value); } } + + sealed class NEU8 : MB where E : struct { public override void To(IMapDataDestination d, object o, int i, E? v) { /*if (null == v) d.SetNull(o, i); else*/ d.SetByte (o, i, (Byte)(object)v.Value); } } + sealed class NEU16 : MB where E : struct { public override void To(IMapDataDestination d, object o, int i, E? v) { /*if (null == v) d.SetNull(o, i); else*/ d.SetUInt16(o, i, (UInt16)(object)v.Value); } } + sealed class NEU32 : MB where E : struct { public override void To(IMapDataDestination d, object o, int i, E? v) { /*if (null == v) d.SetNull(o, i); else*/ d.SetUInt32(o, i, (UInt32)(object)v.Value); } } + sealed class NEU64 : MB where E : struct { public override void To(IMapDataDestination d, object o, int i, E? v) { /*if (null == v) d.SetNull(o, i); else*/ d.SetUInt64(o, i, (UInt64)(object)v.Value); } } + +#if !SILVERLIGHT + + // SqlTypes. + // + sealed class dbS : MB { public override void To(IMapDataDestination d, object o, int i, SqlString v) { d.SetSqlString (o, i, v); } } + + sealed class dbU8 : MB { public override void To(IMapDataDestination d, object o, int i, SqlByte v) { d.SetSqlByte (o, i, v); } } + sealed class dbI16 : MB { public override void To(IMapDataDestination d, object o, int i, SqlInt16 v) { d.SetSqlInt16 (o, i, v); } } + sealed class dbI32 : MB { public override void To(IMapDataDestination d, object o, int i, SqlInt32 v) { d.SetSqlInt32 (o, i, v); } } + sealed class dbI64 : MB { public override void To(IMapDataDestination d, object o, int i, SqlInt64 v) { d.SetSqlInt64 (o, i, v); } } + + sealed class dbR4 : MB { public override void To(IMapDataDestination d, object o, int i, SqlSingle v) { d.SetSqlSingle (o, i, v); } } + sealed class dbR8 : MB { public override void To(IMapDataDestination d, object o, int i, SqlDouble v) { d.SetSqlDouble (o, i, v); } } + sealed class dbD : MB { public override void To(IMapDataDestination d, object o, int i, SqlDecimal v) { d.SetSqlDecimal (o, i, v); } } + sealed class dbM : MB { public override void To(IMapDataDestination d, object o, int i, SqlMoney v) { d.SetSqlMoney (o, i, v); } } + + sealed class dbB : MB { public override void To(IMapDataDestination d, object o, int i, SqlBoolean v) { d.SetSqlBoolean (o, i, v); } } + sealed class dbG : MB { public override void To(IMapDataDestination d, object o, int i, SqlGuid v) { d.SetSqlGuid (o, i, v); } } + sealed class dbDT : MB { public override void To(IMapDataDestination d, object o, int i, SqlDateTime v) { d.SetSqlDateTime (o, i, v); } } + +#endif + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapValue.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapValue.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ +namespace BLToolkit.Mapping +{ + public class MapValue + { + public MapValue(object origValue, params object[] mapValues) + { + _origValue = origValue; + _mapValues = mapValues; + } + + private readonly object _origValue; + public object OrigValue + { + get { return _origValue; } + } + + private readonly object[] _mapValues; + public object[] MapValues + { + get { return _mapValues; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MapValueAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MapValueAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,108 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace BLToolkit.Mapping +{ + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")] + [AttributeUsage( + AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Enum | + AttributeTargets.Class | AttributeTargets.Interface, + AllowMultiple=true)] + public class MapValueAttribute : Attribute + { + public MapValueAttribute(object value1) + { + SetValues(null, null, value1); + } + + public MapValueAttribute(object[] values) + { + SetValues(null, null, values); + } + + public MapValueAttribute(object origValue, object[] values) + { + SetValues(null, origValue, values); + } + + public MapValueAttribute(object origValue, object value1) + { + SetValues(null, origValue, value1); + } + + public MapValueAttribute(object origValue, object value1, object value2) + { + SetValues(null, origValue, value1, value2); + } + + public MapValueAttribute(object origValue, object value1, object value2, object value3) + { + SetValues(null, origValue, value1, value2, value3); + } + + public MapValueAttribute(object origValue, object value1, object value2, object value3, object value4) + { + SetValues(null, origValue, value1, value2, value3, value4); + } + + public MapValueAttribute(object origValue, object value1, object value2, object value3, object value4, object value5) + { + SetValues(null, origValue, value1, value2, value3, value4, value5); + } + + public MapValueAttribute(Type type, object origValue, object[] values) + { + SetValues(type, origValue, values); + } + + public MapValueAttribute(Type type, object origValue, object value1) + { + SetValues(type, origValue, value1); + } + + public MapValueAttribute(Type type, object origValue, object value1, object value2) + { + SetValues(type, origValue, value1, value2); + } + + public MapValueAttribute(Type type, object origValue, object value1, object value2, object value3) + { + SetValues(type, origValue, value1, value2, value3); + } + + public MapValueAttribute(Type type, object origValue, object value1, object value2, object value3, object value4) + { + SetValues(type, origValue, value1, value2, value3, value4); + } + + public MapValueAttribute(Type type, object origValue, object value1, object value2, object value3, object value4, object value5) + { + SetValues(type, origValue, value1, value2, value3, value4, value5); + } + + protected void SetValues(Type type, object origValue, params object[] values) + { + _type = type; + _origValue = origValue; + _values = values; + } + + private Type _type; + public object Type + { + get { return _type; } + } + + private object _origValue; + public object OrigValue + { + get { return _origValue; } + } + + private object[] _values; + public object[] Values + { + get { return _values; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Mapping.xsd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Mapping.xsd Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Source/Mapping/Mapping.xsx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/Mapping.xsx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MappingException.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MappingException.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,88 @@ +using System; +using System.Runtime.Serialization; + +namespace BLToolkit.Mapping +{ + /// + /// Defines the base class for the namespace exceptions. + /// + /// + /// This class is the base class for exceptions that may occur during + /// the execution of the class and other namespace members. + /// + [Serializable] + public class MappingException : Exception + { + /// + /// Initializes a new instance of the class. + /// + /// + /// This constructor initializes the + /// property of the new instance + /// to a system-supplied message that describes the error, + /// such as "A Mapping exception has occurred." + /// + public MappingException() + : base("A Mapping exception has occurred.") + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message. + /// + /// The message to display to the client when the + /// exception is thrown. + /// + public MappingException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message and InnerException property. + /// + /// The message to display to the client when the + /// exception is thrown. + /// The InnerException, if any, that threw + /// the current exception. + /// + /// + public MappingException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified InnerException property. + /// + /// exception is thrown. + /// The InnerException, if any, that threw + /// the current exception. + /// + public MappingException(Exception innerException) + : base(innerException.Message, innerException) + { + } + +#if !SILVERLIGHT + + /// + /// Initializes a new instance of the class + /// with serialized data. + /// + /// The object that holds the serialized object data. + /// The contextual information about the source or + /// destination. + /// This constructor is called during deserialization to + /// reconstitute the exception object transmitted over a stream. + protected MappingException(SerializationInfo info, StreamingContext context) + : base(info,context) + { + } + +#endif + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MappingSchema.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MappingSchema.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3921 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Data.Linq; +using System.Data.SqlTypes; +using System.Diagnostics; +using System.Linq; +using System.IO; +using System.Reflection; +using System.Diagnostics.CodeAnalysis; +using System.Threading; +using System.Xml; + +#if !SILVERLIGHT +using System.Xml.Linq; +#endif + +using BLToolkit.Common; +using BLToolkit.Properties; +using BLToolkit.Reflection; +using BLToolkit.Reflection.Extension; +using BLToolkit.Reflection.MetadataProvider; + +#region ReSharper disable +// ReSharper disable SuggestUseVarKeywordEvident +// ReSharper disable UseObjectOrCollectionInitializer +// ReSharper disable SuggestUseVarKeywordEverywhere +// ReSharper disable RedundantTypeArgumentsOfMethod +#endregion + +using KeyValue = System.Collections.Generic.KeyValuePair; +using Convert = BLToolkit.Common.Convert; + +namespace BLToolkit.Mapping +{ + public class MappingSchema + { + #region Constructors + + public MappingSchema() + { + InitNullValues(); + } + + #endregion + + #region ObjectMapper Support + + private readonly Dictionary _mappers = new Dictionary(); + private readonly Dictionary _pendingMappers = new Dictionary(); + + public ObjectMapper GetObjectMapper(Type type) + { + ObjectMapper om; + + lock (_mappers) + { + if (_mappers.TryGetValue(type, out om)) + return om; + + // This object mapper is initializing right now. + // Note that only one thread can access to _pendingMappers each time. + // + if (_pendingMappers.TryGetValue(type, out om)) + return om; + + om = CreateObjectMapper(type); + + if (om == null) + throw new MappingException( + string.Format("Cannot create object mapper for the '{0}' type.", type.FullName)); + + _pendingMappers.Add(type, om); + + try + { + om.Init(this, type); + } + finally + { + _pendingMappers.Remove(type); + } + + // Officially publish this ready to use object mapper. + // + SetObjectMapperInternal(type, om); + + return om; + } + } + + private void SetObjectMapperInternal(Type type, ObjectMapper om) + { + _mappers.Add(type, om); + + if (type.IsAbstract) + { + var actualType = TypeAccessor.GetAccessor(type).Type; + + if (!_mappers.ContainsKey(actualType)) + _mappers.Add(actualType, om); + } + } + + public void SetObjectMapper(Type type, ObjectMapper om) + { + if (type == null) throw new ArgumentNullException("type"); + + lock (_mappers) + SetObjectMapperInternal(type, om); + } + + protected virtual ObjectMapper CreateObjectMapper(Type type) + { + Attribute attr = TypeHelper.GetFirstAttribute(type, typeof(ObjectMapperAttribute)); + return attr == null? CreateObjectMapperInstance(type): ((ObjectMapperAttribute)attr).ObjectMapper; + } + + protected virtual ObjectMapper CreateObjectMapperInstance(Type type) + { + return new ObjectMapper(); + } + + #endregion + + #region MetadataProvider + + private MetadataProviderBase _metadataProvider; + public MetadataProviderBase MetadataProvider + { + [DebuggerStepThrough] + get { return _metadataProvider ?? (_metadataProvider = CreateMetadataProvider()); } + set { _metadataProvider = value; } + } + + protected virtual MetadataProviderBase CreateMetadataProvider() + { + return MetadataProviderBase.CreateProvider(); + } + + #endregion + + #region Public Members + + public virtual ExtensionList Extensions { get; set; } + + #endregion + + #region Convert + + public virtual void InitNullValues() + { + DefaultSByteNullValue = (SByte) GetNullValue(typeof(SByte)); + DefaultInt16NullValue = (Int16) GetNullValue(typeof(Int16)); + DefaultInt32NullValue = (Int32) GetNullValue(typeof(Int32)); + DefaultInt64NullValue = (Int64) GetNullValue(typeof(Int64)); + DefaultByteNullValue = (Byte) GetNullValue(typeof(Byte)); + DefaultUInt16NullValue = (UInt16) GetNullValue(typeof(UInt16)); + DefaultUInt32NullValue = (UInt32) GetNullValue(typeof(UInt32)); + DefaultUInt64NullValue = (UInt64) GetNullValue(typeof(UInt64)); + DefaultCharNullValue = (Char) GetNullValue(typeof(Char)); + DefaultSingleNullValue = (Single) GetNullValue(typeof(Single)); + DefaultDoubleNullValue = (Double) GetNullValue(typeof(Double)); + DefaultBooleanNullValue = (Boolean) GetNullValue(typeof(Boolean)); + + DefaultStringNullValue = (String) GetNullValue(typeof(String)); + DefaultDateTimeNullValue = (DateTime) GetNullValue(typeof(DateTime)); + DefaultDateTimeOffsetNullValue = (DateTimeOffset)GetNullValue(typeof(DateTimeOffset)); + DefaultLinqBinaryNullValue = (Binary) GetNullValue(typeof(Binary)); + DefaultDecimalNullValue = (Decimal) GetNullValue(typeof(Decimal)); + DefaultGuidNullValue = (Guid) GetNullValue(typeof(Guid)); + DefaultStreamNullValue = (Stream) GetNullValue(typeof(Stream)); +#if !SILVERLIGHT + DefaultXmlReaderNullValue = (XmlReader) GetNullValue(typeof(XmlReader)); + DefaultXmlDocumentNullValue = (XmlDocument) GetNullValue(typeof(XmlDocument)); + DefaultXElementNullValue = (XElement) GetNullValue(typeof(XElement)); +#endif + } + + #region Primitive Types + + [CLSCompliant(false)] + public sbyte DefaultSByteNullValue { get; set; } + + [CLSCompliant(false)] + public virtual SByte ConvertToSByte(object value) + { + return + value is SByte ? (SByte)value : + value is Byte ? (SByte)(Byte)value : + value == null ? DefaultSByteNullValue : + Convert.ToSByte(value); + } + + public short DefaultInt16NullValue { get; set; } + + public virtual Int16 ConvertToInt16(object value) + { + return + value is Int16? (Int16)value: + value == null || value is DBNull? DefaultInt16NullValue: + Convert.ToInt16(value); + } + + public int DefaultInt32NullValue { get; set; } + + public virtual Int32 ConvertToInt32(object value) + { + return + value is Int32? (Int32)value: + value == null || value is DBNull? DefaultInt32NullValue: + Convert.ToInt32(value); + } + + public long DefaultInt64NullValue { get; set; } + + public virtual Int64 ConvertToInt64(object value) + { + return + value is Int64? (Int64)value: + value == null || value is DBNull? DefaultInt64NullValue: + Convert.ToInt64(value); + } + + public byte DefaultByteNullValue { get; set; } + + public virtual Byte ConvertToByte(object value) + { + return + value is Byte? (Byte)value: + value == null || value is DBNull? DefaultByteNullValue: + Convert.ToByte(value); + } + + [CLSCompliant(false)] + public ushort DefaultUInt16NullValue { get; set; } + + [CLSCompliant(false)] + public virtual UInt16 ConvertToUInt16(object value) + { + return + value is UInt16? (UInt16)value: + value is Int16? (UInt16)(Int16)value: + value == null || value is DBNull? DefaultUInt16NullValue: + Convert.ToUInt16(value); + } + + [CLSCompliant(false)] + public uint DefaultUInt32NullValue { get; set; } + + [CLSCompliant(false)] + public virtual UInt32 ConvertToUInt32(object value) + { + return + value is UInt32? (UInt32)value: + value is Int32? (UInt32)(Int32)value: + value == null || value is DBNull? DefaultUInt32NullValue: + Convert.ToUInt32(value); + } + + [CLSCompliant(false)] + public ulong DefaultUInt64NullValue { get; set; } + + [CLSCompliant(false)] + public virtual UInt64 ConvertToUInt64(object value) + { + return + value is UInt64? (UInt64)value: + value is Int64? (UInt64)(Int64)value: + value == null || value is DBNull? DefaultUInt64NullValue: + Convert.ToUInt64(value); + } + + public char DefaultCharNullValue { get; set; } + + public virtual Char ConvertToChar(object value) + { + return + value is Char? (Char)value: + value == null || value is DBNull? DefaultCharNullValue: + Convert.ToChar(value); + } + + public float DefaultSingleNullValue { get; set; } + + public virtual Single ConvertToSingle(object value) + { + return + value is Single? (Single)value: + value == null || value is DBNull? DefaultSingleNullValue: + Convert.ToSingle(value); + } + + public double DefaultDoubleNullValue { get; set; } + + public virtual Double ConvertToDouble(object value) + { + return + value is Double? (Double)value: + value == null || value is DBNull? DefaultDoubleNullValue: + Convert.ToDouble(value); + } + + public bool DefaultBooleanNullValue { get; set; } + + public virtual Boolean ConvertToBoolean(object value) + { + return + value is Boolean? (Boolean)value: + value == null || value is DBNull? DefaultBooleanNullValue: + Convert.ToBoolean(value); + } + + #endregion + + #region Simple Types + + public string DefaultStringNullValue { get; set; } + + public virtual String ConvertToString(object value) + { + return + value is String? (String)value : + value == null || value is DBNull? DefaultStringNullValue: + Convert.ToString(value); + } + + public DateTime DefaultDateTimeNullValue { get; set; } + + public virtual DateTime ConvertToDateTime(object value) + { + return + value is DateTime? (DateTime)value: + value == null || value is DBNull? DefaultDateTimeNullValue: + Convert.ToDateTime(value); + } + + public virtual TimeSpan ConvertToTimeSpan(object value) + { + return ConvertToDateTime(value).TimeOfDay; + } + + public DateTimeOffset DefaultDateTimeOffsetNullValue { get; set; } + + public virtual DateTimeOffset ConvertToDateTimeOffset(object value) + { + return + value is DateTimeOffset? (DateTimeOffset)value: + value == null || value is DBNull? DefaultDateTimeOffsetNullValue: + Convert.ToDateTimeOffset(value); + } + + public Binary DefaultLinqBinaryNullValue { get; set; } + + public virtual Binary ConvertToLinqBinary(object value) + { + return + value is Binary ? (Binary)value: + value is byte[] ? new Binary((byte[])value) : + value == null || value is DBNull? DefaultLinqBinaryNullValue: + Convert.ToLinqBinary(value); + } + + public decimal DefaultDecimalNullValue { get; set; } + + public virtual Decimal ConvertToDecimal(object value) + { + return + value is Decimal? (Decimal)value: + value == null || value is DBNull? DefaultDecimalNullValue: + Convert.ToDecimal(value); + } + + public Guid DefaultGuidNullValue { get; set; } + + public virtual Guid ConvertToGuid(object value) + { + return + value is Guid? (Guid)value: + value == null || value is DBNull? DefaultGuidNullValue: + Convert.ToGuid(value); + } + + public Stream DefaultStreamNullValue { get; set; } + + public virtual Stream ConvertToStream(object value) + { + return + value is Stream? (Stream)value: + value == null || value is DBNull? DefaultStreamNullValue: + Convert.ToStream(value); + } + +#if !SILVERLIGHT + + public XmlReader DefaultXmlReaderNullValue { get; set; } + + public virtual XmlReader ConvertToXmlReader(object value) + { + return + value is XmlReader? (XmlReader)value: + value == null || value is DBNull? DefaultXmlReaderNullValue: + Convert.ToXmlReader(value); + } + + public XmlDocument DefaultXmlDocumentNullValue { get; set; } + + public virtual XmlDocument ConvertToXmlDocument(object value) + { + return + value is XmlDocument? (XmlDocument)value: + value == null || value is DBNull? DefaultXmlDocumentNullValue: + Convert.ToXmlDocument(value); + } + + public XElement DefaultXElementNullValue { get; set; } + + public virtual XElement ConvertToXElement(object value) + { + return + value is XElement ? (XElement)value : + value == null || value is DBNull ? DefaultXElementNullValue : + XElement.Parse(value.ToString()); + } + +#endif + + public virtual byte[] ConvertToByteArray(object value) + { + return + value is byte[]? (byte[])value: + value == null || value is DBNull? null: + Convert.ToByteArray(value); + } + + public virtual char[] ConvertToCharArray(object value) + { + return + value is char[]? (char[])value: + value == null || value is DBNull? null: + Convert.ToCharArray(value); + } + + #endregion + + #region Nullable Types + + [CLSCompliant(false)] + public virtual SByte? ConvertToNullableSByte(object value) + { + return + value is SByte? (SByte?)value: + value is Byte? (SByte?)(Byte)value: + value == null || value is DBNull? null: + Convert.ToNullableSByte(value); + } + + public virtual Int16? ConvertToNullableInt16(object value) + { + return + value is Int16? (Int16?)value: + value == null || value is DBNull? null: + Convert.ToNullableInt16(value); + } + + public virtual Int32? ConvertToNullableInt32(object value) + { + return + value is Int32? (Int32?)value: + value == null || value is DBNull? null: + Convert.ToNullableInt32(value); + } + + public virtual Int64? ConvertToNullableInt64(object value) + { + return + value is Int64? (Int64?)value: + value == null || value is DBNull? null: + Convert.ToNullableInt64(value); + } + + public virtual Byte? ConvertToNullableByte(object value) + { + return + value is Byte? (Byte?)value: + value == null || value is DBNull? null: + Convert.ToNullableByte(value); + } + + [CLSCompliant(false)] + public virtual UInt16? ConvertToNullableUInt16(object value) + { + return + value is UInt16? (UInt16?)value: + value is Int16? (UInt16?)(Int16)value: + value == null || value is DBNull? null: + Convert.ToNullableUInt16(value); + } + + [CLSCompliant(false)] + public virtual UInt32? ConvertToNullableUInt32(object value) + { + return + value is UInt32? (UInt32?)value: + value is Int32? (UInt32?)(Int32)value: + value == null || value is DBNull? null: + Convert.ToNullableUInt32(value); + } + + [CLSCompliant(false)] + public virtual UInt64? ConvertToNullableUInt64(object value) + { + return + value is UInt64? (UInt64?)value: + value is Int64? (UInt64?)(Int64)value: + value == null || value is DBNull? null: + Convert.ToNullableUInt64(value); + } + + public virtual Char? ConvertToNullableChar(object value) + { + return + value is Char? (Char?)value: + value == null || value is DBNull? null: + Convert.ToNullableChar(value); + } + + public virtual Double? ConvertToNullableDouble(object value) + { + return + value is Double? (Double?)value: + value == null || value is DBNull? null: + Convert.ToNullableDouble(value); + } + + public virtual Single? ConvertToNullableSingle(object value) + { + return + value is Single? (Single?)value: + value == null || value is DBNull? null: + Convert.ToNullableSingle(value); + } + + public virtual Boolean? ConvertToNullableBoolean(object value) + { + return + value is Boolean? (Boolean?)value: + value == null || value is DBNull? null: + Convert.ToNullableBoolean(value); + } + + public virtual DateTime? ConvertToNullableDateTime(object value) + { + return + value is DateTime? (DateTime?)value: + value == null || value is DBNull? null: + Convert.ToNullableDateTime(value); + } + + public virtual TimeSpan? ConvertToNullableTimeSpan(object value) + { + DateTime? dt = ConvertToNullableDateTime(value); + return dt == null? null : (TimeSpan?)dt.Value.TimeOfDay; + } + + public virtual DateTimeOffset? ConvertToNullableDateTimeOffset(object value) + { + return + value is DateTimeOffset? (DateTimeOffset?)value: + value == null || value is DBNull? null: + Convert.ToNullableDateTimeOffset(value); + } + + public virtual Decimal? ConvertToNullableDecimal(object value) + { + return + value is Decimal? (Decimal?)value: + value == null || value is DBNull? null: + Convert.ToNullableDecimal(value); + } + + public virtual Guid? ConvertToNullableGuid(object value) + { + return + value is Guid? (Guid?)value: + value == null || value is DBNull? null: + Convert.ToNullableGuid(value); + } + + #endregion + + #region SqlTypes + +#if !SILVERLIGHT + + public virtual SqlByte ConvertToSqlByte(object value) + { + return + value == null || value is DBNull? SqlByte.Null : + value is SqlByte? (SqlByte)value: + Convert.ToSqlByte(value); + } + + public virtual SqlInt16 ConvertToSqlInt16(object value) + { + return + value == null || value is DBNull? SqlInt16.Null: + value is SqlInt16? (SqlInt16)value: + Convert.ToSqlInt16(value); + } + + public virtual SqlInt32 ConvertToSqlInt32(object value) + { + return + value == null || value is DBNull? SqlInt32.Null: + value is SqlInt32? (SqlInt32)value: + Convert.ToSqlInt32(value); + } + + public virtual SqlInt64 ConvertToSqlInt64(object value) + { + return + value == null || value is DBNull? SqlInt64.Null: + value is SqlInt64? (SqlInt64)value: + Convert.ToSqlInt64(value); + } + + public virtual SqlSingle ConvertToSqlSingle(object value) + { + return + value == null || value is DBNull? SqlSingle.Null: + value is SqlSingle? (SqlSingle)value: + Convert.ToSqlSingle(value); + } + + public virtual SqlBoolean ConvertToSqlBoolean(object value) + { + return + value == null || value is DBNull? SqlBoolean.Null: + value is SqlBoolean? (SqlBoolean)value: + Convert.ToSqlBoolean(value); + } + + public virtual SqlDouble ConvertToSqlDouble(object value) + { + return + value == null || value is DBNull? SqlDouble.Null: + value is SqlDouble? (SqlDouble)value: + Convert.ToSqlDouble(value); + } + + public virtual SqlDateTime ConvertToSqlDateTime(object value) + { + return + value == null || value is DBNull? SqlDateTime.Null: + value is SqlDateTime? (SqlDateTime)value: + Convert.ToSqlDateTime(value); + } + + public virtual SqlDecimal ConvertToSqlDecimal(object value) + { + return + value == null || value is DBNull? SqlDecimal.Null: + value is SqlDecimal? (SqlDecimal)value: + value is SqlMoney? ((SqlMoney)value).ToSqlDecimal(): + Convert.ToSqlDecimal(value); + } + + public virtual SqlMoney ConvertToSqlMoney(object value) + { + return + value == null || value is DBNull? SqlMoney.Null: + value is SqlMoney? (SqlMoney)value: + value is SqlDecimal? ((SqlDecimal)value).ToSqlMoney(): + Convert.ToSqlMoney(value); + } + + public virtual SqlString ConvertToSqlString(object value) + { + return + value == null || value is DBNull? SqlString.Null: + value is SqlString? (SqlString)value: + Convert.ToSqlString(value); + } + + public virtual SqlBinary ConvertToSqlBinary(object value) + { + return + value == null || value is DBNull? SqlBinary.Null: + value is SqlBinary? (SqlBinary)value: + Convert.ToSqlBinary(value); + } + + public virtual SqlGuid ConvertToSqlGuid(object value) + { + return + value == null || value is DBNull? SqlGuid.Null: + value is SqlGuid? (SqlGuid)value: + Convert.ToSqlGuid(value); + } + + public virtual SqlBytes ConvertToSqlBytes(object value) + { + return + value == null || value is DBNull? SqlBytes.Null: + value is SqlBytes? (SqlBytes)value: + Convert.ToSqlBytes(value); + } + + public virtual SqlChars ConvertToSqlChars(object value) + { + return + value == null || value is DBNull? SqlChars.Null: + value is SqlChars? (SqlChars)value: + Convert.ToSqlChars(value); + } + + public virtual SqlXml ConvertToSqlXml(object value) + { + return + value == null || value is DBNull? SqlXml.Null: + value is SqlXml? (SqlXml)value: + Convert.ToSqlXml(value); + } + +#endif + + #endregion + + #region General case + + public virtual T GetDefaultNullValue() + { + switch (Type.GetTypeCode(typeof(T))) + { + case TypeCode.Boolean: return (T)(object)DefaultBooleanNullValue; + case TypeCode.Byte: return (T)(object)DefaultByteNullValue; + case TypeCode.Char: return (T)(object)DefaultCharNullValue; + case TypeCode.DateTime: return (T)(object)DefaultDateTimeNullValue; + case TypeCode.Decimal: return (T)(object)DefaultDecimalNullValue; + case TypeCode.Double: return (T)(object)DefaultDoubleNullValue; + case TypeCode.Int16: return (T)(object)DefaultInt16NullValue; + case TypeCode.Int32: return (T)(object)DefaultInt32NullValue; + case TypeCode.Int64: return (T)(object)DefaultInt64NullValue; + case TypeCode.SByte: return (T)(object)DefaultSByteNullValue; + case TypeCode.Single: return (T)(object)DefaultSingleNullValue; + case TypeCode.String: return (T)(object)DefaultStringNullValue; + case TypeCode.UInt16: return (T)(object)DefaultUInt16NullValue; + case TypeCode.UInt32: return (T)(object)DefaultUInt32NullValue; + case TypeCode.UInt64: return (T)(object)DefaultUInt64NullValue; + } + + if (typeof(Guid) == typeof(T)) return (T)(object)DefaultGuidNullValue; + if (typeof(Stream) == typeof(T)) return (T)(object)DefaultStreamNullValue; +#if !SILVERLIGHT + if (typeof(XmlReader) == typeof(T)) return (T)(object)DefaultXmlReaderNullValue; + if (typeof(XmlDocument) == typeof(T)) return (T)(object)DefaultXmlDocumentNullValue; + if (typeof(XElement) == typeof(T)) return (T)(object)DefaultXElementNullValue; +#endif + if (typeof(DateTimeOffset) == typeof(T)) return (T)(object)DefaultDateTimeOffsetNullValue; + + return default(T); + } + + public virtual T ConvertTo(TP value) + { + return Equals(value, default(TP))? + GetDefaultNullValue(): + Convert.From(value); + } + + public virtual object ConvertChangeType(object value, Type conversionType) + { + return ConvertChangeType(value, conversionType, TypeHelper.IsNullable(conversionType)); + } + + public virtual object ConvertChangeType(object value, Type conversionType, bool isNullable) + { + if (conversionType.IsArray) + { + if (null == value) + return null; + + Type srcType = value.GetType(); + + if (srcType == conversionType) + return value; + + if (srcType.IsArray) + { + Type srcElementType = srcType.GetElementType(); + Type dstElementType = conversionType.GetElementType(); + + if (srcElementType.IsArray != dstElementType.IsArray + || (srcElementType.IsArray && + srcElementType.GetArrayRank() != dstElementType.GetArrayRank())) + { + throw new InvalidCastException(string.Format( + Resources.MappingSchema_IncompatibleArrayTypes, + srcType.FullName, conversionType.FullName)); + } + + Array srcArray = (Array)value; + Array dstArray; + + int rank = srcArray.Rank; + + if (rank == 1 && 0 == srcArray.GetLowerBound(0)) + { + int arrayLength = srcArray.Length; + + dstArray = Array.CreateInstance(dstElementType, arrayLength); + + // Int32 is assignable from UInt32, SByte from Byte and so on. + // + if (dstElementType.IsAssignableFrom(srcElementType)) + Array.Copy(srcArray, dstArray, arrayLength); + else + for (int i = 0; i < arrayLength; ++i) + dstArray.SetValue(ConvertChangeType(srcArray.GetValue(i), dstElementType, isNullable), i); + } + else + { +#if SILVERLIGHT + throw new InvalidOperationException(); +#else + var arrayLength = 1; + var dimensions = new int[rank]; + var indices = new int[rank]; + var lbounds = new int[rank]; + + for (int i = 0; i < rank; ++i) + { + arrayLength *= (dimensions[i] = srcArray.GetLength(i)); + lbounds[i] = srcArray.GetLowerBound(i); + } + + dstArray = Array.CreateInstance(dstElementType, dimensions, lbounds); + + for (int i = 0; i < arrayLength; ++i) + { + var index = i; + + for (var j = rank - 1; j >= 0; --j) + { + indices[j] = index % dimensions[j] + lbounds[j]; + index /= dimensions[j]; + } + + dstArray.SetValue(ConvertChangeType(srcArray.GetValue(indices), dstElementType, isNullable), indices); + } + +#endif + } + + return dstArray; + } + } + else if (conversionType.IsEnum) + { + return MapValueToEnum(value, conversionType); + } + + if (isNullable) + { + if (TypeHelper.IsNullable(conversionType)) + { + // Return a null reference or boxed not null value. + // + return value == null || value is DBNull? null: + ConvertChangeType(value, conversionType.GetGenericArguments()[0]); + } + + Type type = conversionType.IsEnum? Enum.GetUnderlyingType(conversionType): conversionType; + + switch (Type.GetTypeCode(type)) + { + case TypeCode.Boolean: return ConvertToNullableBoolean (value); + case TypeCode.Byte: return ConvertToNullableByte (value); + case TypeCode.Char: return ConvertToNullableChar (value); + case TypeCode.DateTime: return ConvertToNullableDateTime(value); + case TypeCode.Decimal: return ConvertToNullableDecimal (value); + case TypeCode.Double: return ConvertToNullableDouble (value); + case TypeCode.Int16: return ConvertToNullableInt16 (value); + case TypeCode.Int32: return ConvertToNullableInt32 (value); + case TypeCode.Int64: return ConvertToNullableInt64 (value); + case TypeCode.SByte: return ConvertToNullableSByte (value); + case TypeCode.Single: return ConvertToNullableSingle (value); + case TypeCode.UInt16: return ConvertToNullableUInt16 (value); + case TypeCode.UInt32: return ConvertToNullableUInt32 (value); + case TypeCode.UInt64: return ConvertToNullableUInt64 (value); + } + + if (typeof(Guid) == conversionType) return ConvertToNullableGuid(value); + if (typeof(DateTimeOffset) == conversionType) return ConvertToNullableDateTimeOffset(value); + if (typeof(TimeSpan) == conversionType) return ConvertToNullableTimeSpan(value); + } + + switch (Type.GetTypeCode(conversionType)) + { + case TypeCode.Boolean: return ConvertToBoolean (value); + case TypeCode.Byte: return ConvertToByte (value); + case TypeCode.Char: return ConvertToChar (value); + case TypeCode.DateTime: return ConvertToDateTime(value); + case TypeCode.Decimal: return ConvertToDecimal (value); + case TypeCode.Double: return ConvertToDouble (value); + case TypeCode.Int16: return ConvertToInt16 (value); + case TypeCode.Int32: return ConvertToInt32 (value); + case TypeCode.Int64: return ConvertToInt64 (value); + case TypeCode.SByte: return ConvertToSByte (value); + case TypeCode.Single: return ConvertToSingle (value); + case TypeCode.String: return ConvertToString (value); + case TypeCode.UInt16: return ConvertToUInt16 (value); + case TypeCode.UInt32: return ConvertToUInt32 (value); + case TypeCode.UInt64: return ConvertToUInt64 (value); + } + + if (typeof(Guid) == conversionType) return ConvertToGuid (value); + if (typeof(Stream) == conversionType) return ConvertToStream (value); +#if !SILVERLIGHT + if (typeof(XmlReader) == conversionType) return ConvertToXmlReader (value); + if (typeof(XmlDocument) == conversionType) return ConvertToXmlDocument (value); + if (typeof(XElement) == conversionType) return ConvertToXElement (value); +#endif + if (typeof(byte[]) == conversionType) return ConvertToByteArray (value); + if (typeof(Binary) == conversionType) return ConvertToLinqBinary (value); + if (typeof(DateTimeOffset) == conversionType) return ConvertToDateTimeOffset(value); + if (typeof(char[]) == conversionType) return ConvertToCharArray (value); + if (typeof(TimeSpan) == conversionType) return ConvertToTimeSpan (value); + +#if !SILVERLIGHT + + if (typeof(SqlInt32) == conversionType) return ConvertToSqlInt32 (value); + if (typeof(SqlString) == conversionType) return ConvertToSqlString (value); + if (typeof(SqlDecimal) == conversionType) return ConvertToSqlDecimal (value); + if (typeof(SqlDateTime) == conversionType) return ConvertToSqlDateTime (value); + if (typeof(SqlBoolean) == conversionType) return ConvertToSqlBoolean (value); + if (typeof(SqlMoney) == conversionType) return ConvertToSqlMoney (value); + if (typeof(SqlGuid) == conversionType) return ConvertToSqlGuid (value); + if (typeof(SqlDouble) == conversionType) return ConvertToSqlDouble (value); + if (typeof(SqlByte) == conversionType) return ConvertToSqlByte (value); + if (typeof(SqlInt16) == conversionType) return ConvertToSqlInt16 (value); + if (typeof(SqlInt64) == conversionType) return ConvertToSqlInt64 (value); + if (typeof(SqlSingle) == conversionType) return ConvertToSqlSingle (value); + if (typeof(SqlBinary) == conversionType) return ConvertToSqlBinary (value); + if (typeof(SqlBytes) == conversionType) return ConvertToSqlBytes (value); + if (typeof(SqlChars) == conversionType) return ConvertToSqlChars (value); + if (typeof(SqlXml) == conversionType) return ConvertToSqlXml (value); + +#endif + + return System.Convert.ChangeType(value, conversionType, Thread.CurrentThread.CurrentCulture); + } + + #endregion + + #endregion + + #region Factory Members + + public virtual DataReaderMapper CreateDataReaderMapper(IDataReader dataReader) + { + return new DataReaderMapper(this, dataReader); + } + + public virtual DataReaderListMapper CreateDataReaderListMapper(IDataReader reader) + { + return new DataReaderListMapper(CreateDataReaderMapper(reader)); + } + + public virtual DataReaderMapper CreateDataReaderMapper( + IDataReader dataReader, + NameOrIndexParameter nameOrIndex) + { + return new ScalarDataReaderMapper(this, dataReader, nameOrIndex); + } + + public virtual DataReaderListMapper CreateDataReaderListMapper( + IDataReader reader, + NameOrIndexParameter nameOrIndex) + { + return new DataReaderListMapper(CreateDataReaderMapper(reader, nameOrIndex)); + } + +#if !SILVERLIGHT + + public virtual DataRowMapper CreateDataRowMapper( + DataRow row, + DataRowVersion version) + { + return new DataRowMapper(row, version); + } + + public virtual DataTableMapper CreateDataTableMapper( + DataTable dataTable, + DataRowVersion version) + { + return new DataTableMapper(dataTable, CreateDataRowMapper(null, version)); + } + +#endif + + public virtual DictionaryMapper CreateDictionaryMapper(IDictionary dictionary) + { + return new DictionaryMapper(dictionary); + } + + public virtual DictionaryListMapper CreateDictionaryListMapper( + IDictionary dic, + NameOrIndexParameter keyFieldNameOrIndex, + ObjectMapper objectMapper) + { + return new DictionaryListMapper(dic, keyFieldNameOrIndex, objectMapper); + } + + public virtual DictionaryIndexListMapper CreateDictionaryListMapper( + IDictionary dic, + MapIndex index, + ObjectMapper objectMapper) + { + return new DictionaryIndexListMapper(dic, index, objectMapper); + } + + public virtual DictionaryListMapper CreateDictionaryListMapper( + IDictionary dic, + NameOrIndexParameter keyFieldNameOrIndex, + ObjectMapper objectMapper) + { + return new DictionaryListMapper(dic, keyFieldNameOrIndex, objectMapper); + } + + public virtual DictionaryIndexListMapper CreateDictionaryListMapper( + IDictionary dic, + MapIndex index, + ObjectMapper objectMapper) + { + return new DictionaryIndexListMapper(dic, index, objectMapper); + } + + public virtual EnumeratorMapper CreateEnumeratorMapper(IEnumerator enumerator) + { + return new EnumeratorMapper(enumerator); + } + + public virtual ObjectListMapper CreateObjectListMapper(IList list, ObjectMapper objectMapper) + { + return new ObjectListMapper(list, objectMapper); + } + + public virtual ScalarListMapper CreateScalarListMapper(IList list, Type type) + { + return new ScalarListMapper(list, type); + } + + public virtual SimpleDestinationListMapper CreateScalarDestinationListMapper(IList list, Type type) + { + return new SimpleDestinationListMapper(CreateScalarListMapper(list, type)); + } + + public virtual SimpleSourceListMapper CreateScalarSourceListMapper(IList list, Type type) + { + return new SimpleSourceListMapper(CreateScalarListMapper(list, type)); + } + + public virtual ScalarListMapper CreateScalarListMapper(IList list) + { + return new ScalarListMapper(this, list); + } + + public virtual SimpleDestinationListMapper CreateScalarDestinationListMapper(IList list) + { + return new SimpleDestinationListMapper(CreateScalarListMapper(list)); + } + + #endregion + + #region GetNullValue + + public virtual object GetNullValue(Type type) + { + return TypeAccessor.GetNullValue(type); + } + + public virtual bool IsNull(object value) + { + return TypeAccessor.IsNull(value); + } + + #endregion + + #region GetMapValues + + private readonly Dictionary _mapValues = new Dictionary(); + + public virtual MapValue[] GetMapValues([JetBrains.Annotations.NotNull] Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + lock (_mapValues) + { + MapValue[] mapValues; + + if (_mapValues.TryGetValue(type, out mapValues)) + return mapValues; + + var typeExt = TypeExtension.GetTypeExtension(type, Extensions); + bool isSet; + + mapValues = MetadataProvider.GetMapValues(typeExt, type, out isSet); + + _mapValues.Add(type, mapValues); + + return mapValues; + } + } + + private readonly Dictionary _memberMapValues = new Dictionary(); + + private Type GetMapValueType(MapValue[] mapValues) + { + if (mapValues != null) + { + var value = mapValues.SelectMany(mv => mv.MapValues).FirstOrDefault(); + if (value != null) + { + return value.GetType(); + } + } + return null; + } + + public virtual MapValue[] GetMapValues([JetBrains.Annotations.NotNull] MemberAccessor memberAccessor) + { + if (memberAccessor == null) throw new ArgumentNullException("memberAccessor"); + + lock (_memberMapValues) + { + MapValue[] mapValues; + + if (_memberMapValues.TryGetValue(memberAccessor, out mapValues)) + return mapValues; + + var typeExt = TypeExtension.GetTypeExtension(memberAccessor.Type, Extensions); + bool isSet; + + mapValues = MetadataProvider.GetMapValues(typeExt, memberAccessor, out isSet); + + _memberMapValues.Add(memberAccessor, mapValues); + + return mapValues; + } + } + + #endregion + + #region GetDefaultValue + + private readonly Dictionary _defaultValues = new Dictionary(); + + public virtual object GetDefaultValue([JetBrains.Annotations.NotNull] Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + lock (_defaultValues) + { + object defaultValue; + + if (_defaultValues.TryGetValue(type, out defaultValue)) + return defaultValue; + + var typeExt = TypeExtension.GetTypeExtension(type, Extensions); + bool isSet; + + defaultValue = MetadataProvider.GetDefaultValue(this, typeExt, type, out isSet); + + _defaultValues.Add(type, defaultValue = TypeExtension.ChangeType(defaultValue, type)); + + return defaultValue; + } + } + + #endregion + + #region GetDataSource, GetDataDestination + + [CLSCompliant(false)] + public virtual IMapDataSource GetDataSource(object obj) + { + if (obj == null) throw new ArgumentNullException("obj"); + + if (obj is IMapDataSource) + return (IMapDataSource)obj; + + if (obj is IDataReader) + return CreateDataReaderMapper((IDataReader)obj); + +#if !SILVERLIGHT + + if (obj is DataRow) + return CreateDataRowMapper((DataRow)obj, DataRowVersion.Default); + + if (obj is DataRowView) + return CreateDataRowMapper( + ((DataRowView)obj).Row, + ((DataRowView)obj).RowVersion); + + if (obj is DataTable) + return CreateDataRowMapper(((DataTable)(obj)).Rows[0], DataRowVersion.Default); + +#endif + + if (obj is IDictionary) + return CreateDictionaryMapper((IDictionary)obj); + + return GetObjectMapper(obj.GetType()); + } + + [CLSCompliant(false)] + public virtual IMapDataDestination GetDataDestination(object obj) + { + if (obj == null) throw new ArgumentNullException("obj"); + + if (obj is IMapDataDestination) + return (IMapDataDestination)obj; + +#if !SILVERLIGHT + + if (obj is DataRow) + return CreateDataRowMapper((DataRow)obj, DataRowVersion.Default); + + if (obj is DataRowView) + return CreateDataRowMapper( + ((DataRowView)obj).Row, + ((DataRowView)obj).RowVersion); + + if (obj is DataTable) + { + DataTable dt = obj as DataTable; + DataRow dr = dt.NewRow(); + + dt.Rows.Add(dr); + + return CreateDataRowMapper(dr, DataRowVersion.Default); + } + +#endif + + if (obj is IDictionary) + return CreateDictionaryMapper((IDictionary)obj); + + return GetObjectMapper(obj.GetType()); + } + + [CLSCompliant(false)] + public virtual IMapDataSourceList GetDataSourceList(object obj) + { + if (obj == null) throw new ArgumentNullException("obj"); + + if (obj is IMapDataSourceList) + return (IMapDataSourceList)obj; + + if (obj is IDataReader) + return CreateDataReaderListMapper((IDataReader)obj); + + Type type = obj.GetType().GetElementType(); + + return TypeHelper.IsScalar(type)? + (IMapDataSourceList)CreateScalarSourceListMapper((IList)obj, type): + CreateObjectListMapper((IList)obj, CreateObjectMapper(type)); + } + + [CLSCompliant(false)] + public virtual IMapDataDestinationList GetDataDestinationList(object obj) + { + if (obj == null) throw new ArgumentNullException("obj"); + + if (obj is IMapDataDestinationList) + return (IMapDataDestinationList)obj; + + Type type = obj.GetType().GetElementType(); + + return TypeHelper.IsScalar(type)? + (IMapDataDestinationList)CreateScalarDestinationListMapper((IList)obj, type): + CreateObjectListMapper((IList)obj, CreateObjectMapper(type)); + } + + #endregion + + #region ValueMapper + + [CLSCompliant(false)] + public virtual IValueMapper DefaultValueMapper + { + get { return ValueMapping.DefaultMapper; } + } + + internal readonly Dictionary SameTypeMappers = new Dictionary(); + internal readonly Dictionary DifferentTypeMappers = new Dictionary(); + + [CLSCompliant(false)] + public void SetValueMapper( + Type sourceType, + Type destType, + IValueMapper mapper) + { + if (sourceType == null) sourceType = typeof(object); + if (destType == null) destType = typeof(object); + + if (sourceType == destType) + { + lock (SameTypeMappers) + { + if (mapper == null) + SameTypeMappers.Remove(sourceType); + else if (SameTypeMappers.ContainsKey(sourceType)) + SameTypeMappers[sourceType] = mapper; + else + SameTypeMappers.Add(sourceType, mapper); + } + } + else + { + KeyValue key = new KeyValue(sourceType, destType); + + lock (DifferentTypeMappers) + { + if (mapper == null) + DifferentTypeMappers.Remove(key); + else if (DifferentTypeMappers.ContainsKey(key)) + DifferentTypeMappers[key] = mapper; + else + DifferentTypeMappers.Add(key, mapper); + } + } + } + + [CLSCompliant(false)] + protected internal virtual IValueMapper GetValueMapper( + Type sourceType, + Type destType) + { + return ValueMapping.GetMapper(sourceType, destType); + } + + [CLSCompliant(false)] + internal protected IValueMapper[] GetValueMappers( + IMapDataSource source, + IMapDataDestination dest, + int[] index) + { + IValueMapper[] mappers = new IValueMapper[index.Length]; + + for (int i = 0; i < index.Length; i++) + { + int n = index[i]; + + if (n < 0) + continue; + + if (!source.SupportsTypedValues(i) || !dest.SupportsTypedValues(n)) + { + mappers[i] = DefaultValueMapper; + continue; + } + + Type sourceType = source.GetFieldType(i); + Type destType = dest. GetFieldType(n); + + if (sourceType == null) sourceType = typeof(object); + if (destType == null) destType = typeof(object); + + IValueMapper t; + + if (sourceType == destType) + { + lock (SameTypeMappers) + if (!SameTypeMappers.TryGetValue(sourceType, out t)) + SameTypeMappers.Add(sourceType, t = GetValueMapper(sourceType, destType)); + } + else + { + var key = new KeyValue(sourceType, destType); + + lock (DifferentTypeMappers) + if (!DifferentTypeMappers.TryGetValue(key, out t)) + DifferentTypeMappers[key] = t = GetValueMapper(sourceType, destType); + } + + mappers[i] = t; + } + + return mappers; + } + + #endregion + + #region Base Mapping + + [CLSCompliant(false)] + internal protected static int[] GetIndex( + IMapDataSource source, + IMapDataDestination dest) + { + int count = source.Count; + int[] index = new int[count]; + + for (int i = 0; i < count; i++) + index[i] = dest.GetOrdinal(source.GetName(i)); + + return index; + } + + [CLSCompliant(false), Obsolete] + protected static void MapInternal( + IMapDataSource source, object sourceObject, + IMapDataDestination dest, object destObject, + int[] index) + { + for (int i = 0; i < index.Length; i++) + { + int n = index[i]; + + if (n >= 0) + dest.SetValue(destObject, n, source.GetValue(sourceObject, i)); + } + } + + [CLSCompliant(false)] + internal protected static void MapInternal( + IMapDataSource source, object sourceObject, + IMapDataDestination dest, object destObject, + int[] index, + IValueMapper[] mappers) + { + for (int i = 0; i < index.Length; i++) + { + int n = index[i]; + + if (n >= 0) + mappers[i].Map(source, sourceObject, i, dest, destObject, n); + } + } + + [CLSCompliant(false)] + protected virtual void MapInternal( + InitContext initContext, + IMapDataSource source, object sourceObject, + IMapDataDestination dest, object destObject, + params object[] parameters) + { + ISupportMapping smSource = sourceObject as ISupportMapping; + ISupportMapping smDest = destObject as ISupportMapping; + + if (smSource != null) + { + if (initContext == null) + { + initContext = new InitContext(); + + initContext.MappingSchema = this; + initContext.DataSource = source; + initContext.SourceObject = sourceObject; + initContext.ObjectMapper = dest as ObjectMapper; + initContext.Parameters = parameters; + } + + initContext.IsSource = true; + smSource.BeginMapping(initContext); + initContext.IsSource = false; + + if (initContext.StopMapping) + return; + } + + if (smDest != null) + { + if (initContext == null) + { + initContext = new InitContext(); + + initContext.MappingSchema = this; + initContext.DataSource = source; + initContext.SourceObject = sourceObject; + initContext.ObjectMapper = dest as ObjectMapper; + initContext.Parameters = parameters; + } + + smDest.BeginMapping(initContext); + + if (initContext.StopMapping) + return; + + if (dest != initContext.ObjectMapper && initContext.ObjectMapper != null) + dest = initContext.ObjectMapper; + } + + int[] index = GetIndex (source, dest); + IValueMapper[] mappers = GetValueMappers(source, dest, index); + + MapInternal(source, sourceObject, dest, destObject, index, mappers); + + if (smDest != null) + smDest.EndMapping(initContext); + + if (smSource != null) + { + initContext.IsSource = true; + smSource.EndMapping(initContext); + initContext.IsSource = false; + } + } + + protected virtual object MapInternal(InitContext initContext) + { + object dest = initContext.ObjectMapper.CreateInstance(initContext); + + if (initContext.StopMapping == false) + { + MapInternal(initContext, + initContext.DataSource, initContext.SourceObject, + initContext.ObjectMapper, dest, + initContext.Parameters); + } + + return dest; + } + + [CLSCompliant(false)] + public void MapSourceToDestination( + IMapDataSource source, object sourceObject, + IMapDataDestination dest, object destObject, + params object[] parameters) + { + MapInternal(null, source, sourceObject, dest, destObject, parameters); + } + + public void MapSourceToDestination( + object sourceObject, + object destObject, + params object[] parameters) + { + IMapDataSource source = GetDataSource (sourceObject); + IMapDataDestination dest = GetDataDestination(destObject); + + MapInternal(null, source, sourceObject, dest, destObject, parameters); + } + + private static readonly ObjectMapper _nullMapper = new ObjectMapper(); + + private class MapInfo + { + public int[] Index; + public IValueMapper[] Mappers; + } + + [CLSCompliant(false)] + public virtual void MapSourceListToDestinationList( + IMapDataSourceList dataSourceList, + IMapDataDestinationList dataDestinationList, + params object[] parameters) + { + if (dataSourceList == null) throw new ArgumentNullException("dataSourceList"); + if (dataDestinationList == null) throw new ArgumentNullException("dataDestinationList"); + + Dictionary infos = new Dictionary(); + + InitContext ctx = new InitContext(); + + ctx.MappingSchema = this; + ctx.Parameters = parameters; + + dataSourceList. InitMapping(ctx); if (ctx.StopMapping) return; + dataDestinationList.InitMapping(ctx); if (ctx.StopMapping) return; + + int[] index = null; + IValueMapper[] mappers = null; + ObjectMapper current = _nullMapper; + IMapDataDestination dest = dataDestinationList.GetDataDestination(ctx); + ObjectMapper om = dest as ObjectMapper; + + while (dataSourceList.SetNextDataSource(ctx)) + { + ctx.ObjectMapper = om; + ctx.StopMapping = false; + + object destObject = dataDestinationList.GetNextObject(ctx); + + if (ctx.StopMapping) continue; + + ISupportMapping smSource = ctx.SourceObject as ISupportMapping; + ISupportMapping smDest = destObject as ISupportMapping; + + if (smSource != null) + { + ctx.IsSource = true; + smSource.BeginMapping(ctx); + ctx.IsSource = false; + + if (ctx.StopMapping) + continue; + } + + if (smDest != null) + { + smDest.BeginMapping(ctx); + + if (ctx.StopMapping) + continue; + } + + IMapDataDestination currentDest = current ?? dest; + + if (current != ctx.ObjectMapper) + { + current = ctx.ObjectMapper; + currentDest = current ?? dest; + + if (current != null) + { + MapInfo info; + if (!infos.TryGetValue(current, out info)) + { + info = new MapInfo(); + + info.Index = GetIndex(ctx.DataSource, currentDest); + info.Mappers = GetValueMappers(ctx.DataSource, currentDest, info.Index); + + infos.Add(current, info); + } + + index = info.Index; + mappers = info.Mappers; + } + else + { + index = GetIndex(ctx.DataSource, currentDest); + mappers = GetValueMappers(ctx.DataSource, currentDest, index); + } + } + + MapInternal( + ctx.DataSource, + ctx.SourceObject, + currentDest, + destObject, + index, + mappers); + + if (smDest != null) + smDest.EndMapping(ctx); + + if (smSource != null) + { + ctx.IsSource = true; + smSource.EndMapping(ctx); + ctx.IsSource = false; + } + } + + dataDestinationList.EndMapping(ctx); + dataSourceList. EndMapping(ctx); + } + + #endregion + + #region ValueToEnum, EnumToValue + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + public virtual object MapValueToEnum(object value, Type type) + { + if (value == null || value == DBNull.Value) + return GetNullValue(type); + + MapValue[] mapValues = GetMapValues(type); + + var mapValueType = GetMapValueType(mapValues); + if (mapValueType != null && value.GetType() != mapValueType) + { + value = ConvertChangeType(value, mapValueType); + } + + if (mapValues != null) + { + var comp = (IComparable)value; + + foreach (MapValue mv in mapValues) + foreach (object mapValue in mv.MapValues) + { + try + { + if (comp.CompareTo(mapValue) == 0) + return mv.OrigValue; + } + catch (ArgumentException ex) + { + Debug.WriteLine(ex.Message, MethodBase.GetCurrentMethod().Name); + } + } + } + + InvalidCastException exInvalidCast = null; + + var enumType = TypeHelper.UnwrapNullableType(type); + try + { + value = ConvertChangeType(value, Enum.GetUnderlyingType(enumType)); + + if (Enum.IsDefined(enumType, value)) + { + // Regular (known) enum field w/o explicit mapping defined. + // + return Enum.ToObject(enumType, value); + } + } + catch (InvalidCastException ex) + { + exInvalidCast = ex; + } + + // Default value. + // + object defaultValue = GetDefaultValue(type); + + if (defaultValue != null) + return defaultValue; + + if (exInvalidCast != null) + { + // Rethrow an InvalidCastException when no default value specified. + // + throw exInvalidCast; + } + + // At this point we have an undefined enum value. + // + return Enum.ToObject(enumType, value); + } + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + public virtual object MapValueToEnum(object value, MemberAccessor ma) + { + if (value == null || value is DBNull) + return GetNullValue(ma.Type); + + MapValue[] mapValues = GetMapValues(ma); + + var mapValueType = GetMapValueType(mapValues); + if (mapValueType != null && value.GetType() != mapValueType) + { + value = ConvertChangeType(value, mapValueType); + } + + if (mapValues != null) + { + var comp = (IComparable)value; + + foreach (MapValue mv in mapValues) + foreach (object mapValue in mv.MapValues) + { + try + { + if (comp.CompareTo(mapValue) == 0) + return mv.OrigValue; + } + catch (ArgumentException ex) + { + Debug.WriteLine(ex.Message, MethodBase.GetCurrentMethod().Name); + } + } + } + + InvalidCastException exInvalidCast = null; + + var enumType = TypeHelper.UnwrapNullableType(ma.Type); + try + { + value = ConvertChangeType(value, Enum.GetUnderlyingType(enumType)); + + if (Enum.IsDefined(enumType, value)) + { + // Regular (known) enum field w/o explicit mapping defined. + // + return Enum.ToObject(enumType, value); + } + } + catch (InvalidCastException ex) + { + exInvalidCast = ex; + } + + // Default value. + // + object defaultValue = GetDefaultValue(ma.Type); + + if (defaultValue != null) + return defaultValue; + + if (exInvalidCast != null) + { + // Rethrow an InvalidCastException when no default value specified. + // + throw exInvalidCast; + } + + // At this point we have an undefined enum value. + // + return Enum.ToObject(enumType, value); + } + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + public virtual object MapEnumToValue(object value, [JetBrains.Annotations.NotNull] Type type, bool convertToUnderlyingType) + { + if (value == null) + return null; + + if (type == null) throw new ArgumentNullException("type"); + + type = value.GetType(); + + object nullValue = GetNullValue(type); + + if (nullValue != null) + { + IComparable comp = (IComparable)value; + + try + { + if (comp.CompareTo(nullValue) == 0) + return null; + } + catch + { + } + } + + MapValue[] mapValues = GetMapValues(type); + + if (mapValues != null) + { + IComparable comp = (IComparable)value; + + foreach (MapValue mv in mapValues) + { + try + { + if (comp.CompareTo(mv.OrigValue) == 0) + return mv.MapValues[0]; + } + catch + { + } + } + } + + return convertToUnderlyingType ? + System.Convert.ChangeType(value, Enum.GetUnderlyingType(type), Thread.CurrentThread.CurrentCulture) : + value; + } + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + public virtual object MapEnumToValue(object value, [JetBrains.Annotations.NotNull] MemberAccessor memberAccessor, bool convertToUnderlyingType) + { + if (value == null) + return null; + + if (memberAccessor == null) throw new ArgumentNullException("memberAccessor"); + + if (value is IEnumerable) + { +#if SILVERLIGHT + var result = new List(); + + foreach (var item in (IEnumerable)value) + { + result.Add(MapEnumToValue(item, memberAccessor, convertToUnderlyingType)); + } + + var type = typeof(object); + + foreach (var var in result) + { + if (var != null) + { + type = var.GetType(); + break; + } + } + + var arr = Array.CreateInstance(type, result.Count); + + Array.Copy(result.ToArray(), arr, arr.Length); + + return arr; +#else + var result = new ArrayList(); + + foreach (var item in (IEnumerable)value) + { + result.Add(MapEnumToValue(item, memberAccessor, convertToUnderlyingType)); + } + + var type = typeof(object); + + foreach (var var in result) + { + if (var != null) + { + type = var.GetType(); + break; + } + } + + return result.ToArray(type); +#endif + } + + object nullValue = GetNullValue(memberAccessor.Type); + + if (nullValue != null) + { + IComparable comp = (IComparable)value; + + try + { + if (comp.CompareTo(nullValue) == 0) + return null; + } + catch + { + } + } + + MapValue[] mapValues = GetMapValues(memberAccessor); + + if (mapValues != null) + { + IComparable comp = (IComparable)value; + + foreach (MapValue mv in mapValues) + { + try + { + if (comp.CompareTo(mv.OrigValue) == 0) + return mv.MapValues[0]; + } + catch + { + } + } + } + + var memberAccessorType = TypeHelper.UnwrapNullableType(memberAccessor.Type); + + return convertToUnderlyingType ? + System.Convert.ChangeType(value, Enum.GetUnderlyingType(memberAccessorType), Thread.CurrentThread.CurrentCulture) : + value; + } + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + public virtual object MapEnumToValue(object value, bool convertToUnderlyingType) + { + if (value == null) + return null; + + return MapEnumToValue(value, value.GetType(), convertToUnderlyingType); + } + + public object MapEnumToValue(object value) + { + return MapEnumToValue(value, false); + } + + public virtual object MapEnumToValue(object value, Type type) + { + return MapEnumToValue(value, type, false); + } + + public T MapValueToEnum(object value) + { + return (T)MapValueToEnum(value, typeof(T)); + } + + #endregion + + #region Object + + #region MapObjectToObject + + public object MapObjectToObject( + object sourceObject, + object destObject, + params object[] parameters) + { + if (sourceObject == null) throw new ArgumentNullException("sourceObject"); + if (destObject == null) throw new ArgumentNullException("destObject"); + + MapInternal( + null, + GetObjectMapper(sourceObject.GetType()), sourceObject, + GetObjectMapper(destObject. GetType()), destObject, + parameters); + + return destObject; + } + + public object MapObjectToObject( + object sourceObject, + Type destObjectType, + params object[] parameters) + { + if (sourceObject == null) throw new ArgumentNullException("sourceObject"); + + InitContext ctx = new InitContext(); + + ctx.MappingSchema = this; + ctx.DataSource = GetObjectMapper(sourceObject.GetType()); + ctx.SourceObject = sourceObject; + ctx.ObjectMapper = GetObjectMapper(destObjectType); + ctx.Parameters = parameters; + + return MapInternal(ctx); + } + + public T MapObjectToObject( + object sourceObject, + params object[] parameters) + { + return (T)MapObjectToObject(sourceObject, typeof(T), parameters); + } + + #endregion + + #region MapObjectToDataRow + +#if !SILVERLIGHT + + public DataRow MapObjectToDataRow( + object sourceObject, + DataRow destRow) + { + if (sourceObject == null) throw new ArgumentNullException("sourceObject"); + + MapInternal( + null, + GetObjectMapper (sourceObject.GetType()), sourceObject, + CreateDataRowMapper(destRow, DataRowVersion.Default), destRow, + null); + + return destRow; + } + + public DataRow MapObjectToDataRow( + object sourceObject, + DataTable destTable) + { + if (destTable == null) throw new ArgumentNullException("destTable"); + if (sourceObject == null) throw new ArgumentNullException("sourceObject"); + + DataRow destRow = destTable.NewRow(); + + destTable.Rows.Add(destRow); + + MapInternal( + null, + GetObjectMapper (sourceObject.GetType()), sourceObject, + CreateDataRowMapper(destRow, DataRowVersion.Default), destRow, + null); + + return destRow; + } + +#endif + + #endregion + + #region MapObjectToDictionary + + public IDictionary MapObjectToDictionary( + object sourceObject, + IDictionary destDictionary) + { + if (sourceObject == null) throw new ArgumentNullException("sourceObject"); + + MapInternal( + null, + GetObjectMapper (sourceObject.GetType()), sourceObject, + CreateDictionaryMapper(destDictionary), destDictionary, + null); + + return destDictionary; + } + + public IDictionary MapObjectToDictionary(object sourceObject) + { + if (sourceObject == null) throw new ArgumentNullException("sourceObject"); + + ObjectMapper om = GetObjectMapper(sourceObject.GetType()); + + var destDictionary = new Dictionary(om.Count); + + MapInternal( + null, + om, sourceObject, + CreateDictionaryMapper(destDictionary), destDictionary, + null); + + return destDictionary; + } + + #endregion + + #endregion + + #region DataRow + +#if !SILVERLIGHT + + #region MapDataRowToObject + + public object MapDataRowToObject( + DataRow dataRow, + object destObject, + params object[] parameters) + { + if (destObject == null) throw new ArgumentNullException("destObject"); + + MapInternal( + null, + CreateDataRowMapper(dataRow, DataRowVersion.Default), dataRow, + GetObjectMapper(destObject. GetType()), destObject, + parameters); + + return destObject; + } + + public object MapDataRowToObject( + DataRow dataRow, + DataRowVersion version, + object destObject, + params object[] parameters) + { + if (destObject == null) throw new ArgumentNullException("destObject"); + + MapInternal( + null, + CreateDataRowMapper(dataRow, version), dataRow, + GetObjectMapper(destObject. GetType()), destObject, + parameters); + + return destObject; + } + + public object MapDataRowToObject( + DataRow dataRow, + Type destObjectType, + params object[] parameters) + { + InitContext ctx = new InitContext(); + + ctx.MappingSchema = this; + ctx.DataSource = CreateDataRowMapper(dataRow, DataRowVersion.Default); + ctx.SourceObject = dataRow; + ctx.ObjectMapper = GetObjectMapper(destObjectType); + ctx.Parameters = parameters; + + return MapInternal(ctx); + } + + public object MapDataRowToObject( + DataRow dataRow, + DataRowVersion version, + Type destObjectType, + params object[] parameters) + { + InitContext ctx = new InitContext(); + + ctx.MappingSchema = this; + ctx.DataSource = CreateDataRowMapper(dataRow, version); + ctx.SourceObject = dataRow; + ctx.ObjectMapper = GetObjectMapper(destObjectType); + ctx.Parameters = parameters; + + return MapInternal(ctx); + } + + public T MapDataRowToObject( + DataRow dataRow, + params object[] parameters) + { + return (T)MapDataRowToObject(dataRow, typeof(T), parameters); + } + + public T MapDataRowToObject( + DataRow dataRow, + DataRowVersion version, + params object[] parameters) + { + return (T)MapDataRowToObject(dataRow, version, typeof(T), parameters); + } + + #endregion + + #region MapDataRowToDataRow + + public DataRow MapDataRowToDataRow( + DataRow sourceRow, + DataRow destRow) + { + MapInternal( + null, + CreateDataRowMapper(sourceRow, DataRowVersion.Default), sourceRow, + CreateDataRowMapper(destRow, DataRowVersion.Default), destRow, + null); + + return destRow; + } + + public DataRow MapDataRowToDataRow( + DataRow sourceRow, + DataRowVersion version, + DataRow destRow) + { + MapInternal( + null, + CreateDataRowMapper(sourceRow, version), sourceRow, + CreateDataRowMapper(destRow, DataRowVersion.Default), destRow, + null); + + return destRow; + } + + public DataRow MapDataRowToDataRow( + DataRow sourceRow, + DataTable destTable) + { + if (destTable == null) throw new ArgumentNullException("destTable"); + + DataRow destRow = destTable.NewRow(); + + destTable.Rows.Add(destRow); + + MapInternal( + null, + CreateDataRowMapper(sourceRow, DataRowVersion.Default), sourceRow, + CreateDataRowMapper(destRow, DataRowVersion.Default), destRow, + null); + + return destRow; + } + + public DataRow MapDataRowToDataRow( + DataRow sourceRow, + DataRowVersion version, + DataTable destTable) + { + if (destTable == null) throw new ArgumentNullException("destTable"); + + DataRow destRow = destTable.NewRow(); + + destTable.Rows.Add(destRow); + + MapInternal( + null, + CreateDataRowMapper(sourceRow, version), sourceRow, + CreateDataRowMapper(destRow, DataRowVersion.Default), destRow, + null); + + return destRow; + } + + #endregion + + #region MapDataRowToDictionary + + public IDictionary MapDataRowToDictionary( + DataRow sourceRow, + IDictionary destDictionary) + { + MapInternal( + null, + CreateDataRowMapper (sourceRow, DataRowVersion.Default), sourceRow, + CreateDictionaryMapper(destDictionary), destDictionary, + null); + + return destDictionary; + } + + public Hashtable MapDataRowToDictionary(DataRow sourceRow) + { + if (sourceRow == null) throw new ArgumentNullException("sourceRow"); + + Hashtable destDictionary = new Hashtable(sourceRow.Table.Columns.Count); + + MapInternal( + null, + CreateDataRowMapper (sourceRow, DataRowVersion.Default), sourceRow, + CreateDictionaryMapper(destDictionary), destDictionary, + null); + + return destDictionary; + } + + public IDictionary MapDataRowToDictionary( + DataRow sourceRow, + DataRowVersion version, + IDictionary destDictionary) + { + MapInternal( + null, + CreateDataRowMapper (sourceRow, version), sourceRow, + CreateDictionaryMapper(destDictionary), destDictionary, + null); + + return destDictionary; + } + + public Hashtable MapDataRowToDictionary( + DataRow sourceRow, + DataRowVersion version) + { + if (sourceRow == null) throw new ArgumentNullException("sourceRow"); + + Hashtable destDictionary = new Hashtable(sourceRow.Table.Columns.Count); + + MapInternal( + null, + CreateDataRowMapper (sourceRow, version), sourceRow, + CreateDictionaryMapper(destDictionary), destDictionary, + null); + + return destDictionary; + } + + #endregion + +#endif + + #endregion + + #region DataReader + + #region MapDataReaderToObject + + public object MapDataReaderToObject( + IDataReader dataReader, + object destObject, + params object[] parameters) + { + if (destObject == null) throw new ArgumentNullException("destObject"); + + MapInternal( + null, + CreateDataReaderMapper(dataReader), dataReader, + GetObjectMapper(destObject. GetType()), destObject, + parameters); + + return destObject; + } + + //NOTE changed to virtual + public virtual object MapDataReaderToObject( + IDataReader dataReader, + Type destObjectType, + params object[] parameters) + { + InitContext ctx = new InitContext(); + + ctx.MappingSchema = this; + ctx.DataSource = CreateDataReaderMapper(dataReader); + ctx.SourceObject = dataReader; + ctx.ObjectMapper = GetObjectMapper(destObjectType); + ctx.Parameters = parameters; + + return MapInternal(ctx); + } + + public T MapDataReaderToObject( + IDataReader dataReader, + params object[] parameters) + { + return (T)MapDataReaderToObject(dataReader, typeof(T), parameters); + } + + #endregion + + #region MapDataReaderToDataRow + +#if !SILVERLIGHT + + public DataRow MapDataReaderToDataRow(IDataReader dataReader, DataRow destRow) + { + MapInternal( + null, + CreateDataReaderMapper(dataReader), dataReader, + CreateDataRowMapper(destRow, DataRowVersion.Default), destRow, + null); + + return destRow; + } + + public DataRow MapDataReaderToDataRow( + IDataReader dataReader, + DataTable destTable) + { + if (destTable == null) throw new ArgumentNullException("destTable"); + + DataRow destRow = destTable.NewRow(); + + destTable.Rows.Add(destRow); + + MapInternal( + null, + CreateDataReaderMapper(dataReader), dataReader, + CreateDataRowMapper(destRow, DataRowVersion.Default), destRow, + null); + + return destRow; + } + +#endif + + #endregion + + #region MapDataReaderToDictionary + + public IDictionary MapDataReaderToDictionary( + IDataReader dataReader, + IDictionary destDictionary) + { + MapInternal( + null, + CreateDataReaderMapper(dataReader), dataReader, + CreateDictionaryMapper(destDictionary), destDictionary, + null); + + return destDictionary; + } + + public IDictionary MapDataReaderToDictionary(IDataReader dataReader) + { + if (dataReader == null) throw new ArgumentNullException("dataReader"); + + var destDictionary = new Dictionary(dataReader.FieldCount); + + MapInternal( + null, + CreateDataReaderMapper(dataReader), dataReader, + CreateDictionaryMapper(destDictionary), destDictionary, + null); + + return destDictionary; + } + + #endregion + + #endregion + + #region Dictionary + + #region MapDictionaryToObject + + public object MapDictionaryToObject( + IDictionary sourceDictionary, + object destObject, + params object[] parameters) + { + if (destObject == null) throw new ArgumentNullException("destObject"); + + MapInternal( + null, + CreateDictionaryMapper(sourceDictionary), sourceDictionary, + GetObjectMapper (destObject. GetType()), destObject, + parameters); + + return destObject; + } + + public object MapDictionaryToObject( + IDictionary sourceDictionary, + Type destObjectType, + params object[] parameters) + { + InitContext ctx = new InitContext(); + + ctx.MappingSchema = this; + ctx.DataSource = CreateDictionaryMapper(sourceDictionary); + ctx.SourceObject = sourceDictionary; + ctx.ObjectMapper = GetObjectMapper(destObjectType); + ctx.Parameters = parameters; + + return MapInternal(ctx); + } + + public T MapDictionaryToObject(IDictionary sourceDictionary, params object[] parameters) + { + return (T)MapDictionaryToObject(sourceDictionary, typeof(T), parameters); + } + + #endregion + + #region MapDictionaryToDataRow + +#if !SILVERLIGHT + + public DataRow MapDictionaryToDataRow( + IDictionary sourceDictionary, + DataRow destRow) + { + MapInternal( + null, + CreateDictionaryMapper(sourceDictionary), sourceDictionary, + CreateDataRowMapper (destRow, DataRowVersion.Default), destRow, + null); + + return destRow; + } + + public DataRow MapDictionaryToDataRow( + IDictionary sourceDictionary, + DataTable destTable) + { + if (destTable == null) throw new ArgumentNullException("destTable"); + + DataRow destRow = destTable.NewRow(); + + destTable.Rows.Add(destRow); + + MapInternal( + null, + CreateDictionaryMapper(sourceDictionary), sourceDictionary, + CreateDataRowMapper (destRow, DataRowVersion.Default), destRow, + null); + + return destRow; + } + +#endif + + #endregion + + #endregion + + #region List + + #region MapListToList + + public IList MapListToList( + ICollection sourceList, + IList destList, + Type destObjectType, + params object[] parameters) + { + if (sourceList == null) throw new ArgumentNullException("sourceList"); + + MapSourceListToDestinationList( + CreateEnumeratorMapper(sourceList.GetEnumerator()), + CreateObjectListMapper(destList, GetObjectMapper(destObjectType)), + parameters); + + return destList; + } + + public IList MapListToList( + ICollection sourceList, + Type destObjectType, + params object[] parameters) + { + if (sourceList == null) throw new ArgumentNullException("sourceList"); + + var destList = new List(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper(sourceList.GetEnumerator()), + CreateObjectListMapper(destList, GetObjectMapper(destObjectType)), + parameters); + + return destList; + } + + public List MapListToList( + ICollection sourceList, + List destList, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateEnumeratorMapper(sourceList.GetEnumerator()), + CreateObjectListMapper(destList, GetObjectMapper(typeof(T))), + parameters); + + return destList; + } + + public List MapListToList( + ICollection sourceList, + params object[] parameters) + { + List destList = new List(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper(sourceList.GetEnumerator()), + CreateObjectListMapper(destList, GetObjectMapper(typeof(T))), + parameters); + + return destList; + } + + #endregion + + #region MapListToDataTable + +#if !SILVERLIGHT + + public DataTable MapListToDataTable( + ICollection sourceList, + DataTable destTable) + { + if (sourceList == null) throw new ArgumentNullException("sourceList"); + + MapSourceListToDestinationList( + CreateEnumeratorMapper(sourceList.GetEnumerator()), + CreateDataTableMapper (destTable, DataRowVersion.Default), + null); + + return destTable; + } + + [SuppressMessage("Microsoft.Globalization", "CA1306:SetLocaleForDataTypes")] + public DataTable MapListToDataTable(ICollection sourceList) + { + if (sourceList == null) throw new ArgumentNullException("sourceList"); + + DataTable destTable = new DataTable(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper(sourceList.GetEnumerator()), + CreateDataTableMapper (destTable, DataRowVersion.Default), + null); + + return destTable; + } + +#endif + + #endregion + + #region MapListToDictionary + + public IDictionary MapListToDictionary( + ICollection sourceList, + IDictionary destDictionary, + NameOrIndexParameter keyFieldNameOrIndex, + Type destObjectType, + params object[] parameters) + { + if (sourceList == null) throw new ArgumentNullException("sourceList"); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceList.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapListToDictionary( + ICollection sourceList, + NameOrIndexParameter keyFieldNameOrIndex, + Type destObjectType, + params object[] parameters) + { + if (sourceList == null) throw new ArgumentNullException("sourceList"); + + IDictionary destDictionary = new Dictionary(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceList.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapListToDictionary( + ICollection sourceList, + IDictionary destDictionary, + NameOrIndexParameter keyFieldNameOrIndex, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceList.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + public Dictionary MapListToDictionary( + ICollection sourceList, + NameOrIndexParameter keyFieldNameOrIndex, + params object[] parameters) + { + Dictionary destDictionary = new Dictionary(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceList.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + #endregion + + #region MapListToDictionaryIndex + + public IDictionary MapListToDictionary( + ICollection sourceList, + IDictionary destDictionary, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + if (sourceList == null) throw new ArgumentNullException("sourceList"); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceList.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapListToDictionary( + ICollection sourceList, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + if (sourceList == null) throw new ArgumentNullException("sourceList"); + + IDictionary destDictionary = new Dictionary(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceList.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapListToDictionary( + ICollection sourceList, + IDictionary destDictionary, + MapIndex index, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceList.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + public Dictionary MapListToDictionary( + ICollection sourceList, + MapIndex index, + params object[] parameters) + { + Dictionary destDictionary = new Dictionary(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceList.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + #endregion + + #endregion + + #region Table + +#if !SILVERLIGHT + + + #region MapDataTableToDataTable + + public DataTable MapDataTableToDataTable( + DataTable sourceTable, + DataTable destTable) + { + MapSourceListToDestinationList( + CreateDataTableMapper(sourceTable, DataRowVersion.Default), + CreateDataTableMapper(destTable, DataRowVersion.Default), + null); + + return destTable; + } + + public DataTable MapDataTableToDataTable( + DataTable sourceTable, + DataRowVersion version, + DataTable destTable) + { + MapSourceListToDestinationList( + CreateDataTableMapper(sourceTable, version), + CreateDataTableMapper(destTable, DataRowVersion.Default), + null); + + return destTable; + } + + public DataTable MapDataTableToDataTable(DataTable sourceTable) + { + if (sourceTable == null) throw new ArgumentNullException("sourceTable"); + + DataTable destTable = sourceTable.Clone(); + + MapSourceListToDestinationList( + CreateDataTableMapper(sourceTable, DataRowVersion.Default), + CreateDataTableMapper(destTable, DataRowVersion.Default), + null); + + return destTable; + } + + public DataTable MapDataTableToDataTable( + DataTable sourceTable, + DataRowVersion version) + { + if (sourceTable == null) throw new ArgumentNullException("sourceTable"); + + DataTable destTable = sourceTable.Clone(); + + MapSourceListToDestinationList( + CreateDataTableMapper(sourceTable, version), + CreateDataTableMapper(destTable, DataRowVersion.Default), + null); + + return destTable; + } + + #endregion + + #region MapDataTableToList + + public IList MapDataTableToList( + DataTable sourceTable, + IList list, + Type destObjectType, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, DataRowVersion.Default), + CreateObjectListMapper(list, GetObjectMapper(destObjectType)), + parameters); + + return list; + } + + public IList MapDataTableToList( + DataTable sourceTable, + DataRowVersion version, + IList list, + Type destObjectType, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, version), + CreateObjectListMapper(list, GetObjectMapper(destObjectType)), + parameters); + + return list; + } + + public ArrayList MapDataTableToList( + DataTable sourceTable, + Type destObjectType, + params object[] parameters) + { + ArrayList list = new ArrayList(); + + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, DataRowVersion.Default), + CreateObjectListMapper(list, GetObjectMapper(destObjectType)), + parameters); + + return list; + } + + public ArrayList MapDataTableToList( + DataTable sourceTable, + DataRowVersion version, + Type destObjectType, + params object[] parameters) + { + ArrayList list = new ArrayList(); + + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, version), + CreateObjectListMapper(list, GetObjectMapper(destObjectType)), + parameters); + + return list; + } + + public List MapDataTableToList( + DataTable sourceTable, + List list, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, DataRowVersion.Default), + CreateObjectListMapper(list, GetObjectMapper(typeof(T))), + parameters); + + return list; + } + + public List MapDataTableToList( + DataTable sourceTable, + DataRowVersion version, + List list, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, version), + CreateObjectListMapper(list, GetObjectMapper(typeof(T))), + parameters); + + return list; + } + + public List MapDataTableToList( + DataTable sourceTable, + params object[] parameters) + { + List list = new List(); + + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, DataRowVersion.Default), + CreateObjectListMapper(list, GetObjectMapper(typeof(T))), + parameters); + + return list; + } + + public List MapDataTableToList( + DataTable sourceTable, + DataRowVersion version, + params object[] parameters) + { + List list = new List(); + + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, version), + CreateObjectListMapper(list, GetObjectMapper(typeof(T))), + parameters); + + return list; + } + + #endregion + + #region MapDataTableToDictionary + + public IDictionary MapDataTableToDictionary( + DataTable sourceTable, + IDictionary destDictionary, + NameOrIndexParameter keyFieldNameOrIndex, + Type destObjectType, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, DataRowVersion.Default), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public Hashtable MapDataTableToDictionary( + DataTable sourceTable, + NameOrIndexParameter keyFieldNameOrIndex, + Type destObjectType, + params object[] parameters) + { + Hashtable destDictionary = new Hashtable(); + + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, DataRowVersion.Default), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapDataTableToDictionary( + DataTable sourceTable, + IDictionary destDictionary, + NameOrIndexParameter keyFieldNameOrIndex, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, DataRowVersion.Default), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + public Dictionary MapDataTableToDictionary( + DataTable sourceTable, + NameOrIndexParameter keyFieldNameOrIndex, + params object[] parameters) + { + Dictionary destDictionary = new Dictionary(); + + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, DataRowVersion.Default), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + #endregion + + #region MapDataTableToDictionary (Index) + + public IDictionary MapDataTableToDictionary( + DataTable sourceTable, + IDictionary destDictionary, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, DataRowVersion.Default), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public Hashtable MapDataTableToDictionary( + DataTable sourceTable, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + Hashtable destDictionary = new Hashtable(); + + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, DataRowVersion.Default), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapDataTableToDictionary( + DataTable sourceTable, + IDictionary destDictionary, + MapIndex index, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, DataRowVersion.Default), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + public Dictionary MapDataTableToDictionary( + DataTable sourceTable, + MapIndex index, + params object[] parameters) + { + Dictionary destDictionary = new Dictionary(); + + MapSourceListToDestinationList( + CreateDataTableMapper (sourceTable, DataRowVersion.Default), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + #endregion + +#endif + + #endregion + + #region DataReader + + #region MapDataReaderToList + + public virtual IList MapDataReaderToList( + IDataReader reader, + IList list, + Type destObjectType, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader), + CreateObjectListMapper (list, GetObjectMapper(destObjectType)), + parameters); + + return list; + } + + public IList MapDataReaderToList( + IDataReader reader, + Type destObjectType, + params object[] parameters) + { + IList list = new List(); + + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader), + CreateObjectListMapper (list, GetObjectMapper(destObjectType)), + parameters); + + return list; + } + + //NOTE changed to virtual + public virtual IList MapDataReaderToList( + IDataReader reader, + IList list, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader), + CreateObjectListMapper ((IList)list, GetObjectMapper(typeof(T))), + parameters); + + return list; + } + + public List MapDataReaderToList( + IDataReader reader, + params object[] parameters) + { + List list = new List(); + + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader), + CreateObjectListMapper (list, GetObjectMapper(typeof(T))), + parameters); + + return list; + } + + #endregion + + #region MapDataReaderToScalarList + + public IList MapDataReaderToScalarList( + IDataReader reader, + NameOrIndexParameter nameOrIndex, + IList list, + Type type) + { + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader, nameOrIndex), + CreateScalarDestinationListMapper(list, type), + null); + + return list; + } + + public IList MapDataReaderToScalarList( + IDataReader reader, + NameOrIndexParameter nameOrIndex, + Type type) + { + IList list = new List(); + + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader, nameOrIndex), + CreateScalarDestinationListMapper(list, type), + null); + + return list; + } + + public IList MapDataReaderToScalarList( + IDataReader reader, + NameOrIndexParameter nameOrIndex, + IList list) + { + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader, nameOrIndex), + CreateScalarDestinationListMapper(list), + null); + + return list; + } + + public List MapDataReaderToScalarList( + IDataReader reader, + NameOrIndexParameter nameOrIndex) + { + List list = new List(); + + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader, nameOrIndex), + CreateScalarDestinationListMapper(list), + null); + + return list; + } + + #endregion + + #region MapDataReaderToDataTable + +#if !SILVERLIGHT + + public DataTable MapDataReaderToDataTable( + IDataReader reader, + DataTable destTable) + { + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader), + CreateDataTableMapper (destTable, DataRowVersion.Default), + null); + + return destTable; + } + + [SuppressMessage("Microsoft.Globalization", "CA1306:SetLocaleForDataTypes")] + public DataTable MapDataReaderToDataTable(IDataReader reader) + { + DataTable destTable = new DataTable(); + + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader), + CreateDataTableMapper (destTable, DataRowVersion.Default), + null); + + return destTable; + } + +#endif + + #endregion + + #region MapDataReaderToDictionary + + public IDictionary MapDataReaderToDictionary( + IDataReader reader, + IDictionary destDictionary, + NameOrIndexParameter keyFieldNameOrIndex, + Type destObjectType, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapDataReaderToDictionary( + IDataReader reader, + NameOrIndexParameter keyFieldNameOrIndex, + Type destObjectType, + params object[] parameters) + { + IDictionary dest = new Dictionary(); + + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader), + CreateDictionaryListMapper(dest, keyFieldNameOrIndex, GetObjectMapper(destObjectType)), + parameters); + + return dest; + } + + public IDictionary MapDataReaderToDictionary( + IDataReader reader, + IDictionary destDictionary, + NameOrIndexParameter keyFieldNameOrIndex, + Type destObjectType, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataReaderListMapper (reader), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapDataReaderToDictionary( + IDataReader reader, + IDictionary destDictionary, + NameOrIndexParameter keyFieldNameOrIndex, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataReaderListMapper (reader), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + public Dictionary MapDataReaderToDictionary( + IDataReader reader, + NameOrIndexParameter keyFieldNameOrIndex, + params object[] parameters) + { + Dictionary dest = new Dictionary(); + + MapSourceListToDestinationList( + CreateDataReaderListMapper (reader), + CreateDictionaryListMapper(dest, keyFieldNameOrIndex, GetObjectMapper(typeof(T))), + parameters); + + return dest; + } + + #endregion + + #region MapDataReaderToDictionary (Index) + + public IDictionary MapDataReaderToDictionary( + IDataReader reader, + IDictionary destDictionary, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapDataReaderToDictionary( + IDataReader reader, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + IDictionary destDictionary = new Dictionary(); + + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapDataReaderToDictionary( + IDataReader reader, + IDictionary destDictionary, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapDataReaderToDictionary( + IDataReader reader, + IDictionary destDictionary, + MapIndex index, + params object[] parameters) + { + MapSourceListToDestinationList( + CreateDataReaderListMapper(reader), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + public Dictionary MapDataReaderToDictionary( + IDataReader reader, + MapIndex index, + params object[] parameters) + { + Dictionary destDictionary = new Dictionary(); + + MapSourceListToDestinationList( + CreateDataReaderListMapper (reader), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + #endregion + + #endregion + + #region Dictionary + + #region MapDictionaryToList + + public IList MapDictionaryToList( + IDictionary sourceDictionary, + IList destList, + Type destObjectType, + params object[] parameters) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + MapSourceListToDestinationList( + CreateEnumeratorMapper(sourceDictionary.Values.GetEnumerator()), + CreateObjectListMapper(destList, GetObjectMapper(destObjectType)), + parameters); + + return destList; + } + + public IList MapDictionaryToList( + IDictionary sourceDictionary, + Type destObjectType, + params object[] parameters) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + IList destList = new List(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper(sourceDictionary.Values.GetEnumerator()), + CreateObjectListMapper(destList, GetObjectMapper(destObjectType)), + parameters); + + return destList; + } + + public List MapDictionaryToList( + IDictionary sourceDictionary, + List destList, + params object[] parameters) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + MapSourceListToDestinationList( + CreateEnumeratorMapper(sourceDictionary.Values.GetEnumerator()), + CreateObjectListMapper(destList, GetObjectMapper(typeof(T))), + parameters); + + return destList; + } + + public List MapDictionaryToList( + IDictionary sourceDictionary, + params object[] parameters) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + List destList = new List(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper(sourceDictionary.Values.GetEnumerator()), + CreateObjectListMapper(destList, GetObjectMapper(typeof(T))), + parameters); + + return destList; + } + + #endregion + + #region MapDictionaryToDataTable + +#if !SILVERLIGHT + + public DataTable MapDictionaryToDataTable( + IDictionary sourceDictionary, + DataTable destTable) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + MapSourceListToDestinationList( + CreateEnumeratorMapper(sourceDictionary.Values.GetEnumerator()), + CreateDataTableMapper (destTable, DataRowVersion.Default), + null); + + return destTable; + } + + [SuppressMessage("Microsoft.Globalization", "CA1306:SetLocaleForDataTypes")] + public DataTable MapDictionaryToDataTable(IDictionary sourceDictionary) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + DataTable destTable = new DataTable(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper(sourceDictionary.Values.GetEnumerator()), + CreateDataTableMapper (destTable, DataRowVersion.Default), + null); + + return destTable; + } + +#endif + + #endregion + + #region MapDictionaryToDictionary + + public IDictionary MapDictionaryToDictionary( + IDictionary sourceDictionary, + IDictionary destDictionary, + NameOrIndexParameter keyFieldNameOrIndex, + Type destObjectType, + params object[] parameters) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceDictionary.Values.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapDictionaryToDictionary( + IDictionary sourceDictionary, + NameOrIndexParameter keyFieldNameOrIndex, + Type destObjectType, + params object[] parameters) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + IDictionary dest = new Dictionary(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceDictionary.Values.GetEnumerator()), + CreateDictionaryListMapper(dest, keyFieldNameOrIndex, GetObjectMapper(destObjectType)), + parameters); + + return dest; + } + + public IDictionary MapDictionaryToDictionary( + IDictionary sourceDictionary, + IDictionary destDictionary, + NameOrIndexParameter keyFieldNameOrIndex, + params object[] parameters) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceDictionary.Values.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, keyFieldNameOrIndex, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + public Dictionary MapDictionaryToDictionary( + IDictionary sourceDictionary, + NameOrIndexParameter keyFieldNameOrIndex, + params object[] parameters) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + Dictionary dest = new Dictionary(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceDictionary.Values.GetEnumerator()), + CreateDictionaryListMapper(dest, keyFieldNameOrIndex, GetObjectMapper(typeof(T))), + parameters); + + return dest; + } + + #endregion + + #region MapDictionaryToDictionary (Index) + + public IDictionary MapDictionaryToDictionary( + IDictionary sourceDictionary, + IDictionary destDictionary, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceDictionary.Values.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapDictionaryToDictionary( + IDictionary sourceDictionary, + MapIndex index, + Type destObjectType, + params object[] parameters) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + IDictionary destDictionary = new Dictionary(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceDictionary.Values.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(destObjectType)), + parameters); + + return destDictionary; + } + + public IDictionary MapDictionaryToDictionary( + IDictionary sourceDictionary, + IDictionary destDictionary, + MapIndex index, + params object[] parameters) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceDictionary.Values.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + public Dictionary MapDictionaryToDictionary( + IDictionary sourceDictionary, + MapIndex index, + params object[] parameters) + { + if (sourceDictionary == null) throw new ArgumentNullException("sourceDictionary"); + + Dictionary destDictionary = new Dictionary(); + + MapSourceListToDestinationList( + CreateEnumeratorMapper (sourceDictionary.Values.GetEnumerator()), + CreateDictionaryListMapper(destDictionary, index, GetObjectMapper(typeof(T))), + parameters); + + return destDictionary; + } + + #endregion + + #endregion + + #region MapToResultSet + + public void MapResultSets(MapResultSet[] resultSets) + { + var initTable = new Dictionary(); + var context = new InitContext(); + + object lastContainer = null; + + context.MappingSchema = this; + + try + { + PrepareRelarions(resultSets); + + // Map relations. + // + foreach (MapResultSet rs in resultSets) + { + if (rs.Relations == null) + continue; + + ObjectMapper masterMapper = GetObjectMapper(rs.ObjectType); + + foreach (MapRelation r in rs.Relations) + { + MemberAccessor ma = masterMapper.TypeAccessor[r.ContainerName]; + + if (ma == null) + throw new MappingException(string.Format(Resources.MapIndex_BadField, + masterMapper.TypeAccessor.OriginalType.Name, r.ContainerName)); + + // Map. + // + var slave = r.SlaveResultSet; + var slaveMapper = GetObjectMapper(r.SlaveResultSet.ObjectType); + var indexedLists = rs.GetIndex(this, r.MasterIndex); + + foreach (object o in slave.List) + { + object key = r.SlaveIndex.GetValueOrIndex(slaveMapper, o); + + if (IsNull(key)) + continue; + + IList masterList; + + if (!indexedLists.TryGetValue(key, out masterList)) + continue; + + foreach (object master in masterList) + { + ISupportMapping msm = master as ISupportMapping; + + if (msm != null) + { + if (initTable.ContainsKey(master) == false) + { + msm.BeginMapping(context); + initTable.Add(master, msm); + } + } + + object container = ma.GetValue(master); + + if (container is IList) + { + if (lastContainer != container) + { + lastContainer = container; + + ISupportMapping sm = container as ISupportMapping; + + if (sm != null) + { + if (initTable.ContainsKey(container) == false) + { + sm.BeginMapping(context); + initTable[container] = sm; + } + } + } + + ((IList)container).Add(o); + } + else + { + ma.SetValue(master, o); + } + } + } + } + } + } + finally + { + foreach (ISupportMapping si in initTable.Values) + si.EndMapping(context); + } + } + + public void MapDataReaderToResultSet( + IDataReader reader, + MapResultSet[] resultSets) + { + if (reader == null) throw new ArgumentNullException("reader"); + + foreach (MapResultSet rs in resultSets) + { + MapDataReaderToList(reader, rs.List, rs.ObjectType, rs.Parameters); + + if (reader.NextResult() == false) + break; + } + + MapResultSets(resultSets); + } + +#if !SILVERLIGHT + + public void MapDataSetToResultSet( + DataSet dataSet, + MapResultSet[] resultSets) + { + for (int i = 0; i < resultSets.Length && i < dataSet.Tables.Count; i++) + { + MapResultSet rs = resultSets[i]; + + MapDataTableToList(dataSet.Tables[i], rs.List, rs.ObjectType, rs.Parameters); + } + + MapResultSets(resultSets); + } + +#endif + + public MapResultSet[] Clone(MapResultSet[] resultSets) + { + MapResultSet[] output = new MapResultSet[resultSets.Length]; + + for (int i = 0; i < resultSets.Length; i++) + output[i] = new MapResultSet(resultSets[i]); + + return output; + } + + private static int GetResultCount(MapNextResult[] nextResults) + { + int n = nextResults.Length; + + foreach (MapNextResult nr in nextResults) + n += GetResultCount(nr.NextResults); + + return n; + } + + private static int GetResultSets( + int current, + MapResultSet[] output, + MapResultSet master, + MapNextResult[] nextResults) + { + foreach (MapNextResult nr in nextResults) + { + output[current] = new MapResultSet(nr.ObjectType); + + master.AddRelation(output[current], nr.SlaveIndex, nr.MasterIndex, nr.ContainerName); + + current += GetResultSets(current + 1, output, output[current], nr.NextResults); + } + + return current; + } + + public MapResultSet[] ConvertToResultSet( + Type masterType, + params MapNextResult[] nextResults) + { + MapResultSet[] output = new MapResultSet[1 + GetResultCount(nextResults)]; + + output[0] = new MapResultSet(masterType); + + GetResultSets(1, output, output[0], nextResults); + + return output; + } + + private void PrepareRelarions(params MapResultSet[] sets) + { + foreach (MapResultSet masterSet in sets) + { + if (masterSet.Relations != null) + continue; + + foreach (MapResultSet slaveSet in sets) + { + bool isSet; + + List relations + = MetadataProvider.GetRelations(this, Extensions, masterSet.ObjectType, slaveSet.ObjectType, out isSet); + + if (!isSet) + continue; + + foreach (MapRelationBase relation in relations) + masterSet.AddRelation(slaveSet, relation); + } + } + } + + #endregion + + #region GetObjectMapper + + public Func GetObjectMapper() + { + return new ExpressionMapper(this) + { + IncludeComplexMapping = Common.Configuration.ExpressionMapper.IncludeComplexMapping + }.GetMapper(); + } + + public Func GetObjectMapper(bool deepCopy) + { + return new ExpressionMapper(this) + { + DeepCopy = deepCopy, + IncludeComplexMapping = Common.Configuration.ExpressionMapper.IncludeComplexMapping + }.GetMapper(); + } + + public Func GetObjectMapper(bool deepCopy, bool includeComplexMapping) + { + return new ExpressionMapper(this) + { + DeepCopy = deepCopy, + IncludeComplexMapping = includeComplexMapping + }.GetMapper(); + } + + #endregion + + #region ConvertParameterValue + + public virtual object ConvertParameterValue(object value, Type systemType) + { + return value; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MemberMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MemberMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,902 @@ +using System; +using System.Data; +using System.Data.SqlTypes; +using System.Diagnostics; +using System.IO; +using System.Xml; + +using BLToolkit.Data.Sql; +using BLToolkit.Reflection; +using BLToolkit.TypeBuilder; + +using Convert = BLToolkit.Common.Convert; +#if !SILVERLIGHT +using System.Xml.Linq; +#endif + +namespace BLToolkit.Mapping +{ + public partial class MemberMapper + { + #region Init + + public virtual void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + MapMemberInfo = mapMemberInfo; + Name = mapMemberInfo.Name; + MemberName = mapMemberInfo.MemberName; + Storage = mapMemberInfo.Storage; + DbType = mapMemberInfo.DbType; + _type = mapMemberInfo.Type; + MemberAccessor = mapMemberInfo.MemberAccessor; + _complexMemberAccessor = mapMemberInfo.ComplexMemberAccessor; + MappingSchema = mapMemberInfo.MappingSchema; + + if (Storage != null) + MemberAccessor = ExprMemberAccessor.GetMemberAccessor(MemberAccessor.TypeAccessor, Storage); + } + + internal static MemberMapper CreateMemberMapper(MapMemberInfo mi) + { + var type = mi.Type; + var mm = null as MemberMapper; + + if (type.IsPrimitive || type.IsEnum) + mm = GetPrimitiveMemberMapper(mi); + + if (mm == null) + { + mm = GetNullableMemberMapper(mi); + + //if (mm != null) + // mi.IsNullable = true; + } + + if (mm == null) mm = GetSimpleMemberMapper(mi); +#if !SILVERLIGHT + if (mm == null) mm = GetSqlTypeMemberMapper(mi); +#endif + return mm ?? new DefaultMemberMapper(); + } + + #endregion + + #region Public Properties + + public MappingSchema MappingSchema { get; private set; } + public string Name { get; private set; } + public string MemberName { get; private set; } + public string Storage { get; private set; } + public DbType DbType { get; private set; } + public MapMemberInfo MapMemberInfo { get; private set; } + public int Ordinal { get; private set; } + public MemberAccessor MemberAccessor { get; private set; } + public bool IsExplicit { get; set; } + + internal void SetOrdinal(int ordinal) + { + Ordinal = ordinal; + } + + private MemberAccessor _complexMemberAccessor; + public MemberAccessor ComplexMemberAccessor + { + [DebuggerStepThrough] + get { return _complexMemberAccessor ?? MemberAccessor; } + } + + Type _type; + public virtual Type Type + { + get { return _type; } + } + + public DbType GetDbType() + { + if (MapMemberInfo.IsDbTypeSet) + return DbType; + + if (DbType != DbType.Object) + return DbType; + + var dataType = SqlDataType.GetDataType(_type); + + switch (dataType.SqlDbType) + { + case SqlDbType.BigInt : return DbType.Int64; + case SqlDbType.Binary : return DbType.Binary; + case SqlDbType.Bit : return DbType.Boolean; + case SqlDbType.Char : return DbType.AnsiStringFixedLength; + case SqlDbType.DateTime : return DbType.DateTime; + case SqlDbType.Decimal : return DbType.Decimal; + case SqlDbType.Float : return DbType.Double; + case SqlDbType.Image : return DbType.Binary; + case SqlDbType.Int : return DbType.Int32; + case SqlDbType.Money : return DbType.Currency; + case SqlDbType.NChar : return DbType.StringFixedLength; + case SqlDbType.NText : return DbType.String; + case SqlDbType.NVarChar : return DbType.String; + case SqlDbType.Real : return DbType.Single; + case SqlDbType.UniqueIdentifier : return DbType.Guid; + case SqlDbType.SmallDateTime : return DbType.DateTime; + case SqlDbType.SmallInt : return DbType.Int16; + case SqlDbType.SmallMoney : return DbType.Currency; + case SqlDbType.Text : return DbType.AnsiString; + case SqlDbType.Timestamp : return DbType.Binary; + case SqlDbType.TinyInt : return DbType.Byte; + case SqlDbType.VarBinary : return DbType.Binary; + case SqlDbType.VarChar : return DbType.AnsiString; + case SqlDbType.Variant : return DbType.Object; + case SqlDbType.Xml : return DbType.Xml; + case SqlDbType.Udt : return DbType.Binary; + case SqlDbType.Date : return DbType.Date; + case SqlDbType.Time : return DbType.Time; +#if !MONO + case SqlDbType.Structured : return DbType.Binary; + case SqlDbType.DateTime2 : return DbType.DateTime2; + case SqlDbType.DateTimeOffset : return DbType.DateTimeOffset; +#endif + } + + return DbType.Object; + } + + public int GetDbSize(object value) + { + if (MapMemberInfo.IsDbSizeSet) + return MapMemberInfo.DbSize; + + if (value == null) + return 0; + + if (value is string) + return ((string)value).Length; + + if (value is byte[]) + return ((byte[])value).Length; + + + var dataType = SqlDataType.GetDataType(_type); + + switch (dataType.SqlDbType) + { + case SqlDbType.BigInt : return 0; + case SqlDbType.Binary : return 0; + case SqlDbType.Bit : return 0; + case SqlDbType.Char : return 0; + case SqlDbType.DateTime : return 0; + case SqlDbType.Decimal : return 0; + case SqlDbType.Float : return 0; + case SqlDbType.Image : return 0; + case SqlDbType.Int : return 0; + case SqlDbType.Money : return 0; + case SqlDbType.NChar : return 0; + case SqlDbType.NText : return 0; + case SqlDbType.NVarChar : return 0; + case SqlDbType.Real : return 0; + case SqlDbType.UniqueIdentifier : return 0; + case SqlDbType.SmallDateTime : return 0; + case SqlDbType.SmallInt : return 0; + case SqlDbType.SmallMoney : return 0; + case SqlDbType.Text : return 0; + case SqlDbType.Timestamp : return 0; + case SqlDbType.TinyInt : return 0; + case SqlDbType.VarBinary : return 0; + case SqlDbType.VarChar : return 0; + case SqlDbType.Variant : return 0; + case SqlDbType.Xml : return 0; + case SqlDbType.Udt : return 0; + case SqlDbType.Date : return 0; + case SqlDbType.Time : return 0; +#if !MONO + case SqlDbType.Structured : return 0; + case SqlDbType.DateTime2 : return 0; + case SqlDbType.DateTimeOffset : return 0; +#endif + } + + return 0; + } + + #endregion + + #region Default Members (GetValue, SetValue) + + public virtual bool SupportsValue { get { return !IsExplicit; } } + + public virtual object GetValue(object o) + { + return MemberAccessor.GetValue(o); + } + + public virtual bool IsNull (object o) { return GetValue(o) == null; } + + // Simple type getters. + // + [CLSCompliant(false)] + public virtual SByte GetSByte (object o) { return MemberAccessor.GetSByte (o); } + public virtual Int16 GetInt16 (object o) { return MemberAccessor.GetInt16 (o); } + public virtual Int32 GetInt32 (object o) { return MemberAccessor.GetInt32 (o); } + public virtual Int64 GetInt64 (object o) { return MemberAccessor.GetInt64 (o); } + + public virtual Byte GetByte (object o) { return MemberAccessor.GetByte (o); } + [CLSCompliant(false)] + public virtual UInt16 GetUInt16 (object o) { return MemberAccessor.GetUInt16 (o); } + [CLSCompliant(false)] + public virtual UInt32 GetUInt32 (object o) { return MemberAccessor.GetUInt32 (o); } + [CLSCompliant(false)] + public virtual UInt64 GetUInt64 (object o) { return MemberAccessor.GetUInt64 (o); } + + public virtual Boolean GetBoolean (object o) { return MemberAccessor.GetBoolean (o); } + public virtual Char GetChar (object o) { return MemberAccessor.GetChar (o); } + public virtual Single GetSingle (object o) { return MemberAccessor.GetSingle (o); } + public virtual Double GetDouble (object o) { return MemberAccessor.GetDouble (o); } + public virtual Decimal GetDecimal (object o) { return MemberAccessor.GetDecimal (o); } + public virtual Guid GetGuid (object o) { return MemberAccessor.GetGuid (o); } + public virtual DateTime GetDateTime(object o) { return MemberAccessor.GetDateTime(o); } + public virtual DateTimeOffset GetDateTimeOffset(object o) { return MemberAccessor.GetDateTimeOffset(o); } + + // Nullable type getters. + // + [CLSCompliant(false)] + public virtual SByte? GetNullableSByte (object o) { return MemberAccessor.GetNullableSByte (o); } + public virtual Int16? GetNullableInt16 (object o) { return MemberAccessor.GetNullableInt16 (o); } + public virtual Int32? GetNullableInt32 (object o) { return MemberAccessor.GetNullableInt32 (o); } + public virtual Int64? GetNullableInt64 (object o) { return MemberAccessor.GetNullableInt64 (o); } + + public virtual Byte? GetNullableByte (object o) { return MemberAccessor.GetNullableByte (o); } + [CLSCompliant(false)] + public virtual UInt16? GetNullableUInt16 (object o) { return MemberAccessor.GetNullableUInt16 (o); } + [CLSCompliant(false)] + public virtual UInt32? GetNullableUInt32 (object o) { return MemberAccessor.GetNullableUInt32 (o); } + [CLSCompliant(false)] + public virtual UInt64? GetNullableUInt64 (object o) { return MemberAccessor.GetNullableUInt64 (o); } + + public virtual Boolean? GetNullableBoolean (object o) { return MemberAccessor.GetNullableBoolean (o); } + public virtual Char? GetNullableChar (object o) { return MemberAccessor.GetNullableChar (o); } + public virtual Single? GetNullableSingle (object o) { return MemberAccessor.GetNullableSingle (o); } + public virtual Double? GetNullableDouble (object o) { return MemberAccessor.GetNullableDouble (o); } + public virtual Decimal? GetNullableDecimal (object o) { return MemberAccessor.GetNullableDecimal (o); } + public virtual Guid? GetNullableGuid (object o) { return MemberAccessor.GetNullableGuid (o); } + public virtual DateTime? GetNullableDateTime(object o) { return MemberAccessor.GetNullableDateTime(o); } + public virtual DateTimeOffset? GetNullableDateTimeOffset(object o) { return MemberAccessor.GetNullableDateTimeOffset(o); } + +#if !SILVERLIGHT + + // SQL type getters. + // + public virtual SqlByte GetSqlByte (object o) { return MemberAccessor.GetSqlByte (o); } + public virtual SqlInt16 GetSqlInt16 (object o) { return MemberAccessor.GetSqlInt16 (o); } + public virtual SqlInt32 GetSqlInt32 (object o) { return MemberAccessor.GetSqlInt32 (o); } + public virtual SqlInt64 GetSqlInt64 (object o) { return MemberAccessor.GetSqlInt64 (o); } + public virtual SqlSingle GetSqlSingle (object o) { return MemberAccessor.GetSqlSingle (o); } + public virtual SqlBoolean GetSqlBoolean (object o) { return MemberAccessor.GetSqlBoolean (o); } + public virtual SqlDouble GetSqlDouble (object o) { return MemberAccessor.GetSqlDouble (o); } + public virtual SqlDateTime GetSqlDateTime(object o) { return MemberAccessor.GetSqlDateTime(o); } + public virtual SqlDecimal GetSqlDecimal (object o) { return MemberAccessor.GetSqlDecimal (o); } + public virtual SqlMoney GetSqlMoney (object o) { return MemberAccessor.GetSqlMoney (o); } + public virtual SqlGuid GetSqlGuid (object o) { return MemberAccessor.GetSqlGuid (o); } + public virtual SqlString GetSqlString (object o) { return MemberAccessor.GetSqlString (o); } + +#endif + + public virtual void SetValue(object o, object value) + { + MemberAccessor.SetValue(o, value); + } + + public virtual void SetNull (object o) { SetValue(o, null); } + + // Simple type setters. + // + [CLSCompliant(false)] + public virtual void SetSByte (object o, SByte value) { MemberAccessor.SetSByte (o, value); } + public virtual void SetInt16 (object o, Int16 value) { MemberAccessor.SetInt16 (o, value); } + public virtual void SetInt32 (object o, Int32 value) { MemberAccessor.SetInt32 (o, value); } + public virtual void SetInt64 (object o, Int64 value) { MemberAccessor.SetInt64 (o, value); } + + public virtual void SetByte (object o, Byte value) { MemberAccessor.SetByte (o, value); } + [CLSCompliant(false)] + public virtual void SetUInt16 (object o, UInt16 value) { MemberAccessor.SetUInt16 (o, value); } + [CLSCompliant(false)] + public virtual void SetUInt32 (object o, UInt32 value) { MemberAccessor.SetUInt32 (o, value); } + [CLSCompliant(false)] + public virtual void SetUInt64 (object o, UInt64 value) { MemberAccessor.SetUInt64 (o, value); } + + public virtual void SetBoolean (object o, Boolean value) { MemberAccessor.SetBoolean (o, value); } + public virtual void SetChar (object o, Char value) { MemberAccessor.SetChar (o, value); } + public virtual void SetSingle (object o, Single value) { MemberAccessor.SetSingle (o, value); } + public virtual void SetDouble (object o, Double value) { MemberAccessor.SetDouble (o, value); } + public virtual void SetDecimal (object o, Decimal value) { MemberAccessor.SetDecimal (o, value); } + public virtual void SetGuid (object o, Guid value) { MemberAccessor.SetGuid (o, value); } + public virtual void SetDateTime(object o, DateTime value) { MemberAccessor.SetDateTime(o, value); } + public virtual void SetDateTimeOffset(object o, DateTimeOffset value) { MemberAccessor.SetDateTimeOffset(o, value); } + + // Nullable type setters. + // + [CLSCompliant(false)] + public virtual void SetNullableSByte (object o, SByte? value) { MemberAccessor.SetNullableSByte (o, value); } + public virtual void SetNullableInt16 (object o, Int16? value) { MemberAccessor.SetNullableInt16 (o, value); } + public virtual void SetNullableInt32 (object o, Int32? value) { MemberAccessor.SetNullableInt32 (o, value); } + public virtual void SetNullableInt64 (object o, Int64? value) { MemberAccessor.SetNullableInt64 (o, value); } + + public virtual void SetNullableByte (object o, Byte? value) { MemberAccessor.SetNullableByte (o, value); } + [CLSCompliant(false)] + public virtual void SetNullableUInt16 (object o, UInt16? value) { MemberAccessor.SetNullableUInt16 (o, value); } + [CLSCompliant(false)] + public virtual void SetNullableUInt32 (object o, UInt32? value) { MemberAccessor.SetNullableUInt32 (o, value); } + [CLSCompliant(false)] + public virtual void SetNullableUInt64 (object o, UInt64? value) { MemberAccessor.SetNullableUInt64 (o, value); } + + public virtual void SetNullableBoolean (object o, Boolean? value) { MemberAccessor.SetNullableBoolean (o, value); } + public virtual void SetNullableChar (object o, Char? value) { MemberAccessor.SetNullableChar (o, value); } + public virtual void SetNullableSingle (object o, Single? value) { MemberAccessor.SetNullableSingle (o, value); } + public virtual void SetNullableDouble (object o, Double? value) { MemberAccessor.SetNullableDouble (o, value); } + public virtual void SetNullableDecimal (object o, Decimal? value) { MemberAccessor.SetNullableDecimal (o, value); } + public virtual void SetNullableGuid (object o, Guid? value) { MemberAccessor.SetNullableGuid (o, value); } + public virtual void SetNullableDateTime(object o, DateTime? value) { MemberAccessor.SetNullableDateTime(o, value); } + public virtual void SetNullableDateTimeOffset(object o, DateTimeOffset? value) { MemberAccessor.SetNullableDateTimeOffset(o, value); } + +#if !SILVERLIGHT + + // SQL type setters. + // + public virtual void SetSqlByte (object o, SqlByte value) { MemberAccessor.SetSqlByte (o, value); } + public virtual void SetSqlInt16 (object o, SqlInt16 value) { MemberAccessor.SetSqlInt16 (o, value); } + public virtual void SetSqlInt32 (object o, SqlInt32 value) { MemberAccessor.SetSqlInt32 (o, value); } + public virtual void SetSqlInt64 (object o, SqlInt64 value) { MemberAccessor.SetSqlInt64 (o, value); } + public virtual void SetSqlSingle (object o, SqlSingle value) { MemberAccessor.SetSqlSingle (o, value); } + public virtual void SetSqlBoolean (object o, SqlBoolean value) { MemberAccessor.SetSqlBoolean (o, value); } + public virtual void SetSqlDouble (object o, SqlDouble value) { MemberAccessor.SetSqlDouble (o, value); } + public virtual void SetSqlDateTime(object o, SqlDateTime value) { MemberAccessor.SetSqlDateTime(o, value); } + public virtual void SetSqlDecimal (object o, SqlDecimal value) { MemberAccessor.SetSqlDecimal (o, value); } + public virtual void SetSqlMoney (object o, SqlMoney value) { MemberAccessor.SetSqlMoney (o, value); } + public virtual void SetSqlGuid (object o, SqlGuid value) { MemberAccessor.SetSqlGuid (o, value); } + public virtual void SetSqlString (object o, SqlString value) { MemberAccessor.SetSqlString (o, value); } + +#endif + + public virtual void CloneValue (object source, object dest) { MemberAccessor.CloneValue(source, dest); } + + #endregion + + #region Intermal Mappers + + #region Complex Mapper + + internal sealed class ComplexMapper : MemberMapper + { + public ComplexMapper(MemberMapper memberMapper) + { + _mapper = memberMapper; + } + + private readonly MemberMapper _mapper; + + public override void Init(MapMemberInfo mapMemberInfo) + { + base.Init(mapMemberInfo); + + var attr = MemberAccessor.GetAttribute(); + + if (attr != null) + { + _createInstance = true; + } + } + + bool _createInstance; + TypeAccessor _typeAccessor; + + object GetObject(object o) + { + var obj = MemberAccessor.GetValue(o); + + if (_createInstance && obj == null) + { + if (_typeAccessor == null) + _typeAccessor = TypeAccessor.GetAccessor(MemberAccessor.Type); + + obj = _typeAccessor.CreateInstanceEx(); + + MemberAccessor.SetValue(o, obj); + } + + return obj; + } + + #region GetValue + + public override object GetValue(object o) + { + var obj = MemberAccessor.GetValue(o); + return obj == null? null: _mapper.GetValue(obj); + } + + // Simple type getters. + // + public override SByte GetSByte (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultSByteNullValue: _mapper.GetSByte (obj); } + public override Int16 GetInt16 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultInt16NullValue: _mapper.GetInt16 (obj); } + public override Int32 GetInt32 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultInt32NullValue: _mapper.GetInt32 (obj); } + public override Int64 GetInt64 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultInt64NullValue: _mapper.GetInt64 (obj); } + + public override Byte GetByte (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultByteNullValue: _mapper.GetByte (obj); } + public override UInt16 GetUInt16 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultUInt16NullValue: _mapper.GetUInt16 (obj); } + public override UInt32 GetUInt32 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultUInt32NullValue: _mapper.GetUInt32 (obj); } + public override UInt64 GetUInt64 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultUInt64NullValue: _mapper.GetUInt64 (obj); } + + public override Boolean GetBoolean (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultBooleanNullValue: _mapper.GetBoolean (obj); } + public override Char GetChar (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultCharNullValue: _mapper.GetChar (obj); } + public override Single GetSingle (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultSingleNullValue: _mapper.GetSingle (obj); } + public override Double GetDouble (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultDoubleNullValue: _mapper.GetDouble (obj); } + public override Decimal GetDecimal (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultDecimalNullValue: _mapper.GetDecimal (obj); } + public override Guid GetGuid (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultGuidNullValue: _mapper.GetGuid (obj); } + public override DateTime GetDateTime(object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultDateTimeNullValue: _mapper.GetDateTime(obj); } + public override DateTimeOffset GetDateTimeOffset(object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultDateTimeOffsetNullValue: _mapper.GetDateTimeOffset(obj); } + + // Nullable type getters. + // + public override SByte? GetNullableSByte (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableSByte (obj); } + public override Int16? GetNullableInt16 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableInt16 (obj); } + public override Int32? GetNullableInt32 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableInt32 (obj); } + public override Int64? GetNullableInt64 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableInt64 (obj); } + + public override Byte? GetNullableByte (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableByte (obj); } + public override UInt16? GetNullableUInt16 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableUInt16 (obj); } + public override UInt32? GetNullableUInt32 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableUInt32 (obj); } + public override UInt64? GetNullableUInt64 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableUInt64 (obj); } + + public override Boolean? GetNullableBoolean (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableBoolean (obj); } + public override Char? GetNullableChar (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableChar (obj); } + public override Single? GetNullableSingle (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableSingle (obj); } + public override Double? GetNullableDouble (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableDouble (obj); } + public override Decimal? GetNullableDecimal (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableDecimal (obj); } + public override Guid? GetNullableGuid (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableGuid (obj); } + public override DateTime? GetNullableDateTime(object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableDateTime(obj); } + public override DateTimeOffset? GetNullableDateTimeOffset(object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableDateTimeOffset(obj); } + +#if !SILVERLIGHT + + // SQL type getters. + // + public override SqlByte GetSqlByte (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlByte. Null: _mapper.GetSqlByte (obj); } + public override SqlInt16 GetSqlInt16 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlInt16. Null: _mapper.GetSqlInt16 (obj); } + public override SqlInt32 GetSqlInt32 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlInt32. Null: _mapper.GetSqlInt32 (obj); } + public override SqlInt64 GetSqlInt64 (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlInt64. Null: _mapper.GetSqlInt64 (obj); } + public override SqlSingle GetSqlSingle (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlSingle. Null: _mapper.GetSqlSingle (obj); } + public override SqlBoolean GetSqlBoolean (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlBoolean. Null: _mapper.GetSqlBoolean (obj); } + public override SqlDouble GetSqlDouble (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlDouble. Null: _mapper.GetSqlDouble (obj); } + public override SqlDateTime GetSqlDateTime(object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlDateTime.Null: _mapper.GetSqlDateTime(obj); } + public override SqlDecimal GetSqlDecimal (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlDecimal. Null: _mapper.GetSqlDecimal (obj); } + public override SqlMoney GetSqlMoney (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlMoney. Null: _mapper.GetSqlMoney (obj); } + public override SqlGuid GetSqlGuid (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlGuid. Null: _mapper.GetSqlGuid (obj); } + public override SqlString GetSqlString (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlString. Null: _mapper.GetSqlString (obj); } + +#endif + + #endregion + + #region SetValue + + public override void SetValue(object o, object value) + { + var obj = MemberAccessor.GetValue(o); + + if (obj != null) + _mapper.SetValue(obj, value); + } + + public override void SetSByte (object o, SByte value) { var obj = GetObject(o); if (obj != null) _mapper.SetSByte (obj, value); } + public override void SetInt16 (object o, Int16 value) { var obj = GetObject(o); if (obj != null) _mapper.SetInt16 (obj, value); } + public override void SetInt32 (object o, Int32 value) { var obj = GetObject(o); if (obj != null) _mapper.SetInt32 (obj, value); } + public override void SetInt64 (object o, Int64 value) { var obj = GetObject(o); if (obj != null) _mapper.SetInt64 (obj, value); } + + public override void SetByte (object o, Byte value) { var obj = GetObject(o); if (obj != null) _mapper.SetByte (obj, value); } + public override void SetUInt16 (object o, UInt16 value) { var obj = GetObject(o); if (obj != null) _mapper.SetUInt16 (obj, value); } + public override void SetUInt32 (object o, UInt32 value) { var obj = GetObject(o); if (obj != null) _mapper.SetUInt32 (obj, value); } + public override void SetUInt64 (object o, UInt64 value) { var obj = GetObject(o); if (obj != null) _mapper.SetUInt64 (obj, value); } + + public override void SetBoolean (object o, Boolean value) { var obj = GetObject(o); if (obj != null) _mapper.SetBoolean (obj, value); } + public override void SetChar (object o, Char value) { var obj = GetObject(o); if (obj != null) _mapper.SetChar (obj, value); } + public override void SetSingle (object o, Single value) { var obj = GetObject(o); if (obj != null) _mapper.SetSingle (obj, value); } + public override void SetDouble (object o, Double value) { var obj = GetObject(o); if (obj != null) _mapper.SetDouble (obj, value); } + public override void SetDecimal (object o, Decimal value) { var obj = GetObject(o); if (obj != null) _mapper.SetDecimal (obj, value); } + public override void SetGuid (object o, Guid value) { var obj = GetObject(o); if (obj != null) _mapper.SetGuid (obj, value); } + public override void SetDateTime(object o, DateTime value) { var obj = GetObject(o); if (obj != null) _mapper.SetDateTime(obj, value); } + public override void SetDateTimeOffset(object o, DateTimeOffset value) { var obj = GetObject(o); if (obj != null) _mapper.SetDateTimeOffset(obj, value); } + + // Nullable type setters. + // + public override void SetNullableSByte (object o, SByte? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableSByte (obj, value); } + public override void SetNullableInt16 (object o, Int16? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableInt16 (obj, value); } + public override void SetNullableInt32 (object o, Int32? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableInt32 (obj, value); } + public override void SetNullableInt64 (object o, Int64? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableInt64 (obj, value); } + + public override void SetNullableByte (object o, Byte? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableByte (obj, value); } + public override void SetNullableUInt16 (object o, UInt16? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableUInt16 (obj, value); } + public override void SetNullableUInt32 (object o, UInt32? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableUInt32 (obj, value); } + public override void SetNullableUInt64 (object o, UInt64? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableUInt64 (obj, value); } + + public override void SetNullableBoolean (object o, Boolean? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableBoolean (obj, value); } + public override void SetNullableChar (object o, Char? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableChar (obj, value); } + public override void SetNullableSingle (object o, Single? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableSingle (obj, value); } + public override void SetNullableDouble (object o, Double? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableDouble (obj, value); } + public override void SetNullableDecimal (object o, Decimal? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableDecimal (obj, value); } + public override void SetNullableGuid (object o, Guid? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableGuid (obj, value); } + public override void SetNullableDateTime(object o, DateTime? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableDateTime(obj, value); } + public override void SetNullableDateTimeOffset(object o, DateTimeOffset? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableDateTimeOffset(obj, value); } + +#if !SILVERLIGHT + + // SQL type setters. + // + public override void SetSqlByte (object o, SqlByte value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlByte (obj, value); } + public override void SetSqlInt16 (object o, SqlInt16 value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlInt16 (obj, value); } + public override void SetSqlInt32 (object o, SqlInt32 value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlInt32 (obj, value); } + public override void SetSqlInt64 (object o, SqlInt64 value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlInt64 (obj, value); } + public override void SetSqlSingle (object o, SqlSingle value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlSingle (obj, value); } + public override void SetSqlBoolean (object o, SqlBoolean value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlBoolean (obj, value); } + public override void SetSqlDouble (object o, SqlDouble value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlDouble (obj, value); } + public override void SetSqlDateTime(object o, SqlDateTime value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlDateTime(obj, value); } + public override void SetSqlDecimal (object o, SqlDecimal value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlDecimal (obj, value); } + public override void SetSqlMoney (object o, SqlMoney value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlMoney (obj, value); } + public override void SetSqlGuid (object o, SqlGuid value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlGuid (obj, value); } + public override void SetSqlString (object o, SqlString value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlString (obj, value); } + +#endif + + #endregion + } + + #endregion + + #region Primitive Mappers + + private static MemberMapper GetPrimitiveMemberMapper(MapMemberInfo mi) + { + if (mi.MapValues != null) + return null; + + var n = mi.Nullable; + var type = mi.MemberAccessor.UnderlyingType; + + if (type == typeof(SByte)) return n? new SByteMapper. Nullable(): new SByteMapper(); + if (type == typeof(Int16)) return n? new Int16Mapper. Nullable(): new Int16Mapper(); + if (type == typeof(Int32)) return n? new Int32Mapper. Nullable(): new Int32Mapper(); + if (type == typeof(Int64)) return n? new Int64Mapper. Nullable(): new Int64Mapper(); + if (type == typeof(Byte)) return n? new ByteMapper. Nullable(): new ByteMapper(); + if (type == typeof(UInt16)) return n? new UInt16Mapper. Nullable(): new UInt16Mapper(); + if (type == typeof(UInt32)) return n? new UInt32Mapper. Nullable(): new UInt32Mapper(); + if (type == typeof(UInt64)) return n? new UInt64Mapper. Nullable(): new UInt64Mapper(); + if (type == typeof(Single)) return n? new SingleMapper. Nullable(): new SingleMapper(); + if (type == typeof(Double)) return n? new DoubleMapper. Nullable(): new DoubleMapper(); + if (type == typeof(Char)) return n? new CharMapper. Nullable(): new CharMapper(); + if (type == typeof(Boolean)) return n? new BooleanMapper.Nullable(): new BooleanMapper(); + + throw new InvalidOperationException(); + } + + #endregion + + #region Simple Mappers + + private static MemberMapper GetSimpleMemberMapper(MapMemberInfo mi) + { + if (mi.MapValues != null) + return null; + + var n = mi.Nullable; + var type = mi.Type; + + if (type == typeof(String)) + if (mi.Trimmable) return n? new StringMapper.Trimmable.NullableT(): new StringMapper.Trimmable(); + else return n? new StringMapper.Nullable() : new StringMapper(); + + if (type == typeof(DateTime)) return n? new DateTimeMapper.Nullable() : new DateTimeMapper(); + if (type == typeof(DateTimeOffset)) return n? new DateTimeOffsetMapper.Nullable() : new DateTimeOffsetMapper(); + if (type == typeof(Decimal)) return n? new DecimalMapper.Nullable() : new DecimalMapper(); + if (type == typeof(Guid)) return n? new GuidMapper.Nullable() : new GuidMapper(); + if (type == typeof(Stream)) return n? new StreamMapper.Nullable() : new StreamMapper(); +#if !SILVERLIGHT + if (type == typeof(XmlReader)) return n? new XmlReaderMapper.Nullable() : new XmlReaderMapper(); + if (type == typeof(XmlDocument)) return n? new XmlDocumentMapper.Nullable() : new XmlDocumentMapper(); + if (type == typeof(XElement)) return n? new XElementMapper.Nullable() : new XElementMapper(); +#endif + return null; + } + + class StringMapper : MemberMapper + { + string _nullValue; + + public override void SetValue(object o, object value) + { + MemberAccessor.SetValue( + o, + value is string? value: + value == null? _nullValue: + MappingSchema.ConvertToString(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + if (mapMemberInfo.NullValue != null) + _nullValue = Convert.ToString(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : StringMapper + { + public override object GetValue(object o) + { + var value = MemberAccessor.GetValue(o); + return (string)value == _nullValue? null: value; + } + } + + public class Trimmable : StringMapper + { + public override void SetValue(object o, object value) + { + MemberAccessor.SetValue( + o, value == null? _nullValue: MappingSchema.ConvertToString(value).TrimEnd(_trim)); + } + + public class NullableT : Trimmable + { + public override object GetValue(object o) + { + var value = MemberAccessor.GetValue(o); + return (string)value == _nullValue? null: value; + } + } + } + } + + #endregion + + #region Nullable Mappers + + private static MemberMapper GetNullableMemberMapper(MapMemberInfo mi) + { + var type = mi.Type; + + if (type.IsGenericType == false || mi.MapValues != null) + return null; + + var underlyingType = Nullable.GetUnderlyingType(type); + + if (underlyingType == null) + return null; + + if (underlyingType.IsEnum) + { + underlyingType = Enum.GetUnderlyingType(underlyingType); + + if (underlyingType == typeof(SByte)) return new NullableSByteMapper. Enum(); + if (underlyingType == typeof(Int16)) return new NullableInt16Mapper. Enum(); + if (underlyingType == typeof(Int32)) return new NullableInt32Mapper. Enum(); + if (underlyingType == typeof(Int64)) return new NullableInt64Mapper. Enum(); + if (underlyingType == typeof(Byte)) return new NullableByteMapper. Enum(); + if (underlyingType == typeof(UInt16)) return new NullableUInt16Mapper.Enum(); + if (underlyingType == typeof(UInt32)) return new NullableUInt32Mapper.Enum(); + if (underlyingType == typeof(UInt64)) return new NullableUInt64Mapper.Enum(); + } + else + { + if (underlyingType == typeof(SByte)) return new NullableSByteMapper(); + if (underlyingType == typeof(Int16)) return new NullableInt16Mapper(); + if (underlyingType == typeof(Int32)) return new NullableInt32Mapper(); + if (underlyingType == typeof(Int64)) return new NullableInt64Mapper(); + if (underlyingType == typeof(Byte)) return new NullableByteMapper(); + if (underlyingType == typeof(UInt16)) return new NullableUInt16Mapper(); + if (underlyingType == typeof(UInt32)) return new NullableUInt32Mapper(); + if (underlyingType == typeof(UInt64)) return new NullableUInt64Mapper(); + if (underlyingType == typeof(Char)) return new NullableCharMapper(); + if (underlyingType == typeof(Single)) return new NullableSingleMapper(); + if (underlyingType == typeof(Boolean)) return new NullableBooleanMapper(); + if (underlyingType == typeof(Double)) return new NullableDoubleMapper(); + if (underlyingType == typeof(DateTime)) return new NullableDateTimeMapper(); + if (underlyingType == typeof(Decimal)) return new NullableDecimalMapper(); + if (underlyingType == typeof(Guid)) return new NullableGuidMapper(); + } + + return null; + } + + abstract class NullableEnumMapper : MemberMapper + { + protected Type MemberType; + protected Type UnderlyingType; + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + MemberType = Nullable.GetUnderlyingType(mapMemberInfo.Type); + UnderlyingType = mapMemberInfo.MemberAccessor.UnderlyingType; + + base.Init(mapMemberInfo); + } + } + + #endregion + + #region SqlTypes + +#if !SILVERLIGHT + + private static MemberMapper GetSqlTypeMemberMapper(MapMemberInfo mi) + { + var type = mi.Type; + + if (TypeHelper.IsSameOrParent(typeof(INullable), type) == false) + return null; + + var d = mi.MapValues != null; + + if (type == typeof(SqlByte)) return d? new SqlByteMapper. Default(): new SqlByteMapper(); + if (type == typeof(SqlInt16)) return d? new SqlInt16Mapper. Default(): new SqlInt16Mapper(); + if (type == typeof(SqlInt32)) return d? new SqlInt32Mapper. Default(): new SqlInt32Mapper(); + if (type == typeof(SqlInt64)) return d? new SqlInt64Mapper. Default(): new SqlInt64Mapper(); + if (type == typeof(SqlSingle)) return d? new SqlSingleMapper. Default(): new SqlSingleMapper(); + if (type == typeof(SqlBoolean)) return d? new SqlBooleanMapper. Default(): new SqlBooleanMapper(); + if (type == typeof(SqlDouble)) return d? new SqlDoubleMapper. Default(): new SqlDoubleMapper(); + if (type == typeof(SqlDateTime)) return d? new SqlDateTimeMapper.Default(): new SqlDateTimeMapper(); + if (type == typeof(SqlDecimal)) return d? new SqlDecimalMapper. Default(): new SqlDecimalMapper(); + if (type == typeof(SqlMoney)) return d? new SqlMoneyMapper. Default(): new SqlMoneyMapper(); + if (type == typeof(SqlGuid)) return d? new SqlGuidMapper. Default(): new SqlGuidMapper(); + if (type == typeof(SqlString)) return d? new SqlStringMapper. Default(): new SqlStringMapper(); + + return null; + } + +#endif + + #endregion + + #endregion + + #region MapFrom, MapTo + + protected object MapFrom(object value) + { + return MapFrom(value, MapMemberInfo); + } + + static readonly char[] _trim = { ' ' }; + + protected object MapFrom(object value, MapMemberInfo mapInfo) + { + if (mapInfo == null) throw new ArgumentNullException("mapInfo"); + + if (value == null) + return mapInfo.NullValue; + + if (mapInfo.Trimmable && value is string) + value = value.ToString().TrimEnd(_trim); + + if (mapInfo.MapValues != null) + { + object origValue; + if (mapInfo.TryGetOrigValue(value, out origValue)) + return origValue; + + // 2012-09-18 ili: this is too slow when we have for ex. enum with 50+ values + // + //var comp = (IComparable)value; + + //foreach (var mv in mapInfo.MapValues) + //foreach (var mapValue in mv.MapValues) + //{ + // try + // { + // if (comp.CompareTo(mapValue) == 0) + // return mv.OrigValue; + // } + // catch + // { + // } + //} + + // Default value. + // + if (mapInfo.DefaultValue != null) + return mapInfo.DefaultValue; + } + + var valueType = value.GetType(); + var memberType = mapInfo.Type; + + if (!TypeHelper.IsSameOrParent(memberType, valueType)) + { + if (memberType.IsGenericType) + { + var underlyingType = Nullable.GetUnderlyingType(memberType); + + if (valueType == underlyingType) + return value; + + memberType = underlyingType; + } + + if (memberType.IsEnum) + { + var underlyingType = mapInfo.MemberAccessor.UnderlyingType; + + if (valueType != underlyingType) + //value = _mappingSchema.ConvertChangeType(value, underlyingType); + return MapFrom(MappingSchema.ConvertChangeType(value, underlyingType), mapInfo); + + //value = Enum.Parse(type, Enum.GetName(type, value)); + value = Enum.ToObject(memberType, value); + } + else + { + value = MappingSchema.ConvertChangeType(value, memberType); + } + } + + return value; + } + + protected object MapTo(object value) + { + return MapTo(value, MapMemberInfo); + } + + protected static object MapTo(object value, MapMemberInfo mapInfo) + { + if (mapInfo == null) throw new ArgumentNullException("mapInfo"); + + if (value == null) + return null; + + if (mapInfo.Nullable && mapInfo.NullValue != null) + { + try + { + var comp = (IComparable)value; + + if (comp.CompareTo(mapInfo.NullValue) == 0) + return null; + } + catch + { + } + } + + if (mapInfo.MapValues != null) + { + object mapValue; + if (mapInfo.TryGetMapValue(value, out mapValue)) + return mapValue; + + //2011-11-16 ili: this is too slow when we have for ex. enum with 50+ values + // + //var comp = (IComparable)value; + + //foreach (var mv in mapInfo.MapValues) + //{ + // try + // { + // if (comp.CompareTo(mv.OrigValue) == 0) + // return mv.MapValues[0]; + // } + // catch + // { + // } + //} + } + + return value; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MemberMapper.generated.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MemberMapper.generated.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1477 @@ +//--------------------------------------------------------------------------------------------------- +// +// This code was generated by BLToolkit template for T4. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// +//--------------------------------------------------------------------------------------------------- +using System; +using System.Data.SqlTypes; +using System.IO; +using System.Xml; + +using Convert = BLToolkit.Common.Convert; +#if !SILVERLIGHT +using System.Xml.Linq; +#endif + +namespace BLToolkit.Mapping +{ + public partial class MemberMapper + { + + class SByteMapper : MemberMapper + { + SByte _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetSByte(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSByte( + o, + value is SByte ? (SByte)value : + value == null ? _nullValue : MappingSchema.ConvertToSByte(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToSByte(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : SByteMapper + { + public override bool IsNull(object o) { return GetSByte(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSByte(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class Int16Mapper : MemberMapper + { + Int16 _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetInt16(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetInt16( + o, + value is Int16 ? (Int16)value : + value == null ? _nullValue : MappingSchema.ConvertToInt16(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToInt16(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : Int16Mapper + { + public override bool IsNull(object o) { return GetInt16(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetInt16(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class Int32Mapper : MemberMapper + { + Int32 _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetInt32(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetInt32( + o, + value is Int32 ? (Int32)value : + value == null ? _nullValue : MappingSchema.ConvertToInt32(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToInt32(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : Int32Mapper + { + public override bool IsNull(object o) { return GetInt32(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetInt32(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class Int64Mapper : MemberMapper + { + Int64 _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetInt64(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetInt64( + o, + value is Int64 ? (Int64)value : + value == null ? _nullValue : MappingSchema.ConvertToInt64(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToInt64(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : Int64Mapper + { + public override bool IsNull(object o) { return GetInt64(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetInt64(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class ByteMapper : MemberMapper + { + Byte _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetByte(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetByte( + o, + value is Byte ? (Byte)value : + value == null ? _nullValue : MappingSchema.ConvertToByte(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToByte(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : ByteMapper + { + public override bool IsNull(object o) { return GetByte(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetByte(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class UInt16Mapper : MemberMapper + { + UInt16 _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetUInt16(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetUInt16( + o, + value is UInt16 ? (UInt16)value : + value == null ? _nullValue : MappingSchema.ConvertToUInt16(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToUInt16(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : UInt16Mapper + { + public override bool IsNull(object o) { return GetUInt16(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetUInt16(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class UInt32Mapper : MemberMapper + { + UInt32 _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetUInt32(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetUInt32( + o, + value is UInt32 ? (UInt32)value : + value == null ? _nullValue : MappingSchema.ConvertToUInt32(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToUInt32(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : UInt32Mapper + { + public override bool IsNull(object o) { return GetUInt32(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetUInt32(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class UInt64Mapper : MemberMapper + { + UInt64 _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetUInt64(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetUInt64( + o, + value is UInt64 ? (UInt64)value : + value == null ? _nullValue : MappingSchema.ConvertToUInt64(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToUInt64(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : UInt64Mapper + { + public override bool IsNull(object o) { return GetUInt64(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetUInt64(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class SingleMapper : MemberMapper + { + Single _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetSingle(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSingle( + o, + value is Single ? (Single)value : + value == null ? _nullValue : MappingSchema.ConvertToSingle(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToSingle(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : SingleMapper + { + public override bool IsNull(object o) { return GetSingle(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSingle(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class DoubleMapper : MemberMapper + { + Double _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetDouble(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetDouble( + o, + value is Double ? (Double)value : + value == null ? _nullValue : MappingSchema.ConvertToDouble(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToDouble(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : DoubleMapper + { + public override bool IsNull(object o) { return GetDouble(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetDouble(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class CharMapper : MemberMapper + { + Char _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetChar(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetChar( + o, + value is Char ? (Char)value : + value == null ? _nullValue : MappingSchema.ConvertToChar(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToChar(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : CharMapper + { + public override bool IsNull(object o) { return GetChar(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetChar(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class BooleanMapper : MemberMapper + { + Boolean _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetBoolean(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetBoolean( + o, + value is Boolean ? (Boolean)value : + value == null ? _nullValue : MappingSchema.ConvertToBoolean(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToBoolean(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : BooleanMapper + { + public override bool IsNull(object o) { return GetBoolean(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetBoolean(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class DateTimeMapper : MemberMapper + { + DateTime _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetDateTime(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetDateTime( + o, + value is DateTime ? (DateTime)value : + value == null ? _nullValue : MappingSchema.ConvertToDateTime(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToDateTime(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : DateTimeMapper + { + public override bool IsNull(object o) { return GetDateTime(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetDateTime(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class DateTimeOffsetMapper : MemberMapper + { + DateTimeOffset _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetDateTimeOffset(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetDateTimeOffset( + o, + value is DateTimeOffset ? (DateTimeOffset)value : + value == null ? _nullValue : MappingSchema.ConvertToDateTimeOffset(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToDateTimeOffset(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : DateTimeOffsetMapper + { + public override bool IsNull(object o) { return GetDateTimeOffset(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetDateTimeOffset(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class DecimalMapper : MemberMapper + { + Decimal _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetDecimal(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetDecimal( + o, + value is Decimal ? (Decimal)value : + value == null ? _nullValue : MappingSchema.ConvertToDecimal(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + _nullValue = Convert.ToDecimal(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : DecimalMapper + { + public override bool IsNull(object o) { return GetDecimal(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetDecimal(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class GuidMapper : MemberMapper + { + Guid _nullValue; + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.SetGuid(o, _nullValue); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetGuid( + o, + value is Guid ? (Guid)value : + value == null ? _nullValue : MappingSchema.ConvertToGuid(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + if (mapMemberInfo.NullValue != null) + _nullValue = mapMemberInfo.NullValue is Guid ? + (Guid)mapMemberInfo.NullValue : new Guid(mapMemberInfo.NullValue.ToString()); + + base.Init(mapMemberInfo); + } + + public class Nullable : GuidMapper + { + public override bool IsNull(object o) { return GetGuid(o) == _nullValue; } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetGuid(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class StreamMapper : MemberMapper + { + Stream _nullValue; + + public override void SetValue(object o, object value) + { + MemberAccessor.SetValue( + o, + value is Stream ? value : + value == null ? _nullValue : MappingSchema.ConvertToStream(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + if (mapMemberInfo.NullValue != null) + _nullValue = mapMemberInfo.MappingSchema.ConvertToStream(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : StreamMapper + { + public override object GetValue(object o) + { + var value = MemberAccessor.GetValue(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class NullableSByteMapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableSByte(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableSByte(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableSByte( + o, value == null || value is SByte? (SByte?)value: MappingSchema.ConvertToNullableSByte(value)); + } + + public class Enum : NullableEnumMapper + { + public override void SetValue(object o, object value) + { + if (value != null) + { + var valueType = value.GetType(); + + if (valueType != MemberType) + { + if (valueType != UnderlyingType) + value = MappingSchema.ConvertToNullableSByte(value); + + value = System.Enum.ToObject(MemberType, (SByte)value); + } + } + + MemberAccessor.SetValue(o, value); + } + } + } + + class NullableInt16Mapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableInt16(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableInt16(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableInt16( + o, value == null || value is Int16? (Int16?)value: MappingSchema.ConvertToNullableInt16(value)); + } + + public class Enum : NullableEnumMapper + { + public override void SetValue(object o, object value) + { + if (value != null) + { + var valueType = value.GetType(); + + if (valueType != MemberType) + { + if (valueType != UnderlyingType) + value = MappingSchema.ConvertToNullableInt16(value); + + value = System.Enum.ToObject(MemberType, (Int16)value); + } + } + + MemberAccessor.SetValue(o, value); + } + } + } + + class NullableInt32Mapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableInt32(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableInt32(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableInt32( + o, value == null || value is Int32? (Int32?)value: MappingSchema.ConvertToNullableInt32(value)); + } + + public class Enum : NullableEnumMapper + { + public override void SetValue(object o, object value) + { + if (value != null) + { + var valueType = value.GetType(); + + if (valueType != MemberType) + { + if (valueType != UnderlyingType) + value = MappingSchema.ConvertToNullableInt32(value); + + value = System.Enum.ToObject(MemberType, (Int32)value); + } + } + + MemberAccessor.SetValue(o, value); + } + } + } + + class NullableInt64Mapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableInt64(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableInt64(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableInt64( + o, value == null || value is Int64? (Int64?)value: MappingSchema.ConvertToNullableInt64(value)); + } + + public class Enum : NullableEnumMapper + { + public override void SetValue(object o, object value) + { + if (value != null) + { + var valueType = value.GetType(); + + if (valueType != MemberType) + { + if (valueType != UnderlyingType) + value = MappingSchema.ConvertToNullableInt64(value); + + value = System.Enum.ToObject(MemberType, (Int64)value); + } + } + + MemberAccessor.SetValue(o, value); + } + } + } + + class NullableByteMapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableByte(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableByte(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableByte( + o, value == null || value is Byte? (Byte?)value: MappingSchema.ConvertToNullableByte(value)); + } + + public class Enum : NullableEnumMapper + { + public override void SetValue(object o, object value) + { + if (value != null) + { + var valueType = value.GetType(); + + if (valueType != MemberType) + { + if (valueType != UnderlyingType) + value = MappingSchema.ConvertToNullableByte(value); + + value = System.Enum.ToObject(MemberType, (Byte)value); + } + } + + MemberAccessor.SetValue(o, value); + } + } + } + + class NullableUInt16Mapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableUInt16(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableUInt16(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableUInt16( + o, value == null || value is UInt16? (UInt16?)value: MappingSchema.ConvertToNullableUInt16(value)); + } + + public class Enum : NullableEnumMapper + { + public override void SetValue(object o, object value) + { + if (value != null) + { + var valueType = value.GetType(); + + if (valueType != MemberType) + { + if (valueType != UnderlyingType) + value = MappingSchema.ConvertToNullableUInt16(value); + + value = System.Enum.ToObject(MemberType, (UInt16)value); + } + } + + MemberAccessor.SetValue(o, value); + } + } + } + + class NullableUInt32Mapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableUInt32(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableUInt32(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableUInt32( + o, value == null || value is UInt32? (UInt32?)value: MappingSchema.ConvertToNullableUInt32(value)); + } + + public class Enum : NullableEnumMapper + { + public override void SetValue(object o, object value) + { + if (value != null) + { + var valueType = value.GetType(); + + if (valueType != MemberType) + { + if (valueType != UnderlyingType) + value = MappingSchema.ConvertToNullableUInt32(value); + + value = System.Enum.ToObject(MemberType, (UInt32)value); + } + } + + MemberAccessor.SetValue(o, value); + } + } + } + + class NullableUInt64Mapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableUInt64(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableUInt64(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableUInt64( + o, value == null || value is UInt64? (UInt64?)value: MappingSchema.ConvertToNullableUInt64(value)); + } + + public class Enum : NullableEnumMapper + { + public override void SetValue(object o, object value) + { + if (value != null) + { + var valueType = value.GetType(); + + if (valueType != MemberType) + { + if (valueType != UnderlyingType) + value = MappingSchema.ConvertToNullableUInt64(value); + + value = System.Enum.ToObject(MemberType, (UInt64)value); + } + } + + MemberAccessor.SetValue(o, value); + } + } + } + + class NullableCharMapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableChar(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableChar(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableChar( + o, value == null || value is Char? (Char?)value: MappingSchema.ConvertToNullableChar(value)); + } + } + + class NullableDoubleMapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableDouble(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableDouble(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableDouble( + o, value == null || value is Double? (Double?)value: MappingSchema.ConvertToNullableDouble(value)); + } + } + + class NullableSingleMapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableSingle(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableSingle(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableSingle( + o, value == null || value is Single? (Single?)value: MappingSchema.ConvertToNullableSingle(value)); + } + } + + class NullableBooleanMapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableBoolean(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableBoolean(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableBoolean( + o, value == null || value is Boolean? (Boolean?)value: MappingSchema.ConvertToNullableBoolean(value)); + } + } + + class NullableDateTimeMapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableDateTime(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableDateTime(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableDateTime( + o, value == null || value is DateTime? (DateTime?)value: MappingSchema.ConvertToNullableDateTime(value)); + } + } + + class NullableDecimalMapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableDecimal(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableDecimal(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableDecimal( + o, value == null || value is Decimal? (Decimal?)value: MappingSchema.ConvertToNullableDecimal(value)); + } + } + + class NullableGuidMapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullableGuid(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullableGuid(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullableGuid( + o, value == null || value is Guid? (Guid?)value: MappingSchema.ConvertToNullableGuid(value)); + } + } + +#if !SILVERLIGHT + + class XmlReaderMapper : MemberMapper + { + XmlReader _nullValue; + + public override void SetValue(object o, object value) + { + MemberAccessor.SetValue( + o, + value is XmlReader ? value : + value == null ? _nullValue : MappingSchema.ConvertToXmlReader(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + if (mapMemberInfo.NullValue != null) + _nullValue = mapMemberInfo.MappingSchema.ConvertToXmlReader(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : XmlReaderMapper + { + public override object GetValue(object o) + { + var value = MemberAccessor.GetValue(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class XmlDocumentMapper : MemberMapper + { + XmlDocument _nullValue; + + public override void SetValue(object o, object value) + { + MemberAccessor.SetValue( + o, + value is XmlDocument ? value : + value == null ? _nullValue : MappingSchema.ConvertToXmlDocument(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + if (mapMemberInfo.NullValue != null) + _nullValue = mapMemberInfo.MappingSchema.ConvertToXmlDocument(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : XmlDocumentMapper + { + public override object GetValue(object o) + { + var value = MemberAccessor.GetValue(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class XElementMapper : MemberMapper + { + XElement _nullValue; + + public override void SetValue(object o, object value) + { + MemberAccessor.SetValue( + o, + value is XElement ? value : + value == null ? _nullValue : MappingSchema.ConvertToXElement(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + if (mapMemberInfo.NullValue != null) + _nullValue = mapMemberInfo.MappingSchema.ConvertToXElement(mapMemberInfo.NullValue); + + base.Init(mapMemberInfo); + } + + public class Nullable : XElementMapper + { + public override object GetValue(object o) + { + var value = MemberAccessor.GetValue(o); + return value == _nullValue ? null : (object)value; + } + } + } + + class SqlByteMapper : MemberMapper + { + public override bool IsNull (object o) { return GetSqlByte(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSqlByte(o, SqlByte.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSqlByte(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSqlByte( + o, value is SqlByte? (SqlByte)value: MappingSchema.ConvertToSqlByte(value)); + } + + public class Default : SqlByteMapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } + + class SqlInt16Mapper : MemberMapper + { + public override bool IsNull (object o) { return GetSqlInt16(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSqlInt16(o, SqlInt16.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSqlInt16(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSqlInt16( + o, value is SqlInt16? (SqlInt16)value: MappingSchema.ConvertToSqlInt16(value)); + } + + public class Default : SqlInt16Mapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } + + class SqlInt32Mapper : MemberMapper + { + public override bool IsNull (object o) { return GetSqlInt32(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSqlInt32(o, SqlInt32.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSqlInt32(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSqlInt32( + o, value is SqlInt32? (SqlInt32)value: MappingSchema.ConvertToSqlInt32(value)); + } + + public class Default : SqlInt32Mapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } + + class SqlInt64Mapper : MemberMapper + { + public override bool IsNull (object o) { return GetSqlInt64(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSqlInt64(o, SqlInt64.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSqlInt64(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSqlInt64( + o, value is SqlInt64? (SqlInt64)value: MappingSchema.ConvertToSqlInt64(value)); + } + + public class Default : SqlInt64Mapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } + + class SqlSingleMapper : MemberMapper + { + public override bool IsNull (object o) { return GetSqlSingle(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSqlSingle(o, SqlSingle.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSqlSingle(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSqlSingle( + o, value is SqlSingle? (SqlSingle)value: MappingSchema.ConvertToSqlSingle(value)); + } + + public class Default : SqlSingleMapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } + + class SqlBooleanMapper : MemberMapper + { + public override bool IsNull (object o) { return GetSqlBoolean(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSqlBoolean(o, SqlBoolean.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSqlBoolean(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSqlBoolean( + o, value is SqlBoolean? (SqlBoolean)value: MappingSchema.ConvertToSqlBoolean(value)); + } + + public class Default : SqlBooleanMapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } + + class SqlDoubleMapper : MemberMapper + { + public override bool IsNull (object o) { return GetSqlDouble(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSqlDouble(o, SqlDouble.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSqlDouble(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSqlDouble( + o, value is SqlDouble? (SqlDouble)value: MappingSchema.ConvertToSqlDouble(value)); + } + + public class Default : SqlDoubleMapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } + + class SqlDateTimeMapper : MemberMapper + { + public override bool IsNull (object o) { return GetSqlDateTime(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSqlDateTime(o, SqlDateTime.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSqlDateTime(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSqlDateTime( + o, value is SqlDateTime? (SqlDateTime)value: MappingSchema.ConvertToSqlDateTime(value)); + } + + public class Default : SqlDateTimeMapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } + + class SqlDecimalMapper : MemberMapper + { + public override bool IsNull (object o) { return GetSqlDecimal(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSqlDecimal(o, SqlDecimal.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSqlDecimal(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSqlDecimal( + o, value is SqlDecimal? (SqlDecimal)value: MappingSchema.ConvertToSqlDecimal(value)); + } + + public class Default : SqlDecimalMapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } + + class SqlMoneyMapper : MemberMapper + { + public override bool IsNull (object o) { return GetSqlMoney(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSqlMoney(o, SqlMoney.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSqlMoney(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSqlMoney( + o, value is SqlMoney? (SqlMoney)value: MappingSchema.ConvertToSqlMoney(value)); + } + + public class Default : SqlMoneyMapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } + + class SqlGuidMapper : MemberMapper + { + public override bool IsNull (object o) { return GetSqlGuid(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSqlGuid(o, SqlGuid.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSqlGuid(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSqlGuid( + o, value is SqlGuid? (SqlGuid)value: MappingSchema.ConvertToSqlGuid(value)); + } + + public class Default : SqlGuidMapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } + + class SqlStringMapper : MemberMapper + { + public override bool IsNull (object o) { return GetSqlString(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSqlString(o, SqlString.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSqlString(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSqlString( + o, value is SqlString? (SqlString)value: MappingSchema.ConvertToSqlString(value)); + } + + public class Default : SqlStringMapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } + +#endif + } +} + diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MemberMapper.tt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MemberMapper.tt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,254 @@ +<#@ template language="C#" debug="True" #> +<#@ output extension="generated.cs" #> +//--------------------------------------------------------------------------------------------------- +// +// This code was generated by BLToolkit template for T4. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// +//--------------------------------------------------------------------------------------------------- +using System; +using System.Data.SqlTypes; +using System.IO; +using System.Xml; + +using Convert = BLToolkit.Common.Convert; + +namespace BLToolkit.Mapping +{ + public partial class MemberMapper + { +<# + CreateMapper(SimpleMapper, + "SByte", "Int16", "Int32", "Int64", + "Byte", "UInt16", "UInt32", "UInt64", + "Single", "Double", "Char", "Boolean", + "DateTime", "DateTimeOffset", "Decimal", "Guid", "Stream"); + CreateMapper(EnumNullableMapper, "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64"); + CreateMapper(NullableMapper, "Char", "Double", "Single", "Boolean", "DateTime", "Decimal", "Guid"); +#> + +#if !SILVERLIGHT +<# + CreateMapper(SimpleMapper, "XmlReader", "XmlDocument"); + CreateMapper(SqlTypeMapper, "Byte", "Int16", "Int32", "Int64", "Single", "Boolean", "Double", "DateTime", "Decimal", "Money", "Guid", "String"); +#> + +#endif + } +} + +<#+ +void CreateMapper(Action mapper, params string[] types) +{ + foreach (string t in types) + mapper(t); +} + +void SimpleMapper(string type) +{ + string getset = type; + string cast = "(" + type + ")"; + + switch (type) + { + case "Stream" : + case "XmlReader" : + case "XmlDocument" : + getset = "Value"; + cast = ""; + break; + } + +#> + + class <#= type #>Mapper : MemberMapper + { + <#= type #> _nullValue; +<#+ + switch (type) + { + case "Stream" : + case "XmlReader" : + case "XmlDocument" : + break; + default : +#> + + public override bool IsNull (object o) { return false; } + public override void SetNull(object o) { MemberAccessor.Set<#= type #>(o, _nullValue); } +<#+ + break; + } +#> + + public override void SetValue(object o, object value) + { + MemberAccessor.Set<#= getset #>( + o, + value is <#= type #> ? <#= cast #>value : + value == null ? _nullValue : MappingSchema.ConvertTo<#= type #>(value)); + } + + public override void Init(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); +<#+ + switch (type) + { + case "Guid" : +#> + + if (mapMemberInfo.NullValue != null) + _nullValue = mapMemberInfo.NullValue is Guid ? + (Guid)mapMemberInfo.NullValue : new Guid(mapMemberInfo.NullValue.ToString()); +<#+ + break; + + case "Stream" : + case "XmlReader" : + case "XmlDocument" : +#> + + if (mapMemberInfo.NullValue != null) + _nullValue = mapMemberInfo.MappingSchema.ConvertTo<#= type #>(mapMemberInfo.NullValue); +<#+ + break; + + default: +#> + + _nullValue = Convert.To<#= type #>(mapMemberInfo.NullValue); +<#+ + + break; + } +#> + + base.Init(mapMemberInfo); + } + + public class Nullable : <#= type #>Mapper + { +<#+ + switch (type) + { + case "Stream" : + case "XmlReader" : + case "XmlDocument" : + break; + default: +#> + public override bool IsNull(object o) { return Get<#= type #>(o) == _nullValue; } + +<#+ + + break; + } +#> + public override object GetValue(object o) + { + var value = MemberAccessor.Get<#= getset #>(o); + return value == _nullValue ? null : (object)value; + } + } + } +<#+ +} + +void NullableMapper(string type) +{ +#> + + class Nullable<#= type #>Mapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullable<#= type #>(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullable<#= type #>(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullable<#= type #>( + o, value == null || value is <#= type #>? (<#= type #>?)value: MappingSchema.ConvertToNullable<#= type #>(value)); + } + } +<#+ +} + +void EnumNullableMapper(string type) +{ +#> + + class Nullable<#= type #>Mapper : MemberMapper + { + public override bool IsNull (object o) { return GetNullable<#= type #>(o) == null; } + public override void SetNull(object o) { MemberAccessor.SetNullable<#= type #>(o, null); } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetNullable<#= type #>( + o, value == null || value is <#= type #>? (<#= type #>?)value: MappingSchema.ConvertToNullable<#= type #>(value)); + } + + public class Enum : NullableEnumMapper + { + public override void SetValue(object o, object value) + { + if (value != null) + { + var valueType = value.GetType(); + + if (valueType != MemberType) + { + if (valueType != UnderlyingType) + value = MappingSchema.ConvertToNullable<#= type #>(value); + + value = System.Enum.ToObject(MemberType, (<#= type #>)value); + } + } + + MemberAccessor.SetValue(o, value); + } + } + } +<#+ +} + +void SqlTypeMapper(string type) +{ +#> + + class Sql<#= type #>Mapper : MemberMapper + { + public override bool IsNull (object o) { return GetSql<#= type #>(o).IsNull; } + public override void SetNull(object o) { MemberAccessor.SetSql<#= type #>(o, Sql<#= type #>.Null); } + + public override object GetValue(object o) + { + var value = MemberAccessor.GetSql<#= type #>(o); + return value.IsNull? null: (object)value.Value; + } + + public override void SetValue(object o, object value) + { + MemberAccessor.SetSql<#= type #>( + o, value is Sql<#= type #>? (Sql<#= type #>)value: MappingSchema.ConvertToSql<#= type #>(value)); + } + + public class Default : Sql<#= type #>Mapper + { + public override bool SupportsValue { get { return false; } } + + public override object GetValue(object o) + { + return MapTo(base.GetValue(o)); + } + + public override void SetValue(object o, object value) + { + base.SetValue(o, MapFrom(value)); + } + } + } +<#+ +} + +#> diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MemberMapperAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MemberMapperAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,52 @@ +using System; + +namespace BLToolkit.Mapping +{ + [AttributeUsage( + AttributeTargets.Class | AttributeTargets.Interface | + AttributeTargets.Property | AttributeTargets.Field, + AllowMultiple=true)] + public class MemberMapperAttribute : MapImplicitAttribute + { + public MemberMapperAttribute(Type memberMapperType) + : this(null, memberMapperType) + { + } + + public MemberMapperAttribute(Type memberType, Type memberMapperType) + { + if (memberMapperType == null) throw new ArgumentNullException("memberMapperType"); + + _memberType = memberType; + _memberMapperType = memberMapperType; + } + + private readonly Type _memberType; + public Type MemberType + { + get { return _memberType; } + } + + private readonly Type _memberMapperType; + public Type MemberMapperType + { + get { return _memberMapperType; } + } + + public virtual MemberMapper MemberMapper + { + get + { + var mm = Activator.CreateInstance(_memberMapperType) as MemberMapper; + + if (mm == null) + throw new ArgumentException( + string.Format("Type '{0}' is not MemberMapper.", _memberMapperType)); + + mm.IsExplicit = true; + + return mm; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MemberMappers/BinarySerialisationMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MemberMappers/BinarySerialisationMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,39 @@ +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +namespace BLToolkit.Mapping.MemberMappers +{ + public class BinarySerialisationMapper : MemberMapper + { + public override void SetValue(object o, object value) + { + if (value != null) this.MemberAccessor.SetValue(o, BinarydesSrialize((byte[])value)); + } + + public override object GetValue(object o) + { + return BinarySerialize(this.MemberAccessor.GetValue(o)); + } + + static byte[] BinarySerialize(object obj) + { + if (obj == null) return null; + MemoryStream memoryStream = new MemoryStream(); + BinaryFormatter binaryFormatter = new BinaryFormatter(); + binaryFormatter.Serialize(memoryStream, obj); + memoryStream.Flush(); + memoryStream.Position = 0; + return memoryStream.ToArray(); + } + + static object BinarydesSrialize(byte[] data) + { + using (var stream = new MemoryStream(data)) + { + var formatter = new BinaryFormatter(); + stream.Seek(0, SeekOrigin.Begin); + return formatter.Deserialize(stream); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MemberMappers/BinarySerialisationToBase64StringMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MemberMappers/BinarySerialisationToBase64StringMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,40 @@ +using System; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +namespace BLToolkit.Mapping.MemberMappers +{ + public class BinarySerialisationToBase64StringMapper : MemberMapper + { + public override void SetValue(object o, object value) + { + if (value != null) this.MemberAccessor.SetValue(o, BinarydeSerialize(Convert.FromBase64String(value.ToString()))); + } + + public override object GetValue(object o) + { + return Convert.ToBase64String(BinarySerialize(this.MemberAccessor.GetValue(o))); + } + + static byte[] BinarySerialize(object obj) + { + if (obj == null) return null; + MemoryStream memoryStream = new MemoryStream(); + BinaryFormatter binaryFormatter = new BinaryFormatter(); + binaryFormatter.Serialize(memoryStream, obj); + memoryStream.Flush(); + memoryStream.Position = 0; + return memoryStream.ToArray(); + } + + static object BinarydeSerialize(byte[] data) + { + using (var stream = new MemoryStream(data)) + { + var formatter = new BinaryFormatter(); + stream.Seek(0, SeekOrigin.Begin); + return formatter.Deserialize(stream); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MemberMappers/JSONSerialisationMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MemberMappers/JSONSerialisationMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,49 @@ +using System; +using System.IO; +using System.Runtime.Serialization.Json; +using System.Text; + +namespace BLToolkit.Mapping.MemberMappers +{ + public class JSONSerialisationMapper : MemberMapper + { + public override void SetValue(object o, object value) + { + if (value != null) this.MemberAccessor.SetValue(o, Deserialize(value.ToString())); + } + + public override object GetValue(object o) + { + return this.serialize(this.MemberAccessor.GetValue(o)); + } + + private string serialize(object obj) + { + if (obj == null) return null; + + DataContractJsonSerializer ser = new DataContractJsonSerializer(this.Type); + MemoryStream ms = new MemoryStream(); + ser.WriteObject(ms, obj); + string jsonString = Encoding.UTF8.GetString(ms.ToArray()); + ms.Close(); + return jsonString; + } + + object Deserialize(string txt) + { + object retVal = null; + if (string.IsNullOrEmpty(txt)) return null; + + try + { + DataContractJsonSerializer ser = new DataContractJsonSerializer(this.Type); + MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(txt)); + retVal = ser.ReadObject(ms); + } + catch (Exception) + { + } + return retVal; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MemberMappers/TimeSpanBigIntMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MemberMappers/TimeSpanBigIntMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ +using System; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +namespace BLToolkit.Mapping.MemberMappers +{ + public class TimeSpanBigIntMapper : MemberMapper + { + public override void SetValue(object o, object value) + { + if (value != null) this.MemberAccessor.SetValue(o, new TimeSpan((long)value)); + } + + public override object GetValue(object o) + { + var val = this.MemberAccessor.GetValue(o); + if (val != null) + return ((TimeSpan) val).Ticks; + return null; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/MemberMappers/XMLSerialisationMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/MemberMappers/XMLSerialisationMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,58 @@ +using System; +using System.IO; +using System.Xml; +using System.Xml.Serialization; + +namespace BLToolkit.Mapping.MemberMappers +{ + public class XMLSerialisationMapper : MemberMapper + { + public override void SetValue(object o, object value) + { + if (value != null) this.MemberAccessor.SetValue(o, this.Deserialize(value.ToString())); + } + + public override object GetValue(object o) + { + return this.XmlSerialize(this.MemberAccessor.GetValue(o)); + } + + string XmlSerialize(object obj) + { + if (obj == null) return null; + XmlSerializer serializer = new XmlSerializer(this.Type); + MemoryStream ms = new MemoryStream(); + XmlWriterSettings settings = new XmlWriterSettings(); + settings.OmitXmlDeclaration = true; + settings.Indent = true; + XmlWriter writer = XmlWriter.Create(ms, settings); + XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); + namespaces.Add(string.Empty, string.Empty); + serializer.Serialize(writer, obj, namespaces); + StreamReader r = new StreamReader(ms); + r.BaseStream.Seek(0, SeekOrigin.Begin); + + return r.ReadToEnd(); + } + + object Deserialize(string txt) + { + object retVal = null; + if (string.IsNullOrEmpty(txt)) return null; + + try + { + XmlSerializer ser = new XmlSerializer(this.Type); + StringReader stringReader = new StringReader(txt); + XmlTextReader xmlReader = new XmlTextReader(stringReader); + retVal = ser.Deserialize(xmlReader); + xmlReader.Close(); + stringReader.Close(); + } + catch (Exception) + { + } + return retVal; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/NotNullAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/NotNullAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; + +namespace BLToolkit.Mapping +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public sealed class NotNullAttribute : NullableAttribute + { + public NotNullAttribute() + : base(false) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/NullDateTimeAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/NullDateTimeAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,27 @@ +using System; + +namespace BLToolkit.Mapping +{ + public class NullDateTimeAttribute : NullValueAttribute + { + public NullDateTimeAttribute() + : base(DateTime.MinValue) + { + } + + public NullDateTimeAttribute(int year, int month, int day) + : base(new DateTime(year, month, day)) + { + } + + public NullDateTimeAttribute(int year, int month, int day, int hour, int minute, int second) + : base(new DateTime(year, month, day, hour, minute, second)) + { + } + + public NullDateTimeAttribute(int year, int month, int day, int hour, int minute, int second, int millisecond) + : base(new DateTime(year, month, day, hour, minute, second, millisecond)) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/NullDecimalAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/NullDecimalAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,43 @@ +using System; + +namespace BLToolkit.Mapping +{ + public class NullDecimalAttribute : NullValueAttribute + { + public NullDecimalAttribute() + : base(0m) + { + } + + public NullDecimalAttribute(decimal nullValue) + : base(nullValue) + { + } + + public NullDecimalAttribute(double value) + : base(new Decimal(value)) + { + } + + public NullDecimalAttribute(int[] bits) + : base(new Decimal(bits)) + { + } + + public NullDecimalAttribute(long value) + : base(new Decimal(value)) + { + } + + [CLSCompliant(false)] + public NullDecimalAttribute(ulong value) + : base(new Decimal(value)) + { + } + + public NullDecimalAttribute(int lo, int mid, int hi, bool isNegative, byte scale) + : base(new Decimal(lo, mid, hi, isNegative, scale)) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/NullGuidAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/NullGuidAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,42 @@ +using System; + +namespace BLToolkit.Mapping +{ + public class NullGuidAttribute : NullValueAttribute + { + public NullGuidAttribute() + : base(Guid.Empty) + { + } + + public NullGuidAttribute(byte[] b) + : base(new Guid(b)) + { + } + + public NullGuidAttribute(string g) + : base(new Guid(g)) + { + } + + public NullGuidAttribute(int a, short b, short c, byte[] d) + : base(new Guid(a, b, c, d)) + { + } + + public NullGuidAttribute(int a, short b, short c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k) + : base(new Guid(a, b, c, d, e, f, g, h, i, j, k)) + { + } + +#if !SILVERLIGHT + + [CLSCompliant(false)] + public NullGuidAttribute(uint a, ushort b, ushort c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k) + : base(new Guid(a, b, c, d, e, f, g, h, i, j, k)) + { + } + +#endif + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/NullValueAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/NullValueAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,41 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace BLToolkit.Mapping +{ + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")] + [AttributeUsage( + AttributeTargets.Class | AttributeTargets.Interface | + AttributeTargets.Property | AttributeTargets.Field | + AttributeTargets.Enum, + AllowMultiple=true)] + public class NullValueAttribute : Attribute + { + public NullValueAttribute() + { + } + + public NullValueAttribute(object value) + { + _value = value; + } + + public NullValueAttribute(Type type, object value) + { + _type = type; + _value = value; + } + + private readonly object _value; + public object Value + { + get { return _value; } + } + + private readonly Type _type; + public Type Type + { + get { return _type; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/NullableAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/NullableAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ +using System; + +namespace BLToolkit.Mapping +{ + [AttributeUsage( + AttributeTargets.Property | AttributeTargets.Field | + AttributeTargets.Class | AttributeTargets.Interface)] + public class NullableAttribute : Attribute + { + public NullableAttribute() + { + IsNullable = true; + } + + public NullableAttribute(bool isNullable) + { + IsNullable = isNullable; + } + + public NullableAttribute(Type type) + { + Type = type; + IsNullable = true; + } + + public NullableAttribute(Type type, bool isNullable) + { + Type = type; + IsNullable = isNullable; + } + + public bool IsNullable { get; set; } + public Type Type { get; private set; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/ObjectListMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/ObjectListMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,93 @@ +using System.Collections; + +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public class ObjectListMapper : IMapDataSourceList, IMapDataDestinationList + { + public ObjectListMapper(IList list, ObjectMapper objectMapper) + { + _list = list; + _mapper = objectMapper; + } + + private readonly IList _list; + private ObjectMapper _mapper; + private int _currentItem; + + #region IMapDataSourceList Members + + void IMapDataSourceList.InitMapping(InitContext initContext) + { + initContext.DataSource = _mapper; + } + + bool IMapDataSourceList.SetNextDataSource(InitContext initContext) + { + if (_currentItem >= _list.Count) + return false; + + initContext.SourceObject = _list[_currentItem]; + _currentItem++; + + return true; + } + + void IMapDataSourceList.EndMapping(InitContext initContext) + { + } + + #endregion + + #region IMapDataDestinationList Members + + void IMapDataDestinationList.InitMapping(InitContext initContext) + { + ISupportMapping sm = _list as ISupportMapping; + + if (sm != null) + { + sm.BeginMapping(initContext); + + if (initContext.ObjectMapper != null && _mapper != initContext.ObjectMapper) + _mapper = initContext.ObjectMapper; + } + } + + IMapDataDestination IMapDataDestinationList.GetDataDestination(InitContext initContext) + { + return _mapper; + } + + private object _currentObject; + + private void AddCurrent() + { + if (_currentObject != null) + { + _list.Add(_currentObject); + _currentObject = null; + } + } + + object IMapDataDestinationList.GetNextObject(InitContext initContext) + { + AddCurrent(); + + return _currentObject = _mapper.CreateInstance(initContext); + } + + void IMapDataDestinationList.EndMapping(InitContext initContext) + { + AddCurrent(); + + ISupportMapping sm = _list as ISupportMapping; + + if (sm != null) + sm.EndMapping(initContext); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/ObjectMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/ObjectMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,786 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; + +namespace BLToolkit.Mapping +{ + using DataAccess; + using Reflection; + using Reflection.Extension; + using Reflection.MetadataProvider; + + [DebuggerDisplay("Type = {TypeAccessor.Type}, OriginalType = {TypeAccessor.OriginalType}")] + public class ObjectMapper : MapDataSourceDestinationBase, IEnumerable + { + #region Protected Members + + protected virtual MemberMapper CreateMemberMapper(MapMemberInfo mapMemberInfo) + { + if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo"); + + MemberMapper mm = null; + + var attr = mapMemberInfo.MemberAccessor.GetAttribute(); + + MemberExtension ext; + + if (_extension != null && _extension.Members.TryGetValue(mapMemberInfo.MemberName,out ext)) + { + AttributeExtensionCollection attrExt; + + if (ext.Attributes.TryGetValue("MemberMapper", out attrExt)) + { + attr = new MemberMapperAttribute((Type)attrExt[0].Values["MemberMapperType"]); + } + } + + if (attr == null) + { + var attrs = TypeHelper.GetAttributes(mapMemberInfo.Type, typeof(MemberMapperAttribute)); + + foreach (MemberMapperAttribute a in attrs) + { + if (a.MemberType == null) + { + mm = a.MemberMapper; + break; + } + } + } + else + mm = attr.MemberMapper; + + if (mm == null) + { + var attrs = TypeHelper.GetAttributes( + mapMemberInfo.MemberAccessor.MemberInfo.DeclaringType, typeof(MemberMapperAttribute)); + + foreach (MemberMapperAttribute a in attrs) + { + if (a.MemberType == mapMemberInfo.Type) + { + mm = a.MemberMapper; + break; + } + } + } + + if (mm == null) + mm = MemberMapper.CreateMemberMapper(mapMemberInfo); + + mm.Init(mapMemberInfo); + + return mm; + } + + [SuppressMessage("Microsoft.Performance", "CA1807:AvoidUnnecessaryStringCreation", MessageId = "stack1")] + protected virtual void Add(MemberMapper memberMapper) + { + if (memberMapper == null) throw new ArgumentNullException("memberMapper"); + + memberMapper.SetOrdinal(_members.Count); + + _members .Add(memberMapper); + _nameToMember .Add(memberMapper.Name.ToLower(), memberMapper); + _memberNameToMember.Add(memberMapper.MemberName, memberMapper); + } + + protected virtual MetadataProviderBase CreateMetadataProvider() + { + return MetadataProviderBase.CreateProvider(); + } + + #endregion + + #region Public Members + + private readonly List _members = new List(); + public MemberMapper this[int index] + { + get { return _members[index]; } + } + + readonly List _associations = new List(); + public List Associations + { + get { return _associations; } + } + + readonly List _inheritanceMapping = new List(); + public List InheritanceMapping + { + get { return _inheritanceMapping; } + } + + [CLSCompliant(false)] + protected TypeExtension _extension; + public TypeExtension Extension + { + get { return _extension; } + set { _extension = value; } + } + + private MetadataProviderBase _metadataProvider; + public MetadataProviderBase MetadataProvider + { + get { return _metadataProvider ?? (_metadataProvider = CreateMetadataProvider()); } + set { _metadataProvider = value; } + } + + private string[] _fieldNames; + public string[] FieldNames + { + get + { + if (_fieldNames == null) + { + _fieldNames = new string[_members.Count]; + + for (var i = 0; i < _fieldNames.Length; i++) + { + _fieldNames[i] = _members[i].Name; + } + } + + return _fieldNames; + } + } + + private readonly Dictionary _nameToMember = new Dictionary(); + private readonly Dictionary _memberNameToMember = new Dictionary(); + public MemberMapper this[string name] + { + get + { + if (name == null) throw new ArgumentNullException("name"); + + lock (_nameToMember) + { + MemberMapper mm; + + if (!_nameToMember.TryGetValue(name, out mm)) + { + if (!_nameToMember.TryGetValue(name.ToLower(CultureInfo.CurrentCulture), out mm)) + { + lock (_memberNameToMember) + if (_memberNameToMember.ContainsKey(name) || _memberNameToMember.ContainsKey(name.ToLower(CultureInfo.CurrentCulture))) + return null; + + mm = GetComplexMapper(name, name); + + if (mm != null) + { + if (_members.Contains(mm)) + { + //throw new MappingException(string.Format( + // "Wrong mapping field name: '{0}', type: '{1}'. Use field name '{2}' instead.", + // name, _typeAccessor.OriginalType.Name, mm.Name)); + return null; + } + + Add(mm); + } + } + else + _nameToMember.Add(name, mm); + } + + return mm; + } + } + } + + public MemberMapper this[string name, bool byPropertyName] + { + get + { + MemberMapper mm; + + if (byPropertyName) + lock (_memberNameToMember) + return _memberNameToMember.TryGetValue(name, out mm) ? mm : null; + + return this[name]; + } + } + + public int GetOrdinal(string name, bool byPropertyName) + { + if (byPropertyName) + { + for (var i = 0; i < _members.Count; ++i) + if (_members[i].MemberName == name) + return i; + + return -1; + } + + return GetOrdinal(name); + } + + [CLSCompliant(false)] + protected TypeAccessor _typeAccessor; + public TypeAccessor TypeAccessor + { + get { return _typeAccessor; } + } + + private MappingSchema _mappingSchema; + public MappingSchema MappingSchema + { + get { return _mappingSchema; } + } + + #endregion + + #region Init Mapper + + public virtual void Init(MappingSchema mappingSchema, Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + _typeAccessor = TypeAccessor.GetAccessor(type); + _mappingSchema = mappingSchema; + _extension = TypeExtension.GetTypeExtension(_typeAccessor.OriginalType, mappingSchema.Extensions); + + _inheritanceMapping.AddRange(GetInheritanceMapping()); + + foreach (MemberAccessor ma in _typeAccessor) + { + var a = GetAssociation(ma); + + if (a != null) + { + _associations.Add(a); + continue; + } + + if (GetMapIgnore(ma)) + continue; + + var mapFieldAttr = GetMapField(ma); // ma.GetAttribute(); + + if (mapFieldAttr == null || (mapFieldAttr.OrigName == null && mapFieldAttr.Format == null)) + { + var mi = new MapMemberInfo(); + + var dbTypeAttribute = GetDbType(ma); // ma.GetAttribute(); + + if (dbTypeAttribute != null) + { + mi.DbType = dbTypeAttribute.DbType; + mi.IsDbTypeSet = true; + + if (dbTypeAttribute.Size != null) + { + mi.DbSize = dbTypeAttribute.Size.Value; + mi.IsDbSizeSet = true; + } + } + + mi.MemberAccessor = ma; + mi.Type = ma.Type; + mi.MappingSchema = mappingSchema; + mi.MemberExtension = _extension[ma.Name]; + mi.Name = GetFieldName (ma); + mi.MemberName = ma.Name; + mi.Storage = GetFieldStorage(ma); + mi.IsInheritanceDiscriminator = GetInheritanceDiscriminator(ma); + mi.Trimmable = GetTrimmable (ma); + mi.SqlIgnore = GetSqlIgnore (ma); + mi.MapValues = GetMapValues (ma); + mi.DefaultValue = GetDefaultValue(ma); + mi.Nullable = GetNullable (ma); + mi.NullValue = GetNullValue (ma, mi.Nullable); + + Add(CreateMemberMapper(mi)); + } + else if (mapFieldAttr.OrigName != null) + { + EnsureMapper(mapFieldAttr.MapName, ma.Name + "." + mapFieldAttr.OrigName); + } + else //if (mapFieldAttr.Format != null) + { + foreach (MemberMapper inner in _mappingSchema.GetObjectMapper(ma.Type)) + EnsureMapper(string.Format(mapFieldAttr.Format, inner.Name), ma.Name + "." + inner.MemberName); + } + } + + foreach (var ae in _extension.Attributes["MapField"]) + { + var mapName = (string)ae["MapName"]; + var origName = (string)ae["OrigName"]; + + if (mapName == null || origName == null) + throw new MappingException(string.Format( + "Type '{0}' has invalid extension. MapField MapName='{1}' OrigName='{2}'.", + type.FullName, mapName, origName)); + + EnsureMapper(mapName, origName); + } + + MetadataProvider.EnsureMapper(TypeAccessor, MappingSchema, EnsureMapper); + } + + private MemberMapper EnsureMapper(string mapName, string origName) + { + var mm = this[mapName]; + + if (mm == null) + { + var name = mapName.ToLower(); + + foreach (var m in _members) + { + if (m.MemberAccessor.Name.ToLower() == name) + { + _nameToMember.Add(name, m); + return m; + } + } + + mm = GetComplexMapper(mapName, origName); + + if (mm != null) + Add(mm); + } + + return mm; + } + + private readonly Dictionary _nameToComplexMapper = new Dictionary(); + + [SuppressMessage("Microsoft.Performance", "CA1807:AvoidUnnecessaryStringCreation", MessageId = "stack0")] + [SuppressMessage("Microsoft.Performance", "CA1807:AvoidUnnecessaryStringCreation", MessageId = "origName")] + protected MemberMapper GetComplexMapper(string mapName, string origName) + { + if (origName == null) throw new ArgumentNullException("origName"); + + var name = origName.ToLower(); + var idx = origName.IndexOf('.'); + + lock (_nameToComplexMapper) + { + MemberMapper mm; + + if (_nameToComplexMapper.TryGetValue(name, out mm)) + return mm; + + if (idx > 0) + { + name = name.Substring(0, idx); + + foreach (MemberAccessor ma in TypeAccessor) + { + if (ma.Name.Length == name.Length && ma.Name.ToLower() == name) + { + var om = MappingSchema.GetObjectMapper(ma.Type); + + if (om != null) + { + mm = om.GetComplexMapper(mapName, origName.Substring(idx + 1)); + + if (mm != null) + { + var mi = new MapMemberInfo + { + MemberAccessor = ma, + ComplexMemberAccessor = mm.ComplexMemberAccessor, + Type = mm.Type, + MappingSchema = MappingSchema, + Name = mapName, + MemberName = origName + }; + + var mapper = new MemberMapper.ComplexMapper(mm); + var key = origName.ToLower(); + + mapper.Init(mi); + + if (_nameToComplexMapper.ContainsKey(key)) + _nameToComplexMapper[key] = mapper; + else + _nameToComplexMapper.Add(key, mapper); + + return mapper; + } + } + + break; + } + } + } + else + { + foreach (var m in _members) + if (m.MemberAccessor.Name.Length == name.Length && m.MemberAccessor.Name.ToLower() == name) + { + if (_nameToComplexMapper.ContainsKey(name)) + _nameToComplexMapper[name] = m; + else + _nameToComplexMapper.Add(name, m); + + return m; + } + } + + // Under some conditions, this way lead to memory leaks. + // In other hand, shaking mappers up every time lead to performance loss. + // So we cache failed requests. + // If this optimization is a memory leak for you, just comment out next line. + // + if (_nameToComplexMapper.ContainsKey(name)) + _nameToComplexMapper[name] = null; + else + _nameToComplexMapper.Add(name, null); + + return null; + } + + } + + private MapValue[] GetMapValues(MemberAccessor member) + { + bool isSet; + + var values = MetadataProvider.GetMapValues(Extension, member, out isSet); + + return isSet? values: _mappingSchema.GetMapValues(member.Type); + } + + protected virtual object GetDefaultValue(MemberAccessor memberAccessor) + { + bool isSet; + + var value = MetadataProvider.GetDefaultValue(MappingSchema, Extension, memberAccessor, out isSet); + + return isSet? value: _mappingSchema.GetDefaultValue(memberAccessor.Type); + } + + protected virtual bool GetNullable(MemberAccessor memberAccessor) + { + bool isSet; + return MetadataProvider.GetNullable(MappingSchema, Extension, memberAccessor, out isSet); + } + + protected virtual bool GetLazyInstance(MemberAccessor memberAccessor) + { + bool isSet; + return MetadataProvider.GetLazyInstance(MappingSchema, Extension, memberAccessor, out isSet); + } + + protected virtual bool GetMapIgnore(MemberAccessor memberAccessor) + { + bool isSet; + return MetadataProvider.GetMapIgnore(Extension, memberAccessor, out isSet); + } + + protected virtual MapFieldAttribute GetMapField(MemberAccessor memberAccessor) + { + bool isSet; + return MetadataProvider.GetMapField(Extension, memberAccessor, out isSet); + } + + [CLSCompliant(false)] + protected virtual DbTypeAttribute GetDbType(MemberAccessor memberAccessor) + { + bool isSet; + return MetadataProvider.GetDbType(Extension, memberAccessor, out isSet); + } + + protected virtual PrimaryKeyAttribute GetPrimaryKey(MemberAccessor memberAccessor) + { + bool isSet; + return MetadataProvider.GetPrimaryKey(Extension, memberAccessor, out isSet); + } + + protected virtual bool GetSqlIgnore(MemberAccessor memberAccessor) + { + bool isSet; + return MetadataProvider.GetSqlIgnore(Extension, memberAccessor, out isSet); + } + + protected virtual string GetFieldName(MemberAccessor memberAccessor) + { + bool isSet; + return MetadataProvider.GetFieldName(Extension, memberAccessor, out isSet); + } + + protected virtual string GetFieldStorage(MemberAccessor memberAccessor) + { + bool isSet; + return MetadataProvider.GetFieldStorage(Extension, memberAccessor, out isSet); + } + + protected virtual bool GetInheritanceDiscriminator(MemberAccessor memberAccessor) + { + bool isSet; + return MetadataProvider.GetInheritanceDiscriminator(Extension, memberAccessor, out isSet); + } + + protected virtual bool GetTrimmable(MemberAccessor memberAccessor) + { + bool isSet; + return MetadataProvider.GetTrimmable(Extension, memberAccessor, out isSet); + } + + protected virtual object GetNullValue(MemberAccessor memberAccessor, bool isNullable) + { + if (isNullable) + { + bool isSet; + return MetadataProvider.GetNullValue(MappingSchema, Extension, memberAccessor, out isSet); + } + + return MappingSchema.GetNullValue(memberAccessor.Type); + } + + protected virtual Association GetAssociation(MemberAccessor memberAccessor) + { + return MetadataProvider.GetAssociation(Extension, memberAccessor); + } + + protected virtual InheritanceMappingAttribute[] GetInheritanceMapping() + { + return MetadataProvider.GetInheritanceMapping(_typeAccessor.OriginalType, Extension); + } + + #endregion + + #region IObjectMappper Members + + public virtual object CreateInstance() + { + return _typeAccessor.CreateInstanceEx(); + } + + public virtual object CreateInstance(InitContext context) + { + return _typeAccessor.CreateInstanceEx(context); + } + + #endregion + + #region IMapDataSource Members + + public override int Count + { + get { return _members.Count; } + } + + public override Type GetFieldType(int index) + { + return _members[index].Type; + } + + public override string GetName(int index) + { + return _members[index].Name; + } + + public override object GetValue(object o, int index) + { + return _members[index].GetValue(o); + } + + public override object GetValue(object o, string name) + { + MemberMapper mm; + + lock (_nameToMember) + if (!_nameToMember.TryGetValue(name, out mm)) + mm = this[name]; + + return mm == null? null: mm.GetValue(o); + } + + public override bool IsNull (object o, int index) { return this[index].IsNull(o); } + + public override bool SupportsTypedValues(int index) { return this[index].SupportsValue; } + + // Simple type getters. + // + [CLSCompliant(false)] + public override SByte GetSByte (object o, int index) { return this[index].GetSByte (o); } + public override Int16 GetInt16 (object o, int index) { return this[index].GetInt16 (o); } + public override Int32 GetInt32 (object o, int index) { return this[index].GetInt32 (o); } + public override Int64 GetInt64 (object o, int index) { return this[index].GetInt64 (o); } + + public override Byte GetByte (object o, int index) { return this[index].GetByte (o); } + [CLSCompliant(false)] + public override UInt16 GetUInt16 (object o, int index) { return this[index].GetUInt16 (o); } + [CLSCompliant(false)] + public override UInt32 GetUInt32 (object o, int index) { return this[index].GetUInt32 (o); } + [CLSCompliant(false)] + public override UInt64 GetUInt64 (object o, int index) { return this[index].GetUInt64 (o); } + + public override Boolean GetBoolean (object o, int index) { return this[index].GetBoolean (o); } + public override Char GetChar (object o, int index) { return this[index].GetChar (o); } + public override Single GetSingle (object o, int index) { return this[index].GetSingle (o); } + public override Double GetDouble (object o, int index) { return this[index].GetDouble (o); } + public override Decimal GetDecimal (object o, int index) { return this[index].GetDecimal (o); } + public override Guid GetGuid (object o, int index) { return this[index].GetGuid (o); } + public override DateTime GetDateTime(object o, int index) { return this[index].GetDateTime(o); } + public override DateTimeOffset GetDateTimeOffset(object o, int index) { return this[index].GetDateTimeOffset(o); } + + // Nullable type getters. + // + [CLSCompliant(false)] + public override SByte? GetNullableSByte (object o, int index) { return this[index].GetNullableSByte (o); } + public override Int16? GetNullableInt16 (object o, int index) { return this[index].GetNullableInt16 (o); } + public override Int32? GetNullableInt32 (object o, int index) { return this[index].GetNullableInt32 (o); } + public override Int64? GetNullableInt64 (object o, int index) { return this[index].GetNullableInt64 (o); } + + public override Byte? GetNullableByte (object o, int index) { return this[index].GetNullableByte (o); } + [CLSCompliant(false)] + public override UInt16? GetNullableUInt16 (object o, int index) { return this[index].GetNullableUInt16 (o); } + [CLSCompliant(false)] + public override UInt32? GetNullableUInt32 (object o, int index) { return this[index].GetNullableUInt32 (o); } + [CLSCompliant(false)] + public override UInt64? GetNullableUInt64 (object o, int index) { return this[index].GetNullableUInt64 (o); } + + public override Boolean? GetNullableBoolean (object o, int index) { return this[index].GetNullableBoolean (o); } + public override Char? GetNullableChar (object o, int index) { return this[index].GetNullableChar (o); } + public override Single? GetNullableSingle (object o, int index) { return this[index].GetNullableSingle (o); } + public override Double? GetNullableDouble (object o, int index) { return this[index].GetNullableDouble (o); } + public override Decimal? GetNullableDecimal (object o, int index) { return this[index].GetNullableDecimal (o); } + public override Guid? GetNullableGuid (object o, int index) { return this[index].GetNullableGuid (o); } + public override DateTime? GetNullableDateTime(object o, int index) { return this[index].GetNullableDateTime(o); } + public override DateTimeOffset? GetNullableDateTimeOffset(object o, int index) { return this[index].GetNullableDateTimeOffset(o); } + +#if !SILVERLIGHT + + // SQL type getters. + // + public override SqlByte GetSqlByte (object o, int index) { return this[index].GetSqlByte (o); } + public override SqlInt16 GetSqlInt16 (object o, int index) { return this[index].GetSqlInt16 (o); } + public override SqlInt32 GetSqlInt32 (object o, int index) { return this[index].GetSqlInt32 (o); } + public override SqlInt64 GetSqlInt64 (object o, int index) { return this[index].GetSqlInt64 (o); } + public override SqlSingle GetSqlSingle (object o, int index) { return this[index].GetSqlSingle (o); } + public override SqlBoolean GetSqlBoolean (object o, int index) { return this[index].GetSqlBoolean (o); } + public override SqlDouble GetSqlDouble (object o, int index) { return this[index].GetSqlDouble (o); } + public override SqlDateTime GetSqlDateTime(object o, int index) { return this[index].GetSqlDateTime(o); } + public override SqlDecimal GetSqlDecimal (object o, int index) { return this[index].GetSqlDecimal (o); } + public override SqlMoney GetSqlMoney (object o, int index) { return this[index].GetSqlMoney (o); } + public override SqlGuid GetSqlGuid (object o, int index) { return this[index].GetSqlGuid (o); } + public override SqlString GetSqlString (object o, int index) { return this[index].GetSqlString (o); } + +#endif + + #endregion + + #region IMapDataDestination Members + + public override int GetOrdinal(string name) + { + MemberMapper mm; + + lock (_nameToMember) + if (!_nameToMember.TryGetValue(name, out mm)) + mm = this[name]; + + return mm == null? -1: mm.Ordinal; + } + + public override void SetValue(object o, int index, object value) + { + _members[index].SetValue(o, value); + } + + public override void SetValue(object o, string name, object value) + { + SetValue(o, GetOrdinal(name), value); + } + + public override void SetNull (object o, int index) { this[index].SetNull (o); } + + // Simple types setters. + // + [CLSCompliant(false)] + public override void SetSByte (object o, int index, SByte value) { this[index].SetSByte (o, value); } + public override void SetInt16 (object o, int index, Int16 value) { this[index].SetInt16 (o, value); } + public override void SetInt32 (object o, int index, Int32 value) { this[index].SetInt32 (o, value); } + public override void SetInt64 (object o, int index, Int64 value) { this[index].SetInt64 (o, value); } + + public override void SetByte (object o, int index, Byte value) { this[index].SetByte (o, value); } + [CLSCompliant(false)] + public override void SetUInt16 (object o, int index, UInt16 value) { this[index].SetUInt16 (o, value); } + [CLSCompliant(false)] + public override void SetUInt32 (object o, int index, UInt32 value) { this[index].SetUInt32 (o, value); } + [CLSCompliant(false)] + public override void SetUInt64 (object o, int index, UInt64 value) { this[index].SetUInt64 (o, value); } + + public override void SetBoolean (object o, int index, Boolean value) { this[index].SetBoolean (o, value); } + public override void SetChar (object o, int index, Char value) { this[index].SetChar (o, value); } + public override void SetSingle (object o, int index, Single value) { this[index].SetSingle (o, value); } + public override void SetDouble (object o, int index, Double value) { this[index].SetDouble (o, value); } + public override void SetDecimal (object o, int index, Decimal value) { this[index].SetDecimal (o, value); } + public override void SetGuid (object o, int index, Guid value) { this[index].SetGuid (o, value); } + public override void SetDateTime(object o, int index, DateTime value) { this[index].SetDateTime(o, value); } + public override void SetDateTimeOffset(object o, int index, DateTimeOffset value) { this[index].SetDateTimeOffset(o, value); } + + // Simple types setters. + // + [CLSCompliant(false)] + public override void SetNullableSByte (object o, int index, SByte? value) { this[index].SetNullableSByte (o, value); } + public override void SetNullableInt16 (object o, int index, Int16? value) { this[index].SetNullableInt16 (o, value); } + public override void SetNullableInt32 (object o, int index, Int32? value) { this[index].SetNullableInt32 (o, value); } + public override void SetNullableInt64 (object o, int index, Int64? value) { this[index].SetNullableInt64 (o, value); } + + public override void SetNullableByte (object o, int index, Byte? value) { this[index].SetNullableByte (o, value); } + [CLSCompliant(false)] + public override void SetNullableUInt16 (object o, int index, UInt16? value) { this[index].SetNullableUInt16 (o, value); } + [CLSCompliant(false)] + public override void SetNullableUInt32 (object o, int index, UInt32? value) { this[index].SetNullableUInt32 (o, value); } + [CLSCompliant(false)] + public override void SetNullableUInt64 (object o, int index, UInt64? value) { this[index].SetNullableUInt64 (o, value); } + + public override void SetNullableBoolean (object o, int index, Boolean? value) { this[index].SetNullableBoolean (o, value); } + public override void SetNullableChar (object o, int index, Char? value) { this[index].SetNullableChar (o, value); } + public override void SetNullableSingle (object o, int index, Single? value) { this[index].SetNullableSingle (o, value); } + public override void SetNullableDouble (object o, int index, Double? value) { this[index].SetNullableDouble (o, value); } + public override void SetNullableDecimal (object o, int index, Decimal? value) { this[index].SetNullableDecimal (o, value); } + public override void SetNullableGuid (object o, int index, Guid? value) { this[index].SetNullableGuid (o, value); } + public override void SetNullableDateTime(object o, int index, DateTime? value) { this[index].SetNullableDateTime(o, value); } + public override void SetNullableDateTimeOffset(object o, int index, DateTimeOffset? value) { this[index].SetNullableDateTimeOffset(o, value); } + +#if !SILVERLIGHT + + // SQL type setters. + // + public override void SetSqlByte (object o, int index, SqlByte value) { this[index].SetSqlByte (o, value); } + public override void SetSqlInt16 (object o, int index, SqlInt16 value) { this[index].SetSqlInt16 (o, value); } + public override void SetSqlInt32 (object o, int index, SqlInt32 value) { this[index].SetSqlInt32 (o, value); } + public override void SetSqlInt64 (object o, int index, SqlInt64 value) { this[index].SetSqlInt64 (o, value); } + public override void SetSqlSingle (object o, int index, SqlSingle value) { this[index].SetSqlSingle (o, value); } + public override void SetSqlBoolean (object o, int index, SqlBoolean value) { this[index].SetSqlBoolean (o, value); } + public override void SetSqlDouble (object o, int index, SqlDouble value) { this[index].SetSqlDouble (o, value); } + public override void SetSqlDateTime(object o, int index, SqlDateTime value) { this[index].SetSqlDateTime(o, value); } + public override void SetSqlDecimal (object o, int index, SqlDecimal value) { this[index].SetSqlDecimal (o, value); } + public override void SetSqlMoney (object o, int index, SqlMoney value) { this[index].SetSqlMoney (o, value); } + public override void SetSqlGuid (object o, int index, SqlGuid value) { this[index].SetSqlGuid (o, value); } + public override void SetSqlString (object o, int index, SqlString value) { this[index].SetSqlString (o, value); } + +#endif + + #endregion + + #region IEnumerable Members + + public IEnumerator GetEnumerator() + { + return _members.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _members.GetEnumerator(); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/ObjectMapperAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/ObjectMapperAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +using System; + +namespace BLToolkit.Mapping +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] + public sealed class ObjectMapperAttribute : Attribute + { + public ObjectMapperAttribute(Type objectMapperType) + { + if (objectMapperType == null) throw new ArgumentNullException("objectMapperType"); + + _objectMapper = Activator.CreateInstance(objectMapperType) as ObjectMapper; + + if (_objectMapper == null) + throw new ArgumentException( + string.Format("Type '{0}' does not implement IObjectMapper interface.", objectMapperType)); + } + + private readonly ObjectMapper _objectMapper; + public ObjectMapper ObjectMapper + { + get { return _objectMapper; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/ObjectMapperT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/ObjectMapperT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,58 @@ +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public static class ObjectMapper + { + public static T CreateInstance() + { + return (T)_instance.CreateInstance(); + } + + public static T CreateInstance(InitContext context) + { + return (T)_instance.CreateInstance(context); + } + + public static int Count + { + get { return _instance.Count; } + } + + public static string GetName(int index) + { + return _instance.GetName(index); + } + + public static object GetValue(T o, int index) + { + return _instance.GetValue(o, index); + } + + public static object GetValue(T o, string name) + { + return _instance.GetValue(o, name); + } + + public static int GetOrdinal(string name) + { + return _instance.GetOrdinal(name); + } + + public static void SetValue(T o, int index, object value) + { + _instance.SetValue(o, index, value); + } + + public static void SetValue(object o, string name, object value) + { + _instance.SetValue(o, name, value); + } + + private static readonly ObjectMapper _instance = Map.GetObjectMapper(typeof(T)); + public static ObjectMapper Instance + { + get { return _instance; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/RelationAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/RelationAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; + +namespace BLToolkit.Mapping +{ + + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = false)] + public sealed class RelationAttribute : Attribute + { + #region Constructors + + public RelationAttribute() + { + } + + public RelationAttribute(Type destination) + { + _destination = destination; + } + + public RelationAttribute(string slaveIndex) + { + SlaveIndex1 = slaveIndex; + } + + public RelationAttribute(string slaveIndex, string masterIndex) + : this(slaveIndex) + { + MasterIndex1 = masterIndex; + } + + public RelationAttribute(Type destination, string slaveIndex) + : this(destination) + { + SlaveIndex1 = slaveIndex; + } + + public RelationAttribute(Type destination, string slaveIndex, string masterIndex) + : this(destination) + { + SlaveIndex1 = slaveIndex; + MasterIndex1 = masterIndex; + } + + #endregion + + private Type _destination; + public Type Destination { get { return _destination; } } + + private string _masterIndex1; + public string MasterIndex1 { get { return _masterIndex1; } set { _masterIndex1 = value; } } + + private string _masterIndex2; + public string MasterIndex2 { get { return _masterIndex2; } set { _masterIndex2 = value; } } + + private string _masterIndex3; + public string MasterIndex3 { get { return _masterIndex3; } set { _masterIndex3 = value; } } + + private string _slaveIndex1; + public string SlaveIndex1 { get { return _slaveIndex1; } set { _slaveIndex1 = value; } } + + private string _slaveIndex2; + public string SlaveIndex2 { get { return _slaveIndex2; } set { _slaveIndex2 = value; } } + + private string _slaveIndex3; + public string SlaveIndex3 { get { return _slaveIndex3; } set { _slaveIndex3 = value; } } + + public MapIndex MasterIndex + { + get + { + List index = new List(); + + AddIndex(index, MasterIndex1); + AddIndex(index, MasterIndex2); + AddIndex(index, MasterIndex3); + + if (index.Count == 0) + return null; + + return new MapIndex(index.ToArray()); + } + } + + public MapIndex SlaveIndex + { + get + { + List index = new List(); + + AddIndex(index, SlaveIndex1); + AddIndex(index, SlaveIndex2); + AddIndex(index, SlaveIndex3); + + if (index.Count == 0) + return null; + + return new MapIndex(index.ToArray()); + } + } + + private void AddIndex(List index, string field) + { + if (!string.IsNullOrEmpty(field)) + index.Add(field); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/ScalarDataReaderMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/ScalarDataReaderMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,126 @@ +using System; +using System.Data; + +using BLToolkit.Common; +using System.Data.SqlTypes; + +namespace BLToolkit.Mapping +{ + public class ScalarDataReaderMapper : DataReaderMapper + { + public ScalarDataReaderMapper( + MappingSchema mappingSchema, + IDataReader dataReader, + NameOrIndexParameter nameOrIndex) + : base(mappingSchema, dataReader) + { + _index = nameOrIndex.ByName? dataReader.GetOrdinal(nameOrIndex.Name): nameOrIndex.Index; + } + + private readonly int _index; + public int Index + { + get { return _index; } + } + + #region IMapDataSource Members + + public override int Count + { + get { return 1; } + } + + public override Type GetFieldType(int index) + { + return DataReader.GetFieldType(_index); + } + + public override string GetName(int index) + { + return DataReader.GetName(_index); + } + + public override object GetValue(object o, int index) + { + return base.GetValue(o, _index); + } + + public override object GetValue(object o, string name) + { + return base.GetValue(o, _index); + } + + public override bool IsNull (object o, int index) { return DataReader.IsDBNull(_index); } + + // Simple type getters. + // + [CLSCompliant(false)] + public override SByte GetSByte (object o, int index) { return base.GetSByte(o, _index); } + public override Int16 GetInt16 (object o, int index) { return DataReader.GetInt16 (_index); } + public override Int32 GetInt32 (object o, int index) { return DataReader.GetInt32 (_index); } + public override Int64 GetInt64 (object o, int index) { return DataReader.GetInt64 (_index); } + + public override Byte GetByte (object o, int index) { return DataReader.GetByte (_index); } + [CLSCompliant(false)] + public override UInt16 GetUInt16 (object o, int index) { return base.GetUInt16(o, _index); } + [CLSCompliant(false)] + public override UInt32 GetUInt32 (object o, int index) { return base.GetUInt32(o, _index); } + [CLSCompliant(false)] + public override UInt64 GetUInt64 (object o, int index) { return base.GetUInt64(o, _index); } + + public override Boolean GetBoolean (object o, int index) { return DataReader.GetBoolean (_index); } + public override Char GetChar (object o, int index) { return DataReader.GetChar (_index); } + public override Single GetSingle (object o, int index) { return DataReader.GetFloat (_index); } + public override Double GetDouble (object o, int index) { return DataReader.GetDouble (_index); } + public override Decimal GetDecimal (object o, int index) { return DataReader.GetDecimal (_index); } + public override Guid GetGuid (object o, int index) { return DataReader.GetGuid (_index); } + public override DateTime GetDateTime(object o, int index) { return DataReader.GetDateTime(_index); } + public override DateTimeOffset GetDateTimeOffset(object o, int index) { return (DateTimeOffset)DataReader.GetValue(_index); } + + // Nullable type getters. + // + [CLSCompliant(false)] + public override SByte? GetNullableSByte (object o, int index) { return base.GetNullableSByte(o, _index); } + public override Int16? GetNullableInt16 (object o, int index) { return DataReader.IsDBNull(_index)? null: (Int16?)DataReader.GetInt16 (_index); } + public override Int32? GetNullableInt32 (object o, int index) { return DataReader.IsDBNull(_index)? null: (Int32?)DataReader.GetInt32 (_index); } + public override Int64? GetNullableInt64 (object o, int index) { return DataReader.IsDBNull(_index)? null: (Int64?)DataReader.GetInt64 (_index); } + + public override Byte? GetNullableByte (object o, int index) { return DataReader.IsDBNull(_index)? null: (Byte?) DataReader.GetByte (_index); } + [CLSCompliant(false)] + public override UInt16? GetNullableUInt16 (object o, int index) { return base.GetNullableUInt16(o, _index); } + [CLSCompliant(false)] + public override UInt32? GetNullableUInt32 (object o, int index) { return base.GetNullableUInt32(o, _index); } + [CLSCompliant(false)] + public override UInt64? GetNullableUInt64 (object o, int index) { return base.GetNullableUInt64(o, _index); } + + public override Boolean? GetNullableBoolean (object o, int index) { return DataReader.IsDBNull(_index)? null: (Boolean?) DataReader.GetBoolean (_index); } + public override Char? GetNullableChar (object o, int index) { return DataReader.IsDBNull(_index)? null: (Char?) DataReader.GetChar (_index); } + public override Single? GetNullableSingle (object o, int index) { return DataReader.IsDBNull(_index)? null: (Single?) DataReader.GetFloat (_index); } + public override Double? GetNullableDouble (object o, int index) { return DataReader.IsDBNull(_index)? null: (Double?) DataReader.GetDouble (_index); } + public override Decimal? GetNullableDecimal (object o, int index) { return DataReader.IsDBNull(_index)? null: (Decimal?) DataReader.GetDecimal (_index); } + public override Guid? GetNullableGuid (object o, int index) { return DataReader.IsDBNull(_index)? null: (Guid?) DataReader.GetGuid (_index); } + public override DateTime? GetNullableDateTime(object o, int index) { return DataReader.IsDBNull(_index)? null: (DateTime?)DataReader.GetDateTime(_index); } + public override DateTimeOffset? GetNullableDateTimeOffset(object o, int index) { return DataReader.IsDBNull(_index)? null: (DateTimeOffset?)DataReader.GetValue(_index); } + +#if !SILVERLIGHT + + // SQL type getters. + // + public override SqlByte GetSqlByte (object o, int index) { return DataReader.IsDBNull(_index)? SqlByte. Null: DataReader.GetByte (_index); } + public override SqlInt16 GetSqlInt16 (object o, int index) { return DataReader.IsDBNull(_index)? SqlInt16. Null: DataReader.GetInt16 (_index); } + public override SqlInt32 GetSqlInt32 (object o, int index) { return DataReader.IsDBNull(_index)? SqlInt32. Null: DataReader.GetInt32 (_index); } + public override SqlInt64 GetSqlInt64 (object o, int index) { return DataReader.IsDBNull(_index)? SqlInt64. Null: DataReader.GetInt64 (_index); } + public override SqlSingle GetSqlSingle (object o, int index) { return DataReader.IsDBNull(_index)? SqlSingle. Null: DataReader.GetFloat (_index); } + public override SqlBoolean GetSqlBoolean (object o, int index) { return DataReader.IsDBNull(_index)? SqlBoolean. Null: DataReader.GetBoolean (_index); } + public override SqlDouble GetSqlDouble (object o, int index) { return DataReader.IsDBNull(_index)? SqlDouble. Null: DataReader.GetDouble (_index); } + public override SqlDateTime GetSqlDateTime(object o, int index) { return DataReader.IsDBNull(_index)? SqlDateTime.Null: DataReader.GetDateTime(_index); } + public override SqlDecimal GetSqlDecimal (object o, int index) { return DataReader.IsDBNull(_index)? SqlDecimal. Null: DataReader.GetDecimal (_index); } + public override SqlMoney GetSqlMoney (object o, int index) { return DataReader.IsDBNull(_index)? SqlMoney. Null: DataReader.GetDecimal (_index); } + public override SqlGuid GetSqlGuid (object o, int index) { return DataReader.IsDBNull(_index)? SqlGuid. Null: DataReader.GetGuid (_index); } + public override SqlString GetSqlString (object o, int index) { return DataReader.IsDBNull(_index)? SqlString. Null: DataReader.GetString (_index); } + +#endif + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/ScalarListMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/ScalarListMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,66 @@ +using System; +using System.Collections; + +namespace BLToolkit.Mapping +{ + public class ScalarListMapper : MapDataSourceDestinationBase + { + public ScalarListMapper(IList list, Type type) + { + _list = list; + _type = type; + } + + private readonly IList _list; + private readonly Type _type; + private int _index; + + #region Destination + + public override Type GetFieldType(int index) + { + return _type; + } + + public override int GetOrdinal(string name) + { + return 0; + } + + public override void SetValue(object o, int index, object value) + { + _list.Add(value); + } + + public override void SetValue(object o, string name, object value) + { + _list.Add(value); + } + + #endregion + + #region Source + + public override int Count + { + get { return _index < _list.Count? 1: 0; } + } + + public override string GetName(int index) + { + return string.Empty; + } + + public override object GetValue(object o, int index) + { + return _list[_index++]; + } + + public override object GetValue(object o, string name) + { + return _list[_index++]; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/ScalarListMapperT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/ScalarListMapperT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; + +using BLToolkit.Common; + +namespace BLToolkit.Mapping +{ + public class ScalarListMapper : MapDataDestinationBase + { + public ScalarListMapper(MappingSchema mappingSchema, IList list) + { + _list = list; + _mappingSchema = mappingSchema; + _nullValue = (T)mappingSchema.GetNullValue(_type); + _isNullable = _type.IsGenericType && _type.GetGenericTypeDefinition() == typeof(Nullable<>); + _underlyingType = _isNullable? Nullable.GetUnderlyingType(_type): _type; + } + + private readonly IList _list; + private readonly MappingSchema _mappingSchema; + private readonly T _nullValue; + private readonly bool _isNullable; + private readonly Type _type = typeof(T); + private readonly Type _underlyingType; + + #region IMapDataDestination Members + + public override Type GetFieldType(int index) { return _type; } + public override int GetOrdinal (string name) { return 0; } + public override void SetValue (object o, int index, object value) { _list.Add((T)_mappingSchema.ConvertChangeType(value, _underlyingType, _isNullable)); } + public override void SetValue (object o, string name, object value) { _list.Add((T)_mappingSchema.ConvertChangeType(value, _underlyingType, _isNullable)); } + + public override void SetNull (object o, int index) { _list.Add(_nullValue); } + + public override bool SupportsTypedValues(int index) { return true; } + + // Simple types setters. + // + [CLSCompliant(false)] + public override void SetSByte (object o, int index, SByte value) { _list.Add(ConvertTo.From(value)); } + public override void SetInt16 (object o, int index, Int16 value) { _list.Add(ConvertTo.From(value)); } + public override void SetInt32 (object o, int index, Int32 value) { _list.Add(ConvertTo.From(value)); } + public override void SetInt64 (object o, int index, Int64 value) { _list.Add(ConvertTo.From(value)); } + + public override void SetByte (object o, int index, Byte value) { _list.Add(ConvertTo.From(value)); } + [CLSCompliant(false)] + public override void SetUInt16 (object o, int index, UInt16 value) { _list.Add(ConvertTo.From(value)); } + [CLSCompliant(false)] + public override void SetUInt32 (object o, int index, UInt32 value) { _list.Add(ConvertTo.From(value)); } + [CLSCompliant(false)] + public override void SetUInt64 (object o, int index, UInt64 value) { _list.Add(ConvertTo.From(value)); } + + public override void SetBoolean (object o, int index, Boolean value) { _list.Add(ConvertTo.From(value)); } + public override void SetChar (object o, int index, Char value) { _list.Add(ConvertTo.From(value)); } + public override void SetSingle (object o, int index, Single value) { _list.Add(ConvertTo.From(value)); } + public override void SetDouble (object o, int index, Double value) { _list.Add(ConvertTo.From(value)); } + public override void SetDecimal (object o, int index, Decimal value) { _list.Add(ConvertTo.From(value)); } + public override void SetGuid (object o, int index, Guid value) { _list.Add(ConvertTo.From(value)); } + public override void SetDateTime (object o, int index, DateTime value) { _list.Add(ConvertTo.From(value)); } + public override void SetDateTimeOffset(object o, int index, DateTimeOffset value) { _list.Add(ConvertTo.From(value)); } + + // Nullable types setters. + // + [CLSCompliant(false)] + public override void SetNullableSByte (object o, int index, SByte? value) { _list.Add(ConvertTo.From(value)); } + public override void SetNullableInt16 (object o, int index, Int16? value) { _list.Add(ConvertTo.From(value)); } + public override void SetNullableInt32 (object o, int index, Int32? value) { _list.Add(ConvertTo.From(value)); } + public override void SetNullableInt64 (object o, int index, Int64? value) { _list.Add(ConvertTo.From(value)); } + + public override void SetNullableByte (object o, int index, Byte? value) { _list.Add(ConvertTo.From(value)); } + [CLSCompliant(false)] + public override void SetNullableUInt16 (object o, int index, UInt16? value) { _list.Add(ConvertTo.From(value)); } + [CLSCompliant(false)] + public override void SetNullableUInt32 (object o, int index, UInt32? value) { _list.Add(ConvertTo.From(value)); } + [CLSCompliant(false)] + public override void SetNullableUInt64 (object o, int index, UInt64? value) { _list.Add(ConvertTo.From(value)); } + + public override void SetNullableBoolean (object o, int index, Boolean? value) { _list.Add(ConvertTo.From(value)); } + public override void SetNullableChar (object o, int index, Char? value) { _list.Add(ConvertTo.From(value)); } + public override void SetNullableSingle (object o, int index, Single? value) { _list.Add(ConvertTo.From(value)); } + public override void SetNullableDouble (object o, int index, Double? value) { _list.Add(ConvertTo.From(value)); } + public override void SetNullableDecimal (object o, int index, Decimal? value) { _list.Add(ConvertTo.From(value)); } + public override void SetNullableGuid (object o, int index, Guid? value) { _list.Add(ConvertTo.From(value)); } + public override void SetNullableDateTime(object o, int index, DateTime? value) { _list.Add(ConvertTo.From(value)); } + public override void SetNullableDateTimeOffset(object o, int index, DateTimeOffset? value) { _list.Add(ConvertTo.From(value)); } + +#if !SILVERLIGHT + + // SQL type setters. + // + public override void SetSqlByte (object o, int index, SqlByte value) { _list.Add(ConvertTo.From(value)); } + public override void SetSqlInt16 (object o, int index, SqlInt16 value) { _list.Add(ConvertTo.From(value)); } + public override void SetSqlInt32 (object o, int index, SqlInt32 value) { _list.Add(ConvertTo.From(value)); } + public override void SetSqlInt64 (object o, int index, SqlInt64 value) { _list.Add(ConvertTo.From(value)); } + public override void SetSqlSingle (object o, int index, SqlSingle value) { _list.Add(ConvertTo.From(value)); } + public override void SetSqlBoolean (object o, int index, SqlBoolean value) { _list.Add(ConvertTo.From(value)); } + public override void SetSqlDouble (object o, int index, SqlDouble value) { _list.Add(ConvertTo.From(value)); } + public override void SetSqlDateTime(object o, int index, SqlDateTime value) { _list.Add(ConvertTo.From(value)); } + public override void SetSqlDecimal (object o, int index, SqlDecimal value) { _list.Add(ConvertTo.From(value)); } + public override void SetSqlMoney (object o, int index, SqlMoney value) { _list.Add(ConvertTo.From(value)); } + public override void SetSqlGuid (object o, int index, SqlGuid value) { _list.Add(ConvertTo.From(value)); } + public override void SetSqlString (object o, int index, SqlString value) { _list.Add(ConvertTo.From(value)); } + +#endif + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/SimpleDestinationListMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/SimpleDestinationListMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,40 @@ +using System; + +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public class SimpleDestinationListMapper : IMapDataDestinationList + { + [CLSCompliant(false)] + public SimpleDestinationListMapper(IMapDataDestination mapper) + { + _mapper = mapper; + } + + private readonly IMapDataDestination _mapper; + + #region IMapDataDestinationList Members + + public virtual void InitMapping(InitContext initContext) + { + } + + [CLSCompliant(false)] + public virtual IMapDataDestination GetDataDestination(InitContext initContext) + { + return _mapper; + } + + public virtual object GetNextObject(InitContext initContext) + { + return _mapper; + } + + public virtual void EndMapping(InitContext initContext) + { + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/SimpleSourceListMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/SimpleSourceListMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ +using System; + +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public class SimpleSourceListMapper : IMapDataSourceList + { + [CLSCompliant(false)] + public SimpleSourceListMapper(IMapDataSource mapper) + { + _mapper = mapper; + } + + private readonly IMapDataSource _mapper; + + #region IMapDataSourceList Members + + public virtual void InitMapping(InitContext initContext) + { + } + + public bool SetNextDataSource(InitContext initContext) + { + initContext.DataSource = _mapper; + return _mapper.Count > 0; + } + + public virtual void EndMapping(InitContext initContext) + { + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/TextDataListMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/TextDataListMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,42 @@ +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public class TextDataListMapper : IMapDataDestinationList + { + public TextDataListMapper(TextDataMapper mapper) + { + _mapper = mapper; + } + + public TextDataListMapper(TextDataWriter writer) + : this(new TextDataMapper(writer)) + { + } + + private readonly TextDataMapper _mapper; + + #region IMapDataDestinationList Members + + void IMapDataDestinationList.InitMapping(InitContext initContext) + { + } + + IMapDataDestination IMapDataDestinationList.GetDataDestination(InitContext initContext) + { + return _mapper; + } + + object IMapDataDestinationList.GetNextObject(InitContext initContext) + { + return _mapper.Writer; + } + + void IMapDataDestinationList.EndMapping(InitContext initContext) + { + _mapper.WriteEnd(); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/TextDataMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/TextDataMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,45 @@ +using System; + +namespace BLToolkit.Mapping +{ + public class TextDataMapper : MapDataDestinationBase + { + public TextDataMapper(TextDataWriter writer) + { + if (writer == null) throw new ArgumentNullException("writer"); + + _writer = writer; + } + + private readonly TextDataWriter _writer; + public TextDataWriter Writer + { + get { return _writer; } + } + + public virtual void WriteEnd() + { + _writer.WriteEnd(); + } + + public override Type GetFieldType(int index) + { + return _writer.GetFieldType(index); + } + + public override int GetOrdinal(string name) + { + return _writer.GetOrdinal(name); + } + + public override void SetValue(object o, int index, object value) + { + _writer.SetValue(index, value); + } + + public override void SetValue(object o, string name, object value) + { + _writer.SetValue(name, value); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/TextDataReader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/TextDataReader.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,381 @@ +using System; +using System.Data; +#if !SILVERLIGHT +using System.Data.Common; +#endif +using System.IO; +using System.Text; + +namespace BLToolkit.Mapping +{ + public class TextDataReader : IDataReader + { + #region Constructors + + public TextDataReader(Stream stream) + : this(stream, Map.DefaultSchema) + { + } + + public TextDataReader(Stream stream, MappingSchema mappingSchema) + { + GC.SuppressFinalize(this); + + if (mappingSchema == null) throw new ArgumentNullException("mappingSchema"); + + _reader = new StreamReader(stream); + _mappingSchema = mappingSchema; + + ReadHeader(); + } + + #endregion + + #region Protected Members + + private readonly StreamReader _reader; + private readonly MappingSchema _mappingSchema; + private string _line = string.Empty; + private string[] _names = _empty; + private string[] _values = _empty; + private int _lineNumber = 0; + + private static readonly string[] _empty = new string[0]; + + private bool IsEof + { + get { return _line == null; } + } + + private bool ReadNextLine() + { + while (!IsEof) + { + _line = _reader.ReadLine(); + _lineNumber++; + + if (!string.IsNullOrEmpty(_line) && _line[0] == '*') + return true; + } + + return false; + } + + private void ReadHeader() + { + while (ReadNextLine()) + { + if (_line.StartsWith("*:")) + { + _names = _line.Substring(2).Split(':'); + _values = new string[_names.Length]; + + for (int i = 0; i < _names.Length; i++) + _names[i] = _names[i].Trim(); + } + else if (_line.StartsWith("**") || _line.StartsWith("*-")) + break; + } + } + + static string Encode(string value) + { + var arr = Convert.FromBase64String(value.Substring(1)); + +#if SILVERLIGHT + return new UnicodeEncoding(false, true).GetString(arr, 0, arr.Length); +#else + return Encoding.Unicode.GetString(arr); +#endif + } + + bool ReadRecord() + { + if (!IsEof) + { + if (_line.StartsWith("*-")) + return false; + + if (_line.StartsWith("**") && _line.Length > 3) + { + var values = _line.Substring(3).Split(_line[2]); + + for (var i = 0; i < _values.Length && i < values.Length; i++) + { + var value = values[i]; + + _values[i] = + value.Length == 0? null: + value[0] == '*'? value.Substring(1): + value[0] == '+'? Encode(value.Substring(1)) : value; + } + + ReadNextLine(); + + return true; + } + + throw new MappingException( + string.Format("Invalid data format in the line {0}.", _lineNumber)); + } + + return false; + } + + #endregion + + #region IDataReader Members + + public virtual void Close() + { + _line = null; + } + + public virtual int Depth + { + get { return 0; } + } + + public virtual Type GetFieldType(int index) + { + return typeof(string); + } + + public virtual string GetName(int index) + { + return _names[index]; + } + +#if !SILVERLIGHT + private DataTable _schemaTable; + + public virtual DataTable GetSchemaTable() + { + if (_schemaTable == null) + { + _schemaTable = new DataTable("SchemaTable"); + + _schemaTable.Columns.AddRange(new DataColumn[] + { + new DataColumn(SchemaTableColumn.ColumnName, typeof(string)), + new DataColumn(SchemaTableColumn.ColumnOrdinal, typeof(int)), + new DataColumn(SchemaTableColumn.ColumnSize, typeof(int)), + new DataColumn(SchemaTableColumn.NumericPrecision, typeof(short)), + new DataColumn(SchemaTableColumn.NumericScale, typeof(short)), + new DataColumn(SchemaTableColumn.DataType, typeof(Type)), + new DataColumn(SchemaTableColumn.NonVersionedProviderType, typeof(int)), + new DataColumn(SchemaTableColumn.ProviderType, typeof(int)), + new DataColumn(SchemaTableColumn.IsLong, typeof(bool)), + new DataColumn(SchemaTableColumn.AllowDBNull, typeof(bool)), + new DataColumn(SchemaTableColumn.IsUnique, typeof(bool)), + new DataColumn(SchemaTableColumn.IsKey, typeof(bool)), + new DataColumn(SchemaTableColumn.BaseSchemaName, typeof(string)), + new DataColumn(SchemaTableColumn.BaseTableName, typeof(string)), + new DataColumn(SchemaTableColumn.BaseColumnName, typeof(string)), + new DataColumn(SchemaTableColumn.IsAliased, typeof(bool)), + new DataColumn(SchemaTableColumn.IsExpression, typeof(bool)), + }); + + for (int i = 0; i < _names.Length; i++) + { + DataRow row = _schemaTable.NewRow(); + + row[SchemaTableColumn.ColumnName] = _names[i]; + row[SchemaTableColumn.ColumnOrdinal] = i; + row[SchemaTableColumn.ColumnSize] = (int)byte.MaxValue; + row[SchemaTableColumn.NumericPrecision] = (short)0; + row[SchemaTableColumn.NumericScale] = (short)0; + row[SchemaTableColumn.DataType] = typeof(string); + row[SchemaTableColumn.NonVersionedProviderType] = 1; + row[SchemaTableColumn.ProviderType] = 1; + row[SchemaTableColumn.IsLong] = false; + row[SchemaTableColumn.AllowDBNull] = true; + row[SchemaTableColumn.IsUnique] = false; + row[SchemaTableColumn.IsKey] = false; + row[SchemaTableColumn.BaseSchemaName] = string.Empty; + row[SchemaTableColumn.BaseTableName] = string.Empty; + row[SchemaTableColumn.BaseColumnName] = string.Empty; + row[SchemaTableColumn.IsAliased] = false; + row[SchemaTableColumn.IsExpression] = false; + + _schemaTable.Rows.Add(row); + } + } + + return _schemaTable; + } + +#endif + + public virtual int FieldCount + { + get { return _names.Length; } + } + + public virtual bool IsClosed + { + get { return IsEof; } + } + + public virtual bool NextResult() + { + ReadHeader(); + return !IsEof; + } + + public virtual bool Read() + { + return ReadRecord(); + } + + public virtual int RecordsAffected + { + get { return -1; } + } + + #endregion + + #region IDisposable Members + + public virtual void Dispose() + { + } + + #endregion + + #region IDataRecord Members + + public virtual bool GetBoolean(int i) + { + return _mappingSchema.ConvertToBoolean(_values[i]); + } + + public virtual byte GetByte(int i) + { + return _mappingSchema.ConvertToByte(_values[i]); + } + + public virtual long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) + { + throw new Exception("The method or operation is not implemented."); + } + + public virtual char GetChar(int i) + { + return _mappingSchema.ConvertToChar(_values[i]); + } + + public virtual long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) + { + throw new Exception("The method or operation is not implemented."); + } + + public virtual IDataReader GetData(int i) + { + throw new Exception("The method or operation is not implemented."); + } + + public virtual string GetDataTypeName(int i) + { + return typeof(string).FullName; + } + + public virtual DateTime GetDateTime(int i) + { + return _mappingSchema.ConvertToDateTime(_values[i]); + } + + public virtual DateTimeOffset GetDateTimeOffset(int i) + { + return _mappingSchema.ConvertToDateTimeOffset(_values[i]); + } + + public virtual decimal GetDecimal(int i) + { + return _mappingSchema.ConvertToDecimal(_values[i]); + } + + public virtual double GetDouble(int i) + { + return _mappingSchema.ConvertToDouble(_values[i]); + } + + public virtual float GetFloat(int i) + { + return _mappingSchema.ConvertToSingle(_values[i]); + } + + public virtual Guid GetGuid(int i) + { + return _mappingSchema.ConvertToGuid(_values[i]); + } + + public virtual short GetInt16(int i) + { + return _mappingSchema.ConvertToInt16(_values[i]); + } + + public virtual int GetInt32(int i) + { + return _mappingSchema.ConvertToInt32(_values[i]); + } + + public virtual long GetInt64(int i) + { + return _mappingSchema.ConvertToInt64(_values[i]); + } + + public virtual int GetOrdinal(string name) + { + for (int i = 0; i < _names.Length; i++) + if (_names[i] == name) + return i; + + return -1; + } + + public virtual string GetString(int i) + { + return _values[i]; + } + + public virtual object GetValue(int i) + { + return _values[i]; + } + + public virtual int GetValues(object[] values) + { + int n = Math.Min(values.Length, _values.Length); + + for (int i = 0; i < n; i++) + values[i] = _values[i]; + + return n; + } + + public virtual bool IsDBNull(int i) + { + return _values[i] == null; + } + + public virtual object this[string name] + { + get + { + for (int i = 0; i < _names.Length; i++) + if (_names[i] == name) + return _values[i]; + + throw new ArgumentException(string.Format("Invalid field name '{0}'", name)); + } + } + + public virtual object this[int i] + { + get { return _values[i]; } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/TextDataWriter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/TextDataWriter.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,194 @@ +using System; +using System.IO; +using System.Text; + +using BLToolkit.Reflection; + +namespace BLToolkit.Mapping +{ + public class TextDataWriter : ISupportMapping + { + #region Constructors + + public TextDataWriter(Stream stream, params string[] fieldNames) + : this(stream, Map.DefaultSchema, fieldNames) + { + } + + public TextDataWriter(Stream stream, Type type) + : this(stream, Map.DefaultSchema, Map.GetObjectMapper(type).FieldNames) + { + } + + public TextDataWriter(Stream stream, MappingSchema mappingSchema, params string[] fieldNames) + : this(new StreamWriter(stream), mappingSchema, fieldNames) + { + } + + public TextDataWriter(Stream stream, MappingSchema mappingSchema, Type type) + : this(stream, mappingSchema, mappingSchema.GetObjectMapper(type).FieldNames) + { + } + + public TextDataWriter(TextWriter writer, params string[] fieldNames) + : this(writer, Map.DefaultSchema, fieldNames) + { + } + + public TextDataWriter(TextWriter writer, Type type) + : this(writer, Map.DefaultSchema, Map.GetObjectMapper(type).FieldNames) + { + } + + public TextDataWriter(TextWriter writer, MappingSchema mappingSchema, params string[] fieldNames) + { + GC.SuppressFinalize(this); + + if (mappingSchema == null) throw new ArgumentNullException("mappingSchema"); + + _writer = writer; + _names = fieldNames; + + _values = new string[_names.Length]; + + WriteHeader(); + } + + public TextDataWriter(TextWriter writer, MappingSchema mappingSchema, Type type) + : this(writer, mappingSchema, mappingSchema.GetObjectMapper(type).FieldNames) + { + } + + #endregion + + #region Public Members + + public virtual void WriteEnd() + { + _writer.WriteLine("*-"); + _writer.Flush(); + } + + public virtual Type GetFieldType(int index) + { + return typeof(string); + } + + public virtual int GetOrdinal(string name) + { + for (int i = 0; i < _names.Length; i++) + if (_names[i] == name) + return i; + + return 0; + } + + public virtual void SetValue(int index, object value) + { + _values[index] = value == null? null: value.ToString(); + } + + public virtual void SetValue(string name, object value) + { + SetValue(GetOrdinal(name), value); + } + + #endregion + + #region Protected Members + + private readonly TextWriter _writer; + private readonly string[] _names; + private readonly string[] _values; + + private void WriteHeader() + { + _writer.Write("*"); + + foreach (string name in _names) + { + _writer.Write(':'); + _writer.Write(name); + } + + _writer.WriteLine(); + } + + private void WriteRecord() + { + _writer.Write("**"); + + char[] delimiters = new char[] { ',', ':', '|', '-', '_' }; + char delimiter = '\0'; + + foreach (char ch in delimiters) + { + bool found = false; + + foreach (string value in _values) + { + if (value != null && value.IndexOf(ch) >= 0) + { + found = true; + break; + } + } + + if (!found) + { + delimiter = ch; + break; + } + } + + if (delimiter == 0) + delimiter = delimiters[0]; + + char[] exChars = new char[] { delimiter, '\r', '\n', '\t', '\0' }; + + foreach (string value in _values) + { + _writer.Write(delimiter); + + if (value != null) + { + if (value.Length == 0) + _writer.Write('*'); + else + { + if (value.IndexOfAny(exChars) >= 0) + { + _writer.Write('+'); + _writer.Write(Convert.ToBase64String(Encoding.Unicode.GetBytes(value))); + } + else + { + if (value[0] == '*' || value[0] == '+') + _writer.Write('*'); + + _writer.Write(value); + } + } + } + } + + _writer.WriteLine(); + _writer.Flush(); + } + + #endregion + + #region ISupportMapping Members + + void ISupportMapping.BeginMapping(InitContext initContext) + { + } + + void ISupportMapping.EndMapping(InitContext initContext) + { + WriteRecord(); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/TrimmableAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/TrimmableAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,40 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using BLToolkit.Common; + +namespace BLToolkit.Mapping +{ + [AttributeUsage( + AttributeTargets.Property | AttributeTargets.Field | + AttributeTargets.Class | AttributeTargets.Interface)] + public sealed class TrimmableAttribute : Attribute + { + public TrimmableAttribute() + { + _isTrimmable = true; + } + + public TrimmableAttribute(bool isTrimmable) + { + _isTrimmable = isTrimmable; + } + + private readonly bool _isTrimmable; + public bool IsTrimmable + { + get { return _isTrimmable; } + } + + private static TrimmableAttribute GetDefaultTrimmableAttribute() + { + return Common.Configuration.TrimOnMapping ? Yes : No; + } + + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly TrimmableAttribute Yes = new TrimmableAttribute(true); + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly TrimmableAttribute No = new TrimmableAttribute(false); + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly TrimmableAttribute Default = GetDefaultTrimmableAttribute(); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Mapping/ValueMapping.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Mapping/ValueMapping.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,155 @@ +using System; + +using BLToolkit.Common; + +using KeyValue = System.Collections.Generic.KeyValuePair; +using Table = System.Collections.Generic.Dictionary, BLToolkit.Mapping.IValueMapper>; + +namespace BLToolkit.Mapping +{ + public static class ValueMapping + { + #region Init + + private static readonly Table _mappers = new Table(); + + #endregion + + #region Default Mapper + + class DefaultValueMapper : IValueMapper + { + public void Map( + IMapDataSource source, object sourceObject, int sourceIndex, + IMapDataDestination dest, object destObject, int destIndex) + { + dest.SetValue(destObject, destIndex, source.GetValue(sourceObject, sourceIndex)); + + //object o = source.GetValue(sourceObject, sourceIndex); + + //if (o == null) dest.SetNull (destObject, destIndex); + //else dest.SetValue(destObject, destIndex, o); + } + } + + private static IValueMapper _defaultMapper = new DefaultValueMapper(); + [CLSCompliant(false)] + public static IValueMapper DefaultMapper + { + get { return _defaultMapper; } + set { _defaultMapper = value; } + } + + #endregion + + #region GetMapper + + private static readonly object _sync = new object(); + + [CLSCompliant(false)] + public static IValueMapper GetMapper(Type t1, Type t2) + { + if (t1 == null) t1 = typeof(object); + if (t2 == null) t2 = typeof(object); + + if (t1.IsEnum) t1 = Enum.GetUnderlyingType(t1); + if (t2.IsEnum) t2 = Enum.GetUnderlyingType(t2); + + var key = new KeyValue(t1, t2); + + lock (_sync) + { + IValueMapper t; + + if (_mappers.TryGetValue(key, out t)) + return t; + + //t = BLToolkit.Mapping.ValueMappingInternal.MapperSelector.GetMapper(t1, t2); + + if (null == t) + { + var type = typeof(GetSetDataChecker<,>).MakeGenericType(t1, t2); + + if (((IGetSetDataChecker)Activator.CreateInstance(type)).Check() == false) + { + t = _defaultMapper; + } + else + { + type = t1 == t2 ? + typeof(ValueMapper<>).MakeGenericType(t1) : + typeof(ValueMapper<,>).MakeGenericType(t1, t2); + + t = (IValueMapper)Activator.CreateInstance(type); + } + } + + _mappers.Add(key, t); + + return t; + } + } + + #endregion + + #region Generic Mappers + + interface IGetSetDataChecker + { + bool Check(); + } + + class GetSetDataChecker : IGetSetDataChecker + { + public bool Check() + { + return + !(MapGetData.I is MapGetData.Default) && + !(MapSetData.I is MapSetData.Default) && + !(MapGetData.I is MapGetData.Default) && + !(MapSetData.I is MapSetData.Default); + } + } + + class ValueMapper : IValueMapper + { + public void Map( + IMapDataSource source, object sourceObject, int sourceIndex, + IMapDataDestination dest, object destObject, int destIndex) + { + if (source.IsNull(sourceObject, sourceIndex)) + dest.SetNull(destObject, destIndex); + else + { + var setter = MapSetData.I; + var getter = MapGetData.I; + + setter.To(dest, destObject, destIndex, + getter.From(source, sourceObject, sourceIndex)); + } + } + } + + class ValueMapper : IValueMapper + { + public void Map( + IMapDataSource source, object sourceObject, int sourceIndex, + IMapDataDestination dest, object destObject, int destIndex) + { + if (source.IsNull(sourceObject, sourceIndex)) + dest.SetNull(destObject, destIndex); + else + { + var setter = MapSetData.I; + var getter = MapGetData.I; + var converter = Convert.From; + + setter.To(dest, destObject, destIndex, + converter(getter.From(source, sourceObject, sourceIndex))); + } + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Net/HttpReader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Net/HttpReader.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,465 @@ +/* + * File: HttpReader.cs + * Created: 01/17/2003 + * Author: Igor Tkachev + * mailto:it@rsdn.ru + */ + +using System; +using System.Collections; +using System.IO; +using System.Net; +using System.Text; +using System.Security.Cryptography.X509Certificates; +using System.Collections.Generic; + +namespace BLToolkit.Net +{ + public delegate void ProcessStream(Stream stream); + + /// + /// Encapsulates WebReader functions. + /// + public class HttpReader + { + #region Costructors + + public HttpReader() + { + BaseUri = string.Empty; + } + + public HttpReader(string baseUri) + { + BaseUri = baseUri; + } + + #endregion + + #region Public Properties + + private X509Certificate _certificate; + public X509Certificate Certificate + { + get { return _certificate; } + set { _certificate = value; } + } + + private string _baseUri; + public string BaseUri + { + get { return _baseUri; } + set { _baseUri = value; } + } + + private string _previousUri; + public string PreviousUri + { + get { return _previousUri; } + set { _previousUri = value; } + } + + private CookieContainer _cookieContainer = new CookieContainer(); + public CookieContainer CookieContainer + { + get { return _cookieContainer; } + set { _cookieContainer = value; } + } + + private string _userAgent = @"HttpReader"; + public string UserAgent + { + get { return _userAgent; } + set { _userAgent = value; } + } + + private string _accept = + @"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, */*"; + public string Accept + { + get { return _accept; } + set { _accept = value; } + } + + private Uri _requestUri; + public Uri RequestUri + { + get { return _requestUri; } + set { _requestUri = value; } + } + + private string _contentType = string.Empty; + public string ContentType + { + get { return _contentType; } + set { _contentType = value; } + } + + private IWebProxy _proxy = new WebProxy(); + public IWebProxy Proxy + { + get { return _proxy; } + set { _proxy = value; } + } + + private ICredentials _credentials = CredentialCache.DefaultCredentials; + public ICredentials Credentials + { + get { return _credentials; } + set { _credentials = value; } + } + + private string _html; + public string Html + { + get { return _html; } + } + + private readonly Hashtable _headers = new Hashtable(); + public Hashtable Headers + { + get { return _headers; } + } + + private string _location; + public string Location + { + get { return _location; } + } + + private bool _sendReferer = true; + public bool SendReferer + { + get { return _sendReferer; } + set { _sendReferer = value; } + } + + private HttpStatusCode _statusCode; + public HttpStatusCode StatusCode + { + get { return _statusCode; } + } + + private int _timeout; + public int Timeout + { + get { return _timeout; } + set { _timeout = value; } + } + + #endregion + + #region Public Methods + + public void LoadCertificate(string fileName) + { + Certificate = X509Certificate.CreateFromCertFile(fileName); + } + + #endregion + + #region Request Methods + + private HttpWebRequest PrepareRequest(string method, string requestUri, ProcessStream requestStreamProcessor) + { + _html = ""; + + string uri = BaseUri; + + if (method != "SOAP") + uri += requestUri; + + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); + + if (Proxy != null) request.Proxy = Proxy; + if (Credentials != null) request.Credentials = Credentials; + + request.CookieContainer = CookieContainer; + request.UserAgent = UserAgent; + request.Accept = Accept; + request.Method = method == "SOAP"? "POST" : method; + request.KeepAlive = true; + + if (SendReferer) + request.Referer = PreviousUri ?? uri; + + foreach (string key in Headers.Keys) + request.Headers.Add(key, Headers[key].ToString()); + + if (method == "POST") + { + request.ContentType = "application/x-www-form-urlencoded"; + request.AllowAutoRedirect = false; + } + else if (method == "SOAP") + { + request.ContentType = "text/xml; charset=utf-8"; + request.AllowAutoRedirect = false; + + request.Headers.Add("SOAPAction", requestUri); + } + else + { + request.ContentType = ContentType; + request.AllowAutoRedirect = true; + } + + PreviousUri = uri; + RequestUri = request.RequestUri; + + if (Certificate != null) + request.ClientCertificates.Add(Certificate); + + if (Timeout != 0) + request.Timeout = Timeout; + + if (requestStreamProcessor != null) + using (Stream st = request.GetRequestStream()) + requestStreamProcessor(st); + + return request; + } + + public HttpStatusCode Request( + string requestUri, + string method, + ProcessStream requestStreamProcessor, + ProcessStream responseStreamProcessor) + { + HttpWebRequest request = PrepareRequest(method, requestUri, requestStreamProcessor); + + using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse()) + using (Stream sm = resp.GetResponseStream()) + { + _statusCode = resp.StatusCode; + _location = resp.Headers["Location"]; + + if (resp.ResponseUri.AbsoluteUri.StartsWith(BaseUri) == false) + BaseUri = resp.ResponseUri.Scheme + "://" + resp.ResponseUri.Host; + + CookieCollection cc = request.CookieContainer.GetCookies(request.RequestUri); + + // This code fixes the situation when a server sets a cookie without the 'path'. + // IE takes this as the root ('/') value, + // the HttpWebRequest class as the RequestUri.AbsolutePath value. + // + foreach (Cookie c in cc) + if (c.Path == request.RequestUri.AbsolutePath) + CookieContainer.Add(new Cookie(c.Name, c.Value, "/", c.Domain)); + + if (responseStreamProcessor != null) + responseStreamProcessor(sm); + } + + return StatusCode; + } + + public IEnumerable Request( + string requestUri, + string method, + ProcessStream requestStreamProcessor) + { + HttpWebRequest request = PrepareRequest(method, requestUri, requestStreamProcessor); + + using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse()) + using (Stream sm = resp.GetResponseStream()) + using (StreamReader sr = new StreamReader(sm, Encoding.Default)) + { + _statusCode = resp.StatusCode; + _location = resp.Headers["Location"]; + + if (resp.ResponseUri.AbsoluteUri.StartsWith(BaseUri) == false) + BaseUri = resp.ResponseUri.Scheme + "://" + resp.ResponseUri.Host; + + CookieCollection cc = request.CookieContainer.GetCookies(request.RequestUri); + + // This code fixes the case when a server sets a cookie without the 'path'. + // IE takes this as the root ('/') value, + // the HttpWebRequest class as the RequestUri.AbsolutePath value. + // + foreach (Cookie c in cc) + if (c.Path == request.RequestUri.AbsolutePath) + CookieContainer.Add(new Cookie(c.Name, c.Value, "/", c.Domain)); + + while (true) + { + string str = sr.ReadLine(); + + if (str == null) + break; + + yield return str; + } + } + } + + class DefaultRequestStreamProcessor + { + public DefaultRequestStreamProcessor(string data) + { + _data = data; + } + + readonly string _data; + + public void Process(Stream stream) + { + byte[] bytes = Encoding.ASCII.GetBytes(_data); + stream.Write(bytes, 0, bytes.Length); + } + } + + class DefaultResponseStreamProcessor + { + public DefaultResponseStreamProcessor(HttpReader reader) + { + _reader = reader; + } + + readonly HttpReader _reader; + + public void Process(Stream stream) + { + using (StreamReader sr = new StreamReader(stream, Encoding.Default)) + _reader._html = sr.ReadToEnd(); + } + } + + public HttpStatusCode Get(string requestUri) + { + DefaultResponseStreamProcessor rp = new DefaultResponseStreamProcessor(this); + + return Request(requestUri, "GET", null, rp.Process); + } + + public HttpStatusCode Get(string requestUri, ProcessStream responseStreamProcessor) + { + return Request(requestUri, "GET", null, responseStreamProcessor); + } + + public HttpStatusCode Post( + string requestUri, + string postData) + { + return Post( + requestUri, + new DefaultRequestStreamProcessor(postData).Process, + new DefaultResponseStreamProcessor(this).Process); + } + + public HttpStatusCode Post( + string requestUri, + ProcessStream requestStreamProcessor) + { + return Post( + requestUri, + requestStreamProcessor, + new DefaultResponseStreamProcessor(this).Process); + } + + public HttpStatusCode Post( + string requestUri, + string postData, + ProcessStream responseStreamProcessor) + { + return Post( + requestUri, + new ProcessStream(new DefaultRequestStreamProcessor(postData).Process), + responseStreamProcessor); + } + + public HttpStatusCode Post( + string requestUri, + ProcessStream requestStreamProcessor, + ProcessStream responseStreamProcessor) + { + Request(requestUri, "POST", requestStreamProcessor, responseStreamProcessor); + + for (int i = 0; i < 10; i++) + { + bool post = false; + + switch (StatusCode) + { + case HttpStatusCode.MultipleChoices: // 300 + case HttpStatusCode.MovedPermanently: // 301 + case HttpStatusCode.Found: // 302 + case HttpStatusCode.SeeOther: // 303 + break; + + case HttpStatusCode.TemporaryRedirect: // 307 + post = true; + break; + + default: + return StatusCode; + } + + if (Location == null) + break; + + Uri uri = new Uri(new Uri(PreviousUri), Location); + + BaseUri = uri.Scheme + "://" + uri.Host; + requestUri = uri.AbsolutePath + uri.Query; + + Request( + requestUri, + post? "POST": "GET", + post? requestStreamProcessor: null, + responseStreamProcessor); + } + + return StatusCode; + } + + private HttpStatusCode Soap( + string soapAction, + ProcessStream inputStreamProcessor, + ProcessStream outputStreamProcessor) + { + return Request("\"" + soapAction + "\"", "SOAP", inputStreamProcessor, outputStreamProcessor); + } + + public HttpStatusCode Soap(string soapAction, string postData) + { + return Soap(soapAction, + new DefaultRequestStreamProcessor(postData).Process, + new DefaultResponseStreamProcessor(this).Process); + } + + public HttpStatusCode Soap(string soapAction, string postData, ProcessStream outputStreamProcessor) + { + return Soap( + soapAction, + new DefaultRequestStreamProcessor(postData).Process, + outputStreamProcessor); + } + + public IEnumerable SoapEx(string soapAction, string postData) + { + return Request("\"" + soapAction + "\"", "SOAP", new DefaultRequestStreamProcessor(postData).Process); + } + + #endregion + + #region Download + + public void Download(string requestUri, string fileName) + { + string uri = BaseUri + requestUri; + + WebClient request = new WebClient(); + + if (Proxy != null) request.Proxy = Proxy; + if (Credentials != null) request.Credentials = Credentials; + + foreach (string key in Headers.Keys) + request.Headers.Add(key, Headers[key].ToString()); + + request.DownloadFile(uri, fileName); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Patterns/DuckType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Patterns/DuckType.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ +using System; + +namespace BLToolkit.Patterns +{ + /// + /// Reserved to internal BLToolkit use. + /// + public abstract class DuckType + { + [CLSCompliant(false)] + protected object[] _objects; + public object[] Objects + { + get { return _objects; } + } + + internal void SetObjects(params object[] objs) + { + _objects = objs; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Patterns/DuckTyping.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Patterns/DuckTyping.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,357 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +using BLToolkit.Common; +using BLToolkit.Properties; +using BLToolkit.Reflection; +using BLToolkit.TypeBuilder; +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.Patterns +{ + /// + /// Duck typing implementation. + /// In computer science, duck typing is a term for dynamic typing typical + /// of some programming languages, such as Smalltalk, Python or ColdFusion, + /// where a variable's value itself determines what the variable can do. + /// Thus an object or set of objects having all the methods described in + /// an interface can be made to implement that interface dynamically + /// at runtime, even if the objects class does not include the interface + /// in its implements clause. + /// + public static class DuckTyping + { + #region Single Duck + + static readonly Dictionary> _duckTypes = new Dictionary>(); + + /// + /// Build a proxy type which implements the requested interface by redirecting all calls to the supplied object type. + /// + /// An interface type to implement. + /// Any type which expected to have all members of the given interface. + /// The duck object type. + public static Type GetDuckType(Type interfaceType, Type objectType) + { + if (interfaceType == null) throw new ArgumentNullException("interfaceType"); + if (!interfaceType.IsInterface) throw new ArgumentException(Resources.DuckTyping_InterfaceTypeMustBeAnInterface, "interfaceType"); + if (!interfaceType.IsPublic && !interfaceType.IsNestedPublic) + throw new ArgumentException(Resources.DuckTyping_InterfaceMustBePublic, "interfaceType"); + + Dictionary types; + + lock(_duckTypes) + if (!_duckTypes.TryGetValue(interfaceType, out types)) + _duckTypes.Add(interfaceType, types = new Dictionary()); + + Type type; + + lock (types) if (!types.TryGetValue(objectType, out type)) + { + type = TypeFactory.GetType( + new CompoundValue(interfaceType, objectType), + interfaceType, //objectType, + new DuckTypeBuilder(MustImplementAttribute.Default, interfaceType, new[] { objectType })); + + types.Add(objectType, type); + } + + return type; + } + + /// + /// Implements the requested interface for supplied object. + /// If the supplied object implements the interface, the object itself will be returned. + /// Otherwise a convenient duck object will be created. + /// + /// An interface type to implement. + /// Any type which has all members of the given interface. + /// When this parameter is set to null, the object type will be used. + /// An object which type expected to have all members of the given interface. + /// An object which implements the interface. + public static object Implement(Type interfaceType, Type baseObjectType, object obj) + { + if (obj == null) throw new ArgumentNullException("obj"); + + var objType = obj.GetType(); + + if (TypeHelper.IsSameOrParent(interfaceType, objType)) + return obj; + + if (obj is DuckType) + { + var duckObject = (DuckType)obj; + + if (duckObject.Objects.Length == 1) + { + // Switch to underlying objects when a duck object was passed. + // + return Implement(interfaceType, baseObjectType, duckObject.Objects[0]); + } + + // Re-aggregate underlying objects to expose new interface. + // + return Aggregate(interfaceType, duckObject.Objects); + } + + if (baseObjectType == null) + baseObjectType = objType; + else if (!TypeHelper.IsSameOrParent(baseObjectType, objType)) + throw new ArgumentException(string.Format(Resources.DuckTyping_NotASubtypeOf, objType.FullName, baseObjectType.FullName), "obj"); + + var duckType = GetDuckType(interfaceType, baseObjectType); + + if (duckType == null) + return null; + + var duck = TypeAccessor.CreateInstanceEx(duckType); + + ((DuckType)duck).SetObjects(obj); + + return duck; + } + + /// + /// Implements the requested interface. + /// If the supplied object implements the interface, the object itself will be returned. + /// Otherwise a convenient duck object will be created. + /// + /// An interface type to implement. + /// An object which type expected to have all members of the given interface. + /// An object which implements the interface. + public static object Implement(Type interfaceType, object obj) + { + return Implement(interfaceType, null, obj); + } + + /// + /// Implements the requested interface for all supplied objects. + /// If any of supplied object implements the interface, the object itself will be returned. + /// Otherwise a convenient duck object will be created. + /// + /// An interface type to implement. + /// Any type which has all members of the given interface. + /// When this parameter is set to null, the object type will be used. + /// An object array which types expected to have all members of the given interface. + /// All objects may have different types. + /// An array of object which implements the interface. + public static object[] Implement(Type interfaceType, Type baseObjectType, params object[] objects) + { + if (objects == null) throw new ArgumentNullException("objects"); + + object[] result = new object[objects.Length]; + + for (int i = 0; i < objects.Length; i++) + result[i] = Implement(interfaceType, baseObjectType, objects[i]); + + return result; + } + + /// + /// Implements the requested interface for all supplied objects. + /// If any of supplied object implements the interface, the object itself will be returned. + /// Otherwise a convenient duck object will be created. + /// + /// An interface type to implement. + /// An object array which types expected to have all members of the given interface. + /// All objects may have different types. + /// An array of object which implements the interface. + public static object[] Implement(Type interfaceType, params object[] objects) + { + return Implement(interfaceType, (Type)null, objects); + } + + /// + /// Implements the requested interface for supplied object. + /// If the supplied object implements the interface, the object itself will be returned. + /// Otherwise a convenient duck object will be created. + /// + /// An interface type to implement. + /// An object which type expected to have all members of the given interface. + /// An object which implements the interface. + public static I Implement(object obj) + where I : class + { + return (I)Implement(typeof(I), null, obj); + } + + /// + /// Implements the requested interface for supplied object. + /// If the supplied object implements the interface, the object itself will be returned. + /// Otherwise a convenient duck object will be created. + /// + /// An interface type to implement. + /// Any type which has all members of the given interface. + /// An object which type expected to have all members of the given interface. + /// An object which implements the interface. + public static I Implement(T obj) + where I : class + { + return (I)Implement(typeof(I), typeof(T), obj); + } + + /// + /// Implements the requested interface for all supplied objects. + /// If any of supplied object implements the interface, the object itself will be returned. + /// Otherwise a convenient duck object will be created. + /// + /// An interface type to implement. + /// An object array which types expected to have all members of the given interface. + /// All objects may have different types. + /// An array of object which implements the interface. + public static I[] Implement(params object[] objects) + where I : class + { + if (objects == null) throw new ArgumentNullException("objects"); + + I[] result = new I[objects.Length]; + + for (int i = 0; i < objects.Length; i++) + result[i] = Implement(objects[i]); + + return result; + } + + /// + /// Implements the requested interface for all supplied objects. + /// If any of supplied object implements the interface, the object itself will be returned. + /// Otherwise a convenient duck object will be created. + /// + /// An interface type to implement. + /// Any type which has all members of the given interface. + /// An object array which types expected to have all members of the given interface. + /// All objects may have different types. + /// An array of object which implements the interface. + public static I[] Implement(params T[] objects) + where I : class + { + if (objects == null) throw new ArgumentNullException("objects"); + + I[] result = new I[objects.Length]; + + for (int i = 0; i < objects.Length; i++) + result[i] = Implement(objects[i]); + + return result; + } + + private static bool _allowStaticMembers; + public static bool AllowStaticMembers + { + get { return _allowStaticMembers; } + set { _allowStaticMembers = value; } + } + + #endregion + + #region Multiple Duck + + /// + /// Build a proxy type which implements the requested interface by redirecting all calls to the supplied object type. + /// + /// An interface type to implement. + /// Array of types which expected to have all members of the given interface. + /// The duck object type. + public static Type GetDuckType(Type interfaceType, Type[] objectTypes) + { + if (interfaceType == null) throw new ArgumentNullException("interfaceType"); + if (!interfaceType.IsInterface) throw new ArgumentException(Resources.DuckTyping_InterfaceTypeMustBeAnInterface, "interfaceType"); + if (!interfaceType.IsPublic && !interfaceType.IsNestedPublic) + throw new ArgumentException(Resources.DuckTyping_InterfaceMustBePublic, "interfaceType"); + + Dictionary types; + + lock (_duckTypes) + if (!_duckTypes.TryGetValue(interfaceType, out types)) + _duckTypes.Add(interfaceType, types = new Dictionary()); + + object key = new CompoundValue(objectTypes); + Type type; + + lock (types) if (!types.TryGetValue(key, out type)) + { + type = TypeFactory.GetType( + new CompoundValue(interfaceType, key), + interfaceType, + new DuckTypeBuilder(MustImplementAttribute.Aggregate, interfaceType, objectTypes)); + + types.Add(key, type); + } + + return type; + } + + /// + /// Implements the requested interface from supplied set of objects. + /// + /// An interface type to implement. + /// Array of types which have all members of the given interface. + /// When this parameter is set to null, the object type will be used. + /// Array of objects which types expected to have all members of the given interface. + /// An object which implements the interface. + public static object Aggregate(Type interfaceType, Type[] baseObjectTypes,params object[] objs) + { + if (objs == null) throw new ArgumentNullException("objs"); + + if (baseObjectTypes == null) + { + baseObjectTypes = new Type[objs.Length]; + + for (int i = 0; i < objs.Length; i++) + if (objs[i] != null) + baseObjectTypes[i] = objs[i].GetType(); + } + else + { + if (baseObjectTypes.Length != objs.Length) + throw new ArgumentException(Resources.DuckTyping_InvalidNumberOfObjs, "baseObjectTypes"); + + for (int i = 0; i < objs.Length; i++) + { + Type objType = objs[i].GetType(); + + if (!TypeHelper.IsSameOrParent(baseObjectTypes[i], objType)) + throw new ArgumentException( + string.Format(Resources.DuckTyping_NotASubtypeOf, objType.FullName, baseObjectTypes[i].FullName), "objs"); + } + } + + Type duckType = GetDuckType(interfaceType, baseObjectTypes); + + if (duckType == null) + return null; + + object duck = TypeAccessor.CreateInstanceEx(duckType); + + ((DuckType)duck).SetObjects(objs); + + return duck; + } + + /// + /// Implements the requested interface from supplied set of objects. + /// + /// An interface type to implement. + /// Array of object which types expected to have of the given interface. + /// An object which implements the interface. + public static object Aggregate(Type interfaceType,params object[] objs) + { + return Aggregate(interfaceType, (Type[])null, objs); + } + + /// + /// Implements the requested interface from supplied set of objects. + /// + /// An interface type to implement. + /// Array of object which type expected to have all members of the given interface. + /// An object which implements the interface. + public static I Aggregate(params object[] objs) + where I : class + { + return (I)Aggregate(typeof(I), null, objs); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Patterns/MustImplementAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Patterns/MustImplementAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,66 @@ +using System; + +namespace BLToolkit.Patterns +{ + [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Method | AttributeTargets.Property)] + public sealed class MustImplementAttribute : Attribute + { + public MustImplementAttribute(bool implement, bool throwException, string exceptionMessage) + { + _implement = implement; + _throwException = throwException; + _exceptionMessage = exceptionMessage; + } + + public MustImplementAttribute(bool implement, bool throwException) + : this(implement, throwException, null) + { + } + + public MustImplementAttribute(bool implement, string exceptionMessage) + : this(implement, true, exceptionMessage) + { + } + + public MustImplementAttribute(bool implement) + : this(implement, true, null) + { + } + + public MustImplementAttribute() + : this(true, true, null) + { + } + + private readonly bool _implement; + public bool Implement + { + get { return _implement; } + } + + private bool _throwException; + public bool ThrowException + { + get { return _throwException; } + set { _throwException = value; } + } + + private string _exceptionMessage; + public string ExceptionMessage + { + get { return _exceptionMessage; } + set { _exceptionMessage = value; } + } + + /// + /// All methods are optional and throws at run tune. + /// + public static readonly MustImplementAttribute Default = new MustImplementAttribute(false, true, null); + + /// + /// All methods are optional and does nothing at run tune. + /// Return value and all output parameters will be set to appropriate default values. + /// + public static readonly MustImplementAttribute Aggregate = new MustImplementAttribute(false, false, null); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,49 @@ +using System; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security; +using System.Resources; + +using BLToolkit; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle (BLToolkitConstants.ProductName)] +[assembly: AssemblyDescription (BLToolkitConstants.ProductDescription)] +[assembly: AssemblyProduct (BLToolkitConstants.ProductName)] +[assembly: AssemblyCopyright (BLToolkitConstants.Copyright)] +[assembly: AssemblyCulture ("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany (BLToolkitConstants.ProductName)] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM componenets. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9a7e41f3-ca15-4dc5-b724-65b7cdbbdcd1")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion (BLToolkitConstants.FullVersionString)] +[assembly: AssemblyFileVersion(BLToolkitConstants.FullVersionString)] + +// The AllowPartiallyTrustedCallersAttribute requires the assembly to be signed with a strong name key. +// This attribute is necessary since the control is called by either an intranet or Internet +// Web page that should be running under restricted permissions. +#if !SILVERLIGHT +[assembly: AllowPartiallyTrustedCallers] +//[assembly: SecurityRules(SecurityRuleSet.Level2, SkipVerificationInFullTrust = true)] +#endif + +[assembly: CLSCompliant(true)] +[assembly: NeutralResourcesLanguageAttribute("en-US")] diff -r 000000000000 -r f990fcb411a9 Source/Properties/BLToolkitConstants.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Properties/BLToolkitConstants.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,39 @@ +using System; + +namespace BLToolkit +{ + /// + /// Global library constants. + /// + public static partial class BLToolkitConstants + { + /// + /// Major component of version. + /// + public const string MajorVersion = "4"; + + /// + /// Minor component of version. + /// + public const string MinorVersion = "1"; + + /// + /// Build component of version. + /// + public const string Build = "21"; + + /// + /// Full version string. + /// + public const string FullVersionString = MajorVersion + "." + MinorVersion + "." + Build + "." + Revision; + + /// + /// Full BLT version. + /// + public static readonly Version FullVersion = new Version(FullVersionString); + + public const string ProductName = "BLToolkit"; + public const string ProductDescription = "Business Logic Toolkit for .NET"; + public const string Copyright = "\xA9 2002-2013 www.bltoolkit.net"; + } +} diff -r 000000000000 -r f990fcb411a9 Source/Properties/JetBrains.Annotations.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Properties/JetBrains.Annotations.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,281 @@ +using System; +using System.Collections.Generic; + +namespace JetBrains.Annotations +{ + /// + /// Indicates that marked method builds string by format pattern and (optional) arguments. + /// Parameter, which contains format string, should be given in constructor. + /// The format string should be in -like form + /// + [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + internal sealed class StringFormatMethodAttribute : Attribute + { + private readonly string _formatParameterName; + + /// + /// Initializes new instance of StringFormatMethodAttribute + /// + /// Specifies which parameter of an annotated method should be treated as format-string + public StringFormatMethodAttribute(string formatParameterName) + { + _formatParameterName = formatParameterName; + } + + /// + /// Gets format parameter name + /// + public string FormatParameterName + { + get { return _formatParameterName; } + } + } + + /// + /// Indicates that the function argument should be string literal and match one of the parameters of the caller function. + /// For example, has such parameter. + /// + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] + internal sealed class InvokerParameterNameAttribute : Attribute + { + } + + /// + /// Indicates that the marked method is assertion method, i.e. it halts control flow if one of the conditions is satisfied. + /// To set the condition, mark one of the parameters with attribute + /// + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + internal sealed class AssertionMethodAttribute : Attribute + { + } + + /// + /// Indicates the condition parameter of the assertion method. + /// The method itself should be marked by attribute. + /// The mandatory argument of the attribute is the assertion type. + /// + /// + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] + internal sealed class AssertionConditionAttribute : Attribute + { + private readonly AssertionConditionType _conditionType; + + /// + /// Initializes new instance of AssertionConditionAttribute + /// + /// Specifies condition type + public AssertionConditionAttribute(AssertionConditionType conditionType) + { + _conditionType = conditionType; + } + + /// + /// Gets condition type + /// + public AssertionConditionType ConditionType + { + get { return _conditionType; } + } + } + + /// + /// Specifies assertion type. If the assertion method argument satisifes the condition, then the execution continues. + /// Otherwise, execution is assumed to be halted + /// + internal enum AssertionConditionType + { + /// + /// Indicates that the marked parameter should be evaluated to true + /// + IS_TRUE = 0, + + /// + /// Indicates that the marked parameter should be evaluated to false + /// + IS_FALSE = 1, + + /// + /// Indicates that the marked parameter should be evaluated to null value + /// + IS_NULL = 2, + + /// + /// Indicates that the marked parameter should be evaluated to not null value + /// + IS_NOT_NULL = 3, + } + + /// + /// Indicates that the marked method unconditionally terminates control flow execution. + /// For example, it could unconditionally throw exception + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + internal sealed class TerminatesProgramAttribute : Attribute + { + } + + /// + /// Indicates that the value of marked element could be null sometimes, so the check for null is necessary before its usage + /// + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] + internal sealed class CanBeNullAttribute : Attribute + { + } + + /// + /// Indicates that the value of marked element could never be null + /// + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] + internal sealed class NotNullAttribute : Attribute + { + } + + /// + /// Indicates that the value of marked type (or its derivatives) cannot be compared using '==' or '!=' operators. + /// There is only exception to compare with null, it is permitted + /// + [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)] + internal sealed class CannotApplyEqualityOperatorAttribute : Attribute + { + } + + /// + /// When applied to target attribute, specifies a requirement for any type which is marked with + /// target attribute to implement or inherit specific type or types + /// + /// + /// + /// [BaseTypeRequired(typeof(IComponent)] // Specify requirement + /// public class ComponentAttribute : Attribute + /// {} + /// + /// [Component] // ComponentAttribute requires implementing IComponent interface + /// public class MyComponent : IComponent + /// {} + /// + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] + [BaseTypeRequired(typeof(Attribute))] + internal sealed class BaseTypeRequiredAttribute : Attribute + { + private readonly Type[] _baseTypes; + + /// + /// Initializes new instance of BaseTypeRequiredAttribute + /// + /// Specifies which types are required + public BaseTypeRequiredAttribute(Type baseType) + : this(new Type[] { baseType }) + { + } + + /// + /// Initializes new instance of BaseTypeRequiredAttribute + /// + /// Specifies which types are required + public BaseTypeRequiredAttribute(params Type[] baseTypes) + { + _baseTypes = baseTypes; + } + + /// + /// Gets enumerations of specified base types + /// + public IEnumerable BaseTypes + { + get { return _baseTypes; } + } + } + + /// + /// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library), + /// so this symbol will not be marked as unused (as well as by other usage inspections) + /// + [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = false)] + internal class UsedImplicitlyAttribute : Attribute + { + readonly ImplicitUseFlags _flags; + /// + /// Gets value indicating what is meant to be used + /// + [UsedImplicitly] + public ImplicitUseFlags Flags + { + get { return _flags; } + } + + /// + /// Initializes new instance of UsedImplicitlyAttribute + /// + public UsedImplicitlyAttribute() + : this(ImplicitUseFlags.Default) + { + } + + /// + /// Initializes new instance of UsedImplicitlyAttribute with specified flags + /// + /// Value of type indicating usage kind + public UsedImplicitlyAttribute(ImplicitUseFlags flags) + { + _flags = flags; + } + } + + /// + /// Should be used on attributes and causes ReSharper to not mark symbols marked with such attributes as unused (as well as by other usage inspections) + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] + internal class MeansImplicitUseAttribute : Attribute + { + readonly ImplicitUseFlags _flags; + /// + /// Gets value indicating what is meant to be used + /// + [UsedImplicitly] + public ImplicitUseFlags Flags + { + get { return _flags; } + } + + /// + /// Initializes new instance of MeansImplicitUseAttribute + /// + [UsedImplicitly] + public MeansImplicitUseAttribute() + : this(ImplicitUseFlags.Default) + { + } + + /// + /// Initializes new instance of MeansImplicitUseAttribute with specified flags + /// + /// Value of type indicating usage kind + [UsedImplicitly] + public MeansImplicitUseAttribute(ImplicitUseFlags flags) + { + _flags = flags; + } + } + + /// + /// Specify what is considered used implicitly when marked with or + /// + [Flags] + internal enum ImplicitUseFlags + { + /// + /// Only entity marked with attribute considered used + /// + Default = 0, + + /// + /// Entity marked with attribute and all its members considered used + /// + IncludeMembers = 1 + } + + [AttributeUsage(AttributeTargets.Parameter, Inherited = true)] + internal sealed class InstantHandleAttribute : Attribute { } +} diff -r 000000000000 -r f990fcb411a9 Source/Properties/Resources.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Properties/Resources.Designer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,585 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.1 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BLToolkit.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BLToolkit.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The '{0}' must be an interface.. + /// + internal static string AbstractClassBuilder_TypeIsNotAnInterface { + get { + return ResourceManager.GetString("AbstractClassBuilder_TypeIsNotAnInterface", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Can not figure out the target method for the method '{0}.{1}'.. + /// + internal static string AsyncAspectBuilder_NoTargetMethod { + get { + return ResourceManager.GetString("AsyncAspectBuilder_NoTargetMethod", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Parameter 'cacheAspectType' must be of CacheAspect type. + /// + internal static string CacheAttribute_ParentTypeConstraintViolated { + get { + return ResourceManager.GetString("CacheAttribute_ParentTypeConstraintViolated", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid cast from {0} to {1}. + /// + internal static string Convert_InvalidCast { + get { + return ResourceManager.GetString("Convert_InvalidCast", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Index has more then one field for the method '{0}.{1}'. Use CompoundValue as the Key type. + /// + internal static string DataAccessor_IndexIsComplex { + get { + return ResourceManager.GetString("DataAccessor_IndexIsComplex", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Key type for the method '{0}.{1}' can be of type object or CompoundValue.. + /// + internal static string DataAccessor_InvalidKeyType { + get { + return ResourceManager.GetString("DataAccessor_InvalidKeyType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Index is not defined for the method '{0}.{1}'.. + /// + internal static string DataAccessor_UnknownIndex { + get { + return ResourceManager.GetString("DataAccessor_UnknownIndex", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DbManager object is not provided.. + /// + internal static string DataAccessorBase_NoDbManager { + get { + return ResourceManager.GetString("DataAccessorBase_NoDbManager", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Key type for the method '{0}.{1}' can be of type object, CompoundValue, or a scalar type.. + /// + internal static string DataAccessorBuilder_BadKeyType { + get { + return ResourceManager.GetString("DataAccessorBuilder_BadKeyType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Can not determine object type for the method '{0}.{1}'. + /// + internal static string DataAccessorBuilder_BadListItemType { + get { + return ResourceManager.GetString("DataAccessorBuilder_BadListItemType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cannot create an instance of the type '{0}'. + /// + internal static string DataAccessorBuilder_CantCreateTypeInstance { + get { + return ResourceManager.GetString("DataAccessorBuilder_CantCreateTypeInstance", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ExecuteNonQuery does not support the Destination attribute. + /// + internal static string DataAccessorBuilder_CantExecuteNonQueryToDestination { + get { + return ResourceManager.GetString("DataAccessorBuilder_CantExecuteNonQueryToDestination", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DataSetTable attribute for method '{0}.{1}' may not be an index. + /// + internal static string DataAccessorBuilder_DataSetTableMustBeByName { + get { + return ResourceManager.GetString("DataAccessorBuilder_DataSetTableMustBeByName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The type '{0}' does not have 'Equals' method. + /// + internal static string DataAccessorBuilder_EqualsMethodIsNotPublic { + get { + return ResourceManager.GetString("DataAccessorBuilder_EqualsMethodIsNotPublic", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The return type '{0}' of the method '{1}' is incompatible with the destination parameter type '{2}'.. + /// + internal static string DataAccessorBuilder_IncompatibleDestinationType { + get { + return ResourceManager.GetString("DataAccessorBuilder_IncompatibleDestinationType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ExecuteScalar destination must be an out or a ref parameter.. + /// + internal static string DataAccessorBuilder_ScalarDestinationIsNotByRef { + get { + return ResourceManager.GetString("DataAccessorBuilder_ScalarDestinationIsNotByRef", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Scalar field name is not defined for the method '{0}.{1}'.. + /// + internal static string DataAccessorBuilder_ScalarFieldNameMissing { + get { + return ResourceManager.GetString("DataAccessorBuilder_ScalarFieldNameMissing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to More then one parameter is marked as destination. + /// + internal static string DataAccessorBuilderTooManyDestinations { + get { + return ResourceManager.GetString("DataAccessorBuilderTooManyDestinations", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No such parameter: '{0}'. + /// + internal static string DataAccessot_ParameterNotFound { + get { + return ResourceManager.GetString("DataAccessot_ParameterNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DataSet must be initialized before calling Update routine. Cannot update database from a null dataset.. + /// + internal static string DbManager_CannotUpdateNullDataset { + get { + return ResourceManager.GetString("DbManager_CannotUpdateNullDataset", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DataTable must be initialized before calling Update routine. Cannot update database from a null data table.. + /// + internal static string DbManager_CannotUpdateNullDataTable { + get { + return ResourceManager.GetString("DbManager_CannotUpdateNullDataTable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The connection does not match the data provider type.. + /// + internal static string DbManager_ConnectionTypeMismatch { + get { + return ResourceManager.GetString("DbManager_ConnectionTypeMismatch", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to dataProvider.ConnectionType must be a valid connection type. + /// + internal static string DbManager_InvalidDataProviderConnectionType { + get { + return ResourceManager.GetString("DbManager_InvalidDataProviderConnectionType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to dataProvider.Name must be a valid string. + /// + internal static string DbManager_InvalidDataProviderName { + get { + return ResourceManager.GetString("DbManager_InvalidDataProviderName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to dataProvider.ProviderName must be a valid string. + /// + internal static string DbManager_InvalidDataProviderProviderName { + get { + return ResourceManager.GetString("DbManager_InvalidDataProviderProviderName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to providerName must be a valid string. + /// + internal static string DbManager_InvalidProviderName { + get { + return ResourceManager.GetString("DbManager_InvalidProviderName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Parameter count does not match Parameter Value count.. + /// + internal static string DbManager_MismatchParameterCount { + get { + return ResourceManager.GetString("DbManager_MismatchParameterCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Both `{0}' and `{1}' data providers are default. + /// + internal static string DbManager_MoreThenOneDefaultProvider { + get { + return ResourceManager.GetString("DbManager_MoreThenOneDefaultProvider", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Only objects of type IDbDataParameter or arrays of IDbDataParameter are supported. + /// + internal static string DbManager_NotDbDataParameter { + get { + return ResourceManager.GetString("DbManager_NotDbDataParameter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The '{0}' key does not exist in the configuration file.. + /// + internal static string DbManager_UnknownConfiguration { + get { + return ResourceManager.GetString("DbManager_UnknownConfiguration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The '{0}' type of the connection could not be recognized.. + /// + internal static string DbManager_UnknownConnectionType { + get { + return ResourceManager.GetString("DbManager_UnknownConnectionType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A suitable data provider is not available for configuration '{0}'.. + /// + internal static string DbManager_UnknownDataProvider { + get { + return ResourceManager.GetString("DbManager_UnknownDataProvider", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The interface must be public.. + /// + internal static string DuckTyping_InterfaceMustBePublic { + get { + return ResourceManager.GetString("DuckTyping_InterfaceMustBePublic", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 'interfaceType' must be an interface.. + /// + internal static string DuckTyping_InterfaceTypeMustBeAnInterface { + get { + return ResourceManager.GetString("DuckTyping_InterfaceTypeMustBeAnInterface", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid number of 'baseObjectTypes' or 'objs'.. + /// + internal static string DuckTyping_InvalidNumberOfObjs { + get { + return ResourceManager.GetString("DuckTyping_InvalidNumberOfObjs", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to '{0}' is not a subtype of '{1}'.. + /// + internal static string DuckTyping_NotASubtypeOf { + get { + return ResourceManager.GetString("DuckTyping_NotASubtypeOf", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Failed to query type '{0}' for method '{1}'.. + /// + internal static string EmitHelper_NoSuchMethod { + get { + return ResourceManager.GetString("EmitHelper_NoSuchMethod", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type '{0}' is not expected.. + /// + internal static string EmitHelper_NotExpectedType { + get { + return ResourceManager.GetString("EmitHelper_NotExpectedType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to MethodInfo can not be changed.. + /// + internal static string InterceptCallInfo_CallMethodInfoIsNotMutable { + get { + return ResourceManager.GetString("InterceptCallInfo_CallMethodInfoIsNotMutable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type '{0}' does not contain field '{1}'.. + /// + internal static string MapIndex_BadField { + get { + return ResourceManager.GetString("MapIndex_BadField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to At least one field name or index must be specified. + /// + internal static string MapIndex_EmptyFields { + get { + return ResourceManager.GetString("MapIndex_EmptyFields", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to At least one field index must be specified. + /// + internal static string MapIndex_EmptyIndices { + get { + return ResourceManager.GetString("MapIndex_EmptyIndices", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to At least one field name must be specified. + /// + internal static string MapIndex_EmptyNames { + get { + return ResourceManager.GetString("MapIndex_EmptyNames", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Can not convert array of type '{0}' to array of '{1}'.. + /// + internal static string MappingSchema_IncompatibleArrayTypes { + get { + return ResourceManager.GetString("MappingSchema_IncompatibleArrayTypes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The index parameter must be greater or equal to zero.. + /// + internal static string NameOrIndexParameter_BadIndex { + get { + return ResourceManager.GetString("NameOrIndexParameter_BadIndex", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Name must be a valid string.. + /// + internal static string NameOrIndexParameter_BadName { + get { + return ResourceManager.GetString("NameOrIndexParameter_BadName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Can not figure out the overloaded method for the method '{0}.{1}'.. + /// + internal static string OverloadAspectBuilder_NoOverloadedMethod { + get { + return ResourceManager.GetString("OverloadAspectBuilder_NoOverloadedMethod", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The '{0}' type does not have appropriate getter. See '{1}' member '{2}' of '{3}' type.. + /// + internal static string TypeBuilder_CannotGetGetter { + get { + return ResourceManager.GetString("TypeBuilder_CannotGetGetter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The '{0}' type does not have appropriate setter. See '{1}' member '{2}' of '{3}' type.. + /// + internal static string TypeBuilder_CannotGetSetter { + get { + return ResourceManager.GetString("TypeBuilder_CannotGetSetter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not build the '{0}' property of the '{1}' type: generic type '{2}' and it's generic parameter types should have only one parameter type.. + /// + internal static string TypeBuilder_GenericShouldBeSingleTyped { + get { + return ResourceManager.GetString("TypeBuilder_GenericShouldBeSingleTyped", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not build the '{0}' type: default constructor not found.. + /// + internal static string TypeBuilder_NoDefaultCtor { + get { + return ResourceManager.GetString("TypeBuilder_NoDefaultCtor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not build the '{0}' property of the '{1}' type: type '{2}' has to have constructor taking type '{3}'.. + /// + internal static string TypeBuilder_PropertyTypeHasNoCtorWithParamType { + get { + return ResourceManager.GetString("TypeBuilder_PropertyTypeHasNoCtorWithParamType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not build the '{0}' property of the '{1}' type: type '{2}' has to have public constructor.. + /// + internal static string TypeBuilder_PropertyTypeHasNoPublicCtor { + get { + return ResourceManager.GetString("TypeBuilder_PropertyTypeHasNoPublicCtor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not build the '{0}' property of the '{1}' type: type '{2}' has to have public default constructor.. + /// + internal static string TypeBuilder_PropertyTypeHasNoPublicDefaultCtor { + get { + return ResourceManager.GetString("TypeBuilder_PropertyTypeHasNoPublicDefaultCtor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type '{0}' must implement required public method '{1}'. + /// + internal static string TypeBuilder_PublicMethodMustBeImplemented { + get { + return ResourceManager.GetString("TypeBuilder_PublicMethodMustBeImplemented", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type '{0}' does not implement public method '{1}'. + /// + internal static string TypeBuilder_PublicMethodNotImplemented { + get { + return ResourceManager.GetString("TypeBuilder_PublicMethodNotImplemented", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The method '{0}' of '{1}' has parameter '{2}' wich can't be handled. Please specify attrbutes [Parent] or [PropertyInfo] to get access to them.. + /// + internal static string TypeBuilder_UnknownParameterType { + get { + return ResourceManager.GetString("TypeBuilder_UnknownParameterType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not build the '{0}' type.. + /// + internal static string TypeFactory_BuildFailed { + get { + return ResourceManager.GetString("TypeFactory_BuildFailed", resourceCulture); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Properties/Resources.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Properties/Resources.resx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The connection does not match the data provider type. + + + A suitable data provider is not available for configuration '{0}'. + + + The '{0}' key does not exist in the configuration file. + + + The '{0}' type of the connection could not be recognized. + + + Only objects of type IDbDataParameter or arrays of IDbDataParameter are supported + + + Parameter count does not match Parameter Value count. + + + dataProvider.Name must be a valid string + + + dataProvider.ProviderName must be a valid string + + + dataProvider.ConnectionType must be a valid connection type + + + providerName must be a valid string + + + DataSet must be initialized before calling Update routine. Cannot update database from a null dataset. + + + DataTable must be initialized before calling Update routine. Cannot update database from a null data table. + + + Type '{0}' is not expected. + + + Failed to query type '{0}' for method '{1}'. + + + Invalid cast from {0} to {1} + + + The '{0}' type does not have appropriate getter. See '{1}' member '{2}' of '{3}' type. + + + The '{0}' type does not have appropriate setter. See '{1}' member '{2}' of '{3}' type. + + + The method '{0}' of '{1}' has parameter '{2}' wich can't be handled. Please specify attrbutes [Parent] or [PropertyInfo] to get access to them. + + + Could not build the '{0}' type: default constructor not found. + + + Could not build the '{0}' property of the '{1}' type: type '{2}' has to have public default constructor. + + + Could not build the '{0}' property of the '{1}' type: type '{2}' has to have public constructor. + + + Could not build the '{0}' property of the '{1}' type: type '{2}' has to have constructor taking type '{3}'. + + + Type '{0}' must implement required public method '{1}' + + + Type '{0}' does not implement public method '{1}' + + + The interface must be public. + + + 'interfaceType' must be an interface. + + + '{0}' is not a subtype of '{1}'. + + + Invalid number of 'baseObjectTypes' or 'objs'. + + + At least one field name must be specified + + + At least one field index must be specified + + + At least one field name or index must be specified + + + Type '{0}' does not contain field '{1}'. + + + Can not convert array of type '{0}' to array of '{1}'. + + + Can not figure out the target method for the method '{0}.{1}'. + + + Can not figure out the overloaded method for the method '{0}.{1}'. + + + Both `{0}' and `{1}' data providers are default + + + Could not build the '{0}' type. + + + The '{0}' must be an interface. + + + Index is not defined for the method '{0}.{1}'. + + + Key type for the method '{0}.{1}' can be of type object or CompoundValue. + + + No such parameter: '{0}' + + + Index has more then one field for the method '{0}.{1}'. Use CompoundValue as the Key type + + + Can not determine object type for the method '{0}.{1}' + + + Key type for the method '{0}.{1}' can be of type object, CompoundValue, or a scalar type. + + + Scalar field name is not defined for the method '{0}.{1}'. + + + More then one parameter is marked as destination + + + DataSetTable attribute for method '{0}.{1}' may not be an index + + + ExecuteNonQuery does not support the Destination attribute + + + ExecuteScalar destination must be an out or a ref parameter. + + + The return type '{0}' of the method '{1}' is incompatible with the destination parameter type '{2}'. + + + Cannot create an instance of the type '{0}' + + + The type '{0}' does not have 'Equals' method + + + Parameter 'cacheAspectType' must be of CacheAspect type + + + MethodInfo can not be changed. + + + Name must be a valid string. + + + The index parameter must be greater or equal to zero. + + + DbManager object is not provided. + + + Could not build the '{0}' property of the '{1}' type: generic type '{2}' and it's generic parameter types should have only one parameter type. + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Properties/Revision.generated.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Properties/Revision.generated.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +// Autogenerated. Do not modify! + +namespace BLToolkit +{ + partial class BLToolkitConstants + { + // + // Revision component of version. + // + public const string Revision = "0"; + } +} diff -r 000000000000 -r f990fcb411a9 Source/Properties/Revision.tt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Properties/Revision.tt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ +<#@ template language="C#v3.5" debug="True" #> +<#@ output extension=".generated.cs" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +// Autogenerated. Do not modify! + +namespace BLToolkit +{ + partial class BLToolkitConstants + { + // + // Revision component of version. + // + public const string Revision = "<#= Revision() #>"; + } +} + +<#+ +string Revision() +{ + try + { + return System.IO.File.ReadAllLines(@"..\..\_svn\entries").ElementAt(3); + } + catch + { + return "0"; + } +} +#> diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Emit/AssemblyBuilderHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Emit/AssemblyBuilderHelper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,315 @@ +using System; +using System.Configuration.Assemblies; +using System.Reflection; +using System.Reflection.Emit; +using System.Security; +using System.Threading; + +namespace BLToolkit.Reflection.Emit +{ + /// + /// A wrapper around the and classes. + /// + /// + /// + /// AssemblyBuilder Class + /// ModuleBuilder Class + public class AssemblyBuilderHelper + { + /// + /// Initializes a new instance of the class + /// with the specified parameters. + /// + /// The path where the assembly will be saved. + public AssemblyBuilderHelper(string path) : this(path, null, null) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified parameters. + /// + /// The path where the assembly will be saved. + /// The assembly version. + /// The key pair file to sign the assembly. + public AssemblyBuilderHelper(string path, Version version, string keyFile) + { + if (path == null) throw new ArgumentNullException("path"); + + var idx = path.IndexOf(','); + + if (idx > 0) + { + path = path.Substring(0, idx); + + if (path.Length >= 200) + { + idx = path.IndexOf('`'); + + if (idx > 0) + { + var idx2 = path.LastIndexOf('.'); + + if (idx2 > 0 && idx2 > idx) + path = path.Substring(0, idx + 1) + path.Substring(idx2 + 1); + } + } + } + + path = path.Replace("+", ".").Replace("<", "_").Replace(">", "_"); + + if (path.Length >= 260) + { + path = path.Substring(0, 248); + + for (var i = 0; i < int.MaxValue; i++) + { + var newPath = string.Format("{0}_{1:0000}.dll", path, i); + + if (!System.IO.File.Exists(newPath)) + { + path = newPath; + break; + } + } + } + + var assemblyName = System.IO.Path.GetFileNameWithoutExtension(path); + var assemblyDir = System.IO.Path.GetDirectoryName(path); + + Path = path; + _assemblyName.Name = assemblyName; + + if (version != null) + _assemblyName.Version = version; + +#if !SILVERLIGHT + + if (!string.IsNullOrEmpty(keyFile)) + { + _assemblyName.Flags |= AssemblyNameFlags.PublicKey; + _assemblyName.KeyPair = new StrongNameKeyPair(System.IO.File.OpenRead(keyFile)); + _assemblyName.HashAlgorithm = AssemblyHashAlgorithm.SHA1; + } + +#endif + +#if DEBUG + _assemblyName.Flags |= AssemblyNameFlags.EnableJITcompileTracking; +#else + _assemblyName.Flags |= AssemblyNameFlags.EnableJITcompileOptimizer; +#endif + + _createAssemblyBuilder = _ => + { +#if SILVERLIGHT + _assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.Run); +#else + _assemblyBuilder = + string.IsNullOrEmpty(assemblyDir)? + Thread.GetDomain().DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.RunAndSave): + Thread.GetDomain().DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.RunAndSave, assemblyDir); +#endif + + _assemblyBuilder.SetCustomAttribute(BLToolkitAttribute); + +#if !SILVERLIGHT + + _assemblyBuilder.SetCustomAttribute( + new CustomAttributeBuilder( + typeof(AllowPartiallyTrustedCallersAttribute) + .GetConstructor(Type.EmptyTypes), + new object[0])); + +#endif + }; + } + + /// + /// Gets the path where the assembly will be saved. + /// + public string Path { get; private set; } + + private readonly AssemblyName _assemblyName = new AssemblyName(); + /// + /// Gets AssemblyName. + /// + public AssemblyName AssemblyName + { + get { return _assemblyName; } + } + + readonly Action _createAssemblyBuilder; + + AssemblyBuilder _assemblyBuilder; + /// + /// Gets AssemblyBuilder. + /// + public AssemblyBuilder AssemblyBuilder + { + get + { + if (_assemblyBuilder == null) + _createAssemblyBuilder(0); + return _assemblyBuilder; + } + } + + /// + /// Gets the path where the assembly will be saved. + /// + public string ModulePath + { + get { return System.IO.Path.GetFileName(Path); } + } + + private ModuleBuilder _moduleBuilder; + /// + /// Gets ModuleBuilder. + /// + public ModuleBuilder ModuleBuilder + { + get + { + if (_moduleBuilder == null) + { + _moduleBuilder = AssemblyBuilder.DefineDynamicModule(ModulePath); + _moduleBuilder.SetCustomAttribute(BLToolkitAttribute); + + } + + return _moduleBuilder; + } + } + + private CustomAttributeBuilder _blToolkitAttribute; + /// + /// Retrieves a cached instance of builder. + /// + public CustomAttributeBuilder BLToolkitAttribute + { + get + { + if (_blToolkitAttribute == null) + { + var at = typeof(TypeBuilder.BLToolkitGeneratedAttribute); + var ci = at.GetConstructor(Type.EmptyTypes); + + _blToolkitAttribute = new CustomAttributeBuilder(ci, new object[0]); + } + + return _blToolkitAttribute; + } + } + + /// + /// Converts the supplied to a . + /// + /// The . + /// An . + public static implicit operator AssemblyBuilder(AssemblyBuilderHelper assemblyBuilder) + { + if (assemblyBuilder == null) throw new ArgumentNullException("assemblyBuilder"); + + return assemblyBuilder.AssemblyBuilder; + } + + /// + /// Converts the supplied to a . + /// + /// The . + /// A . + public static implicit operator ModuleBuilder(AssemblyBuilderHelper assemblyBuilder) + { + if (assemblyBuilder == null) throw new ArgumentNullException("assemblyBuilder"); + + return assemblyBuilder.ModuleBuilder; + } + + /// + /// Saves this dynamic assembly to disk. + /// + public void Save() + { +#if !SILVERLIGHT + + if (_assemblyBuilder != null) + _assemblyBuilder.Save(ModulePath); + +#endif + } + + #region DefineType Overrides + + /// + /// Constructs a for a type with the specified name. + /// + /// The full path of the type. + /// Returns the created . + /// ModuleBuilder.DefineType Method + public TypeBuilderHelper DefineType(string name) + { + return new TypeBuilderHelper(this, ModuleBuilder.DefineType(name)); + } + + /// + /// Constructs a for a type with the specified name and base type. + /// + /// The full path of the type. + /// The Type that the defined type extends. + /// Returns the created . + /// ModuleBuilder.DefineType Method + public TypeBuilderHelper DefineType(string name, Type parent) + { + return new TypeBuilderHelper(this, ModuleBuilder.DefineType(name, TypeAttributes.Public, parent)); + } + + /// + /// Constructs a for a type with the specified name, its attributes, and base type. + /// + /// The full path of the type. + /// The attribute to be associated with the type. + /// The Type that the defined type extends. + /// Returns the created . + /// ModuleBuilder.DefineType Method + public TypeBuilderHelper DefineType(string name, TypeAttributes attrs, Type parent) + { + return new TypeBuilderHelper(this, ModuleBuilder.DefineType(name, attrs, parent)); + } + + /// + /// Constructs a for a type with the specified name, base type, + /// and the interfaces that the defined type implements. + /// + /// The full path of the type. + /// The Type that the defined type extends. + /// The list of interfaces that the type implements. + /// Returns the created . + /// ModuleBuilder.DefineType Method + public TypeBuilderHelper DefineType(string name, Type parent, params Type[] interfaces) + { + return new TypeBuilderHelper( + this, + ModuleBuilder.DefineType(name, TypeAttributes.Public, parent, interfaces)); + } + + /// + /// Constructs a for a type with the specified name, its attributes, base type, + /// and the interfaces that the defined type implements. + /// + /// The full path of the type. + /// The attribute to be associated with the type. + /// The Type that the defined type extends. + /// The list of interfaces that the type implements. + /// Returns the created . + /// ModuleBuilder.DefineType Method + public TypeBuilderHelper DefineType(string name, TypeAttributes attrs, Type parent, params Type[] interfaces) + { + return new TypeBuilderHelper( + this, + ModuleBuilder.DefineType(name, attrs, parent, interfaces)); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Emit/ConstructorBuilderHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Emit/ConstructorBuilderHelper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,62 @@ +using System; +using System.Reflection.Emit; + +namespace BLToolkit.Reflection.Emit +{ + /// + /// A wrapper around the class. + /// + public class ConstructorBuilderHelper : MethodBuilderBase + { + /// + /// Initializes a new instance of the class + /// with the specified parameters. + /// + /// Associated . + /// A + public ConstructorBuilderHelper(TypeBuilderHelper typeBuilder, ConstructorBuilder constructorBuilder) + : base(typeBuilder) + { + if (constructorBuilder == null) throw new ArgumentNullException("constructorBuilder"); + + _constructorBuilder = constructorBuilder; + _constructorBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute); + } + + private readonly ConstructorBuilder _constructorBuilder; + /// + /// Gets ConstructorBuilder. + /// + public ConstructorBuilder ConstructorBuilder + { + get { return _constructorBuilder; } + } + + /// + /// Converts the supplied to a . + /// + /// The . + /// A . + public static implicit operator ConstructorBuilder(ConstructorBuilderHelper constructorBuilder) + { + if (constructorBuilder == null) throw new ArgumentNullException("constructorBuilder"); + + return constructorBuilder.ConstructorBuilder; + } + + private EmitHelper _emitter; + /// + /// Gets . + /// + public override EmitHelper Emitter + { + get + { + if (_emitter == null) + _emitter = new EmitHelper(this, _constructorBuilder.GetILGenerator()); + + return _emitter; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Emit/EmitHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Emit/EmitHelper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3666 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.SymbolStore; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.InteropServices; + +using BLToolkit.Common; +using BLToolkit.Properties; + +// ReSharper disable InconsistentNaming + +namespace BLToolkit.Reflection.Emit +{ + /// + /// A wrapper around the class. + /// + /// + /// + /// ILGenerator Class + public class EmitHelper + { + /// + /// Initializes a new instance of the class + /// with the specified . + /// + /// The to use. + public EmitHelper(ILGenerator ilGenerator) + { + if (ilGenerator == null) throw new ArgumentNullException("ilGenerator"); + + _ilGenerator = ilGenerator; + } + + /// + /// Initializes a new instance of the class + /// with the specified . + /// + /// Associated . + /// The to use. + public EmitHelper(MethodBuilderBase methodBuilder, ILGenerator ilGenerator) + { + if (methodBuilder == null) throw new ArgumentNullException("methodBuilder"); + if (ilGenerator == null) throw new ArgumentNullException("ilGenerator"); + + _method = methodBuilder; + _ilGenerator = ilGenerator; + } + + private readonly MethodBuilderBase _method; + /// + /// Gets . + /// + public MethodBuilderBase Method + { + get { return _method; } + } + + private readonly ILGenerator _ilGenerator; + /// + /// Gets MSIL generator. + /// + public ILGenerator ILGenerator + { + get { return _ilGenerator; } + } + + /// + /// Converts the supplied to a . + /// + /// The . + /// An ILGenerator. + public static implicit operator ILGenerator(EmitHelper emitHelper) + { + if (emitHelper == null) throw new ArgumentNullException("emitHelper"); + + return emitHelper.ILGenerator; + } + + #region ILGenerator Methods + + /// + /// Begins a catch block. + /// + /// The Type object that represents the exception. + /// ILGenerator.BeginCatchBlock Method + public EmitHelper BeginCatchBlock(Type exceptionType) + { + _ilGenerator.BeginCatchBlock(exceptionType); return this; + } + + /// + /// Begins an exception block for a filtered exception. + /// + /// ILGenerator.BeginCatchBlock Method + public EmitHelper BeginExceptFilterBlock() + { + _ilGenerator.BeginExceptFilterBlock(); return this; + } + + /// + /// Begins an exception block for a non-filtered exception. + /// + /// The label for the end of the block. + public Label BeginExceptionBlock() + { + return _ilGenerator.BeginExceptionBlock(); + } + + /// + /// Begins an exception fault block in the Microsoft intermediate language (MSIL) stream. + /// + /// Current instance of the . + public EmitHelper BeginFaultBlock() + { + _ilGenerator.BeginFaultBlock(); return this; + } + + /// + /// Begins a finally block in the Microsoft intermediate language (MSIL) instruction stream. + /// + /// Current instance of the . + public EmitHelper BeginFinallyBlock() + { + _ilGenerator.BeginFinallyBlock(); return this; + } + + /// + /// Begins a lexical scope. + /// + /// Current instance of the . + public EmitHelper BeginScope() + { + _ilGenerator.BeginScope(); return this; + } + + /// + /// Declares a local variable. + /// + /// The Type of the local variable. + /// The declared local variable. + public LocalBuilder DeclareLocal(Type localType) + { + return _ilGenerator.DeclareLocal(localType); + } + + /// + /// Declares a local variable, optionally pinning the object referred to by the variable. + /// + /// The Type of the local variable. + /// true to pin the object in memory; otherwise, false. + /// The declared local variable. + public LocalBuilder DeclareLocal(Type localType, bool pinned) + { + return _ilGenerator.DeclareLocal(localType, pinned); + } + + /// + /// Declares a new label. + /// + /// Returns a new label that can be used as a token for branching. + public Label DefineLabel() + { + return _ilGenerator.DefineLabel(); + } + + /// + /// Ends an exception block. + /// + /// Current instance of the . + public EmitHelper EndExceptionBlock() + { + _ilGenerator.EndExceptionBlock(); return this; + } + + /// + /// Ends a lexical scope. + /// + /// Current instance of the . + public EmitHelper EndScope() + { + _ilGenerator.EndScope(); return this; + } + + /// + /// Marks the Microsoft intermediate language (MSIL) stream's current position + /// with the given label. + /// + /// The label for which to set an index. + /// Current instance of the . + public EmitHelper MarkLabel(Label loc) + { + _ilGenerator.MarkLabel(loc); return this; + } + + /// + /// Marks a sequence point in the Microsoft intermediate language (MSIL) stream. + /// + /// The document for which the sequence point is being defined. + /// The line where the sequence point begins. + /// The column in the line where the sequence point begins. + /// The line where the sequence point ends. + /// The column in the line where the sequence point ends. + /// Current instance of the . + public EmitHelper MarkSequencePoint( + ISymbolDocumentWriter document, + int startLine, + int startColumn, + int endLine, + int endColumn) + { + _ilGenerator.MarkSequencePoint(document, startLine, startColumn, endLine, endColumn); + return this; + } + + /// + /// Emits an instruction to throw an exception. + /// + /// The class of the type of exception to throw. + /// Current instance of the . + public EmitHelper ThrowException(Type exceptionType) + { + _ilGenerator.ThrowException(exceptionType); return this; + } + + /// + /// Specifies the namespace to be used in evaluating locals and watches for + /// the current active lexical scope. + /// + /// The namespace to be used in evaluating locals and watches for the current active lexical scope. + /// Current instance of the . + public EmitHelper UsingNamespace(string namespaceName) + { + _ilGenerator.UsingNamespace(namespaceName); return this; + } + + #endregion + + #region Emit Wrappers + + /// + /// Calls ILGenerator.Emit() that + /// adds two values and pushes the result onto the evaluation stack. + /// + /// OpCodes.Add + /// ILGenerator.Emit + public EmitHelper add + { + get { _ilGenerator.Emit(OpCodes.Add); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// adds two integers, performs an overflow check, and pushes the result onto the evaluation stack. + /// + /// OpCodes.Add_Ovf + /// ILGenerator.Emit + public EmitHelper add_ovf + { + get { _ilGenerator.Emit(OpCodes.Add_Ovf); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// adds two unsigned integer values, performs an overflow check, and pushes the result onto the evaluation stack. + /// + /// OpCodes.Add_Ovf_Un + /// ILGenerator.Emit + public EmitHelper add_ovf_un + { + get { _ilGenerator.Emit(OpCodes.Add_Ovf_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// computes the bitwise AND of two values and pushes the result onto the evalution stack. + /// + /// OpCodes.And + /// ILGenerator.Emit + public EmitHelper and + { + get { _ilGenerator.Emit(OpCodes.And); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// returns an unmanaged pointer to the argument list of the current method. + /// + /// OpCodes.Arglist + /// ILGenerator.Emit + public EmitHelper arglist + { + get { _ilGenerator.Emit(OpCodes.Arglist); return this; } + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction if two values are equal. + /// + /// The label to branch from this location. + /// OpCodes.Beq + /// ILGenerator.Emit + public EmitHelper beq(Label label) + { + _ilGenerator.Emit(OpCodes.Beq, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction (short form) if two values are equal. + /// + /// The label to branch from this location. + /// OpCodes.Beq_S + /// ILGenerator.Emit + public EmitHelper beq_s(Label label) + { + _ilGenerator.Emit(OpCodes.Beq_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction if the first value is greater than or equal to the second value. + /// + /// The label to branch from this location. + /// OpCodes.Bge + /// ILGenerator.Emit + public EmitHelper bge(Label label) + { + _ilGenerator.Emit(OpCodes.Bge, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction (short form) + /// if the first value is greater than or equal to the second value. + /// + /// The label to branch from this location. + /// OpCodes.Bge_S + /// ILGenerator.Emit + public EmitHelper bge_s(Label label) + { + _ilGenerator.Emit(OpCodes.Bge_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction if the the first value is greather than the second value, + /// when comparing unsigned integer values or unordered float values. + /// + /// The label to branch from this location. + /// OpCodes.Bge_Un + /// ILGenerator.Emit + public EmitHelper bge_un(Label label) + { + _ilGenerator.Emit(OpCodes.Bge_Un, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction (short form) if if the the first value is greather than the second value, + /// when comparing unsigned integer values or unordered float values. + /// + /// The label to branch from this location. + /// OpCodes.Bge_Un_S + /// ILGenerator.Emit + public EmitHelper bge_un_s(Label label) + { + _ilGenerator.Emit(OpCodes.Bge_Un_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction if the first value is greater than the second value. + /// + /// The label to branch from this location. + /// OpCodes.Bgt + /// ILGenerator.Emit + public EmitHelper bgt(Label label) + { + _ilGenerator.Emit(OpCodes.Bgt, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction (short form) if the first value is greater than the second value. + /// + /// The label to branch from this location. + /// OpCodes.Bgt_S + /// ILGenerator.Emit + public EmitHelper bgt_s(Label label) + { + _ilGenerator.Emit(OpCodes.Bgt_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction if the first value is greater than the second value, + /// when comparing unsigned integer values or unordered float values. + /// + /// The label to branch from this location. + /// OpCodes.Bgt_Un + /// ILGenerator.Emit + public EmitHelper bgt_un(Label label) + { + _ilGenerator.Emit(OpCodes.Bgt_Un, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction (short form) if the first value is greater than the second value, + /// when comparing unsigned integer values or unordered float values. + /// + /// The label to branch from this location. + /// OpCodes.Bgt_Un_S + /// ILGenerator.Emit + public EmitHelper bgt_un_s(Label label) + { + _ilGenerator.Emit(OpCodes.Bgt_Un_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction if the first value is less than or equal to the second value. + /// + /// The label to branch from this location. + /// OpCodes.Ble + /// ILGenerator.Emit + public EmitHelper ble(Label label) + { + _ilGenerator.Emit(OpCodes.Ble, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction (short form) if the first value is less than or equal to the second value. + /// + /// The label to branch from this location. + /// OpCodes.Ble_S + /// ILGenerator.Emit + public EmitHelper ble_s(Label label) + { + _ilGenerator.Emit(OpCodes.Ble_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction if the first value is less than or equal to the second value, + /// when comparing unsigned integer values or unordered float values. + /// + /// The label to branch from this location. + /// OpCodes.Ble_Un + /// ILGenerator.Emit + public EmitHelper ble_un(Label label) + { + _ilGenerator.Emit(OpCodes.Ble_Un, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction (short form) if the first value is less than or equal to the second value, + /// when comparing unsigned integer values or unordered float values. + /// + /// The label to branch from this location. + /// OpCodes.Ble_Un_S + /// ILGenerator.Emit + public EmitHelper ble_un_s(Label label) + { + _ilGenerator.Emit(OpCodes.Ble_Un_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction if the first value is less than the second value. + /// + /// The label to branch from this location. + /// OpCodes.Blt + /// ILGenerator.Emit + public EmitHelper blt(Label label) + { + _ilGenerator.Emit(OpCodes.Blt, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction (short form) if the first value is less than the second value. + /// + /// The label to branch from this location. + /// OpCodes.Blt_S + /// ILGenerator.Emit + public EmitHelper blt_s(Label label) + { + _ilGenerator.Emit(OpCodes.Blt_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction if the first value is less than the second value, + /// when comparing unsigned integer values or unordered float values. + /// + /// The label to branch from this location. + /// OpCodes.Blt_Un + /// ILGenerator.Emit + public EmitHelper blt_un(Label label) + { + _ilGenerator.Emit(OpCodes.Blt_Un, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction (short form) if the first value is less than the second value, + /// when comparing unsigned integer values or unordered float values. + /// + /// The label to branch from this location. + /// OpCodes.Blt_Un_S + /// ILGenerator.Emit + public EmitHelper blt_un_s(Label label) + { + _ilGenerator.Emit(OpCodes.Blt_Un_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction when two unsigned integer values or unordered float values are not equal. + /// + /// The label to branch from this location. + /// OpCodes.Bne_Un + /// ILGenerator.Emit + public EmitHelper bne_un(Label label) + { + _ilGenerator.Emit(OpCodes.Bne_Un, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction (short form) + /// when two unsigned integer values or unordered float values are not equal. + /// + /// The label to branch from this location. + /// OpCodes.Bne_Un_S + /// ILGenerator.Emit + public EmitHelper bne_un_s(Label label) + { + _ilGenerator.Emit(OpCodes.Bne_Un_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// converts a value type to an object reference. + /// + /// A Type + /// OpCodes.Box + /// ILGenerator.Emit + public EmitHelper box(Type type) + { + _ilGenerator.Emit(OpCodes.Box, type); return this; + } + + /// + /// Converts a value type to an object reference if the value is a value type. + /// + /// A Type + /// OpCodes.Box + /// ILGenerator.Emit + public EmitHelper boxIfValueType(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + return type.IsValueType? box(type): this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// unconditionally transfers control to a target instruction. + /// + /// The label to branch from this location. + /// OpCodes.Br + /// ILGenerator.Emit + public EmitHelper br(Label label) + { + _ilGenerator.Emit(OpCodes.Br, label); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// signals the Common Language Infrastructure (CLI) to inform the debugger that a break point has been tripped. + /// + /// OpCodes.Break + /// ILGenerator.Emit + public EmitHelper @break + { + get { _ilGenerator.Emit(OpCodes.Break); return this; } + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction if value is false, a null reference (Nothing in Visual Basic), or zero. + /// + /// The label to branch from this location. + /// OpCodes.Brfalse + /// ILGenerator.Emit + public EmitHelper brfalse(Label label) + { + _ilGenerator.Emit(OpCodes.Brfalse, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction if value is false, a null reference, or zero. + /// + /// The label to branch from this location. + /// OpCodes.Brfalse_S + /// ILGenerator.Emit + public EmitHelper brfalse_s(Label label) + { + _ilGenerator.Emit(OpCodes.Brfalse_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction if value is true, not null, or non-zero. + /// + /// The label to branch from this location. + /// OpCodes.Brtrue + /// ILGenerator.Emit + public EmitHelper brtrue(Label label) + { + _ilGenerator.Emit(OpCodes.Brtrue, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// transfers control to a target instruction (short form) if value is true, not null, or non-zero. + /// + /// The label to branch from this location. + /// OpCodes.Brtrue_S + /// ILGenerator.Emit + public EmitHelper brtrue_s(Label label) + { + _ilGenerator.Emit(OpCodes.Brtrue_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// unconditionally transfers control to a target instruction (short form). + /// + /// The label to branch from this location. + /// OpCodes.Br_S + /// ILGenerator.Emit + public EmitHelper br_s(Label label) + { + _ilGenerator.Emit(OpCodes.Br_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, methodInfo) that + /// calls the method indicated by the passed method descriptor. + /// + /// The method to be called. + /// OpCodes.Call + /// ILGenerator.Emit + public EmitHelper call(MethodInfo methodInfo) + { + _ilGenerator.Emit(OpCodes.Call, methodInfo); return this; + } + + /// + /// Calls ILGenerator.Emit(, constructorInfo) that + /// calls the method indicated by the passed method descriptor. + /// + /// The constructor to be called. + /// OpCodes.Call + /// ILGenerator.Emit + public EmitHelper call(ConstructorInfo constructorInfo) + { + _ilGenerator.Emit(OpCodes.Call, constructorInfo); return this; + } + + /// + /// Calls ILGenerator.EmitCall(, methodInfo, optionalParameterTypes) that + /// calls the method indicated by the passed method descriptor. + /// + /// The method to be called. + /// The types of the optional arguments if the method is a varargs method. + /// OpCodes.Call + /// ILGenerator.EmitCall + public EmitHelper call(MethodInfo methodInfo, Type[] optionalParameterTypes) + { + _ilGenerator.EmitCall(OpCodes.Call, methodInfo, optionalParameterTypes); return this; + } + + /// + /// Calls ILGenerator.EmitCall(, methodInfo, optionalParameterTypes) that + /// calls the method indicated by the passed method descriptor. + /// + /// A Type + /// The name of the method to be called. + /// The types of the optional arguments if the method is a varargs method. + /// OpCodes.Call + /// ILGenerator.EmitCall + public EmitHelper call(Type type, string methodName, params Type[] optionalParameterTypes) + { + if (type == null) throw new ArgumentNullException("type"); + + MethodInfo methodInfo = type.GetMethod(methodName, optionalParameterTypes); + + if (methodInfo == null) + throw CreateNoSuchMethodException(type, methodName); + + return call(methodInfo); + } + + /// + /// Calls ILGenerator.EmitCall(, methodInfo, optionalParameterTypes) that + /// calls the method indicated by the passed method descriptor. + /// + /// A Type + /// The name of the method to be called. + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// The types of the optional arguments if the method is a varargs method. + /// OpCodes.Call + /// ILGenerator.EmitCall + public EmitHelper call(Type type, string methodName, BindingFlags flags, params Type[] optionalParameterTypes) + { + if (type == null) throw new ArgumentNullException("type"); + + MethodInfo methodInfo = type.GetMethod(methodName, flags, null, optionalParameterTypes, null); + + if (methodInfo == null) + throw CreateNoSuchMethodException(type, methodName); + + return call(methodInfo); + } + +#if !SILVERLIGHT + + /// + /// Calls ILGenerator.EmitCalli(, , Type, Type[]) that + /// calls the method indicated on the evaluation stack (as a pointer to an entry point) + /// with arguments described by a calling convention using an unmanaged calling convention. + /// + /// The unmanaged calling convention to be used. + /// The Type of the result. + /// The types of the required arguments to the instruction. + /// OpCodes.Calli + /// ILGenerator.EmitCalli + public EmitHelper calli(CallingConvention unmanagedCallConv, Type returnType, Type[] parameterTypes) + { + _ilGenerator.EmitCalli(OpCodes.Calli, unmanagedCallConv, returnType, parameterTypes); + return this; + } + + /// + /// Calls ILGenerator.EmitCalli(, , Type, Type[], Type[]) that + /// calls the method indicated on the evaluation stack (as a pointer to an entry point) + /// with arguments described by a calling convention using a managed calling convention. + /// + /// The managed calling convention to be used. + /// The Type of the result. + /// The types of the required arguments to the instruction. + /// The types of the optional arguments for vararg calls. + /// OpCodes.Calli + /// ILGenerator.EmitCalli + public EmitHelper calli(CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes) + { + _ilGenerator.EmitCalli(OpCodes.Calli, callingConvention, returnType, parameterTypes, optionalParameterTypes); + return this; + } + +#endif + + /// + /// Calls ILGenerator.Emit(, methodInfo) that + /// calls a late-bound method on an object, pushing the return value onto the evaluation stack. + /// + /// The method to be called. + /// OpCodes.Callvirt + /// ILGenerator.Emit + public EmitHelper callvirt(MethodInfo methodInfo) + { + _ilGenerator.Emit(OpCodes.Callvirt, methodInfo); return this; + } + + /// + /// Calls ILGenerator.EmitCall(, methodInfo, optionalParameterTypes) that + /// calls a late-bound method on an object, pushing the return value onto the evaluation stack. + /// + /// The method to be called. + /// The types of the optional arguments if the method is a varargs method. + /// OpCodes.Callvirt + /// ILGenerator.EmitCall + public EmitHelper callvirt(MethodInfo methodInfo, Type[] optionalParameterTypes) + { + _ilGenerator.EmitCall(OpCodes.Callvirt, methodInfo, optionalParameterTypes); return this; + } + + /// + /// Calls ILGenerator.EmitCall(, methodInfo, optionalParameterTypes) that + /// calls a late-bound method on an object, pushing the return value onto the evaluation stack. + /// + /// The method to be called. + /// The declaring type of the method. + /// The types of the optional arguments if the method is a varargs method. + /// OpCodes.Callvirt + /// ILGenerator.EmitCall + public EmitHelper callvirt(Type type, string methodName, params Type[] optionalParameterTypes) + { + if (type == null) throw new ArgumentNullException("type"); + + MethodInfo methodInfo = type.GetMethod(methodName, optionalParameterTypes); + + if (methodInfo == null) + throw CreateNoSuchMethodException(type, methodName); + + return callvirt(methodInfo); + } + + /// + /// Calls ILGenerator.EmitCall(, methodInfo, optionalParameterTypes) that + /// calls a late-bound method on an object, pushing the return value onto the evaluation stack. + /// + /// The method to be called. + /// The declaring type of the method. + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// The types of the optional arguments if the method is a varargs method. + /// OpCodes.Callvirt + /// ILGenerator.EmitCall + public EmitHelper callvirt(Type type, string methodName, BindingFlags flags, params Type[] optionalParameterTypes) + { + MethodInfo methodInfo = + optionalParameterTypes == null? + type.GetMethod(methodName, flags): + type.GetMethod(methodName, flags, null, optionalParameterTypes, null); + + if (methodInfo == null) + throw CreateNoSuchMethodException(type, methodName); + + return callvirt(methodInfo, null); + } + + /// + /// Calls ILGenerator.EmitCall(, methodInfo, optionalParameterTypes) that + /// calls a late-bound method on an object, pushing the return value onto the evaluation stack. + /// + /// The method to be called. + /// The declaring type of the method. + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// OpCodes.Callvirt + /// ILGenerator.EmitCall + public EmitHelper callvirt(Type type, string methodName, BindingFlags flags) + { + return callvirt(type, methodName, flags, null); + } + + /// + /// Calls ILGenerator.EmitCall(, methodInfo, optionalParameterTypes) that + /// calls a late-bound method on an object, pushing the return value onto the evaluation stack. + /// + /// The non-generic method to be called. + /// The declaring type of the method. + /// The types of the optional arguments if the method is a varargs method. + /// OpCodes.Callvirt + /// ILGenerator.EmitCall + public EmitHelper callvirtNoGenerics(Type type, string methodName, params Type[] optionalParameterTypes) + { + MethodInfo methodInfo = type.GetMethod( + methodName, + BindingFlags.Instance | BindingFlags.Public, + GenericBinder.NonGeneric, + optionalParameterTypes, null); + + if (methodInfo == null) + throw CreateNoSuchMethodException(type, methodName); + + return callvirt(methodInfo); + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// attempts to cast an object passed by reference to the specified class. + /// + /// A Type + /// OpCodes.Castclass + /// ILGenerator.Emit + public EmitHelper castclass(Type type) + { + _ilGenerator.Emit(OpCodes.Castclass, type); return this; + } + + /// + /// Attempts to cast an object passed by reference to the specified class + /// or to unbox if the type is a value type. + /// + /// A Type + public EmitHelper castType(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + return type.IsValueType? unbox_any(type): castclass(type); + } + + /// + /// Calls ILGenerator.Emit() that + /// compares two values. If they are equal, the integer value 1 (int32) is pushed onto the evaluation stack; + /// otherwise 0 (int32) is pushed onto the evaluation stack. + /// + /// OpCodes.Ceq + /// ILGenerator.Emit + public EmitHelper ceq + { + get { _ilGenerator.Emit(OpCodes.Ceq); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// compares two values. If the first value is greater than the second, + /// the integer value 1 (int32) is pushed onto the evaluation stack; + /// otherwise 0 (int32) is pushed onto the evaluation stack. + /// + /// OpCodes.Cgt + /// ILGenerator.Emit + public EmitHelper cgt + { + get { _ilGenerator.Emit(OpCodes.Cgt); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// compares two unsigned or unordered values. + /// If the first value is greater than the second, the integer value 1 (int32) is pushed onto the evaluation stack; + /// otherwise 0 (int32) is pushed onto the evaluation stack. + /// + /// OpCodes.Cgt_Un + /// ILGenerator.Emit + public EmitHelper cgt_un + { + get { _ilGenerator.Emit(OpCodes.Cgt_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// constrains the type on which a virtual method call is made. + /// + /// A Type + /// OpCodes.Constrained + /// ILGenerator.Emit + public EmitHelper constrained(Type type) + { + _ilGenerator.Emit(OpCodes.Constrained, type); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// throws if value is not a finite number. + /// + /// OpCodes.Ckfinite + /// ILGenerator.Emit + public EmitHelper ckfinite + { + get { _ilGenerator.Emit(OpCodes.Ckfinite); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// compares two values. If the first value is less than the second, + /// the integer value 1 (int32) is pushed onto the evaluation stack; + /// otherwise 0 (int32) is pushed onto the evaluation stack. + /// + /// OpCodes.Clt + /// ILGenerator.Emit + public EmitHelper clt + { + get { _ilGenerator.Emit(OpCodes.Clt); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// compares the unsigned or unordered values value1 and value2. + /// If value1 is less than value2, then the integer value 1 (int32) is pushed onto the evaluation stack; + /// otherwise 0 (int32) is pushed onto the evaluation stack. + /// + /// OpCodes.Clt_Un + /// ILGenerator.Emit + public EmitHelper clt_un + { + get { _ilGenerator.Emit(OpCodes.Clt_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the value on top of the evaluation stack to natural int. + /// + /// OpCodes.Conv_I + /// ILGenerator.Emit + public EmitHelper conv_i + { + get { _ilGenerator.Emit(OpCodes.Conv_I); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the value on top of the evaluation stack to int8, then extends (pads) it to int32. + /// + /// OpCodes.Conv_I1 + /// ILGenerator.Emit + public EmitHelper conv_i1 + { + get { _ilGenerator.Emit(OpCodes.Conv_I1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the value on top of the evaluation stack to int16, then extends (pads) it to int32. + /// + /// OpCodes.Conv_I2 + /// ILGenerator.Emit + public EmitHelper conv_i2 + { + get { _ilGenerator.Emit(OpCodes.Conv_I2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the value on top of the evaluation stack to int32. + /// + /// OpCodes.Conv_I4 + /// ILGenerator.Emit + public EmitHelper conv_i4 + { + get { _ilGenerator.Emit(OpCodes.Conv_I4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the value on top of the evaluation stack to int64. + /// + /// OpCodes.Conv_I8 + /// ILGenerator.Emit + public EmitHelper conv_i8 + { + get { _ilGenerator.Emit(OpCodes.Conv_I8); return this; } + } + + /// + /// Converts the value on top of the evaluation stack to the specified type. + /// + /// ILGenerator.Emit + public EmitHelper conv(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + switch (Type.GetTypeCode(type)) + { + case TypeCode.Boolean: + case TypeCode.SByte: conv_i1.end(); break; + case TypeCode.Int16: conv_i2.end(); break; + case TypeCode.Int32: conv_i4.end(); break; + case TypeCode.Int64: conv_i8.end(); break; + + case TypeCode.Byte: conv_u1.end(); break; + case TypeCode.Char: + case TypeCode.UInt16: conv_u2.end(); break; + case TypeCode.UInt32: conv_u4.end(); break; + case TypeCode.UInt64: conv_u8.end(); break; + + case TypeCode.Single: conv_r4.end(); break; + case TypeCode.Double: conv_r8.end(); break; + + default: + { + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + ConstructorInfo ci = type.GetConstructor(type.GetGenericArguments()); + if (ci != null) + { + newobj(ci); + break; + } + } + + throw CreateNotExpectedTypeException(type); + } + } + + return this; + } + + + /// + /// Calls ILGenerator.Emit() that + /// converts the signed value on top of the evaluation stack to signed natural int, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_I + /// ILGenerator.Emit + public EmitHelper conv_ovf_i + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_I); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the signed value on top of the evaluation stack to signed int8 and extends it to int32, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_I1 + /// ILGenerator.Emit + public EmitHelper conv_ovf_i1 + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_I1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the unsigned value on top of the evaluation stack to signed int8 and extends it to int32, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_I1_Un + /// ILGenerator.Emit + public EmitHelper conv_ovf_i1_un + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_I1_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the signed value on top of the evaluation stack to signed int16 and extending it to int32, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_I2 + /// ILGenerator.Emit + public EmitHelper conv_ovf_i2 + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_I2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the unsigned value on top of the evaluation stack to signed int16 and extends it to int32, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_I2_Un + /// ILGenerator.Emit + public EmitHelper conv_ovf_i2_un + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_I2_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the signed value on top of the evaluation tack to signed int32, throwing on overflow. + /// + /// OpCodes.Conv_Ovf_I4 + /// ILGenerator.Emit + public EmitHelper conv_ovf_i4 + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_I2_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the unsigned value on top of the evaluation stack to signed int32, throwing on overflow. + /// + /// OpCodes.Conv_Ovf_I4_Un + /// ILGenerator.Emit + public EmitHelper conv_ovf_i4_un + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_I4_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the signed value on top of the evaluation stack to signed int64, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_I8 + /// ILGenerator.Emit + public EmitHelper conv_ovf_i8 + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_I8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the unsigned value on top of the evaluation stack to signed int64, throwing on overflow. + /// + /// OpCodes.Conv_Ovf_I8_Un + /// ILGenerator.Emit + public EmitHelper conv_ovf_i8_un + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_I8_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the unsigned value on top of the evaluation stack to signed natural int, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_I_Un + /// ILGenerator.Emit + public EmitHelper conv_ovf_i_un + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_I_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the signed value on top of the evaluation stack to unsigned natural int, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_U + /// ILGenerator.Emit + public EmitHelper conv_ovf_u + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_U); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the signed value on top of the evaluation stack to unsigned int8 and extends it to int32, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_U1 + /// ILGenerator.Emit + public EmitHelper conv_ovf_u1 + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_U1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the unsigned value on top of the evaluation stack to unsigned int8 and extends it to int32, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_U1_Un + /// ILGenerator.Emit + public EmitHelper conv_ovf_u1_un + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_U1_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the signed value on top of the evaluation stack to unsigned int16 and extends it to int32, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_U2 + /// ILGenerator.Emit + public EmitHelper conv_ovf_u2 + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_U2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the unsigned value on top of the evaluation stack to unsigned int16 and extends it to int32, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_U2_Un + /// ILGenerator.Emit + public EmitHelper conv_ovf_u2_un + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_U2_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// Converts the signed value on top of the evaluation stack to unsigned int32, throwing on overflow. + /// + /// OpCodes.Conv_Ovf_U4 + /// ILGenerator.Emit + public EmitHelper conv_ovf_u4 + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_U4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the unsigned value on top of the evaluation stack to unsigned int32, throwing on overflow. + /// + /// OpCodes.Conv_Ovf_U4_Un + /// ILGenerator.Emit + public EmitHelper conv_ovf_u4_un + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_U4_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the signed value on top of the evaluation stack to unsigned int64, throwing on overflow. + /// + /// OpCodes.Conv_Ovf_U8 + /// ILGenerator.Emit + public EmitHelper conv_ovf_u8 + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_U8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the unsigned value on top of the evaluation stack to unsigned int64, throwing on overflow. + /// + /// OpCodes.Conv_Ovf_U8_Un + /// ILGenerator.Emit + public EmitHelper conv_ovf_u8_un + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_U8_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the unsigned value on top of the evaluation stack to unsigned natural int, + /// throwing on overflow. + /// + /// OpCodes.Conv_Ovf_U_Un + /// ILGenerator.Emit + public EmitHelper conv_ovf_u_un + { + get { _ilGenerator.Emit(OpCodes.Conv_Ovf_U_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the value on top of the evaluation stack to float32. + /// + /// OpCodes.Conv_R4 + /// ILGenerator.Emit + public EmitHelper conv_r4 + { + get { _ilGenerator.Emit(OpCodes.Conv_R4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the value on top of the evaluation stack to float64. + /// + /// OpCodes.Conv_R8 + /// ILGenerator.Emit + public EmitHelper conv_r8 + { + get { _ilGenerator.Emit(OpCodes.Conv_R8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the unsigned integer value on top of the evaluation stack to float32. + /// + /// OpCodes.Conv_R_Un + /// ILGenerator.Emit + public EmitHelper conv_r_un + { + get { _ilGenerator.Emit(OpCodes.Conv_R_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the value on top of the evaluation stack to unsigned natural int, and extends it to natural int. + /// + /// OpCodes.Conv_U + /// ILGenerator.Emit + public EmitHelper conv_u + { + get { _ilGenerator.Emit(OpCodes.Conv_U); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the value on top of the evaluation stack to unsigned int8, and extends it to int32. + /// + /// OpCodes.Conv_U1 + /// ILGenerator.Emit + public EmitHelper conv_u1 + { + get { _ilGenerator.Emit(OpCodes.Conv_U1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the value on top of the evaluation stack to unsigned int16, and extends it to int32. + /// + /// OpCodes.Conv_U2 + /// ILGenerator.Emit + public EmitHelper conv_u2 + { + get { _ilGenerator.Emit(OpCodes.Conv_U2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the value on top of the evaluation stack to unsigned int32, and extends it to int32. + /// + /// OpCodes.Conv_U4 + /// ILGenerator.Emit + public EmitHelper conv_u4 + { + get { _ilGenerator.Emit(OpCodes.Conv_U4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// converts the value on top of the evaluation stack to unsigned int64, and extends it to int64. + /// + /// OpCodes.Conv_U8 + /// ILGenerator.Emit + public EmitHelper conv_u8 + { + get { _ilGenerator.Emit(OpCodes.Conv_U8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// copies a specified number bytes from a source address to a destination address. + /// + /// OpCodes.Cpblk + /// ILGenerator.Emit + public EmitHelper cpblk + { + get { _ilGenerator.Emit(OpCodes.Cpblk); return this; } + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// copies the value type located at the address of an object (type &, * or natural int) + /// to the address of the destination object (type &, * or natural int). + /// + /// A Type + /// OpCodes.Cpobj + /// ILGenerator.Emit + public EmitHelper cpobj(Type type) + { + _ilGenerator.Emit(OpCodes.Cpobj, type); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// divides two values and pushes the result as a floating-point (type F) or + /// quotient (type int32) onto the evaluation stack. + /// + /// OpCodes.Div + /// ILGenerator.Emit + public EmitHelper div + { + get { _ilGenerator.Emit(OpCodes.Div); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// divides two unsigned integer values and pushes the result (int32) onto the evaluation stack. + /// + /// OpCodes.Div_Un + /// ILGenerator.Emit + public EmitHelper div_un + { + get { _ilGenerator.Emit(OpCodes.Div_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// copies the current topmost value on the evaluation stack, and then pushes the copy onto the evaluation stack. + /// + /// OpCodes.Dup + /// ILGenerator.Emit + public EmitHelper dup + { + get { _ilGenerator.Emit(OpCodes.Dup); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// transfers control from the filter clause of an exception back to + /// the Common Language Infrastructure (CLI) exception handler. + /// + /// OpCodes.Endfilter + /// ILGenerator.Emit + public EmitHelper endfilter + { + get { _ilGenerator.Emit(OpCodes.Endfilter); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// transfers control from the fault or finally clause of an exception block back to + /// the Common Language Infrastructure (CLI) exception handler. + /// + /// OpCodes.Endfinally + /// ILGenerator.Emit + public EmitHelper endfinally + { + get { _ilGenerator.Emit(OpCodes.Endfinally); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// initializes a specified block of memory at a specific address to a given size and initial value. + /// + /// OpCodes.Initblk + /// ILGenerator.Emit + public EmitHelper initblk + { + get { _ilGenerator.Emit(OpCodes.Initblk); return this; } + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// initializes all the fields of the object at a specific address to a null reference or + /// a 0 of the appropriate primitive type. + /// + /// A Type + /// OpCodes.Initobj + /// ILGenerator.Emit + public EmitHelper initobj(Type type) + { + _ilGenerator.Emit(OpCodes.Initobj, type); return this; + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// tests whether an object reference (type O) is an instance of a particular class. + /// + /// A Type + /// OpCodes.Isinst + /// ILGenerator.Emit + public EmitHelper isinst(Type type) + { + _ilGenerator.Emit(OpCodes.Isinst, type); return this; + } + + /// + /// Calls ILGenerator.Emit(, methodInfo) that + /// exits current method and jumps to specified method. + /// + /// The method to be jumped. + /// OpCodes.Jmp + /// ILGenerator.Emit + public EmitHelper jmp(MethodInfo methodInfo) + { + _ilGenerator.Emit(OpCodes.Jmp, methodInfo); return this; + } + + /// + /// Calls ILGenerator.Emit(, short) that + /// loads an argument (referenced by a specified index value) onto the stack. + /// + /// Index of the argument that is pushed onto the stack. + /// OpCodes.Ldarg + /// ILGenerator.Emit + public EmitHelper ldarg(short index) + { + _ilGenerator.Emit(OpCodes.Ldarg, index); return this; + } + + /// + /// Loads an argument onto the stack. + /// + /// A representing a parameter. + /// True, if parameter must be converted to a reference. + /// + public EmitHelper ldargEx(ParameterInfo parameterInfo, bool box) + { + ldarg(parameterInfo); + + Type type = parameterInfo.ParameterType; + + if (parameterInfo.ParameterType.IsByRef) + type = parameterInfo.ParameterType.GetElementType(); + + if (parameterInfo.ParameterType.IsByRef) + { + if (type.IsValueType && type.IsPrimitive == false) + ldobj(type); + else + ldind(type); + } + + if (box) + boxIfValueType(type); + + return this; + } + + /// + /// Calls ILGenerator.Emit(, short) or + /// ILGenerator.Emit(, byte) that + /// loads an argument (referenced by a specified index value) onto the stack. + /// + /// Index of the argument that is pushed onto the stack. + /// OpCodes.Ldarg + /// ILGenerator.Emit + public EmitHelper ldarg(int index) + { + switch (index) + { + case 0: ldarg_0.end(); break; + case 1: ldarg_1.end(); break; + case 2: ldarg_2.end(); break; + case 3: ldarg_3.end(); break; + default: + if (index <= byte. MaxValue) ldarg_s((byte)index); + else if (index <= short.MaxValue) ldarg ((short)index); + else + throw new ArgumentOutOfRangeException("index"); + + break; + } + + return this; + } + + /// + /// Loads an argument onto the stack. + /// + /// A representing a parameter. + public EmitHelper ldarg(ParameterInfo parameterInfo) + { + if (parameterInfo == null) throw new ArgumentNullException("parameterInfo"); + + bool isStatic = + Method is MethodBuilderHelper && ((MethodBuilderHelper)Method).MethodBuilder.IsStatic; + + return ldarg(parameterInfo.Position + (isStatic? 0: 1)); + } + + /// + /// Calls ILGenerator.Emit(, short) that + /// load an argument address onto the evaluation stack. + /// + /// Index of the address addr of the argument that is pushed onto the stack. + /// OpCodes.Ldarga + /// ILGenerator.Emit + public EmitHelper ldarga(short index) + { + _ilGenerator.Emit(OpCodes.Ldarga, index); return this; + } + + /// + /// Calls ILGenerator.Emit(, byte) that + /// load an argument address, in short form, onto the evaluation stack. + /// + /// Index of the address addr of the argument that is pushed onto the stack. + /// OpCodes.Ldarga_S + /// ILGenerator.Emit + public EmitHelper ldarga_s(byte index) + { + _ilGenerator.Emit(OpCodes.Ldarga_S, index); return this; + } + + /// + /// Load an argument address onto the evaluation stack. + /// + /// Index of the address addr of the argument that is pushed onto the stack. + public EmitHelper ldarga(int index) + { + if (index <= byte. MaxValue) ldarga_s((byte)index); + else if (index <= short.MaxValue) ldarga ((short)index); + else + throw new ArgumentOutOfRangeException("index"); + + return this; + } + + /// + /// Loads an argument address onto the stack. + /// + /// A representing a parameter. + public EmitHelper ldarga(ParameterInfo parameterInfo) + { + if (parameterInfo == null) throw new ArgumentNullException("parameterInfo"); + + bool isStatic = + Method is MethodBuilderHelper && ((MethodBuilderHelper)Method).MethodBuilder.IsStatic; + + return ldarga(parameterInfo.Position + (isStatic? 0: 1)); + } + + + /// + /// Calls ILGenerator.Emit() that + /// loads the argument at index 0 onto the evaluation stack. + /// + /// OpCodes.Ldarg_0 + /// ILGenerator.Emit + public EmitHelper ldarg_0 + { + get { _ilGenerator.Emit(OpCodes.Ldarg_0); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the argument at index 1 onto the evaluation stack. + /// + /// OpCodes.Ldarg_1 + /// ILGenerator.Emit + public EmitHelper ldarg_1 + { + get { _ilGenerator.Emit(OpCodes.Ldarg_1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the argument at index 2 onto the evaluation stack. + /// + /// OpCodes.Ldarg_2 + /// ILGenerator.Emit + public EmitHelper ldarg_2 + { + get { _ilGenerator.Emit(OpCodes.Ldarg_2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the argument at index 3 onto the evaluation stack. + /// + /// OpCodes.Ldarg_3 + /// ILGenerator.Emit + public EmitHelper ldarg_3 + { + get { _ilGenerator.Emit(OpCodes.Ldarg_3); return this; } + } + + /// + /// Calls ILGenerator.Emit(, byte) that + /// loads the argument (referenced by a specified short form index) onto the evaluation stack. + /// + /// Index of the argument value that is pushed onto the stack. + /// OpCodes.Ldarg_S + /// ILGenerator.Emit + public EmitHelper ldarg_s(byte index) + { + _ilGenerator.Emit(OpCodes.Ldarg_S, index); return this; + } + + /// + /// Calls ILGenerator.Emit( or ) that + /// pushes a supplied value of type int32 onto the evaluation stack as an int32. + /// + /// The value pushed onto the stack. + /// OpCodes.Ldc_I4_0 + /// OpCodes.Ldc_I4_1 + /// ILGenerator.Emit + public EmitHelper ldc_bool(bool b) + { + _ilGenerator.Emit(b? OpCodes.Ldc_I4_1: OpCodes.Ldc_I4_0); return this; + } + + /// + /// Calls ILGenerator.Emit(, int) that + /// pushes a supplied value of type int32 onto the evaluation stack as an int32. + /// + /// The value pushed onto the stack. + /// OpCodes.Ldc_I4 + /// ILGenerator.Emit + public EmitHelper ldc_i4(int num) + { + _ilGenerator.Emit(OpCodes.Ldc_I4, num); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// pushes the integer value of 0 onto the evaluation stack as an int32. + /// + /// OpCodes.Ldc_I4_0 + /// ILGenerator.Emit + public EmitHelper ldc_i4_0 + { + get { _ilGenerator.Emit(OpCodes.Ldc_I4_0); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// pushes the integer value of 1 onto the evaluation stack as an int32. + /// + /// OpCodes.Ldc_I4_1 + /// ILGenerator.Emit + public EmitHelper ldc_i4_1 + { + get { _ilGenerator.Emit(OpCodes.Ldc_I4_1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// pushes the integer value of 2 onto the evaluation stack as an int32. + /// + /// OpCodes.Ldc_I4_2 + /// ILGenerator.Emit + public EmitHelper ldc_i4_2 + { + get { _ilGenerator.Emit(OpCodes.Ldc_I4_2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// pushes the integer value of 3 onto the evaluation stack as an int32. + /// + /// OpCodes.Ldc_I4_3 + /// ILGenerator.Emit + public EmitHelper ldc_i4_3 + { + get { _ilGenerator.Emit(OpCodes.Ldc_I4_3); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// pushes the integer value of 4 onto the evaluation stack as an int32. + /// + /// OpCodes.Ldc_I4_4 + /// ILGenerator.Emit + public EmitHelper ldc_i4_4 + { + get { _ilGenerator.Emit(OpCodes.Ldc_I4_4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// pushes the integer value of 5 onto the evaluation stack as an int32. + /// + /// OpCodes.Ldc_I4_0 + /// ILGenerator.Emit + public EmitHelper ldc_i4_5 + { + get { _ilGenerator.Emit(OpCodes.Ldc_I4_5); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// pushes the integer value of 6 onto the evaluation stack as an int32. + /// + /// OpCodes.Ldc_I4_6 + /// ILGenerator.Emit + public EmitHelper ldc_i4_6 + { + get { _ilGenerator.Emit(OpCodes.Ldc_I4_6); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// pushes the integer value of 7 onto the evaluation stack as an int32. + /// + /// OpCodes.Ldc_I4_7 + /// ILGenerator.Emit + public EmitHelper ldc_i4_7 + { + get { _ilGenerator.Emit(OpCodes.Ldc_I4_7); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// pushes the integer value of 8 onto the evaluation stack as an int32. + /// + /// OpCodes.Ldc_I4_8 + /// ILGenerator.Emit + public EmitHelper ldc_i4_8 + { + get { _ilGenerator.Emit(OpCodes.Ldc_I4_8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// pushes the integer value of -1 onto the evaluation stack as an int32. + /// + /// OpCodes.Ldc_I4_M1 + /// ILGenerator.Emit + public EmitHelper ldc_i4_m1 + { + get { _ilGenerator.Emit(OpCodes.Ldc_I4_M1); return this; } + } + + /// + /// Calls the best form of ILGenerator.Emit(Ldc_I4_X) that + /// pushes the integer value of -1 onto the evaluation stack as an int32. + /// + /// + public EmitHelper ldc_i4_(int num) + { + switch (num) + { + case -1: ldc_i4_m1.end(); break; + case 0: ldc_i4_0. end(); break; + case 1: ldc_i4_1. end(); break; + case 2: ldc_i4_2. end(); break; + case 3: ldc_i4_3. end(); break; + case 4: ldc_i4_4. end(); break; + case 5: ldc_i4_5. end(); break; + case 6: ldc_i4_6. end(); break; + case 7: ldc_i4_7. end(); break; + case 8: ldc_i4_8. end(); break; + default: + if (num >= sbyte.MinValue && num <= sbyte.MaxValue) + ldc_i4_s((sbyte)num); + else + ldc_i4 (num); + + break; + } + + return this; + } + + /// + /// Calls ILGenerator.Emit(, byte) that + /// pushes the supplied int8 value onto the evaluation stack as an int32, short form. + /// + /// The value pushed onto the stack. + /// OpCodes.Ldc_I4_S + /// ILGenerator.Emit + [CLSCompliant(false)] + public EmitHelper ldc_i4_s(sbyte num) + { + _ilGenerator.Emit(OpCodes.Ldc_I4_S, num); return this; + } + + /// + /// Calls ILGenerator.Emit(, long) that + /// pushes a supplied value of type int64 onto the evaluation stack as an int64. + /// + /// The value pushed onto the stack. + /// OpCodes.Ldc_I8 + /// ILGenerator.Emit + public EmitHelper ldc_i8(long num) + { + _ilGenerator.Emit(OpCodes.Ldc_I8, num); return this; + } + + /// + /// Calls ILGenerator.Emit(, float) that + /// pushes a supplied value of type float32 onto the evaluation stack as type F (float). + /// + /// The value pushed onto the stack. + /// OpCodes.Ldc_R4 + /// ILGenerator.Emit + public EmitHelper ldc_r4(float num) + { + _ilGenerator.Emit(OpCodes.Ldc_R4, num); return this; + } + + /// + /// Calls ILGenerator.Emit(, double) that + /// pushes a supplied value of type float64 onto the evaluation stack as type F (float). + /// + /// The value pushed onto the stack. + /// OpCodes.Ldc_R8 + /// ILGenerator.Emit + public EmitHelper ldc_r8(double num) + { + _ilGenerator.Emit(OpCodes.Ldc_R8, num); return this; + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// loads the address of the array element at a specified array index onto the top of the evaluation stack + /// as type & (managed pointer). + /// + /// A Type + /// OpCodes.Ldelema + /// ILGenerator.Emit + public EmitHelper ldelema(Type type) + { + _ilGenerator.Emit(OpCodes.Ldelema, type); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the element with type natural int at a specified array index onto the top of the evaluation stack + /// as a natural int. + /// + /// OpCodes.Ldelem_I + /// ILGenerator.Emit + public EmitHelper ldelem_i + { + get { _ilGenerator.Emit(OpCodes.Ldelem_I); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the element with type int8 at a specified array index onto the top of the evaluation stack as an int32. + /// + /// OpCodes.Ldelem_I1 + /// ILGenerator.Emit + public EmitHelper ldelem_i1 + { + get { _ilGenerator.Emit(OpCodes.Ldelem_I1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the element with type int16 at a specified array index onto the top of the evaluation stack as an int32. + /// + /// OpCodes.Ldelem_I2 + /// ILGenerator.Emit + public EmitHelper ldelem_i2 + { + get { _ilGenerator.Emit(OpCodes.Ldelem_I2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the element with type int32 at a specified array index onto the top of the evaluation stack as an int32. + /// + /// OpCodes.Ldelem_I4 + /// ILGenerator.Emit + public EmitHelper ldelem_i4 + { + get { _ilGenerator.Emit(OpCodes.Ldelem_I4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the element with type int64 at a specified array index onto the top of the evaluation stack as an int64. + /// + /// OpCodes.Ldelem_I8 + /// ILGenerator.Emit + public EmitHelper ldelem_i8 + { + get { _ilGenerator.Emit(OpCodes.Ldelem_I8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the element with type float32 at a specified array index onto the top of the evaluation stack as type F (float). + /// + /// OpCodes.Ldelem_R4 + /// ILGenerator.Emit + public EmitHelper ldelem_r4 + { + get { _ilGenerator.Emit(OpCodes.Ldelem_R4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the element with type float64 at a specified array index onto the top of the evaluation stack as type F (float). + /// + /// OpCodes.Ldelem_R8 + /// ILGenerator.Emit + public EmitHelper ldelem_r8 + { + get { _ilGenerator.Emit(OpCodes.Ldelem_R8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the element containing an object reference at a specified array index + /// onto the top of the evaluation stack as type O (object reference). + /// + /// OpCodes.Ldelem_Ref + /// ILGenerator.Emit + public EmitHelper ldelem_ref + { + get { _ilGenerator.Emit(OpCodes.Ldelem_Ref); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the element with type unsigned int8 at a specified array index onto the top of the evaluation stack as an int32. + /// + /// OpCodes.Ldelem_U1 + /// ILGenerator.Emit + public EmitHelper ldelem_u1 + { + get { _ilGenerator.Emit(OpCodes.Ldelem_U1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the element with type unsigned int16 at a specified array index + /// onto the top of the evaluation stack as an int32. + /// + /// OpCodes.Ldelem_U2 + /// ILGenerator.Emit + public EmitHelper ldelem_u2 + { + get { _ilGenerator.Emit(OpCodes.Ldelem_U2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the element with type unsigned int32 at a specified array index + /// onto the top of the evaluation stack as an int32. + /// + /// OpCodes.Ldelem_U4 + /// ILGenerator.Emit + public EmitHelper ldelem_u4 + { + get { _ilGenerator.Emit(OpCodes.Ldelem_U4); return this; } + } + + /// + /// Calls ILGenerator.Emit(, fieldInfo) that + /// finds the value of a field in the object whose reference is currently on the evaluation stack. + /// + /// A representing a field. + /// OpCodes.Ldfld + /// ILGenerator.Emit + public EmitHelper ldfld(FieldInfo fieldInfo) + { + _ilGenerator.Emit(OpCodes.Ldfld, fieldInfo); return this; + } + + /// + /// Calls ILGenerator.Emit(, fieldInfo) that + /// finds the address of a field in the object whose reference is currently on the evaluation stack. + /// + /// A representing a field. + /// OpCodes.Ldflda + /// ILGenerator.Emit + public EmitHelper ldflda(FieldInfo fieldInfo) + { + _ilGenerator.Emit(OpCodes.Ldflda, fieldInfo); return this; + } + + /// + /// Calls ILGenerator.Emit(, methodInfo) that + /// pushes an unmanaged pointer (type natural int) to the native code implementing a specific method + /// onto the evaluation stack. + /// + /// The method to be called. + /// OpCodes.Ldftn + /// ILGenerator.Emit + public EmitHelper ldftn(MethodInfo methodInfo) + { + _ilGenerator.Emit(OpCodes.Ldftn, methodInfo); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// loads a value of type natural int as a natural int onto the evaluation stack indirectly. + /// + /// OpCodes.Ldind_I + /// ILGenerator.Emit + public EmitHelper ldind_i + { + get { _ilGenerator.Emit(OpCodes.Ldind_I); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads a value of type int8 as an int32 onto the evaluation stack indirectly. + /// + /// OpCodes.Ldind_I1 + /// ILGenerator.Emit + public EmitHelper ldind_i1 + { + get { _ilGenerator.Emit(OpCodes.Ldind_I1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads a value of type int16 as an int32 onto the evaluation stack indirectly. + /// + /// OpCodes.Ldind_I2 + /// ILGenerator.Emit + public EmitHelper ldind_i2 + { + get { _ilGenerator.Emit(OpCodes.Ldind_I2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads a value of type int32 as an int32 onto the evaluation stack indirectly. + /// + /// OpCodes.Ldind_I4 + /// ILGenerator.Emit + public EmitHelper ldind_i4 + { + get { _ilGenerator.Emit(OpCodes.Ldind_I4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads a value of type int64 as an int64 onto the evaluation stack indirectly. + /// + /// OpCodes.Ldind_I8 + /// ILGenerator.Emit + public EmitHelper ldind_i8 + { + get { _ilGenerator.Emit(OpCodes.Ldind_I8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads a value of type float32 as a type F (float) onto the evaluation stack indirectly. + /// + /// OpCodes.Ldind_R4 + /// ILGenerator.Emit + public EmitHelper ldind_r4 + { + get { _ilGenerator.Emit(OpCodes.Ldind_R4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads a value of type float64 as a type F (float) onto the evaluation stack indirectly. + /// + /// OpCodes.Ldind_R8 + /// ILGenerator.Emit + public EmitHelper ldind_r8 + { + get { _ilGenerator.Emit(OpCodes.Ldind_R8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads an object reference as a type O (object reference) onto the evaluation stack indirectly. + /// + /// OpCodes.Ldind_Ref + /// ILGenerator.Emit + public EmitHelper ldind_ref + { + get { _ilGenerator.Emit(OpCodes.Ldind_Ref); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads a value of type unsigned int8 as an int32 onto the evaluation stack indirectly. + /// + /// OpCodes.Ldind_U1 + /// ILGenerator.Emit + public EmitHelper ldind_u1 + { + get { _ilGenerator.Emit(OpCodes.Ldind_U1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads a value of type unsigned int16 as an int32 onto the evaluation stack indirectly. + /// + /// OpCodes.Ldind_U2 + /// ILGenerator.Emit + public EmitHelper ldind_u2 + { + get { _ilGenerator.Emit(OpCodes.Ldind_U2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads a value of type unsigned int32 as an int32 onto the evaluation stack indirectly. + /// + /// OpCodes.Ldind_U4 + /// ILGenerator.Emit + public EmitHelper ldind_u4 + { + get { _ilGenerator.Emit(OpCodes.Ldind_U4); return this; } + } + + /// + /// Loads a value of the type from a supplied address. + /// + /// A Type. + public EmitHelper ldind(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + switch (Type.GetTypeCode(type)) + { + case TypeCode.Boolean: + case TypeCode.Byte: + case TypeCode.SByte: ldind_i1.end(); break; + + case TypeCode.Char: + case TypeCode.Int16: + case TypeCode.UInt16: ldind_i2.end(); break; + + case TypeCode.Int32: + case TypeCode.UInt32: ldind_i4.end(); break; + + case TypeCode.Int64: + case TypeCode.UInt64: ldind_i8.end(); break; + + case TypeCode.Single: ldind_r4.end(); break; + case TypeCode.Double: ldind_r8.end(); break; + + default: + if (type.IsClass) + ldind_ref.end(); + else if (type.IsValueType) + stobj(type); + else + throw CreateNotExpectedTypeException(type); + break; + } + + return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// pushes the number of elements of a zero-based, one-dimensional array onto the evaluation stack. + /// + /// OpCodes.Ldlen + /// ILGenerator.Emit + public EmitHelper ldlen + { + get { _ilGenerator.Emit(OpCodes.Ldlen); return this; } + } + + /// + /// Calls ILGenerator.Emit(, short) that + /// load an argument address onto the evaluation stack. + /// + /// Index of the local variable value pushed onto the stack. + /// OpCodes.Ldloc + /// ILGenerator.Emit + public EmitHelper ldloc(short index) + { + _ilGenerator.Emit(OpCodes.Ldloc, index); return this; + } + + /// + /// Calls ILGenerator.Emit(, ) that + /// load an argument address onto the evaluation stack. + /// + /// Local variable builder. + /// OpCodes.Ldloc + /// ILGenerator.Emit + public EmitHelper ldloc(LocalBuilder localBuilder) + { + _ilGenerator.Emit(OpCodes.Ldloc, localBuilder); return this; + } + + /// + /// Calls ILGenerator.Emit(, short) that + /// loads the address of the local variable at a specific index onto the evaluation stack. + /// + /// Index of the local variable. + /// OpCodes.Ldloca + /// ILGenerator.Emit + public EmitHelper ldloca(short index) + { + _ilGenerator.Emit(OpCodes.Ldloca, index); return this; + } + + /// + /// Calls ILGenerator.Emit(, byte) that + /// loads the address of the local variable at a specific index onto the evaluation stack, short form. + /// + /// Index of the local variable. + /// OpCodes.Ldloca_S + /// ILGenerator.Emit + public EmitHelper ldloca_s(byte index) + { + _ilGenerator.Emit(OpCodes.Ldloca_S, index); return this; + } + + /// + /// Calls ILGenerator.Emit(, ) that + /// loads the address of the local variable at a specific index onto the evaluation stack. + /// + /// A representing the local variable. + /// OpCodes.Ldloca + /// ILGenerator.Emit + public EmitHelper ldloca(LocalBuilder local) + { + _ilGenerator.Emit(OpCodes.Ldloca, local); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the local variable at index 0 onto the evaluation stack. + /// + /// OpCodes.Ldloc_0 + /// ILGenerator.Emit + public EmitHelper ldloc_0 + { + get { _ilGenerator.Emit(OpCodes.Ldloc_0); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the local variable at index 1 onto the evaluation stack. + /// + /// OpCodes.Ldloc_1 + /// ILGenerator.Emit + public EmitHelper ldloc_1 + { + get { _ilGenerator.Emit(OpCodes.Ldloc_1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the local variable at index 2 onto the evaluation stack. + /// + /// OpCodes.Ldloc_2 + /// ILGenerator.Emit + public EmitHelper ldloc_2 + { + get { _ilGenerator.Emit(OpCodes.Ldloc_2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// loads the local variable at index 3 onto the evaluation stack. + /// + /// OpCodes.Ldloc_3 + /// ILGenerator.Emit + public EmitHelper ldloc_3 + { + get { _ilGenerator.Emit(OpCodes.Ldloc_3); return this; } + } + + /// + /// Calls ILGenerator.Emit(, byte) that + /// loads the local variable at a specific index onto the evaluation stack, short form. + /// + /// Index of the local variable. + /// OpCodes.Ldloc_S + /// ILGenerator.Emit + public EmitHelper ldloc_s(byte index) + { + _ilGenerator.Emit(OpCodes.Ldloca_S, index); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// pushes a null reference (type O) onto the evaluation stack. + /// + /// OpCodes.Ldnull + /// ILGenerator.Emit + public EmitHelper ldnull + { + get { _ilGenerator.Emit(OpCodes.Ldnull); return this; } + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// copies the value type object pointed to by an address to the top of the evaluation stack. + /// + /// A Type + /// OpCodes.Ldobj + /// ILGenerator.Emit + public EmitHelper ldobj(Type type) + { + _ilGenerator.Emit(OpCodes.Ldobj, type); return this; + } + + /// + /// Calls ILGenerator.Emit(, fieldInfo) that + /// pushes the value of a static field onto the evaluation stack. + /// + /// A representing a field. + /// OpCodes.Ldsfld + /// ILGenerator.Emit + public EmitHelper ldsfld(FieldInfo fieldInfo) + { + _ilGenerator.Emit(OpCodes.Ldsfld, fieldInfo); return this; + } + + /// + /// Calls ILGenerator.Emit(, fieldInfo) that + /// pushes the address of a static field onto the evaluation stack. + /// + /// A representing a field. + /// OpCodes.Ldsflda + /// ILGenerator.Emit + public EmitHelper ldsflda(FieldInfo fieldInfo) + { + _ilGenerator.Emit(OpCodes.Ldsflda, fieldInfo); return this; + } + + /// + /// Calls -or- , + /// if given string is a null reference. + /// + /// The String to be emitted. + /// + /// + public EmitHelper ldstrEx(string str) + { + return str == null ? ldnull : ldstr(str); + } + + /// + /// Calls ILGenerator.Emit(, string) that + /// pushes a new object reference to a string literal stored in the metadata. + /// + /// The String to be emitted. + /// OpCodes.Ldstr + /// ILGenerator.Emit + public EmitHelper ldstr(string str) + { + _ilGenerator.Emit(OpCodes.Ldstr, str); return this; + } + + /// + /// Calls ILGenerator.Emit(, string) that + /// pushes a new object reference to a string literal stored in the metadata. + /// + /// The to be emitted. + /// ILGenerator.Emit + public EmitHelper ldNameOrIndex(NameOrIndexParameter nameOrIndex) + { + return nameOrIndex.ByName? + ldstr (nameOrIndex.Name) .call(typeof(NameOrIndexParameter), "op_Implicit", typeof(string)): + ldc_i4_(nameOrIndex.Index).call(typeof(NameOrIndexParameter), "op_Implicit", typeof(int)); + } + + /// + /// Calls ILGenerator.Emit(, methodInfo) that + /// converts a metadata token to its runtime representation, pushing it onto the evaluation stack. + /// + /// The method to be called. + /// OpCodes.Ldtoken + /// ILGenerator.Emit + public EmitHelper ldtoken(MethodInfo methodInfo) + { + _ilGenerator.Emit(OpCodes.Ldtoken, methodInfo); return this; + } + + /// + /// Calls ILGenerator.Emit(, fieldInfo) that + /// converts a metadata token to its runtime representation, + /// pushing it onto the evaluation stack. + /// + /// A representing a field. + /// OpCodes.Ldtoken + /// ILGenerator.Emit + public EmitHelper ldtoken(FieldInfo fieldInfo) + { + _ilGenerator.Emit(OpCodes.Ldtoken, fieldInfo); return this; + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// converts a metadata token to its runtime representation, pushing it onto the evaluation stack. + /// + /// A Type + /// OpCodes.Ldtoken + /// ILGenerator.Emit + public EmitHelper ldtoken(Type type) + { + _ilGenerator.Emit(OpCodes.Ldtoken, type); return this; + } + + /// + /// Calls ILGenerator.Emit(, methodInfo) that + /// pushes an unmanaged pointer (type natural int) to the native code implementing a particular virtual method + /// associated with a specified object onto the evaluation stack. + /// + /// The method to be called. + /// OpCodes.Ldvirtftn + /// ILGenerator.Emit + public EmitHelper ldvirtftn(MethodInfo methodInfo) + { + _ilGenerator.Emit(OpCodes.Ldvirtftn, methodInfo); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// exits a protected region of code, unconditionally tranferring control to a specific target instruction. + /// + /// The label. + /// OpCodes.Leave + /// ILGenerator.Emit + public EmitHelper leave(Label label) + { + _ilGenerator.Emit(OpCodes.Leave, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// exits a protected region of code, unconditionally transferring control to a target instruction (short form). + /// + /// The label. + /// OpCodes.Leave_S + /// ILGenerator.Emit + public EmitHelper leave_s(Label label) + { + _ilGenerator.Emit(OpCodes.Leave_S, label); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// allocates a certain number of bytes from the local dynamic memory pool and pushes the address + /// (a transient pointer, type *) of the first allocated byte onto the evaluation stack. + /// + /// OpCodes.Localloc + /// ILGenerator.Emit + public EmitHelper localloc + { + get { _ilGenerator.Emit(OpCodes.Localloc); return this; } + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// pushes a typed reference to an instance of a specific type onto the evaluation stack. + /// + /// A Type + /// OpCodes.Mkrefany + /// ILGenerator.Emit + public EmitHelper mkrefany(Type type) + { + _ilGenerator.Emit(OpCodes.Mkrefany, type); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// multiplies two values and pushes the result on the evaluation stack. + /// (a transient pointer, type *) of the first allocated byte onto the evaluation stack. + /// + /// OpCodes.Mul + /// ILGenerator.Emit + public EmitHelper mul + { + get { _ilGenerator.Emit(OpCodes.Mul); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// multiplies two integer values, performs an overflow check, + /// and pushes the result onto the evaluation stack. + /// + /// OpCodes.Mul_Ovf + /// ILGenerator.Emit + public EmitHelper mul_ovf + { + get { _ilGenerator.Emit(OpCodes.Mul_Ovf); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// multiplies two unsigned integer values, performs an overflow check, + /// and pushes the result onto the evaluation stack. + /// + /// OpCodes.Mul_Ovf_Un + /// ILGenerator.Emit + public EmitHelper mul_ovf_un + { + get { _ilGenerator.Emit(OpCodes.Mul_Ovf_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// negates a value and pushes the result onto the evaluation stack. + /// + /// OpCodes.Neg + /// ILGenerator.Emit + public EmitHelper neg + { + get { _ilGenerator.Emit(OpCodes.Neg); return this; } + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// pushes an object reference to a new zero-based, one-dimensional array whose elements + /// are of a specific type onto the evaluation stack. + /// + /// A Type + /// OpCodes.Newarr + /// ILGenerator.Emit + public EmitHelper newarr(Type type) + { + _ilGenerator.Emit(OpCodes.Newarr, type); return this; + } + + /// + /// Calls ILGenerator.Emit(, ) that + /// creates a new object or a new instance of a value type, + /// pushing an object reference (type O) onto the evaluation stack. + /// + /// A representing a constructor. + /// OpCodes.Newobj + /// ILGenerator.Emit + public EmitHelper newobj(ConstructorInfo constructorInfo) + { + _ilGenerator.Emit(OpCodes.Newobj, constructorInfo); return this; + } + + /// + /// Calls ILGenerator.Emit(, ConstructorInfo) that + /// creates a new object or a new instance of a value type, + /// pushing an object reference (type O) onto the evaluation stack. + /// + /// A type. + /// An array of System.Type objects representing + /// the number, order, and type of the parameters for the desired constructor. + /// -or- An empty array of System.Type objects, to get a constructor that takes + /// no parameters. Such an empty array is provided by the static field System.Type.EmptyTypes. + public EmitHelper newobj(Type type, params Type[] parameters) + { + if (type == null) throw new ArgumentNullException("type"); + + ConstructorInfo ci = type.GetConstructor(parameters); + + return newobj(ci); + } + + /// + /// Calls ILGenerator.Emit() that + /// fills space if opcodes are patched. No meaningful operation is performed although + /// a processing cycle can be consumed. + /// + /// OpCodes.Nop + /// ILGenerator.Emit + public EmitHelper nop + { + get { _ilGenerator.Emit(OpCodes.Nop); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// computes the bitwise complement of the integer value on top of the stack + /// and pushes the result onto the evaluation stack as the same type. + /// + /// OpCodes.Not + /// ILGenerator.Emit + public EmitHelper not + { + get { _ilGenerator.Emit(OpCodes.Not); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// compute the bitwise complement of the two integer values on top of the stack and + /// pushes the result onto the evaluation stack. + /// + /// OpCodes.Or + /// ILGenerator.Emit + public EmitHelper or + { + get { _ilGenerator.Emit(OpCodes.Or); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// removes the value currently on top of the evaluation stack. + /// + /// OpCodes.Pop + /// ILGenerator.Emit + public EmitHelper pop + { + get { _ilGenerator.Emit(OpCodes.Pop); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// specifies that the subsequent array address operation performs + /// no type check at run time, and that it returns a managed pointer + /// whose mutability is restricted. + /// + /// OpCodes.Refanytype + /// ILGenerator.Emit + public EmitHelper @readonly + { + get { _ilGenerator.Emit(OpCodes.Readonly); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// retrieves the type token embedded in a typed reference. + /// + /// OpCodes.Refanytype + /// ILGenerator.Emit + public EmitHelper refanytype + { + get { _ilGenerator.Emit(OpCodes.Refanytype); return this; } + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// retrieves the address (type &) embedded in a typed reference. + /// + /// A Type + /// OpCodes.Refanyval + /// ILGenerator.Emit + public EmitHelper refanyval(Type type) + { + _ilGenerator.Emit(OpCodes.Refanyval, type); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// divides two values and pushes the remainder onto the evaluation stack. + /// + /// OpCodes.Rem + /// ILGenerator.Emit + public EmitHelper rem + { + get { _ilGenerator.Emit(OpCodes.Rem); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// divides two unsigned values and pushes the remainder onto the evaluation stack. + /// + /// OpCodes.Rem_Un + /// ILGenerator.Emit + public EmitHelper rem_un + { + get { _ilGenerator.Emit(OpCodes.Rem_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// returns from the current method, pushing a return value (if present) + /// from the caller's evaluation stack onto the callee's evaluation stack. + /// + /// OpCodes.Ret + /// ILGenerator.Emit + public EmitHelper ret() + { + _ilGenerator.Emit(OpCodes.Ret); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// rethrows the current exception. + /// + /// OpCodes.Rethrow + /// ILGenerator.Emit + public EmitHelper rethrow + { + get { _ilGenerator.Emit(OpCodes.Rethrow); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// shifts an integer value to the left (in zeroes) by a specified number of bits, + /// pushing the result onto the evaluation stack. + /// + /// OpCodes.Shl + /// ILGenerator.Emit + public EmitHelper shl + { + get { _ilGenerator.Emit(OpCodes.Shl); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// shifts an integer value (in sign) to the right by a specified number of bits, + /// pushing the result onto the evaluation stack. + /// + /// OpCodes.Shr + /// ILGenerator.Emit + public EmitHelper shr + { + get { _ilGenerator.Emit(OpCodes.Shr); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// shifts an unsigned integer value (in zeroes) to the right by a specified number of bits, + /// pushing the result onto the evaluation stack. + /// + /// OpCodes.Shr_Un + /// ILGenerator.Emit + public EmitHelper shr_un + { + get { _ilGenerator.Emit(OpCodes.Shr_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// pushes the size, in bytes, of a supplied value type onto the evaluation stack. + /// + /// A Type + /// OpCodes.Sizeof + /// ILGenerator.Emit + public EmitHelper @sizeof(Type type) + { + _ilGenerator.Emit(OpCodes.Sizeof, type); return this; + } + + /// + /// Calls ILGenerator.Emit(, short) that + /// stores the value on top of the evaluation stack in the argument slot at a specified index. + /// + /// Slot index. + /// OpCodes.Starg + /// ILGenerator.Emit + public EmitHelper starg(short index) + { + _ilGenerator.Emit(OpCodes.Starg, index); return this; + } + + /// + /// Calls ILGenerator.Emit(, byte) that + /// stores the value on top of the evaluation stack in the argument slot at a specified index, + /// short form. + /// + /// Slot index. + /// OpCodes.Starg_S + /// ILGenerator.Emit + public EmitHelper starg_s(byte index) + { + _ilGenerator.Emit(OpCodes.Starg_S, index); return this; + } + + /// + /// Stores the value on top of the evaluation stack in the argument slot at a specified index. + /// + /// Slot index. + /// OpCodes.Starg + /// ILGenerator.Emit + public EmitHelper starg(int index) + { + if (index < byte. MaxValue) starg_s((byte)index); + else if (index < short.MaxValue) starg ((short)index); + else + throw new ArgumentOutOfRangeException("index"); + + return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// replaces the array element at a given index with the natural int value + /// on the evaluation stack. + /// + /// OpCodes.Stelem_I + /// ILGenerator.Emit + public EmitHelper stelem_i + { + get { _ilGenerator.Emit(OpCodes.Stelem_I); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// replaces the array element at a given index with the int8 value on the evaluation stack. + /// + /// OpCodes.Stelem_I1 + /// ILGenerator.Emit + public EmitHelper stelem_i1 + { + get { _ilGenerator.Emit(OpCodes.Stelem_I1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// replaces the array element at a given index with the int16 value on the evaluation stack. + /// + /// OpCodes.Stelem_I2 + /// ILGenerator.Emit + public EmitHelper stelem_i2 + { + get { _ilGenerator.Emit(OpCodes.Stelem_I2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// replaces the array element at a given index with the int32 value on the evaluation stack. + /// + /// OpCodes.Stelem_I4 + /// ILGenerator.Emit + public EmitHelper stelem_i4 + { + get { _ilGenerator.Emit(OpCodes.Stelem_I4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// replaces the array element at a given index with the int64 value on the evaluation stack. + /// + /// OpCodes.Stelem_I8 + /// ILGenerator.Emit + public EmitHelper stelem_i8 + { + get { _ilGenerator.Emit(OpCodes.Stelem_I8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// replaces the array element at a given index with the float32 value on the evaluation stack. + /// + /// OpCodes.Stelem_R4 + /// ILGenerator.Emit + public EmitHelper stelem_r4 + { + get { _ilGenerator.Emit(OpCodes.Stelem_R4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// replaces the array element at a given index with the float64 value on the evaluation stack. + /// + /// OpCodes.Stelem_R8 + /// ILGenerator.Emit + public EmitHelper stelem_r8 + { + get { _ilGenerator.Emit(OpCodes.Stelem_R8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// replaces the array element at a given index with the object ref value (type O) + /// on the evaluation stack. + /// + /// OpCodes.Stelem_Ref + /// ILGenerator.Emit + public EmitHelper stelem_ref + { + get { _ilGenerator.Emit(OpCodes.Stelem_Ref); return this; } + } + + /// + /// Calls ILGenerator.Emit(, ) that + /// replaces the value stored in the field of an object reference or pointer with a new value. + /// + /// A representing a field. + /// OpCodes.Stfld + /// ILGenerator.Emit + public EmitHelper stfld(FieldInfo fieldInfo) + { + _ilGenerator.Emit(OpCodes.Stfld, fieldInfo); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// stores a value of type natural int at a supplied address. + /// + /// OpCodes.Stind_I + /// ILGenerator.Emit + public EmitHelper stind_i + { + get { _ilGenerator.Emit(OpCodes.Stind_I); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// stores a value of type int8 at a supplied address. + /// + /// OpCodes.Stind_I1 + /// ILGenerator.Emit + public EmitHelper stind_i1 + { + get { _ilGenerator.Emit(OpCodes.Stind_I1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// stores a value of type int16 at a supplied address. + /// + /// OpCodes.Stind_I2 + /// ILGenerator.Emit + public EmitHelper stind_i2 + { + get { _ilGenerator.Emit(OpCodes.Stind_I2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// stores a value of type int32 at a supplied address. + /// + /// OpCodes.Stind_I4 + /// ILGenerator.Emit + public EmitHelper stind_i4 + { + get { _ilGenerator.Emit(OpCodes.Stind_I4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// stores a value of type int64 at a supplied address. + /// + /// OpCodes.Stind_I8 + /// ILGenerator.Emit + public EmitHelper stind_i8 + { + get { _ilGenerator.Emit(OpCodes.Stind_I8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// stores a value of type float32 at a supplied address. + /// + /// OpCodes.Stind_R4 + /// ILGenerator.Emit + public EmitHelper stind_r4 + { + get { _ilGenerator.Emit(OpCodes.Stind_R4); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// stores a value of type float64 at a supplied address. + /// + /// OpCodes.Stind_R8 + /// ILGenerator.Emit + public EmitHelper stind_r8 + { + get { _ilGenerator.Emit(OpCodes.Stind_R8); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// stores an object reference value at a supplied address. + /// + /// OpCodes.Stind_Ref + /// ILGenerator.Emit + public EmitHelper stind_ref + { + get { _ilGenerator.Emit(OpCodes.Stind_Ref); return this; } + } + + /// + /// Stores a value of the type at a supplied address. + /// + /// A Type. + public EmitHelper stind(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + switch (Type.GetTypeCode(type)) + { + case TypeCode.Boolean: + case TypeCode.Byte: + case TypeCode.SByte: stind_i1.end(); break; + + case TypeCode.Char: + case TypeCode.Int16: + case TypeCode.UInt16: stind_i2.end(); break; + + case TypeCode.Int32: + case TypeCode.UInt32: stind_i4.end(); break; + + case TypeCode.Int64: + case TypeCode.UInt64: stind_i8.end(); break; + + case TypeCode.Single: stind_r4.end(); break; + case TypeCode.Double: stind_r8.end(); break; + + default: + if (type.IsClass) + stind_ref.end(); + else if (type.IsValueType) + stobj(type); + else + throw CreateNotExpectedTypeException(type); + break; + } + + return this; + } + + /// + /// Calls ILGenerator.Emit(, ) that + /// pops the current value from the top of the evaluation stack and stores it + /// in the local variable list at a specified index. + /// + /// A local variable. + /// OpCodes.Stloc + /// ILGenerator.Emit + public EmitHelper stloc(LocalBuilder local) + { + _ilGenerator.Emit(OpCodes.Stloc, local); return this; + } + + /// + /// Calls ILGenerator.Emit(, short) that + /// pops the current value from the top of the evaluation stack and stores it + /// in the local variable list at a specified index. + /// + /// A local variable index. + /// OpCodes.Stloc + /// ILGenerator.Emit + public EmitHelper stloc(short index) + { + if (index >= byte.MinValue && index <= byte.MaxValue) + return stloc_s((byte)index); + + _ilGenerator.Emit(OpCodes.Stloc, index); + return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// pops the current value from the top of the evaluation stack and stores it + /// in the local variable list at index 0. + /// + /// OpCodes.Stloc_0 + /// ILGenerator.Emit + public EmitHelper stloc_0 + { + get { _ilGenerator.Emit(OpCodes.Stloc_0); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// pops the current value from the top of the evaluation stack and stores it + /// in the local variable list at index 1. + /// + /// OpCodes.Stloc_1 + /// ILGenerator.Emit + public EmitHelper stloc_1 + { + get { _ilGenerator.Emit(OpCodes.Stloc_1); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// pops the current value from the top of the evaluation stack and stores it + /// in the local variable list at index 2. + /// + /// OpCodes.Stloc_2 + /// ILGenerator.Emit + public EmitHelper stloc_2 + { + get { _ilGenerator.Emit(OpCodes.Stloc_2); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// pops the current value from the top of the evaluation stack and stores it + /// in the local variable list at index 3. + /// + /// OpCodes.Stloc_3 + /// ILGenerator.Emit + public EmitHelper stloc_3 + { + get { _ilGenerator.Emit(OpCodes.Stloc_3); return this; } + } + + /// + /// Calls ILGenerator.Emit(, ) that + /// pops the current value from the top of the evaluation stack and stores it + /// in the local variable list at index (short form). + /// + /// A local variable. + /// OpCodes.Stloc_S + /// ILGenerator.Emit + public EmitHelper stloc_s(LocalBuilder local) + { + _ilGenerator.Emit(OpCodes.Stloc_S, local); return this; + } + + /// + /// Calls ILGenerator.Emit(, byte) that + /// pops the current value from the top of the evaluation stack and stores it + /// in the local variable list at index (short form). + /// + /// A local variable index. + /// OpCodes.Stloc_S + /// ILGenerator.Emit + public EmitHelper stloc_s(byte index) + { + switch (index) + { + case 0: stloc_0.end(); break; + case 1: stloc_1.end(); break; + case 2: stloc_2.end(); break; + case 3: stloc_3.end(); break; + + default: + _ilGenerator.Emit(OpCodes.Stloc_S, index); break; + } + + return this; + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// copies a value of a specified type from the evaluation stack into a supplied memory address. + /// + /// A Type + /// OpCodes.Stobj + /// ILGenerator.Emit + public EmitHelper stobj(Type type) + { + _ilGenerator.Emit(OpCodes.Stobj, type); return this; + } + + /// + /// Calls ILGenerator.Emit(, fieldInfo) that + /// replaces the value of a static field with a value from the evaluation stack. + /// + /// A representing a field. + /// OpCodes.Stsfld + /// ILGenerator.Emit + public EmitHelper stsfld(FieldInfo fieldInfo) + { + _ilGenerator.Emit(OpCodes.Stsfld, fieldInfo); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// subtracts one value from another and pushes the result onto the evaluation stack. + /// + /// OpCodes.Sub + /// ILGenerator.Emit + public EmitHelper sub + { + get { _ilGenerator.Emit(OpCodes.Sub); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// subtracts one integer value from another, performs an overflow check, + /// and pushes the result onto the evaluation stack. + /// + /// OpCodes.Sub_Ovf + /// ILGenerator.Emit + public EmitHelper sub_ovf + { + get { _ilGenerator.Emit(OpCodes.Sub_Ovf); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// subtracts one unsigned integer value from another, performs an overflow check, + /// and pushes the result onto the evaluation stack. + /// + /// OpCodes.Sub_Ovf_Un + /// ILGenerator.Emit + public EmitHelper sub_ovf_un + { + get { _ilGenerator.Emit(OpCodes.Sub_Ovf_Un); return this; } + } + + /// + /// Calls ILGenerator.Emit(, label[]) that + /// implements a jump table. + /// + /// The array of label objects to which to branch from this location. + /// OpCodes.Switch + /// ILGenerator.Emit + public EmitHelper @switch(Label[] labels) + { + _ilGenerator.Emit(OpCodes.Switch, labels); return this; + } + + /// + /// Calls ILGenerator.Emit() that + /// performs a postfixed method call instruction such that the current method's stack frame + /// is removed before the actual call instruction is executed. + /// + /// OpCodes.Tailcall + /// ILGenerator.Emit + public EmitHelper tailcall + { + get { _ilGenerator.Emit(OpCodes.Tailcall); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// throws the exception object currently on the evaluation stack. + /// + /// OpCodes.Throw + /// ILGenerator.Emit + public EmitHelper @throw + { + get { _ilGenerator.Emit(OpCodes.Throw); return this; } + } + + /// + /// Calls ILGenerator.Emit(, label) that + /// indicates that an address currently atop the evaluation stack might not be aligned + /// to the natural size of the immediately following ldind, stind, ldfld, stfld, ldobj, stobj, + /// initblk, or cpblk instruction. + /// + /// The label to branch from this location. + /// OpCodes.Unaligned + /// ILGenerator.Emit + public EmitHelper unaligned(Label label) + { + _ilGenerator.Emit(OpCodes.Unaligned, label); return this; + } + + /// + /// Calls ILGenerator.Emit(, long) that + /// indicates that an address currently atop the evaluation stack might not be aligned + /// to the natural size of the immediately following ldind, stind, ldfld, stfld, ldobj, stobj, + /// initblk, or cpblk instruction. + /// + /// An address is pushed onto the stack. + /// OpCodes.Unaligned + /// ILGenerator.Emit + public EmitHelper unaligned(long addr) + { + _ilGenerator.Emit(OpCodes.Unaligned, addr); return this; + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// converts the boxed representation of a value type to its unboxed form. + /// + /// A Type + /// OpCodes.Unbox + /// ILGenerator.Emit + public EmitHelper unbox(Type type) + { + _ilGenerator.Emit(OpCodes.Unbox, type); return this; + } + + /// + /// Calls ILGenerator.Emit(, type) that + /// converts the boxed representation of a value type to its unboxed form. + /// + /// A Type + /// OpCodes.Unbox_Any + /// ILGenerator.Emit + public EmitHelper unbox_any(Type type) + { + _ilGenerator.Emit(OpCodes.Unbox_Any, type); + return this; + } + + /// + /// Calls if given type is a value type. + /// + /// A Type + /// OpCodes.Unbox + /// ILGenerator.Emit + public EmitHelper unboxIfValueType(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + return type.IsValueType? unbox_any(type): this; + } + + /// + /// Calls ILGenerator.Emit() that + /// specifies that an address currently atop the evaluation stack might be volatile, + /// and the results of reading that location cannot be cached or that multiple stores + /// to that location cannot be suppressed. + /// + /// OpCodes.Volatile + /// ILGenerator.Emit + public EmitHelper @volatile + { + get { _ilGenerator.Emit(OpCodes.Volatile); return this; } + } + + /// + /// Calls ILGenerator.Emit() that + /// computes the bitwise XOR of the top two values on the evaluation stack, + /// pushing the result onto the evaluation stack. + /// + /// OpCodes.Xor + /// ILGenerator.Emit + public EmitHelper xor + { + get { _ilGenerator.Emit(OpCodes.Xor); return this; } + } + + /// + /// Ends sequence of property calls. + /// + [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] + public void end() + { + } + + #endregion + + /// + /// Loads default value of given type onto the evaluation stack. + /// + /// A Type + public EmitHelper LoadInitValue(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + switch (Type.GetTypeCode(type)) + { + case TypeCode.Boolean: + case TypeCode.Char: + case TypeCode.SByte: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Byte: + case TypeCode.UInt16: + case TypeCode.UInt32: + ldc_i4_0.end(); + break; + + case TypeCode.Int64: + case TypeCode.UInt64: + ldc_i4_0.conv_i8.end(); + break; + + case TypeCode.Single: + case TypeCode.Double: + ldc_r4(0).end(); + break; + + case TypeCode.String: + ldsfld(typeof(string).GetField("Empty")); + break; + + default: + if (type.IsClass || type.IsInterface) + ldnull.end(); + else + throw CreateNotExpectedTypeException(type); + break; + } + + return this; + } + + /// + /// Loads supplied object value (if possible) onto the evaluation stack. + /// + /// Any object instance or null reference. + /// True is a value was loaded, otherwise false. + public bool LoadWellKnownValue(object o) + { + if (o == null) + ldnull.end(); + else + switch (Type.GetTypeCode(o.GetType())) + { + case TypeCode.Boolean: ldc_bool((Boolean)o); break; + case TypeCode.Char: ldc_i4_ ((Char) o); break; + case TypeCode.Single: ldc_r4 ((Single) o); break; + case TypeCode.Double: ldc_r8 ((Double) o); break; + case TypeCode.String: ldstr ((String) o); break; + case TypeCode.SByte: ldc_i4_ ((SByte) o); break; + case TypeCode.Int16: ldc_i4_ ((Int16) o); break; + case TypeCode.Int32: ldc_i4_ ((Int32) o); break; + case TypeCode.Int64: ldc_i8 ((Int64) o); break; + case TypeCode.Byte: ldc_i4_ ((Byte) o); break; + case TypeCode.UInt16: ldc_i4_ ((UInt16) o); break; + case TypeCode.UInt32: ldc_i4_ (unchecked((Int32)(UInt32)o)); break; + case TypeCode.UInt64: ldc_i8 (unchecked((Int64)(UInt64)o)); break; + default: + return false; + } + + return true; + } + + /// + /// Initialize parameter with some default value. + /// + /// A method parameter. + /// The parameter index. + public EmitHelper Init(ParameterInfo parameterInfo, int index) + { + if (parameterInfo == null) throw new ArgumentNullException("parameterInfo"); + + Type type = TypeHelper.GetUnderlyingType(parameterInfo.ParameterType); + + if (parameterInfo.ParameterType.IsByRef) + { + type = type.GetElementType(); + + return type.IsValueType && type.IsPrimitive == false? + ldarg(index).initobj(type): + ldarg(index).LoadInitValue(type).stind(type); + } + else + { + return type.IsValueType && type.IsPrimitive == false? + ldarga(index).initobj(type): + LoadInitValue(type).starg(index); + } + } + + /// + /// Initialize all output parameters with some default value. + /// + /// A method parameters array. + public EmitHelper InitOutParameters(ParameterInfo[] parameters) + { + for (int i = 0; i < parameters.Length; i++) + { + ParameterInfo pi = parameters[i]; + + if (pi.IsOut) + Init(pi, i + 1); + } + + return this; + } + + /// + /// Initialize local variable with some default value. + /// + /// A method local variable. + public EmitHelper Init(LocalBuilder localBuilder) + { + if (localBuilder == null) throw new ArgumentNullException("localBuilder"); + + Type type = localBuilder.LocalType; + + if (type.IsEnum) + type = Enum.GetUnderlyingType(type); + + return type.IsValueType && type.IsPrimitive == false? + ldloca(localBuilder).initobj(type): + LoadInitValue(type).stloc(localBuilder); + } + + /// + /// Loads a type instance at runtime. + /// + /// A type + public EmitHelper LoadType(Type type) + { + return type == null? + ldnull: + ldtoken(type).call(typeof(Type), "GetTypeFromHandle", typeof(RuntimeTypeHandle)); + } + + /// + /// Loads a field instance at runtime. + /// + /// A representing a field. + public EmitHelper LoadField(FieldInfo fieldInfo) + { + return fieldInfo.IsStatic ? ldsfld(fieldInfo) : ldarg_0.ldfld(fieldInfo); + } + + /// + /// Cast an object passed by reference to the specified type + /// or unbox a boxed value type. + /// + /// A type + public EmitHelper CastFromObject(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + return + type == typeof(object)? this: + (type.IsValueType? unbox_any(type): + castclass(type)); + } + + /// + /// Cast an object passed by reference to the specified type + /// or unbox a boxed value type unless + /// is a parent of . + /// + /// A type required. + /// A type available. + public EmitHelper CastIfNecessary(Type expectedType, Type actualType) + { + if (expectedType == null) throw new ArgumentNullException("expectedType"); + if (actualType == null) throw new ArgumentNullException("actualType"); + + return + TypeHelper.IsSameOrParent(expectedType, actualType)? this: + actualType.IsValueType? unbox_any(expectedType): + castclass(expectedType); + } + + /// + /// Increase max stack size by specified delta. + /// + /// Number of bytes to enlarge max stack size. + public void AddMaxStackSize(int size) + { + // m_maxStackSize isn't public so we need some hacking here. + // + FieldInfo fi = _ilGenerator.GetType().GetField( + "m_maxStackSize", BindingFlags.Instance | BindingFlags.NonPublic); + + if (fi != null) + { + size += (int)fi.GetValue(_ilGenerator); + fi.SetValue(_ilGenerator, size); + } + } + + private static Exception CreateNoSuchMethodException(Type type, string methodName) + { + return new InvalidOperationException( + string.Format(Resources.EmitHelper_NoSuchMethod, type.FullName, methodName)); + } + + private static Exception CreateNotExpectedTypeException(Type type) + { + return new ArgumentException( + string.Format(Resources.EmitHelper_NotExpectedType, type.FullName)); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Emit/Examples.CS.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Emit/Examples.CS.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,58 @@ + + + + + + +using System; + +using NUnit.Framework; + +using BLToolkit.Reflection; +using BLToolkit.Reflection.Emit; + +namespace Examples.Reflection.Emit +{ + [TestFixture] + public class HelloWorld + { + public interface IHello + { + void SayHello(string toWhom); + } + + [Test] + public void Test() + { + EmitHelper emit = new AssemblyBuilderHelper("HelloWorld.dll") + .DefineType ("Hello", typeof(object), typeof(IHello)) + .DefineMethod(typeof(IHello).GetMethod("SayHello")) + .Emitter; + + /*[a]*/emit/*[/a]*/ + // string.Format("Hello, {0}!", toWhom) + // + ./*[a]*/ldstr/*[/a]*/ ("Hello, {0}!") + ./*[a]*/ldarg_1/*[/a]*/ + ./*[a]*/call/*[/a]*/ (typeof(string), "Format", typeof(string), typeof(object)) + + // Console.WriteLine("Hello, World!"); + // + ./*[a]*/call/*[/a]*/ (typeof(Console), "WriteLine", typeof(string)) + ./*[a]*/ret/*[/a]*/() + ; + + Type type = emit.Method.Type.Create(); + + IHello hello = (IHello)TypeAccessor.CreateInstance(type); + + hello.SayHello("World"); + } + } +} + + + + + + diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Emit/Examples.VB.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Emit/Examples.VB.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,57 @@ + + + + + + +Imports System +Imports NUnit.Framework + +Imports BLToolkit.Reflection +Imports BLToolkit.Reflection.Emit + +Namespace Examples.Reflection.Emit + + <TestFixture()> _ + Public Class HelloWorld + + Public Interface IHello + Sub SayHello(ByVal toWhom As String) + End Interface + + <Test()> _ + Sub Test() + Dim assemblyHelper As AssemblyBuilderHelper = New AssemblyBuilderHelper("HelloWorld.dll") + Dim typeHelper As TypeBuilderHelper = assemblyHelper.DefineType("Hello", GetType(Object), GetType(IHello)) + Dim methodHelper As MethodBuilderHelper = typeHelper.DefineMethod(GetType(IHello).GetMethod("SayHello")) + Dim emit As EmitHelper = methodHelper.Emitter + + ' string.Format("Hello, {0} World!", toWhom) + ' + emit _ + .ldstr("Hello, {0} World!") _ + .ldarg_1 _ + .call(GetType(String), "Format", GetType(String), GetType(Object)) + + ' Console.WriteLine("Hello, World!"); + ' + emit _ + .call(GetType(Console), "WriteLine", GetType(String)) _ + .ret() + + Dim type As Type = typeHelper.Create() + + Dim hello As IHello = TypeAccessor.CreateInstance(type) + + hello.SayHello("VB") + End Sub + + End Class + +End Namespace + + + + + + diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Emit/MethodBuilderBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Emit/MethodBuilderBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +using System; + +namespace BLToolkit.Reflection.Emit +{ + /// + /// Base class for wrappers around methods and constructors. + /// + public abstract class MethodBuilderBase + { + /// + /// Initializes a new instance of the class + /// with the specified parameters. + /// + /// Associated . + protected MethodBuilderBase(TypeBuilderHelper typeBuilder) + { + if (typeBuilder == null) throw new ArgumentNullException("typeBuilder"); + + _type = typeBuilder; + } + + private readonly TypeBuilderHelper _type; + /// + /// Gets associated . + /// + public TypeBuilderHelper Type + { + get { return _type; } + } + + /// + /// Gets . + /// + public abstract EmitHelper Emitter { get; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Emit/MethodBuilderHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Emit/MethodBuilderHelper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,207 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Emit; +using System.Reflection; + +namespace BLToolkit.Reflection.Emit +{ + /// + /// A wrapper around the class. + /// + /// + /// + /// MethodBuilder Class + public class MethodBuilderHelper : MethodBuilderBase + { + /// + /// Initializes a new instance of the class + /// with the specified parameters. + /// + /// Associated . + /// A + public MethodBuilderHelper(TypeBuilderHelper typeBuilder, MethodBuilder methodBuilder) + : base(typeBuilder) + { + if (methodBuilder == null) throw new ArgumentNullException("methodBuilder"); + + _methodBuilder = methodBuilder; + + methodBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute); + } + + /// + /// Sets a custom attribute using a custom attribute type. + /// + /// Attribute type. + public void SetCustomAttribute(Type attributeType) + { + if (attributeType == null) throw new ArgumentNullException("attributeType"); + + ConstructorInfo ci = attributeType.GetConstructor(System.Type.EmptyTypes); + CustomAttributeBuilder caBuilder = new CustomAttributeBuilder(ci, new object[0]); + + _methodBuilder.SetCustomAttribute(caBuilder); + } + + /// + /// Sets a custom attribute using a custom attribute type + /// and named properties. + /// + /// Attribute type. + /// Named properties of the custom attribute. + /// Values for the named properties of the custom attribute. + public void SetCustomAttribute( + Type attributeType, + PropertyInfo[] properties, + object[] propertyValues) + { + if (attributeType == null) throw new ArgumentNullException("attributeType"); + + ConstructorInfo ci = attributeType.GetConstructor(System.Type.EmptyTypes); + CustomAttributeBuilder caBuilder = new CustomAttributeBuilder( + ci, new object[0], properties, propertyValues); + + _methodBuilder.SetCustomAttribute(caBuilder); + } + + /// + /// Sets a custom attribute using a custom attribute type + /// and named property. + /// + /// Attribute type. + /// A named property of the custom attribute. + /// Value for the named property of the custom attribute. + public void SetCustomAttribute( + Type attributeType, + string propertyName, + object propertyValue) + { + SetCustomAttribute( + attributeType, + new PropertyInfo[] { attributeType.GetProperty(propertyName) }, + new object[] { propertyValue }); + } + + /// + /// Initializes a new instance of the class + /// with the specified parameters. + /// + /// Associated . + /// A + /// Generic arguments of the method. + /// The return type of the method. + /// The types of the parameters of the method. + internal MethodBuilderHelper( + TypeBuilderHelper typeBuilder, + MethodBuilder methodBuilder, + Type[] genericArguments, + Type returnType, + Type[] parameterTypes + ) + : base(typeBuilder) + { + if (methodBuilder == null) throw new ArgumentNullException("methodBuilder"); + if (genericArguments == null) throw new ArgumentNullException("genericArguments"); + + _methodBuilder = methodBuilder; + + var genArgNames = genericArguments.Select(t => t.Name).ToArray(); + var genParams = methodBuilder.DefineGenericParameters(genArgNames); + + // Copy parameter constraints. + // + List interfaceConstraints = null; + + for (var i = 0; i < genParams.Length; i++) + { + genParams[i].SetGenericParameterAttributes(genericArguments[i].GenericParameterAttributes); + + foreach (var constraint in genericArguments[i].GetGenericParameterConstraints()) + { + if (constraint.IsClass) + genParams[i].SetBaseTypeConstraint(constraint); + else + { + if (interfaceConstraints == null) + interfaceConstraints = new List(); + interfaceConstraints.Add(constraint); + } + } + + if (interfaceConstraints != null && interfaceConstraints.Count != 0) + { + genParams[i].SetInterfaceConstraints(interfaceConstraints.ToArray()); + interfaceConstraints.Clear(); + } + } + + // When a method contains a generic parameter we need to replace all + // generic types from methodInfoDeclaration with local ones. + // + for (var i = 0; i < parameterTypes.Length; i++) + parameterTypes[i] = TypeHelper.TranslateGenericParameters(parameterTypes[i], genParams); + + methodBuilder.SetParameters(parameterTypes); + methodBuilder.SetReturnType(TypeHelper.TranslateGenericParameters(returnType, genParams)); + + // Once all generic stuff is done is it is safe to call SetCustomAttribute + // + methodBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute); + } + + private readonly MethodBuilder _methodBuilder; + /// + /// Gets MethodBuilder. + /// + public MethodBuilder MethodBuilder + { + get { return _methodBuilder; } + } + + /// + /// Converts the supplied to a . + /// + /// The . + /// A . + public static implicit operator MethodBuilder(MethodBuilderHelper methodBuilder) + { + if (methodBuilder == null) throw new ArgumentNullException("methodBuilder"); + + return methodBuilder.MethodBuilder; + } + + private EmitHelper _emitter; + /// + /// Gets . + /// + public override EmitHelper Emitter + { + get + { + if (_emitter == null) + _emitter = new EmitHelper(this, _methodBuilder.GetILGenerator()); + + return _emitter; + } + } + + private MethodInfo _overriddenMethod; + /// + /// Gets or sets the base type method overridden by this method, if any. + /// + public MethodInfo OverriddenMethod + { + get { return _overriddenMethod; } + set { _overriddenMethod = value; } + } + + /// + /// Returns the type that declares this method. + /// + public Type DeclaringType + { + get { return _methodBuilder.DeclaringType; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Emit/TypeBuilderHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Emit/TypeBuilderHelper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,578 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; + +namespace BLToolkit.Reflection.Emit +{ + using TypeBuilder.Builders; + + /// + /// A wrapper around the class. + /// + /// + /// + /// TypeBuilder Class + public class TypeBuilderHelper + { + /// + /// Initializes a new instance of the class + /// with the specified parameters. + /// + /// Associated . + /// A + public TypeBuilderHelper(AssemblyBuilderHelper assemblyBuilder, System.Reflection.Emit.TypeBuilder typeBuilder) + { + if (assemblyBuilder == null) throw new ArgumentNullException("assemblyBuilder"); + if (typeBuilder == null) throw new ArgumentNullException("typeBuilder"); + + _assembly = assemblyBuilder; + _typeBuilder = typeBuilder; + + _typeBuilder.SetCustomAttribute(_assembly.BLToolkitAttribute); + } + + private readonly AssemblyBuilderHelper _assembly; + /// + /// Gets associated . + /// + public AssemblyBuilderHelper Assembly + { + get { return _assembly; } + } + + private readonly System.Reflection.Emit.TypeBuilder _typeBuilder; + /// + /// Gets . + /// + public System.Reflection.Emit.TypeBuilder TypeBuilder + { + get { return _typeBuilder; } + } + + /// + /// Converts the supplied to a . + /// + /// The . + /// A . + public static implicit operator System.Reflection.Emit.TypeBuilder(TypeBuilderHelper typeBuilder) + { + if (typeBuilder == null) throw new ArgumentNullException("typeBuilder"); + + return typeBuilder.TypeBuilder; + } + + #region DefineMethod Overrides + + /// + /// Adds a new method to the class, with the given name and method signature. + /// + /// The name of the method. name cannot contain embedded nulls. + /// The attributes of the method. + /// The return type of the method. + /// The types of the parameters of the method. + /// The defined method. + public MethodBuilderHelper DefineMethod( + string name, MethodAttributes attributes, Type returnType, params Type[] parameterTypes) + { + return new MethodBuilderHelper(this, _typeBuilder.DefineMethod(name, attributes, returnType, parameterTypes)); + } + + /// + /// Adds a new method to the class, with the given name and method signature. + /// + /// The name of the method. name cannot contain embedded nulls. + /// The attributes of the method. + /// The calling convention of the method. + /// The return type of the method. + /// The types of the parameters of the method. + /// The defined method. + public MethodBuilderHelper DefineMethod( + string name, + MethodAttributes attributes, + CallingConventions callingConvention, + Type returnType, + Type[] parameterTypes) + { + return new MethodBuilderHelper(this, _typeBuilder.DefineMethod( + name, attributes, callingConvention, returnType, parameterTypes)); + } + + /// + /// Adds a new method to the class, with the given name and method signature. + /// + /// The name of the method. name cannot contain embedded nulls. + /// The attributes of the method. + /// The return type of the method. + /// The defined method. + public MethodBuilderHelper DefineMethod(string name, MethodAttributes attributes, Type returnType) + { + return new MethodBuilderHelper( + this, + _typeBuilder.DefineMethod(name, attributes, returnType, Type.EmptyTypes)); + } + + /// + /// Adds a new method to the class, with the given name and method signature. + /// + /// The name of the method. name cannot contain embedded nulls. + /// The attributes of the method. + /// The defined method. + public MethodBuilderHelper DefineMethod(string name, MethodAttributes attributes) + { + return new MethodBuilderHelper( + this, + _typeBuilder.DefineMethod(name, attributes, typeof(void), Type.EmptyTypes)); + } + + /// + /// Adds a new method to the class, with the given name and method signature. + /// + /// The name of the method. name cannot contain embedded nulls. + /// The attributes of the method. + /// The defined method. + /// The calling convention of the method. + public MethodBuilderHelper DefineMethod( + string name, + MethodAttributes attributes, + CallingConventions callingConvention) + { + return new MethodBuilderHelper( + this, + _typeBuilder.DefineMethod(name, attributes, callingConvention)); + } + + /// + /// Adds a new method to the class, with the given name and method signature. + /// + /// The name of the method. name cannot contain embedded nulls. + /// The attributes of the method. + /// The calling convention of the method. + /// Generic arguments of the method. + /// The return type of the method. + /// The types of the parameters of the method. + /// The defined generic method. + public MethodBuilderHelper DefineGenericMethod( + string name, + MethodAttributes attributes, + CallingConventions callingConvention, + Type[] genericArguments, + Type returnType, + Type[] parameterTypes) + { + return new MethodBuilderHelper( + this, + _typeBuilder.DefineMethod(name, attributes, callingConvention), genericArguments, returnType, parameterTypes); + } + + + private Dictionary _overriddenMethods; + + /// + /// Retrieves the map of base type methods overridden by this type. + /// + public Dictionary OverriddenMethods + { + get { return _overriddenMethods ?? (_overriddenMethods = new Dictionary()); } + } + + /// + /// Adds a new method to the class, with the given name and method signature. + /// + /// The name of the method. name cannot contain embedded nulls. + /// The method whose declaration is to be used. + /// The attributes of the method. + /// The defined method. + public MethodBuilderHelper DefineMethod( + string name, + MethodInfo methodInfoDeclaration, + MethodAttributes attributes) + { + if (methodInfoDeclaration == null) throw new ArgumentNullException("methodInfoDeclaration"); + + MethodBuilderHelper method; + ParameterInfo[] pi = methodInfoDeclaration.GetParameters(); + Type[] parameters = new Type[pi.Length]; + + for (int i = 0; i < pi.Length; i++) + parameters[i] = pi[i].ParameterType; + + if (methodInfoDeclaration.ContainsGenericParameters) + { + method = DefineGenericMethod( + name, + attributes, + methodInfoDeclaration.CallingConvention, + methodInfoDeclaration.GetGenericArguments(), + methodInfoDeclaration.ReturnType, + parameters); + } + else + { + method = DefineMethod( + name, + attributes, + methodInfoDeclaration.CallingConvention, + methodInfoDeclaration.ReturnType, + parameters); + } + + // Compiler overrides methods only for interfaces. We do the same. + // If we wanted to override virtual methods, then methods should've had + // MethodAttributes.VtableLayoutMask attribute + // and the following condition should've been used below: + // if ((methodInfoDeclaration is FakeMethodInfo) == false) + // + if (methodInfoDeclaration.DeclaringType.IsInterface +#if !SILVERLIGHT + && !(methodInfoDeclaration is FakeMethodInfo) +#endif + ) + { + OverriddenMethods.Add(methodInfoDeclaration, method.MethodBuilder); + _typeBuilder.DefineMethodOverride(method.MethodBuilder, methodInfoDeclaration); + } + + method.OverriddenMethod = methodInfoDeclaration; + + for (int i = 0; i < pi.Length; i++) + method.MethodBuilder.DefineParameter(i + 1, pi[i].Attributes, pi[i].Name); + + return method; + } + + /// + /// Adds a new method to the class, with the given name and method signature. + /// + /// The name of the method. name cannot contain embedded nulls. + /// The method whose declaration is to be used. + /// The defined method. + public MethodBuilderHelper DefineMethod(string name, MethodInfo methodInfoDeclaration) + { + return DefineMethod(name, methodInfoDeclaration, MethodAttributes.Virtual); + } + + /// + /// Adds a new private method to the class. + /// + /// The method whose declaration is to be used. + /// The defined method. + public MethodBuilderHelper DefineMethod(MethodInfo methodInfoDeclaration) + { + if (methodInfoDeclaration == null) throw new ArgumentNullException("methodInfoDeclaration"); + + var isInterface = methodInfoDeclaration.DeclaringType.IsInterface; +#if SILVERLIGHT + var isFake = false; +#else + var isFake = methodInfoDeclaration is FakeMethodInfo; +#endif + + var name = isInterface && !isFake? + methodInfoDeclaration.DeclaringType.FullName + "." + methodInfoDeclaration.Name: + methodInfoDeclaration.Name; + + var attributes = + MethodAttributes.Virtual | + MethodAttributes.HideBySig | + MethodAttributes.PrivateScope | + methodInfoDeclaration.Attributes & MethodAttributes.SpecialName; + + if (isInterface && !isFake) + attributes |= MethodAttributes.Private; + else if ((attributes & MethodAttributes.SpecialName) != 0) + attributes |= MethodAttributes.Public; + else + attributes |= methodInfoDeclaration.Attributes & + (MethodAttributes.Public | MethodAttributes.Private); + + return DefineMethod(name, methodInfoDeclaration, attributes); + } + + #endregion + + /// + /// Creates a Type object for the class. + /// + /// Returns the new Type object for this class. + public Type Create() + { + return TypeBuilder.CreateType(); + } + + /// + /// Sets a custom attribute using a custom attribute type. + /// + /// Attribute type. + public void SetCustomAttribute(Type attributeType) + { + if (attributeType == null) throw new ArgumentNullException("attributeType"); + + ConstructorInfo ci = attributeType.GetConstructor(Type.EmptyTypes); + CustomAttributeBuilder caBuilder = new CustomAttributeBuilder(ci, new object[0]); + + _typeBuilder.SetCustomAttribute(caBuilder); + } + + /// + /// Sets a custom attribute using a custom attribute type + /// and named properties. + /// + /// Attribute type. + /// Named properties of the custom attribute. + /// Values for the named properties of the custom attribute. + public void SetCustomAttribute( + Type attributeType, + PropertyInfo[] properties, + object[] propertyValues) + { + if (attributeType == null) throw new ArgumentNullException("attributeType"); + + ConstructorInfo ci = attributeType.GetConstructor(Type.EmptyTypes); + CustomAttributeBuilder caBuilder = new CustomAttributeBuilder( + ci, new object[0], properties, propertyValues); + + _typeBuilder.SetCustomAttribute(caBuilder); + } + + /// + /// Sets a custom attribute using a custom attribute type + /// and named property. + /// + /// Attribute type. + /// A named property of the custom attribute. + /// Value for the named property of the custom attribute. + public void SetCustomAttribute( + Type attributeType, + string propertyName, + object propertyValue) + { + SetCustomAttribute( + attributeType, + new PropertyInfo[] { attributeType.GetProperty(propertyName) }, + new object[] { propertyValue } ); + } + + private ConstructorBuilderHelper _typeInitializer; + /// + /// Gets the initializer for this type. + /// + public ConstructorBuilderHelper TypeInitializer + { + get + { + if (_typeInitializer == null) + _typeInitializer = new ConstructorBuilderHelper(this, _typeBuilder.DefineTypeInitializer()); + + return _typeInitializer; + } + } + + /// + /// Returns true if the initializer for this type has a body. + /// + public bool IsTypeInitializerDefined + { + get { return _typeInitializer != null; } + } + + private ConstructorBuilderHelper _defaultConstructor; + /// + /// Gets the default constructor for this type. + /// + public ConstructorBuilderHelper DefaultConstructor + { + get + { + if (_defaultConstructor == null) + { + ConstructorBuilder builder = _typeBuilder.DefineConstructor( + MethodAttributes.Public, + CallingConventions.Standard, + Type.EmptyTypes); + + _defaultConstructor = new ConstructorBuilderHelper(this, builder); + } + + return _defaultConstructor; + } + } + + /// + /// Returns true if the default constructor for this type has a body. + /// + public bool IsDefaultConstructorDefined + { + get { return _defaultConstructor != null; } + } + + private ConstructorBuilderHelper _initConstructor; + /// + /// Gets the init context constructor for this type. + /// + public ConstructorBuilderHelper InitConstructor + { + get + { + if (_initConstructor == null) + { + ConstructorBuilder builder = _typeBuilder.DefineConstructor( + MethodAttributes.Public, + CallingConventions.Standard, + new Type[] { typeof(InitContext) }); + + _initConstructor = new ConstructorBuilderHelper(this, builder); + } + + return _initConstructor; + } + } + + /// + /// Returns true if a constructor with parameter of for this type has a body. + /// + public bool IsInitConstructorDefined + { + get { return _initConstructor != null; } + } + + /// + /// Adds a new field to the class, with the given name, attributes and field type. + /// + /// The name of the field. cannot contain embedded nulls. + /// The type of the field. + /// The attributes of the field. + /// The defined field. + public FieldBuilder DefineField( + string fieldName, + Type type, + FieldAttributes attributes) + { + return _typeBuilder.DefineField(fieldName, type, attributes); + } + + #region DefineConstructor Overrides + + /// + /// Adds a new public constructor to the class, with the given parameters. + /// + /// The types of the parameters of the method. + /// The defined constructor. + public ConstructorBuilderHelper DefinePublicConstructor(params Type[] parameterTypes) + { + return new ConstructorBuilderHelper( + this, + _typeBuilder.DefineConstructor( + MethodAttributes.Public, CallingConventions.Standard, parameterTypes)); + } + + /// + /// Adds a new constructor to the class, with the given attributes and parameters. + /// + /// The attributes of the field. + /// The calling convention of the method. + /// The types of the parameters of the method. + /// The defined constructor. + public ConstructorBuilderHelper DefineConstructor( + MethodAttributes attributes, + CallingConventions callingConvention, + params Type[] parameterTypes) + { + return new ConstructorBuilderHelper( + this, + _typeBuilder.DefineConstructor(attributes, callingConvention, parameterTypes)); + } + + #endregion + + #region DefineNestedType Overrides + + /// + /// Defines a nested type given its name.. + /// + /// The short name of the type. + /// Returns the created . + /// + /// TypeBuilder.DefineNestedType Method + public TypeBuilderHelper DefineNestedType(string name) + { + return new TypeBuilderHelper(_assembly, _typeBuilder.DefineNestedType(name)); + } + + /// + /// Defines a public nested type given its name and the type that it extends. + /// + /// The short name of the type. + /// The type that the nested type extends. + /// Returns the created . + /// + /// TypeBuilder.DefineNestedType Method + public TypeBuilderHelper DefineNestedType(string name, Type parent) + { + return new TypeBuilderHelper( + _assembly, + _typeBuilder.DefineNestedType(name, TypeAttributes.NestedPublic, parent)); + } + + /// + /// Defines a nested type given its name, attributes, and the type that it extends. + /// + /// The short name of the type. + /// The attributes of the type. + /// The type that the nested type extends. + /// Returns the created . + /// + /// TypeBuilder.DefineNestedType Method + public TypeBuilderHelper DefineNestedType( + string name, + TypeAttributes attributes, + Type parent) + { + return new TypeBuilderHelper( + _assembly, + _typeBuilder.DefineNestedType(name, attributes, parent)); + } + + /// + /// Defines a public nested type given its name, the type that it extends, and the interfaces that it implements. + /// + /// The short name of the type. + /// The type that the nested type extends. + /// The interfaces that the nested type implements. + /// Returns the created . + /// + /// TypeBuilder.DefineNestedType Method + public TypeBuilderHelper DefineNestedType( + string name, + Type parent, + params Type[] interfaces) + { + return new TypeBuilderHelper( + _assembly, + _typeBuilder.DefineNestedType(name, TypeAttributes.NestedPublic, parent, interfaces)); + } + + /// + /// Defines a nested type given its name, attributes, the type that it extends, and the interfaces that it implements. + /// + /// The short name of the type. + /// The attributes of the type. + /// The type that the nested type extends. + /// The interfaces that the nested type implements. + /// Returns the created . + /// ModuleBuilder.DefineType Method + public TypeBuilderHelper DefineNestedType( + string name, + TypeAttributes attributes, + Type parent, + params Type[] interfaces) + { + return new TypeBuilderHelper( + _assembly, + _typeBuilder.DefineNestedType(name, attributes, parent, interfaces)); + } + + #endregion + + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/ExprMemberAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/ExprMemberAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,717 @@ +using System; +using System.Data.SqlTypes; +using System.Linq.Expressions; +using System.Reflection; +using System.Reflection.Emit; + +namespace BLToolkit.Reflection +{ + using Common; + using Emit; + + public abstract class ExprMemberAccessor : MemberAccessor + { + protected ExprMemberAccessor(TypeAccessor typeAccessor, MemberInfo memberInfo) + : base(typeAccessor, memberInfo) + { + } + + #region Public Properties + + protected bool HasSetterValue; + public override bool HasGetter { get { return true; } } + public override bool HasSetter { get { return HasSetterValue; } } + + #endregion + + static public MemberAccessor GetMemberAccessor(TypeAccessor typeAccessor, string memberName) + { + var par = Expression.Parameter(typeof(object), "obj"); + var expr = Expression.PropertyOrField(Expression.Convert(par, typeAccessor.Type), memberName); + + var type = expr.Type; + + var underlyingType = type; + var isNullable = false; + + if (underlyingType.IsGenericType && underlyingType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + underlyingType = underlyingType.GetGenericArguments()[0]; + isNullable = true; + } + + if (underlyingType.IsEnum) + underlyingType = Enum.GetUnderlyingType(underlyingType); + + if (isNullable) + { + switch (Type.GetTypeCode(underlyingType)) + { + case TypeCode.Boolean : return new NullableBooleanAccessor (typeAccessor, par, expr); + case TypeCode.Char : return new NullableCharAccessor (typeAccessor, par, expr); + case TypeCode.SByte : return new NullableSByteAccessor (typeAccessor, par, expr); + case TypeCode.Byte : return new NullableByteAccessor (typeAccessor, par, expr); + case TypeCode.Int16 : return new NullableInt16Accessor (typeAccessor, par, expr); + case TypeCode.UInt16 : return new NullableUInt16Accessor (typeAccessor, par, expr); + case TypeCode.Int32 : return new NullableInt32Accessor (typeAccessor, par, expr); + case TypeCode.UInt32 : return new NullableUInt32Accessor (typeAccessor, par, expr); + case TypeCode.Int64 : return new NullableInt64Accessor (typeAccessor, par, expr); + case TypeCode.UInt64 : return new NullableUInt64Accessor (typeAccessor, par, expr); + case TypeCode.Single : return new NullableSingleAccessor (typeAccessor, par, expr); + case TypeCode.Double : return new NullableDoubleAccessor (typeAccessor, par, expr); + case TypeCode.Decimal : return new NullableDecimalAccessor (typeAccessor, par, expr); + case TypeCode.DateTime : return new NullableDateTimeAccessor(typeAccessor, par, expr); + case TypeCode.Object : + if (type == typeof(Guid)) return new NullableGuidAccessor (typeAccessor, par, expr); + if (type == typeof(DateTimeOffset)) return new NullableDateTimeOffsetAccessor(typeAccessor, par, expr); + if (type == typeof(TimeSpan)) return new NullableTimeSpanAccessor (typeAccessor, par, expr); + break; + default : break; + } + } + else + { + switch (Type.GetTypeCode(underlyingType)) + { + case TypeCode.Boolean : return new BooleanAccessor (typeAccessor, par, expr); + case TypeCode.Char : return new CharAccessor (typeAccessor, par, expr); + case TypeCode.SByte : return new SByteAccessor (typeAccessor, par, expr); + case TypeCode.Byte : return new ByteAccessor (typeAccessor, par, expr); + case TypeCode.Int16 : return new Int16Accessor (typeAccessor, par, expr); + case TypeCode.UInt16 : return new UInt16Accessor (typeAccessor, par, expr); + case TypeCode.Int32 : return new Int32Accessor (typeAccessor, par, expr); + case TypeCode.UInt32 : return new UInt32Accessor (typeAccessor, par, expr); + case TypeCode.Int64 : return new Int64Accessor (typeAccessor, par, expr); + case TypeCode.UInt64 : return new UInt64Accessor (typeAccessor, par, expr); + case TypeCode.Single : return new SingleAccessor (typeAccessor, par, expr); + case TypeCode.Double : return new DoubleAccessor (typeAccessor, par, expr); + case TypeCode.Decimal : return new DecimalAccessor (typeAccessor, par, expr); + case TypeCode.DateTime : return new DateTimeAccessor(typeAccessor, par, expr); + case TypeCode.Object : + if (type == typeof(Guid)) return new GuidAccessor (typeAccessor, par, expr); + if (type == typeof(DateTimeOffset)) return new DateTimeOffsetAccessor(typeAccessor, par, expr); + if (type == typeof(TimeSpan)) return new TimeSpanAccessor (typeAccessor, par, expr); + break; + default : break; + } + } + +#if !SILVERLIGHT + + if (type == typeof(SqlByte)) return new SqlByteAccessor (typeAccessor, par, expr); + if (type == typeof(SqlInt16)) return new SqlInt16Accessor (typeAccessor, par, expr); + if (type == typeof(SqlInt32)) return new SqlInt32Accessor (typeAccessor, par, expr); + if (type == typeof(SqlInt64)) return new SqlInt64Accessor (typeAccessor, par, expr); + if (type == typeof(SqlSingle)) return new SqlSingleAccessor (typeAccessor, par, expr); + if (type == typeof(SqlBoolean)) return new SqlBooleanAccessor (typeAccessor, par, expr); + if (type == typeof(SqlDouble)) return new SqlDoubleAccessor (typeAccessor, par, expr); + if (type == typeof(SqlDateTime)) return new SqlDateTimeAccessor(typeAccessor, par, expr); + if (type == typeof(SqlDecimal)) return new SqlDecimalAccessor (typeAccessor, par, expr); + if (type == typeof(SqlMoney)) return new SqlMoneyAccessor (typeAccessor, par, expr); + if (type == typeof(SqlString)) return new SqlStringAccessor (typeAccessor, par, expr); + if (type == typeof(SqlGuid)) return new SqlGuidAccessor (typeAccessor, par, expr); + +#endif + + return (MemberAccessor)Activator.CreateInstance( + typeof(BaseAccessor<>).MakeGenericType(type), + new object[] { typeAccessor, par, expr }); + } + + class BaseAccessor : ExprMemberAccessor + { + protected readonly Func Getter; + protected readonly Action Setter; + + static int _counter; + + public BaseAccessor(TypeAccessor typeAccessor, ParameterExpression par, MemberExpression expr) + : base(typeAccessor, expr.Member) + { + Expression ex = expr; + + if (TypeHelper.IsEnumOrNullableEnum(ex.Type) && ex.Type != typeof(T)) + ex = Expression.Convert(ex, typeof(T)); + + Getter = Expression.Lambda>(ex, par).Compile(); + + var mi = expr.Member; + + HasSetterValue = !(mi is PropertyInfo) || ((PropertyInfo)mi).GetSetMethod(true) != null; + + if (HasSetterValue) + { + var dm = new DynamicMethod( + "setter_" + mi.Name + "_" + ++_counter, + typeof(void), + new[] { typeof(object), typeof(T) }, + typeAccessor.Type); + var emit = new EmitHelper(dm.GetILGenerator()); + + emit + .ldarg_0 + .castType (typeAccessor.Type) + .ldarg_1 + .end(); + + if (mi is FieldInfo) emit.stfld ((FieldInfo)mi); + else emit.callvirt(((PropertyInfo)mi).GetSetMethod(true)); + + emit.ret(); + + Setter = (Action)dm.CreateDelegate(typeof(Action)); + } + else + { + Setter = (_,__) => {}; + } + } + + public override object GetValue(object obj) + { + return Getter(obj); + } + + public override void SetValue(object obj, object value) + { + Setter(obj, ConvertTo.From(value)); + } + } + + class NullableAccessor : BaseAccessor + where T : struct + { + public NullableAccessor(TypeAccessor typeAccessor, ParameterExpression par, MemberExpression member) + : base(typeAccessor, par, member) + { + } + + public override bool IsNull(object obj) + { + return Getter(obj) == null; + } + } + + #region Basic Types + + class BooleanAccessor : BaseAccessor + { + public BooleanAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Boolean GetBoolean(object obj) { return Getter(obj); } + public override void SetBoolean(object obj, Boolean value) { Setter(obj, value); } + } + + class CharAccessor : BaseAccessor + { + public CharAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Char GetChar(object obj) { return Getter(obj); } + public override void SetChar(object obj, Char value) { Setter(obj, value); } + } + + class SByteAccessor : BaseAccessor + { + public SByteAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SByte GetSByte(object obj) { return Getter(obj); } + public override void SetSByte(object obj, SByte value) { Setter(obj, value); } + } + + class ByteAccessor : BaseAccessor + { + public ByteAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Byte GetByte(object obj) { return Getter(obj); } + public override void SetByte(object obj, Byte value) { Setter(obj, value); } + } + + class Int16Accessor : BaseAccessor + { + public Int16Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Int16 GetInt16(object obj) { return Getter(obj); } + public override void SetInt16(object obj, Int16 value) { Setter(obj, value); } + } + + class UInt16Accessor : BaseAccessor + { + public UInt16Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override UInt16 GetUInt16(object obj) { return Getter(obj); } + public override void SetUInt16(object obj, UInt16 value) { Setter(obj, value); } + } + + class Int32Accessor : BaseAccessor + { + public Int32Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Int32 GetInt32(object obj) { return Getter(obj); } + public override void SetInt32(object obj, Int32 value) { Setter(obj, value); } + } + + class UInt32Accessor : BaseAccessor + { + public UInt32Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override UInt32 GetUInt32(object obj) { return Getter(obj); } + public override void SetUInt32(object obj, UInt32 value) { Setter(obj, value); } + } + + class Int64Accessor : BaseAccessor + { + public Int64Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Int64 GetInt64(object obj) { return Getter(obj); } + public override void SetInt64(object obj, Int64 value) { Setter(obj, value); } + } + + class UInt64Accessor : BaseAccessor + { + public UInt64Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override UInt64 GetUInt64(object obj) { return Getter(obj); } + public override void SetUInt64(object obj, UInt64 value) { Setter(obj, value); } + } + + class SingleAccessor : BaseAccessor + { + public SingleAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Single GetSingle(object obj) { return Getter(obj); } + public override void SetSingle(object obj, Single value) { Setter(obj, value); } + } + + class DoubleAccessor : BaseAccessor + { + public DoubleAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Double GetDouble(object obj) { return Getter(obj); } + public override void SetDouble(object obj, Double value) { Setter(obj, value); } + } + + class DecimalAccessor : BaseAccessor + { + public DecimalAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Decimal GetDecimal(object obj) { return Getter(obj); } + public override void SetDecimal(object obj, Decimal value) { Setter(obj, value); } + } + + class DateTimeAccessor : BaseAccessor + { + public DateTimeAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override DateTime GetDateTime(object obj) { return Getter(obj); } + public override void SetDateTime(object obj, DateTime value) { Setter(obj, value); } + } + + class GuidAccessor : BaseAccessor + { + public GuidAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Guid GetGuid(object obj) { return Getter(obj); } + public override void SetGuid(object obj, Guid value) { Setter(obj, value); } + } + + class DateTimeOffsetAccessor : BaseAccessor + { + public DateTimeOffsetAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override DateTimeOffset GetDateTimeOffset(object obj) { return Getter(obj); } + public override void SetDateTimeOffset(object obj, DateTimeOffset value) { Setter(obj, value); } + } + + class TimeSpanAccessor : BaseAccessor + { + public TimeSpanAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override TimeSpan GetTimeSpan(object obj) { return Getter(obj); } + public override void SetTimeSpan(object obj, TimeSpan value) { Setter(obj, value); } + } + + #endregion + + #region Nullable + + class NullableBooleanAccessor : NullableAccessor + { + public NullableBooleanAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Boolean? GetNullableBoolean(object obj) { return Getter(obj); } + public override void SetNullableBoolean(object obj, Boolean? value) { Setter(obj, value); } + } + + class NullableCharAccessor : NullableAccessor + { + public NullableCharAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Char? GetNullableChar(object obj) { return Getter(obj); } + public override void SetNullableChar(object obj, Char? value) { Setter(obj, value); } + } + + class NullableSByteAccessor : NullableAccessor + { + public NullableSByteAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SByte? GetNullableSByte(object obj) { return Getter(obj); } + public override void SetNullableSByte(object obj, SByte? value) { Setter(obj, value); } + } + + class NullableByteAccessor : NullableAccessor + { + public NullableByteAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Byte? GetNullableByte(object obj) { return Getter(obj); } + public override void SetNullableByte(object obj, Byte? value) { Setter(obj, value); } + } + + class NullableInt16Accessor : NullableAccessor + { + public NullableInt16Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Int16? GetNullableInt16(object obj) { return Getter(obj); } + public override void SetNullableInt16(object obj, Int16? value) { Setter(obj, value); } + } + + class NullableUInt16Accessor : NullableAccessor + { + public NullableUInt16Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override UInt16? GetNullableUInt16(object obj) { return Getter(obj); } + public override void SetNullableUInt16(object obj, UInt16? value) { Setter(obj, value); } + } + + class NullableInt32Accessor : NullableAccessor + { + public NullableInt32Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Int32? GetNullableInt32(object obj) { return Getter(obj); } + public override void SetNullableInt32(object obj, Int32? value) { Setter(obj, value); } + } + + class NullableUInt32Accessor : NullableAccessor + { + public NullableUInt32Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override UInt32? GetNullableUInt32(object obj) { return Getter(obj); } + public override void SetNullableUInt32(object obj, UInt32? value) { Setter(obj, value); } + } + + class NullableInt64Accessor : NullableAccessor + { + public NullableInt64Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Int64? GetNullableInt64(object obj) { return Getter(obj); } + public override void SetNullableInt64(object obj, Int64? value) { Setter(obj, value); } + } + + class NullableUInt64Accessor : NullableAccessor + { + public NullableUInt64Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override UInt64? GetNullableUInt64(object obj) { return Getter(obj); } + public override void SetNullableUInt64(object obj, UInt64? value) { Setter(obj, value); } + } + + class NullableSingleAccessor : NullableAccessor + { + public NullableSingleAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Single? GetNullableSingle(object obj) { return Getter(obj); } + public override void SetNullableSingle(object obj, Single? value) { Setter(obj, value); } + } + + class NullableDoubleAccessor : NullableAccessor + { + public NullableDoubleAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Double? GetNullableDouble(object obj) { return Getter(obj); } + public override void SetNullableDouble(object obj, Double? value) { Setter(obj, value); } + } + + class NullableDecimalAccessor : NullableAccessor + { + public NullableDecimalAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Decimal? GetNullableDecimal(object obj) { return Getter(obj); } + public override void SetNullableDecimal(object obj, Decimal? value) { Setter(obj, value); } + } + + class NullableDateTimeAccessor : NullableAccessor + { + public NullableDateTimeAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override DateTime? GetNullableDateTime(object obj) { return Getter(obj); } + public override void SetNullableDateTime(object obj, DateTime? value) { Setter(obj, value); } + } + + class NullableGuidAccessor : NullableAccessor + { + public NullableGuidAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override Guid? GetNullableGuid(object obj) { return Getter(obj); } + public override void SetNullableGuid(object obj, Guid? value) { Setter(obj, value); } + } + + class NullableDateTimeOffsetAccessor : NullableAccessor + { + public NullableDateTimeOffsetAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override DateTimeOffset? GetNullableDateTimeOffset(object obj) { return Getter(obj); } + public override void SetNullableDateTimeOffset(object obj, DateTimeOffset? value) { Setter(obj, value); } + } + + class NullableTimeSpanAccessor : NullableAccessor + { + public NullableTimeSpanAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override TimeSpan? GetNullableTimeSpan(object obj) { return Getter(obj); } + public override void SetNullableTimeSpan(object obj, TimeSpan? value) { Setter(obj, value); } + } + + #endregion + + #region Sql Types + +#if !SILVERLIGHT + + class SqlByteAccessor : BaseAccessor + { + public SqlByteAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SqlByte GetSqlByte(object obj) { return Getter(obj); } + public override void SetSqlByte(object obj, SqlByte value) { Setter(obj, value); } + } + + class SqlInt16Accessor : BaseAccessor + { + public SqlInt16Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SqlInt16 GetSqlInt16(object obj) { return Getter(obj); } + public override void SetSqlInt16(object obj, SqlInt16 value) { Setter(obj, value); } + } + + class SqlInt32Accessor : BaseAccessor + { + public SqlInt32Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SqlInt32 GetSqlInt32(object obj) { return Getter(obj); } + public override void SetSqlInt32(object obj, SqlInt32 value) { Setter(obj, value); } + } + + class SqlInt64Accessor : BaseAccessor + { + public SqlInt64Accessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SqlInt64 GetSqlInt64(object obj) { return Getter(obj); } + public override void SetSqlInt64(object obj, SqlInt64 value) { Setter(obj, value); } + } + + class SqlSingleAccessor : BaseAccessor + { + public SqlSingleAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SqlSingle GetSqlSingle(object obj) { return Getter(obj); } + public override void SetSqlSingle(object obj, SqlSingle value) { Setter(obj, value); } + } + + class SqlBooleanAccessor : BaseAccessor + { + public SqlBooleanAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SqlBoolean GetSqlBoolean(object obj) { return Getter(obj); } + public override void SetSqlBoolean(object obj, SqlBoolean value) { Setter(obj, value); } + } + + class SqlDoubleAccessor : BaseAccessor + { + public SqlDoubleAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SqlDouble GetSqlDouble(object obj) { return Getter(obj); } + public override void SetSqlDouble(object obj, SqlDouble value) { Setter(obj, value); } + } + + class SqlDateTimeAccessor : BaseAccessor + { + public SqlDateTimeAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SqlDateTime GetSqlDateTime(object obj) { return Getter(obj); } + public override void SetSqlDateTime(object obj, SqlDateTime value) { Setter(obj, value); } + } + + class SqlDecimalAccessor : BaseAccessor + { + public SqlDecimalAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SqlDecimal GetSqlDecimal(object obj) { return Getter(obj); } + public override void SetSqlDecimal(object obj, SqlDecimal value) { Setter(obj, value); } + } + + class SqlMoneyAccessor : BaseAccessor + { + public SqlMoneyAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SqlMoney GetSqlMoney(object obj) { return Getter(obj); } + public override void SetSqlMoney(object obj, SqlMoney value) { Setter(obj, value); } + } + + class SqlStringAccessor : BaseAccessor + { + public SqlStringAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SqlString GetSqlString(object obj) { return Getter(obj); } + public override void SetSqlString(object obj, SqlString value) { Setter(obj, value); } + } + + class SqlGuidAccessor : BaseAccessor + { + public SqlGuidAccessor(TypeAccessor accessor, ParameterExpression expression, MemberExpression expr) + : base(accessor, expression, expr) + { + } + + public override SqlGuid GetSqlGuid(object obj) { return Getter(obj); } + public override void SetSqlGuid(object obj, SqlGuid value) { Setter(obj, value); } + } + +#endif + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/ExprTypeAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/ExprTypeAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,125 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Reflection; + +namespace BLToolkit.Reflection +{ + using TypeBuilder; + + class ExprTypeAccessor : TypeAccessor + { + static ExprTypeAccessor() + { + // Create Instance. + // + var type = typeof(T); + var typeInit = typeof(InitContext); + var initPar = Expression.Parameter(typeInit, "ctx"); + + if (type.IsValueType) + { + _createInstance = () => default(T); + _createInstanceInit = ctx => default(T); + } + else + { + var ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Type.EmptyTypes, null); + var ctorInit = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new[] { typeInit }, null); + + if (ctor == null && ctorInit == null) + { + Expression> mi = () => ThrowException(); + + var body = Expression.Call(null, ((MethodCallExpression)mi.Body).Method); + + _createInstance = Expression.Lambda>(body).Compile(); + _createInstanceInit = Expression.Lambda>(body, initPar).Compile(); + } + else + { + _createInstance = ctor != null ? + Expression.Lambda>(Expression.New(ctor)).Compile() : + Expression.Lambda>(Expression.New(ctorInit, Expression.Constant(null))).Compile(); + + _createInstanceInit = ctorInit != null ? + Expression.Lambda>(Expression.New(ctorInit, initPar), initPar).Compile() : + Expression.Lambda>(Expression.New(ctor), initPar).Compile(); + } + } + + var originalType = typeof(TOriginal); + + // Add fields. + // + foreach (var fi in originalType.GetFields(BindingFlags.Instance | BindingFlags.Public)) + _members.Add(fi); + + foreach (var pi in originalType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) + if (pi.GetIndexParameters().Length == 0) + _members.Add(pi); + + // Add explicit iterface implementation properties support + // Or maybe we should support all private fields/properties? + var interfaceMethods = originalType.GetInterfaces().SelectMany(ti => originalType.GetInterfaceMap(ti).TargetMethods).ToList(); + + if (interfaceMethods.Count > 0) + { + foreach (var pi in originalType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic)) + { + if (pi.GetIndexParameters().Length == 0) + { + var getMethod = pi.GetGetMethod(true); + var setMethod = pi.GetSetMethod(true); + + if ((getMethod == null || interfaceMethods.Contains(getMethod)) && + (setMethod == null || interfaceMethods.Contains(setMethod))) + { + _members.Add(pi); + } + } + } + } + + // ObjectFactory + // + var attr = TypeHelper.GetFirstAttribute(type, typeof(ObjectFactoryAttribute)); + + if (attr != null) + _objectFactory = ((ObjectFactoryAttribute)attr).ObjectFactory; + } + + static T ThrowException() + { + throw new TypeBuilderException(string.Format("The '{0}' type must have default or init constructor.", typeof(TOriginal).FullName)); + } + + static readonly List _members = new List(); + static readonly IObjectFactory _objectFactory; + + public ExprTypeAccessor() + { + foreach (var member in _members) + AddMember(ExprMemberAccessor.GetMemberAccessor(this, member.Name)); + + ObjectFactory = _objectFactory; + } + + static readonly Func _createInstance; + public override object CreateInstance() + { + return _createInstance(); + } + + static readonly Func _createInstanceInit; + + public override object CreateInstance(InitContext context) + { + return _createInstanceInit(context); + } + + public override Type Type { get { return typeof(T); } } + public override Type OriginalType { get { return typeof(TOriginal); } } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Extension/AttributeExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Extension/AttributeExtension.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +using System; + +namespace BLToolkit.Reflection.Extension +{ + public class AttributeExtension + { + public AttributeExtension() + { + Values = new ValueCollection(); + } + + private AttributeExtension(ValueCollection values) + { + Values = values; + } + + public string Name { get; set; } + public ValueCollection Values { get; private set; } + + public object Value + { + get { return this == _null? null: Values.Value; } + } + + public object this[string valueName] + { + get { return this == _null? null: Values[valueName]; } + } + + public object this[string valueName, object defaultValue] + { + get { return this[valueName] ?? defaultValue; } + } + + private AttributeNameCollection _attributes; + public AttributeNameCollection Attributes + { + get { return _attributes ?? (_attributes = new AttributeNameCollection()); } + } + + private static readonly AttributeExtension _null = new AttributeExtension(ValueCollection.Null); + public static AttributeExtension Null + { + get { return _null; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Extension/AttributeExtensionCollection.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Extension/AttributeExtensionCollection.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; + +namespace BLToolkit.Reflection.Extension +{ + public class AttributeExtensionCollection : List + { + public new AttributeExtension this[int index] + { + get + { + return this == _null || index < 0 || index >= Count ? AttributeExtension.Null : base[index]; + } + } + + public object Value + { + get { return this == _null? null: this[0].Value; } + } + + public new void Add(AttributeExtension attributeExtension) + { + if (this != _null) + base.Add(attributeExtension); + } + + private static readonly AttributeExtensionCollection _null = new AttributeExtensionCollection(); + public static AttributeExtensionCollection Null + { + get { return _null; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Extension/AttributeNameCollection.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Extension/AttributeNameCollection.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; + +namespace BLToolkit.Reflection.Extension +{ + public class AttributeNameCollection : Dictionary + { + public new AttributeExtensionCollection this[string attributeName] + { + get + { + if (this == _null) + return AttributeExtensionCollection.Null; + + AttributeExtensionCollection ext; + + return TryGetValue(attributeName, out ext) ? ext : AttributeExtensionCollection.Null; + } + } + + public void Add(AttributeExtension attributeExtension) + { + if (this != _null) + { + // Add attribute. + // + AttributeExtensionCollection attr; + + if (!TryGetValue(attributeExtension.Name, out attr)) + Add(attributeExtension.Name, attr = new AttributeExtensionCollection()); + + attr.Add(attributeExtension); + + /* + // Convert value type. + // + bool isType = attributeExtension.Name.EndsWith(TypeExtension.AttrName.TypePostfix); + + if (isType) + { + string attrName = attributeExtension.Name.Substring( + 0, attributeExtension.Name.Length - 5); + + AttributeExtensionCollection ext = + (AttributeExtensionCollection)_attributes[attrName]; + + if (ext != null && ext.Count == 1) + ext[0].Values.ChangeValueType(attributeExtension.Value.ToString()); + } + else + { + string attrName = attributeExtension.Name + TypeExtension.AttrName.TypePostfix; + + AttributeExtensionCollection ext = + (AttributeExtensionCollection)_attributes[attrName]; + + if (ext != null && ext.Count == 1) + attributeExtension.Values.ChangeValueType(ext.Value.ToString()); + } + */ + } + } + + public void Add(string name, string value) + { + if (this != _null) + { + var attrName = name; + var valueName = string.Empty; + var idx = name.IndexOf(TypeExtension.ValueName.Delimiter); + + if (idx > 0) + { + valueName = name.Substring(idx + 1).TrimStart(TypeExtension.ValueName.Delimiter); + attrName = name.Substring(0, idx); + } + + if (valueName.Length == 0) + valueName = TypeExtension.ValueName.Value; + else if (valueName == TypeExtension.ValueName.Type) + valueName = TypeExtension.ValueName.ValueType; + + AttributeExtensionCollection ext; + + if (TryGetValue(attrName, out ext)) + ext[0].Values.Add(valueName, value); + else + { + var attributeExtension = new AttributeExtension { Name = name }; + + attributeExtension.Values.Add(valueName, value); + + Add(attributeExtension); + } + } + } + + private static readonly AttributeNameCollection _null = new AttributeNameCollection(); + public static AttributeNameCollection Null + { + get { return _null; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Extension/ExtensionList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Extension/ExtensionList.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; + +namespace BLToolkit.Reflection.Extension +{ + public class ExtensionList : Dictionary + { + public new TypeExtension this[string typeName] + { + get + { + TypeExtension value; + lock (this) + return TryGetValue(typeName, out value) ? value : TypeExtension.Null; + } + } + + public TypeExtension this[Type type] + { + get + { + lock (this) + foreach (var ext in Values) + if (ext.Name == type.Name || ext.Name == type.FullName) + return ext; + + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + return this[Nullable.GetUnderlyingType(type)]; + + return TypeExtension.Null; + } + } + + public void Add(TypeExtension typeInfo) + { + lock (this) + Add(typeInfo.Name, typeInfo); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Extension/MemberExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Extension/MemberExtension.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +using System; + +namespace BLToolkit.Reflection.Extension +{ + public class MemberExtension + { + public MemberExtension() + { + _attributes = new AttributeNameCollection(); + } + + private MemberExtension(AttributeNameCollection attributes) + { + _attributes = attributes; + } + + public string Name { get; set; } + + public AttributeExtensionCollection this[string attributeName] + { + get { return _attributes[attributeName]; } + } + + private readonly AttributeNameCollection _attributes; + public AttributeNameCollection Attributes + { + get { return _attributes; } + } + + private static readonly MemberExtension _null = new MemberExtension(AttributeNameCollection.Null); + public static MemberExtension Null + { + get { return _null; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Extension/MemberExtensionCollection.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Extension/MemberExtensionCollection.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; + +namespace BLToolkit.Reflection.Extension +{ + public class MemberExtensionCollection : Dictionary + { + public new MemberExtension this[string memberName] + { + get + { + if (this == _null) + return MemberExtension.Null; + + MemberExtension value; + + return TryGetValue(memberName, out value) ? value : MemberExtension.Null; + } + } + + public void Add(MemberExtension memberInfo) + { + if (this != _null) + Add(memberInfo.Name, memberInfo); + } + + private static readonly MemberExtensionCollection _null = new MemberExtensionCollection(); + public static MemberExtensionCollection Null + { + get { return _null; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Extension/TypeExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Extension/TypeExtension.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,305 @@ +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Xml.Linq; + +namespace BLToolkit.Reflection.Extension +{ + public class TypeExtension + { + #region Consts + + public static class NodeName + { + public const string Type = "Type"; + public const string Member = "Member"; + public const string Association = "Association"; + public const string Relation = "Relation"; + public const string MasterIndex = "MasterIndex"; + public const string SlaveIndex = "SlaveIndex"; + } + + public static class AttrName + { + public const string Name = "Name"; + public const string DestinationType = "DestinationType"; + } + + public static class ValueName + { + public const char Delimiter = '-'; + public const string Value = "Value"; + public const string Type = "Type"; + public const string ValueType = "Value-Type"; + public const string TypePostfix = "-Type"; + } + + #endregion + + #region Public Instance Members + + public TypeExtension() + : this(new MemberExtensionCollection(), new AttributeNameCollection()) + { + } + + private TypeExtension( + MemberExtensionCollection members, + AttributeNameCollection attributes) + { + _members = members; + _attributes = attributes; + } + + public string Name { get; set; } + + public MemberExtension this[string memberName] + { + get { return _members[memberName]; } + } + + private readonly MemberExtensionCollection _members; + public MemberExtensionCollection Members + { + get { return _members; } + } + + private readonly AttributeNameCollection _attributes; + public AttributeNameCollection Attributes + { + get { return _attributes; } + } + + private static readonly TypeExtension _null = new TypeExtension(MemberExtensionCollection.Null, AttributeNameCollection.Null); + public static TypeExtension Null + { + get { return _null; } + } + + #endregion + + #region Conversion + + public static bool ToBoolean(object value, bool defaultValue) + { + return value == null? defaultValue: ToBoolean(value); + } + + public static bool ToBoolean(object value) + { + if (value != null) + { + if (value is bool) + return (bool)value; + + var s = value as string; + + if (s != null) + { + if (s == "1") + return true; + + s = s.ToLower(); + + if (s == "true" || s == "yes" || s == "on") + return true; + } + + return Convert.ToBoolean(value); + } + + return false; + } + + public static object ChangeType(object value, Type type) + { + if (value == null || type == value.GetType()) + return value; + + if (type == typeof(string)) + return value.ToString(); + + if (type == typeof(bool)) + return ToBoolean(value); + + if (type.IsEnum) + { + if (value is string) + return Enum.Parse(type, value.ToString(), false); + } + + return Convert.ChangeType(value, type, Thread.CurrentThread.CurrentCulture); + } + + #endregion + + #region Public Static Members + + public static ExtensionList GetExtensions(string xmlFile) + { + return GetExtensions(xmlFile, Assembly.GetCallingAssembly()); + } + + public static ExtensionList GetExtensions(string xmlFile, Assembly assembly) + { + StreamReader streamReader = null; + + try + { + if (File.Exists(xmlFile)) + { + streamReader = File.OpenText(xmlFile); + } +#if !SILVERLIGHT + else + { + var combinePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, xmlFile); + + if (File.Exists(combinePath)) + streamReader = File.OpenText(combinePath); + } +#endif + + var embedded = streamReader == null; + var stream = embedded ? assembly.GetManifestResourceStream(xmlFile) : streamReader.BaseStream; + + if (embedded && stream == null) + { + var names = assembly.GetManifestResourceNames(); + + // Prepare file name with a dot to avoid partial name matching. + // + xmlFile = "." + xmlFile; + + foreach (var name in names) + { + if (name.EndsWith(xmlFile)) + { + stream = assembly.GetManifestResourceStream(name); + break; + } + } + } + + if (stream == null) + throw new TypeExtensionException( + string.Format("Could not find file '{0}'.", xmlFile)); + + using (stream) + return GetExtensions(stream); + } + finally + { + if (streamReader != null) + streamReader.Close(); + } + } + + public static ExtensionList GetExtensions(Stream xmlDocStream) + { + var doc = XDocument.Load(new StreamReader(xmlDocStream)); + + return CreateTypeInfo(doc); + } + + public static TypeExtension GetTypeExtension(Type type, ExtensionList typeExtensions) + { + var attrs = type.GetCustomAttributes(typeof(TypeExtensionAttribute), true); + + if (attrs != null && attrs.Length != 0) + { + var attr = (TypeExtensionAttribute)attrs[0]; + + if (!string.IsNullOrEmpty(attr.FileName)) + typeExtensions = GetExtensions(attr.FileName, type.Assembly); + + if (typeExtensions != null && !string.IsNullOrEmpty(attr.TypeName)) + return typeExtensions[attr.TypeName]; + } + + return typeExtensions != null? typeExtensions[type]: Null; + } + + #endregion + + #region Private Static Members + + private static ExtensionList CreateTypeInfo(XDocument doc) + { + var list = new ExtensionList(); + + foreach (var typeNode in doc.Root.Elements().Where(_ => _.Name.LocalName == NodeName.Type)) + list.Add(ParseType(typeNode)); + + return list; + } + + private static TypeExtension ParseType(XElement typeNode) + { + var ext = new TypeExtension(); + + foreach (var attr in typeNode.Attributes()) + { + if (attr.Name.LocalName == AttrName.Name) + ext.Name = attr.Value; + else + ext.Attributes.Add(attr.Name.LocalName, attr.Value); + } + + foreach (var node in typeNode.Elements()) + { + if (node.Name.LocalName == NodeName.Member) + ext.Members.Add(ParseMember(node)); + else + ext.Attributes.Add(ParseAttribute(node)); + } + + return ext; + } + + private static MemberExtension ParseMember(XElement memberNode) + { + var ext = new MemberExtension(); + + foreach (var attr in memberNode.Attributes()) + { + if (attr.Name.LocalName == AttrName.Name) + ext.Name = attr.Value; + else + ext.Attributes.Add(attr.Name.LocalName, attr.Value); + } + + foreach (var node in memberNode.Elements()) + ext.Attributes.Add(ParseAttribute(node)); + + return ext; + } + + private static AttributeExtension ParseAttribute(XElement attributeNode) + { + var ext = new AttributeExtension + { + Name = attributeNode.Name.LocalName + }; + + ext.Values.Add(ValueName.Value, attributeNode.Value); + + foreach (var attr in attributeNode.Attributes()) + { + if (attr.Name.LocalName == ValueName.Type) + ext.Values.Add(ValueName.ValueType, attr.Value); + else + ext.Values.Add(attr.Name.LocalName, attr.Value); + } + + foreach (var node in attributeNode.Elements()) + ext.Attributes.Add(ParseAttribute(node)); + + return ext; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Extension/TypeExtension.xsd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Extension/TypeExtension.xsd Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Extension/TypeExtension.xsx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Extension/TypeExtension.xsx Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Extension/TypeExtensionAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Extension/TypeExtensionAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +using System; + +namespace BLToolkit.Reflection.Extension +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum)] + public class TypeExtensionAttribute : Attribute + { + public TypeExtensionAttribute() + { + } + + public TypeExtensionAttribute(string typeName) + : this(null, typeName) + { + } + + public TypeExtensionAttribute(string fileName, string typeName) + { + FileName = fileName; + TypeName = typeName; + } + + public string FileName { get; set; } + public string TypeName { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Extension/TypeExtensionException.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Extension/TypeExtensionException.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,88 @@ +using System; +using System.Runtime.Serialization; + +namespace BLToolkit.Reflection.Extension +{ + /// + /// Defines the base class for the namespace exceptions. + /// + /// + /// This class is the base class for exceptions that may occur during + /// execution of the namespace members. + /// + [Serializable] + public class TypeExtensionException : Exception + { + /// + /// Initializes a new instance of the class. + /// + /// + /// This constructor initializes the + /// property of the new instance + /// to a system-supplied message that describes the error, + /// such as "BLToolkit Type Extension error has occurred." + /// + public TypeExtensionException() + : base("An BLToolkit Type Extension error has occurred.") + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message. + /// + /// The message to display to the client when the + /// exception is thrown. + /// + public TypeExtensionException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message and InnerException property. + /// + /// The message to display to the client when the + /// exception is thrown. + /// The InnerException, if any, that threw + /// the current exception. + /// + /// + public TypeExtensionException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class + /// with the InnerException property. + /// + /// The InnerException, if any, that threw + /// the current exception. + /// + public TypeExtensionException(Exception innerException) + : base(innerException.Message, innerException) + { + } + +#if !SILVERLIGHT + + /// + /// Initializes a new instance of the class + /// with serialized data. + /// + /// The object that holds the serialized object data. + /// The contextual information about the source or + /// destination. + /// This constructor is called during deserialization to + /// reconstitute the exception object transmitted over a stream. + protected TypeExtensionException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + +#endif + } +} + diff -r 000000000000 -r f990fcb411a9 Source/Reflection/Extension/ValueCollection.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/Extension/ValueCollection.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,75 @@ +using System; + +namespace BLToolkit.Reflection.Extension +{ + public class ValueCollection : System.Collections.Generic.Dictionary + { + private object _value; + public object Value + { + get { return _value; } + } + + public new object this[string name] + { + get + { + object value; + return TryGetValue(name, out value) ? value : null; + } + } + + public void Add(string name, string value) + { + if (this != _null) + { + var isType = name.EndsWith(TypeExtension.ValueName.TypePostfix); + + if (isType) + { + var type = Type.GetType(value, true); + var valueName = name.Substring(0, name.Length - TypeExtension.ValueName.TypePostfix.Length); + + Add(name, type); + + object val; + + TryGetValue(valueName, out val); + + if (val != null && val.GetType() != type) + { + base[valueName] = val = TypeExtension.ChangeType(val.ToString(), type); + + if (valueName == TypeExtension.ValueName.Value) + _value = val; + } + } + else + { + object val; + + var type = TryGetValue(name + TypeExtension.ValueName.TypePostfix, out val) ? (Type)val : null; + + val = value; + + if (type != null && type != _value.GetType()) + val = TypeExtension.ChangeType(value, type); + + if (ContainsKey(name)) + base[name] = val; + else + Add(name, val); + + if (name == TypeExtension.ValueName.Value) + _value = val; + } + } + } + + private static readonly Extension.ValueCollection _null = new Extension.ValueCollection(); + public static Extension.ValueCollection Null + { + get { return _null; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/GenericBinder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/GenericBinder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,89 @@ +using System; +using System.Globalization; +using System.Reflection; + +namespace BLToolkit.Reflection +{ + /// + /// Selects a member from a list of candidates, and performs type conversion + /// from actual argument type to formal argument type. + /// + [Serializable] + public class GenericBinder : Binder + { + private readonly bool _genericMethodDefinition; + public GenericBinder(bool genericMethodDefinition) + { + _genericMethodDefinition = genericMethodDefinition; + } + + #region System.Reflection.Binder methods + + public override MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, + ParameterModifier[] modifiers, CultureInfo culture, string[] names, out object state) + { + throw new InvalidOperationException("GenericBinder.BindToMethod"); + } + + public override FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo culture) + { + throw new InvalidOperationException("GenericBinder.BindToField"); + } + + public override MethodBase SelectMethod( + BindingFlags bindingAttr, + MethodBase[] matchMethods, + Type[] parameterTypes, + ParameterModifier[] modifiers) + { + for (int i = 0; i < matchMethods.Length; ++i) + { + if (matchMethods[i].IsGenericMethodDefinition != _genericMethodDefinition) + continue; + + ParameterInfo[] pis = matchMethods[i].GetParameters(); + bool match = (pis.Length == parameterTypes.Length); + + for (int j = 0; match && j < pis.Length; ++j) + { + match = TypeHelper.CompareParameterTypes(pis[j].ParameterType, parameterTypes[j]); + } + + if (match) + return matchMethods[i]; + } + + return null; + } + + public override PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, + Type[] indexes, ParameterModifier[] modifiers) + { + throw new InvalidOperationException("GenericBinder.SelectProperty"); + } + + public override object ChangeType(object value, Type type, CultureInfo culture) + { + throw new InvalidOperationException("GenericBinder.ChangeType"); + } + + public override void ReorderArgumentArray(ref object[] args, object state) + { + throw new InvalidOperationException("GenericBinder.ReorderArgumentArray"); + } + + #endregion + + private static GenericBinder _generic; + public static GenericBinder Generic + { + get { return _generic ?? (_generic = new GenericBinder(true)); } + } + + private static GenericBinder _nonGeneric; + public static GenericBinder NonGeneric + { + get { return _nonGeneric ?? (_nonGeneric = new GenericBinder(false)); } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/IObjectFactory.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/IObjectFactory.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.Reflection +{ + public interface IObjectFactory + { + object CreateInstance(TypeAccessor typeAccessor, InitContext context); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/InitContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/InitContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; + +using BLToolkit.Mapping; + +namespace BLToolkit.Reflection +{ + public class InitContext + { + public object[] MemberParameters { get; set; } + public object[] Parameters { get; set; } + public bool IsInternal { get; set; } + public bool IsLazyInstance { get; set; } + public object Parent { get; set; } + public object SourceObject { get; set; } + public ObjectMapper ObjectMapper { get; set; } + public MappingSchema MappingSchema { get; set; } + public bool IsSource { get; set; } + public bool StopMapping { get; set; } + [CLSCompliant(false)] + public IMapDataSource DataSource { get; set; } + + private Dictionary _items; + public Dictionary Items + { + [DebuggerStepThrough] + get { return _items ?? (_items = new Dictionary()); } + } + + public bool IsDestination + { + [DebuggerStepThrough] get { return !IsSource; } + [DebuggerStepThrough] set { IsSource = !value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/MemberAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/MemberAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,305 @@ +using System; +using System.Data.SqlTypes; +using System.Linq.Expressions; +using System.Reflection; +using System.ComponentModel; +using BLToolkit.Data.Linq; + +#if !SILVERLIGHT && !DATA +using BLToolkit.ComponentModel; +#endif + +namespace BLToolkit.Reflection +{ + public abstract class MemberAccessor + { + protected MemberAccessor(TypeAccessor typeAccessor, MemberInfo memberInfo) + { + TypeAccessor = typeAccessor; + MemberInfo = memberInfo; + } + + #region Public Properties + + public MemberInfo MemberInfo { get; private set; } + public TypeAccessor TypeAccessor { get; private set; } + +#if !SILVERLIGHT && !DATA + + private PropertyDescriptor _propertyDescriptor; + public PropertyDescriptor PropertyDescriptor + { + get + { + if (_propertyDescriptor == null) + _propertyDescriptor = new MemberPropertyDescriptor(TypeAccessor.OriginalType, Name); + + return _propertyDescriptor; + } + } + +#endif + + public virtual bool HasGetter { get { return false; } } + public virtual bool HasSetter { get { return false; } } + + public Type Type + { + get + { + return MemberInfo is PropertyInfo? + ((PropertyInfo)MemberInfo).PropertyType: + ((FieldInfo) MemberInfo).FieldType; + } + } + + public string Name + { + get { return MemberInfo.Name; } + } + + private Type _underlyingType; + public Type UnderlyingType + { + get { return _underlyingType ?? (_underlyingType = TypeHelper.GetUnderlyingType(Type)); } + } + + #endregion + + #region Public Methods + + public bool IsDefined() where T : Attribute + { + return MemberInfo.IsDefined(typeof(T), true); + } + + [Obsolete("Use generic version instead")] + public Attribute GetAttribute(Type attributeType) + { + var attrs = MemberInfo.GetCustomAttributes(attributeType, true); + + return attrs.Length > 0? (Attribute)attrs[0]: null; + } + + public T GetAttribute() where T : Attribute + { + var attrs = MemberInfo.GetCustomAttributes(typeof(T), true); + + return attrs.Length > 0? (T)attrs[0]: null; + } + + [Obsolete("Use generic version instead")] + public object[] GetAttributes(Type attributeType) + { + var attrs = MemberInfo.GetCustomAttributes(attributeType, true); + + return attrs.Length > 0? attrs: null; + } + + public T[] GetAttributes() where T : Attribute + { + Array attrs = MemberInfo.GetCustomAttributes(typeof(T), true); + + return attrs.Length > 0? (T[])attrs: null; + } + + public object[] GetAttributes() + { + var attrs = MemberInfo.GetCustomAttributes(true); + + return attrs.Length > 0? attrs: null; + } + + public object[] GetTypeAttributes(Type attributeType) + { + return TypeHelper.GetAttributes(TypeAccessor.OriginalType, attributeType); + } + + #endregion + + #region Set/Get Value + + public virtual Boolean IsNull(object o) + { + return true; + } + + static object GetDefaultValue() + { + return default(T); + } + + object _defaultValue; + + public virtual object GetValue(object o) + { + if (_defaultValue == null && Type.IsValueType && !TypeHelper.IsNullableType(Type)) + { + var mi = ReflectionHelper.Expressor.MethodExpressor(_ => GetDefaultValue()); + + _defaultValue = + Expression.Lambda>( + Expression.Call(mi.GetGenericMethodDefinition().MakeGenericMethod(Type))) + .Compile()(); + } + + return _defaultValue; + } + + public virtual void SetValue(object o, object value) + { + } + + public virtual void CloneValue(object source, object dest) + { + var value = GetValue(source); + + SetValue(dest, value is ICloneable? ((ICloneable)value).Clone(): value); + } + + + // Simple types getters. + // + [CLSCompliant(false)] + public virtual SByte GetSByte (object o) { return (SByte) GetValue(o); } + public virtual Int16 GetInt16 (object o) { return (Int16) GetValue(o); } + public virtual Int32 GetInt32 (object o) { return (Int32) GetValue(o); } + public virtual Int64 GetInt64 (object o) { return (Int64) GetValue(o); } + + public virtual Byte GetByte (object o) { return (Byte) GetValue(o); } + [CLSCompliant(false)] + public virtual UInt16 GetUInt16 (object o) { return (UInt16) GetValue(o); } + [CLSCompliant(false)] + public virtual UInt32 GetUInt32 (object o) { return (UInt32) GetValue(o); } + [CLSCompliant(false)] + public virtual UInt64 GetUInt64 (object o) { return (UInt64) GetValue(o); } + + public virtual Boolean GetBoolean (object o) { return (Boolean) GetValue(o); } + public virtual Char GetChar (object o) { return (Char) GetValue(o); } + public virtual Single GetSingle (object o) { return (Single) GetValue(o); } + public virtual Double GetDouble (object o) { return (Double) GetValue(o); } + public virtual Decimal GetDecimal (object o) { return (Decimal) GetValue(o); } + public virtual Guid GetGuid (object o) { return (Guid) GetValue(o); } + public virtual DateTime GetDateTime(object o) { return (DateTime)GetValue(o); } + public virtual TimeSpan GetTimeSpan(object o) { return (TimeSpan)GetValue(o); } + public virtual DateTimeOffset GetDateTimeOffset(object o) { return (DateTimeOffset)GetValue(o); } + + // Nullable types getters. + // + [CLSCompliant(false)] + public virtual SByte? GetNullableSByte (object o) { return (SByte?) GetValue(o); } + public virtual Int16? GetNullableInt16 (object o) { return (Int16?) GetValue(o); } + public virtual Int32? GetNullableInt32 (object o) { return (Int32?) GetValue(o); } + public virtual Int64? GetNullableInt64 (object o) { return (Int64?) GetValue(o); } + + public virtual Byte? GetNullableByte (object o) { return (Byte?) GetValue(o); } + [CLSCompliant(false)] + public virtual UInt16? GetNullableUInt16 (object o) { return (UInt16?) GetValue(o); } + [CLSCompliant(false)] + public virtual UInt32? GetNullableUInt32 (object o) { return (UInt32?) GetValue(o); } + [CLSCompliant(false)] + public virtual UInt64? GetNullableUInt64 (object o) { return (UInt64?) GetValue(o); } + + public virtual Boolean? GetNullableBoolean (object o) { return (Boolean?) GetValue(o); } + public virtual Char? GetNullableChar (object o) { return (Char?) GetValue(o); } + public virtual Single? GetNullableSingle (object o) { return (Single?) GetValue(o); } + public virtual Double? GetNullableDouble (object o) { return (Double?) GetValue(o); } + public virtual Decimal? GetNullableDecimal (object o) { return (Decimal?) GetValue(o); } + public virtual Guid? GetNullableGuid (object o) { return (Guid?) GetValue(o); } + public virtual DateTime? GetNullableDateTime(object o) { return (DateTime?)GetValue(o); } + public virtual TimeSpan? GetNullableTimeSpan(object o) { return (TimeSpan?)GetValue(o); } + public virtual DateTimeOffset? GetNullableDateTimeOffset(object o) { return (DateTimeOffset?)GetValue(o); } + +#if !SILVERLIGHT + + // SQL type getters. + // + public virtual SqlByte GetSqlByte (object o) { return (SqlByte) GetValue(o); } + public virtual SqlInt16 GetSqlInt16 (object o) { return (SqlInt16) GetValue(o); } + public virtual SqlInt32 GetSqlInt32 (object o) { return (SqlInt32) GetValue(o); } + public virtual SqlInt64 GetSqlInt64 (object o) { return (SqlInt64) GetValue(o); } + public virtual SqlSingle GetSqlSingle (object o) { return (SqlSingle) GetValue(o); } + public virtual SqlBoolean GetSqlBoolean (object o) { return (SqlBoolean) GetValue(o); } + public virtual SqlDouble GetSqlDouble (object o) { return (SqlDouble) GetValue(o); } + public virtual SqlDateTime GetSqlDateTime(object o) { return (SqlDateTime)GetValue(o); } + public virtual SqlDecimal GetSqlDecimal (object o) { return (SqlDecimal) GetValue(o); } + public virtual SqlMoney GetSqlMoney (object o) { return (SqlMoney) GetValue(o); } + public virtual SqlGuid GetSqlGuid (object o) { return (SqlGuid) GetValue(o); } + public virtual SqlString GetSqlString (object o) { return (SqlString) GetValue(o); } + +#endif + + // Simple type setters. + // + [CLSCompliant(false)] + public virtual void SetSByte (object o, SByte value) { SetValue(o, value); } + public virtual void SetInt16 (object o, Int16 value) { SetValue(o, value); } + public virtual void SetInt32 (object o, Int32 value) { SetValue(o, value); } + public virtual void SetInt64 (object o, Int64 value) { SetValue(o, value); } + + public virtual void SetByte (object o, Byte value) { SetValue(o, value); } + [CLSCompliant(false)] + public virtual void SetUInt16 (object o, UInt16 value) { SetValue(o, value); } + [CLSCompliant(false)] + public virtual void SetUInt32 (object o, UInt32 value) { SetValue(o, value); } + [CLSCompliant(false)] + public virtual void SetUInt64 (object o, UInt64 value) { SetValue(o, value); } + + public virtual void SetBoolean (object o, Boolean value) { SetValue(o, value); } + public virtual void SetChar (object o, Char value) { SetValue(o, value); } + public virtual void SetSingle (object o, Single value) { SetValue(o, value); } + public virtual void SetDouble (object o, Double value) { SetValue(o, value); } + public virtual void SetDecimal (object o, Decimal value) { SetValue(o, value); } + public virtual void SetGuid (object o, Guid value) { SetValue(o, value); } + public virtual void SetDateTime(object o, DateTime value) { SetValue(o, value); } + public virtual void SetTimeSpan(object o, TimeSpan value) { SetValue(o, value); } + public virtual void SetDateTimeOffset(object o, DateTimeOffset value) { SetValue(o, value); } + + // Simple type setters. + // + [CLSCompliant(false)] + public virtual void SetNullableSByte (object o, SByte? value) { SetValue(o, value); } + public virtual void SetNullableInt16 (object o, Int16? value) { SetValue(o, value); } + public virtual void SetNullableInt32 (object o, Int32? value) { SetValue(o, value); } + public virtual void SetNullableInt64 (object o, Int64? value) { SetValue(o, value); } + + public virtual void SetNullableByte (object o, Byte? value) { SetValue(o, value); } + [CLSCompliant(false)] + public virtual void SetNullableUInt16 (object o, UInt16? value) { SetValue(o, value); } + [CLSCompliant(false)] + public virtual void SetNullableUInt32 (object o, UInt32? value) { SetValue(o, value); } + [CLSCompliant(false)] + public virtual void SetNullableUInt64 (object o, UInt64? value) { SetValue(o, value); } + + public virtual void SetNullableBoolean (object o, Boolean? value) { SetValue(o, value); } + public virtual void SetNullableChar (object o, Char? value) { SetValue(o, value); } + public virtual void SetNullableSingle (object o, Single? value) { SetValue(o, value); } + public virtual void SetNullableDouble (object o, Double? value) { SetValue(o, value); } + public virtual void SetNullableDecimal (object o, Decimal? value) { SetValue(o, value); } + public virtual void SetNullableGuid (object o, Guid? value) { SetValue(o, value); } + public virtual void SetNullableDateTime(object o, DateTime? value) { SetValue(o, value); } + public virtual void SetNullableTimeSpan(object o, TimeSpan? value) { SetValue(o, value); } + public virtual void SetNullableDateTimeOffset(object o, DateTimeOffset? value) { SetValue(o, value); } + +#if !SILVERLIGHT + + // SQL type setters. + // + public virtual void SetSqlByte (object o, SqlByte value) { SetValue(o, value); } + public virtual void SetSqlInt16 (object o, SqlInt16 value) { SetValue(o, value); } + public virtual void SetSqlInt32 (object o, SqlInt32 value) { SetValue(o, value); } + public virtual void SetSqlInt64 (object o, SqlInt64 value) { SetValue(o, value); } + public virtual void SetSqlSingle (object o, SqlSingle value) { SetValue(o, value); } + public virtual void SetSqlBoolean (object o, SqlBoolean value) { SetValue(o, value); } + public virtual void SetSqlDouble (object o, SqlDouble value) { SetValue(o, value); } + public virtual void SetSqlDateTime(object o, SqlDateTime value) { SetValue(o, value); } + public virtual void SetSqlDecimal (object o, SqlDecimal value) { SetValue(o, value); } + public virtual void SetSqlMoney (object o, SqlMoney value) { SetValue(o, value); } + public virtual void SetSqlGuid (object o, SqlGuid value) { SetValue(o, value); } + public virtual void SetSqlString (object o, SqlString value) { SetValue(o, value); } + +#endif + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/MetadataProvider/AttributeMetadataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/MetadataProvider/AttributeMetadataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,799 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using BLToolkit.Data.Sql.SqlProvider; + +using BLToolkit.TypeBuilder; + +namespace BLToolkit.Reflection.MetadataProvider +{ + using DataAccess; + using Extension; + using Mapping; + + public class AttributeMetadataProvider : MetadataProviderBase + { + #region Helpers + + private TypeAccessor _typeAccessor; + private object[] _mapFieldAttributes; + private object[] _nonUpdatableAttributes; + readonly object _sync = new object(); + + void EnsureMapper(TypeAccessor typeAccessor) + { + if (_typeAccessor != typeAccessor) + { + _typeAccessor = typeAccessor; + _mapFieldAttributes = null; + _nonUpdatableAttributes = null; + } + } + + protected object[] GetMapFieldAttributes(TypeAccessor typeAccessor) + { + lock (_sync) + { + EnsureMapper(typeAccessor); + + return _mapFieldAttributes ?? (_mapFieldAttributes = TypeHelper.GetAttributes(typeAccessor.Type, typeof (MapFieldAttribute))); + } + } + + object[] GetNonUpdatableAttributes(TypeAccessor typeAccessor) + { + lock (_sync) + { + EnsureMapper(typeAccessor); + + return _nonUpdatableAttributes ?? (_nonUpdatableAttributes = TypeHelper.GetAttributes(typeAccessor.Type, typeof(NonUpdatableAttribute))); + } + } + + #endregion + + #region GetFieldName + + public override string GetFieldName(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var a = member.GetAttribute(); + + if (a != null && a.MapName != null) + { + isSet = true; + return a.MapName; + } + + foreach (MapFieldAttribute attr in GetMapFieldAttributes(member.TypeAccessor)) + { + if (attr.MapName != null && string.Equals(attr.OrigName, member.Name, StringComparison.InvariantCultureIgnoreCase)) + { + isSet = true; + return attr.MapName; + } + } + + return base.GetFieldName(typeExtension, member, out isSet); + } + + #endregion + + #region GetFieldStorage + + public override string GetFieldStorage(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var a = member.GetAttribute(); + + if (a != null) + { + isSet = true; + return a.Storage; + } + + foreach (MapFieldAttribute attr in GetMapFieldAttributes(member.TypeAccessor)) + { + if (string.Equals(attr.OrigName, member.Name, StringComparison.InvariantCultureIgnoreCase)) + { + isSet = true; + return attr.Storage; + } + } + + return base.GetFieldStorage(typeExtension, member, out isSet); + } + + #endregion + + #region GetInheritanceDiscriminator + + public override bool GetInheritanceDiscriminator(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var a = member.GetAttribute(); + + if (a != null) + { + isSet = true; + return a.IsInheritanceDiscriminator; + } + + foreach (MapFieldAttribute attr in GetMapFieldAttributes(member.TypeAccessor)) + { + if (string.Equals(attr.OrigName, member.Name, StringComparison.InvariantCultureIgnoreCase)) + { + isSet = true; + return attr.IsInheritanceDiscriminator; + } + } + + return base.GetInheritanceDiscriminator(typeExtension, member, out isSet); + } + + #endregion + + #region EnsureMapper + + public override void EnsureMapper(TypeAccessor typeAccessor, MappingSchema mappingSchema, EnsureMapperHandler handler) + { + foreach (MapFieldAttribute attr in GetMapFieldAttributes(typeAccessor)) + { + if (attr.OrigName != null) + handler(attr.MapName, attr.OrigName); + else + { + var ma = typeAccessor[attr.MapName]; + + foreach (MemberMapper inner in mappingSchema.GetObjectMapper(ma.Type)) + handler(string.Format(attr.Format, inner.Name), ma.Name + "." + inner.MemberName); + } + } + } + + #endregion + + #region GetMapIgnore + + public override bool GetMapIgnore(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var attr = member.GetAttribute() ?? (MapIgnoreAttribute)TypeHelper.GetFirstAttribute(member.Type, typeof(MapIgnoreAttribute)); + + if (attr != null) + { + isSet = true; + return attr.Ignore; + } + + if (member.GetAttribute() != null || + member.GetAttribute() != null || + TypeHelper.GetFirstAttribute(member.Type, typeof(MapImplicitAttribute)) != null) + { + isSet = true; + return false; + } + + return base.GetMapIgnore(typeExtension, member, out isSet) || member.GetAttribute() != null; + } + + #endregion + + #region GetMapField + + public override MapFieldAttribute GetMapField(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var attr = member.GetAttribute() ?? (MapFieldAttribute)TypeHelper.GetFirstAttribute(member.Type, typeof(MapFieldAttribute)); + + if (attr != null) + { + isSet = true; + return attr; + } + + return base.GetMapField(typeExtension, member, out isSet); + } + + #endregion + + #region GetDbType + + [CLSCompliant(false)] + public override DbTypeAttribute GetDbType(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var attr = member.GetAttribute() ?? (DbTypeAttribute)TypeHelper.GetFirstAttribute(member.Type, typeof(DbTypeAttribute)); + + if (attr != null) + { + isSet = true; + return attr; + } + + return base.GetDbType(typeExtension, member, out isSet); + } + + #endregion + + #region GetPrimaryKey + + public override PrimaryKeyAttribute GetPrimaryKey(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var attr = member.GetAttribute() ?? (PrimaryKeyAttribute)TypeHelper.GetFirstAttribute(member.Type, typeof(PrimaryKeyAttribute)); + + if (attr != null) + { + isSet = true; + return attr; + } + + return base.GetPrimaryKey(typeExtension, member, out isSet); + } + + #endregion + + #region GetTrimmable + + public override bool GetTrimmable(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + if (member.Type == typeof(string)) + { + var attr = member.GetAttribute(); + + if (attr != null) + { + isSet = true; + return attr.IsTrimmable; + } + + attr = (TrimmableAttribute)TypeHelper.GetFirstAttribute( + member.MemberInfo.DeclaringType, typeof(TrimmableAttribute)); + + if (attr != null) + { + isSet = true; + return attr.IsTrimmable; + } + } + + return base.GetTrimmable(typeExtension, member, out isSet); + } + + #endregion + + #region GetMapValues + + public override MapValue[] GetMapValues(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + List list = null; + + object[] attrs = member.GetAttributes(); + + if (attrs != null) + { + list = new List(attrs.Length); + + foreach (MapValueAttribute a in attrs) + list.Add(new MapValue(a.OrigValue, a.Values)); + } + + attrs = member.GetTypeAttributes(typeof(MapValueAttribute)); + + var memberType = TypeHelper.UnwrapNullableType(member.Type); + + if (attrs != null && attrs.Length > 0) + { + if (list == null) + list = new List(attrs.Length); + + foreach (MapValueAttribute a in attrs) + if (a.Type == null && a.OrigValue != null && a.OrigValue.GetType() == memberType || + a.Type is Type && (Type)a.Type == memberType) + list.Add(new MapValue(a.OrigValue, a.Values)); + } + + var typeMapValues = GetMapValues(typeExtension, memberType, out isSet); + + if (list == null) + return typeMapValues; + + if (typeMapValues != null) + list.AddRange(typeMapValues); + + isSet = true; + + return list.ToArray(); + } + + const FieldAttributes EnumField = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal; + + static List GetEnumMapValues(Type type) + { + var list = null as List; + var fields = type.GetFields(); + + foreach (var fi in fields) + { + if ((fi.Attributes & EnumField) == EnumField) + { + var enumAttributes = Attribute.GetCustomAttributes(fi, typeof(MapValueAttribute)); + + foreach (MapValueAttribute attr in enumAttributes) + { + if (list == null) + list = new List(fields.Length); + + var origValue = Enum.Parse(type, fi.Name, false); + + list.Add(new MapValue(origValue, attr.Values)); + } + } + } + + return list; + } + + public override MapValue[] GetMapValues(TypeExtension typeExtension, Type type, out bool isSet) + { + List list = null; + + if (TypeHelper.IsNullable(type)) + type = type.GetGenericArguments()[0]; + + if (type.IsEnum) + list = GetEnumMapValues(type); + + var attrs = TypeHelper.GetAttributes(type, typeof(MapValueAttribute)); + + if (attrs != null && attrs.Length != 0) + { + if (list == null) + list = new List(attrs.Length); + + for (var i = 0; i < attrs.Length; i++) + { + var a = (MapValueAttribute)attrs[i]; + list.Add(new MapValue(a.OrigValue, a.Values)); + } + } + + isSet = list != null; + + return isSet? list.ToArray(): null; + } + + #endregion + + #region GetDefaultValue + + public override object GetDefaultValue(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + // Check member [DefaultValue(0)] + // + var attr = member.GetAttribute(); + + if (attr != null) + { + isSet = true; + return attr.Value; + } + + // Check type [DefaultValues(typeof(int), 0)] + // + var attrs = member.GetTypeAttributes(typeof(DefaultValueAttribute)); + + foreach (DefaultValueAttribute a in attrs) + if (a.Type == null && a.Value != null && a.Value.GetType() == member.Type || + a.Type != null && a.Type == member.Type) + { + isSet = true; + return a.Value; + } + + return GetDefaultValue(mappingSchema, typeExtension, member.Type, out isSet); + } + + public override object GetDefaultValue(MappingSchema mappingSchema, TypeExtension typeExtension, Type type, out bool isSet) + { + object value = null; + + if (type.IsEnum) + value = GetEnumDefaultValueFromType(type); + + if (value == null) + { + var attrs = TypeHelper.GetAttributes(type, typeof(DefaultValueAttribute)); + + if (attrs != null && attrs.Length != 0) + value = ((DefaultValueAttribute)attrs[0]).Value; + } + + isSet = value != null; + + return TypeExtension.ChangeType(value, type); + } + + private static object GetEnumDefaultValueFromType(Type type) + { + var fields = type.GetFields(); + + foreach (var fi in fields) + { + if ((fi.Attributes & EnumField) == EnumField) + { + var attrs = Attribute.GetCustomAttributes(fi, typeof(DefaultValueAttribute)); + + if (attrs.Length > 0) + return Enum.Parse(type, fi.Name, false); + } + } + + return null; + } + + #endregion + + #region GetNullable + + public override bool GetNullable(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + // Check member [Nullable(true | false)] + // + var attr1 = member.GetAttribute(); + + if (attr1 != null) + { + isSet = true; + return attr1.IsNullable; + } + + // Check member [NullValue(0)] + // + var attr2 = member.GetAttribute(); + + if (attr2 != null) + return isSet = true; + + // Check type [Nullable(true || false)] + // + attr1 = (NullableAttribute)TypeHelper.GetFirstAttribute( + member.MemberInfo.DeclaringType, typeof(NullableAttribute)); + + if (attr1 != null) + { + isSet = true; + return attr1.IsNullable; + } + + // Check type [NullValues(typeof(int), 0)] + // + var attrs = member.GetTypeAttributes(typeof(NullValueAttribute)); + + foreach (NullValueAttribute a in attrs) + if (a.Type == null && a.Value != null && a.Value.GetType() == member.Type || + a.Type != null && a.Type == member.Type) + return isSet = true; + + if (member.Type.IsEnum) + return isSet = mappingSchema.GetNullValue(member.Type) != null; + + if (member.Type.IsClass) + { + var pk = member.GetAttribute(); + + if (pk != null) + { + isSet = false; + return false; + } + } + + return base.GetNullable(mappingSchema, typeExtension, member, out isSet); + } + + #endregion + + #region GetLazyInstance + + public override bool GetLazyInstance(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var attr1 = member.GetAttribute(); + + if (attr1 != null) + { + isSet = true; + return attr1.IsLazy; + } + + attr1 = (LazyInstanceAttribute)TypeHelper.GetFirstAttribute(member.MemberInfo.DeclaringType, typeof(LazyInstanceAttribute)); + + if (attr1 != null) + { + isSet = true; + return attr1.IsLazy; + } + + return base.GetLazyInstance(mappingSchema, typeExtension, member, out isSet); + } + + #endregion + + #region GetNullValue + + private static object CheckNullValue(object value, MemberAccessor member) + { + if (value is Type && (Type)value == typeof(DBNull)) + { + value = DBNull.Value; + + if (member.Type == typeof(string)) + value = null; + } + + return value; + } + + public override object GetNullValue(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + // Check member [NullValue(0)] + // + var attr = member.GetAttribute(); + + if (attr != null) + { + isSet = true; + return CheckNullValue(attr.Value, member); + } + + // Check type [NullValues(typeof(int), 0)] + // + var attrs = member.GetTypeAttributes(typeof(NullValueAttribute)); + + foreach (NullValueAttribute a in attrs) + { + if (a.Type == null && a.Value != null && a.Value.GetType() == member.Type || + a.Type != null && a.Type == member.Type) + { + isSet = true; + return CheckNullValue(a.Value, member); + } + } + + if (member.Type.IsEnum) + { + var value = CheckNullValue(mappingSchema.GetNullValue(member.Type), member); + + if (value != null) + { + isSet = true; + return value; + } + } + + isSet = false; + return null; + } + + #endregion + + #region GetDbName + + public override string GetDatabaseName(Type type, ExtensionList extensions, out bool isSet) + { + var attrs = type.GetCustomAttributes(typeof(TableNameAttribute), true); + + if (attrs.Length > 0) + { + var name = ((TableNameAttribute)attrs[0]).Database; + isSet = name != null; + return name; + } + + return base.GetDatabaseName(type, extensions, out isSet); + } + + #endregion + + #region GetTableName + + public override string GetOwnerName(Type type, ExtensionList extensions, out bool isSet) + { + var attrs = type.GetCustomAttributes(typeof(TableNameAttribute), true); + + if (attrs.Length > 0) + { + var name = ((TableNameAttribute)attrs[0]).Owner; + isSet = name != null; + return name; + } + + return base.GetOwnerName(type, extensions, out isSet); + } + + #endregion + + #region GetTableName + + public override string GetTableName(Type type, ExtensionList extensions, out bool isSet) + { + var attrs = type.GetCustomAttributes(typeof(TableNameAttribute), true); + + if (attrs.Length > 0) + { + var name = ((TableNameAttribute)attrs[0]).Name; + isSet = name != null; + return name; + } + + return base.GetTableName(type, extensions, out isSet); + } + + #endregion + + #region GetPrimaryKeyOrder + + public override int GetPrimaryKeyOrder(Type type, TypeExtension typeExt, MemberAccessor member, out bool isSet) + { + var attr = member.GetAttribute(); + + if (attr != null) + { + isSet = true; + return attr.Order; + } + + return base.GetPrimaryKeyOrder(type, typeExt, member, out isSet); + } + + #endregion + + public override string GetSequenceName(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var attr = member.GetAttribute(); + + if (attr != null) + { + isSet = true; + return attr.SequenceName; + } + + return base.GetSequenceName(typeExtension, member, out isSet); + } + + #region GetNonUpdatableFlag + + public override NonUpdatableAttribute GetNonUpdatableAttribute(Type type, TypeExtension typeExt, MemberAccessor member, out bool isSet) + { + var attr = member.GetAttribute(); + + if (attr != null) + { + isSet = true; + return attr; + } + + foreach (NonUpdatableAttribute a in GetNonUpdatableAttributes(member.TypeAccessor)) + { + if (string.Equals(a.FieldName, member.Name, StringComparison.InvariantCultureIgnoreCase)) + { + isSet = true; + return a; + } + } + + return base.GetNonUpdatableAttribute(type, typeExt, member, out isSet); + } + + #endregion + + #region GetSqlIgnore + + public override bool GetSqlIgnore(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var attr = member.GetAttribute(); + + if (attr == null) + attr = (SqlIgnoreAttribute)TypeHelper.GetFirstAttribute(member.Type, typeof(SqlIgnoreAttribute)); + + if (attr != null) + { + isSet = true; + return attr.Ignore; + } + + return base.GetSqlIgnore(typeExtension, member, out isSet); + } + + #endregion + + #region GetRelations + + public override List GetRelations(MappingSchema schema, ExtensionList typeExt, Type master, Type slave, out bool isSet) + { + var masterAccessor = TypeAccessor.GetAccessor(master); + var slaveAccessor = slave != null ? TypeAccessor.GetAccessor(slave) : null; + var relations = new List(); + + foreach (MemberAccessor ma in masterAccessor) + { + var attr = ma.GetAttribute(); + + if (attr == null || (slave != null && attr.Destination != slave && ma.Type != slave)) + continue; + + if (slave == null) + slaveAccessor = TypeAccessor.GetAccessor(attr.Destination ?? ma.Type); + + + var toMany = TypeHelper.IsSameOrParent(typeof(IEnumerable), ma.Type); + + if (toMany && attr.Destination == null) + throw new InvalidOperationException("Destination type should be set for enumerable relations: " + ma.Type.FullName + "." + ma.Name); + + var masterIndex = attr.MasterIndex; + var slaveIndex = attr.SlaveIndex; + + if (slaveIndex == null) + { + var accessor = toMany ? masterAccessor : slaveAccessor; + var tex = TypeExtension.GetTypeExtension(accessor.Type, typeExt); + var keys = GetPrimaryKeyFields(schema, accessor, tex); + + if (keys.Count > 0) + slaveIndex = new MapIndex(keys.ToArray()); + } + + if (slaveIndex == null) + throw new InvalidOperationException("Slave index is not set for relation: " + ma.Type.FullName + "." + ma.Name); + + if (masterIndex == null) + masterIndex = slaveIndex; + + var relation = new MapRelationBase(attr.Destination ?? ma.Type, slaveIndex, masterIndex, ma.Name); + + relations.Add(relation); + } + + isSet = true; + return relations; + } + + #endregion + + #region GetAssociation + + public override Association GetAssociation(TypeExtension typeExtension, MemberAccessor member) + { + var aa = member.GetAttribute(); + + if (aa == null) + return base.GetAssociation(typeExtension, member); + + return new Association( + member, + aa.GetThisKeys(), + aa.GetOtherKeys(), + aa.Storage, + aa.CanBeNull); + } + + #endregion + + #region GetInheritanceMapping + + public override InheritanceMappingAttribute[] GetInheritanceMapping(Type type, TypeExtension typeExtension) + { + var attrs = type.GetCustomAttributes(typeof(InheritanceMappingAttribute), true); + + if (attrs.Length > 0) + { + var maps = new InheritanceMappingAttribute[attrs.Length]; + + for (var i = 0; i < attrs.Length; i++) + maps[i] = (InheritanceMappingAttribute)attrs[i]; + + return maps; + } + + return base.GetInheritanceMapping(type, typeExtension); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/MetadataProvider/ExtensionMetadataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/MetadataProvider/ExtensionMetadataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,659 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Reflection; + +using BLToolkit.Common; +using BLToolkit.DataAccess; + +using Convert=System.Convert; + +namespace BLToolkit.Reflection.MetadataProvider +{ + using Extension; + using Mapping; + + public class ExtensionMetadataProvider : MetadataProviderBase + { + #region Helpers + + private static object GetValue(TypeExtension typeExtension, MemberAccessor member, string elemName, out bool isSet) + { + AttributeExtensionCollection ext; + isSet = typeExtension[member.Name].Attributes.TryGetValue(elemName, out ext); + return isSet ? ext.Value : null; + } + + #endregion + + #region GetFieldName + + public override string GetFieldName(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var value = GetValue(typeExtension, member, "MapField", out isSet); + + if (value != null) + return value.ToString(); + + return base.GetFieldName(typeExtension, member, out isSet); + } + + #endregion + + #region GetFieldStorage + + public override string GetFieldStorage(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var value = GetValue(typeExtension, member, "FieldStorage", out isSet); + + if (value != null) + return value.ToString(); + + return base.GetFieldStorage(typeExtension, member, out isSet); + } + + #endregion + + #region GetInheritanceDiscriminator + + public override bool GetInheritanceDiscriminator(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var value = GetValue(typeExtension, member, "IsInheritanceDiscriminator", out isSet); + + if (value != null) + return TypeExtension.ToBoolean(value); + + return base.GetInheritanceDiscriminator(typeExtension, member, out isSet); + } + + #endregion + + #region GetMapIgnore + + public override bool GetMapIgnore(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var value = GetValue(typeExtension, member, "MapIgnore", out isSet); + + if (value != null) + return TypeExtension.ToBoolean(value); + + return base.GetMapIgnore(typeExtension, member, out isSet) || GetAssociation(typeExtension, member) != null; + } + + #endregion + + #region GetMapField + + public override MapFieldAttribute GetMapField(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var extList = typeExtension[member.Name]["MapField"]; + + if (extList != AttributeExtensionCollection.Null) + { + isSet = true; + var attr = new MapFieldAttribute(); + + var extFormat = extList.FirstOrDefault(x => x.Name == "Format"); + var extMapName = extList.FirstOrDefault(x => x.Name == "MapName"); + var extIsInheritanceDiscriminator = extList.FirstOrDefault(x => x.Name == "IsInheritanceDiscriminator"); + var extOrigName = extList.FirstOrDefault(x => x.Name == "OrigName"); + var extStorage = extList.FirstOrDefault(x => x.Name == "Storage"); + + if (extFormat != null) + attr.Format = (string)extFormat.Value; + if (extMapName != null) + attr.MapName = (string)extMapName.Value; + if (extFormat != null) + attr.IsInheritanceDiscriminator = Convert.ToBoolean(extIsInheritanceDiscriminator.Value); + if (extFormat != null) + attr.OrigName = (string)extOrigName.Value; + if (extFormat != null) + attr.Storage = (string)extStorage.Value; + return attr; + } + + return base.GetMapField(typeExtension, member, out isSet); + } + + #endregion + + #region GetDbType + + [CLSCompliant(false)] + public override DbTypeAttribute GetDbType(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var extList = typeExtension[member.Name]["DbType"]; + + if (extList != AttributeExtensionCollection.Null) + { + isSet = true; + var attr = new DbTypeAttribute(DbType.String); + + var extDbType = extList.FirstOrDefault(x => x.Name == "DbType"); + var extSize = extList.FirstOrDefault(x => x.Name == "Size"); + + DbType dbType; + if (extDbType != null) + { +#if SILVERLIGHT || FW4 + DbType.TryParse(extDbType.Value.ToString(), out dbType); +#else + dbType = (DbType)Enum.Parse(typeof(DbType), extDbType.Value.ToString()); +#endif + attr.DbType = dbType; + } + if (extSize != null) + { + attr.Size = int.Parse(extSize.Value.ToString()); + } + return attr; + } + + return base.GetDbType(typeExtension, member, out isSet); + } + + #endregion + + #region GetPrimaryKey + + public override PrimaryKeyAttribute GetPrimaryKey(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var extList = typeExtension[member.Name]["PrimaryKey"]; + + if (extList != AttributeExtensionCollection.Null) + { + isSet = true; + int order = -1; + var extOrder = extList.FirstOrDefault(x => x.Name == "Order"); + if (extOrder != null) + { + order = int.Parse(extOrder.Value.ToString()); + } + var attr = new PrimaryKeyAttribute(order); + return attr; + } + + return base.GetPrimaryKey(typeExtension, member, out isSet); + } + + #endregion + + + #region GetTrimmable + + public override bool GetTrimmable(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + if (member.Type == typeof(string)) + { + var value = GetValue(typeExtension, member, "Trimmable", out isSet); + + if (value != null) + return TypeExtension.ToBoolean(value); + } + + return base.GetTrimmable(typeExtension, member, out isSet); + } + + #endregion + + #region GetMapValues + + public override MapValue[] GetMapValues(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var extList = typeExtension[member.Name]["MapValue"]; + + if (extList == AttributeExtensionCollection.Null) + return GetMapValues(typeExtension, member.Type, out isSet); + + var list = new List(extList.Count); + + foreach (var ext in extList) + { + var origValue = ext["OrigValue"]; + + if (origValue != null) + { + origValue = TypeExtension.ChangeType(origValue, member.Type); + list.Add(new MapValue(origValue, ext.Value)); + } + } + + isSet = true; + + return list.ToArray(); + } + + const FieldAttributes EnumField = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal; + + static List GetEnumMapValues(TypeExtension typeExt, Type type) + { + List mapValues = null; + + var fields = type.GetFields(); + + foreach (var fi in fields) + { + if ((fi.Attributes & EnumField) == EnumField) + { + var attrExt = typeExt[fi.Name]["MapValue"]; + + if (attrExt.Count == 0) + continue; + + var list = new List(attrExt.Count); + var origValue = Enum.Parse(type, fi.Name, false); + + list.AddRange(from ae in attrExt where ae.Value != null select ae.Value); + + if (list.Count > 0) + { + if (mapValues == null) + mapValues = new List(fields.Length); + + mapValues.Add(new MapValue(origValue, list.ToArray())); + } + } + } + + return mapValues; + } + + static List GetTypeMapValues(TypeExtension typeExt, Type type) + { + var extList = typeExt.Attributes["MapValue"]; + + if (extList == AttributeExtensionCollection.Null) + return null; + + var attrs = new List(extList.Count); + + foreach (var ext in extList) + { + var origValue = ext["OrigValue"]; + + if (origValue != null) + { + origValue = TypeExtension.ChangeType(origValue, type); + attrs.Add(new MapValue(origValue, ext.Value)); + } + } + + return attrs; + } + + public override MapValue[] GetMapValues(TypeExtension typeExt, Type type, out bool isSet) + { + List list = null; + + if (TypeHelper.IsNullable(type)) + type = type.GetGenericArguments()[0]; + + if (type.IsEnum) + list = GetEnumMapValues(typeExt, type); + + if (list == null) + list = GetTypeMapValues(typeExt, type); + + isSet = list != null; + + return isSet? list.ToArray(): null; + } + + #endregion + + #region GetDefaultValue + + public override object GetDefaultValue(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var value = typeExtension[member.Name]["DefaultValue"].Value; + + if (value != null) + { + isSet = true; + return TypeExtension.ChangeType(value, member.Type); + } + + return GetDefaultValue(mappingSchema, typeExtension, member.Type, out isSet); + } + + public override object GetDefaultValue(MappingSchema mappingSchema, TypeExtension typeExt, Type type, out bool isSet) + { + object value = null; + + if (type.IsEnum) + value = GetEnumDefaultValueFromExtension(typeExt, type); + + if (value == null) + value = typeExt.Attributes["DefaultValue"].Value; + + isSet = value != null; + + return TypeExtension.ChangeType(value, type); + } + + private static object GetEnumDefaultValueFromExtension(TypeExtension typeExt, Type type) + { + var fields = type.GetFields(); + + foreach (var fi in fields) + if ((fi.Attributes & EnumField) == EnumField) + if (typeExt[fi.Name]["DefaultValue"].Value != null) + return Enum.Parse(type, fi.Name, false); + + return null; + } + + #endregion + + #region GetNullable + + public override bool GetNullable(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + // Check extension + // + var value = GetValue(typeExtension, member, "Nullable", out isSet); + + if (isSet) + return TypeExtension.ToBoolean(value); + + // Check extension + // + if (GetValue(typeExtension, member, "NullValue", out isSet) != null) + return true; + + return base.GetNullable(mappingSchema, typeExtension, member, out isSet); + } + + #endregion + + #region GetNullable + + public override bool GetLazyInstance(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + // Check extension + // + var value = GetValue(typeExtension, member, "LazyInstance", out isSet); + + if (isSet) + return TypeExtension.ToBoolean(value); + + // Check extension + // + if (GetValue(typeExtension, member, "LazyInstance", out isSet) != null) + return true; + + return base.GetLazyInstance(mappingSchema, typeExtension, member, out isSet); + } + + #endregion + + #region GetNullable + + public override object GetNullValue(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + // Check extension + // + var value = GetValue(typeExtension, member, "NullValue", out isSet); + + return isSet? TypeExtension.ChangeType(value, member.Type): null; + } + + #endregion + + #region GetDbName + + public override string GetDatabaseName(Type type, ExtensionList extensions, out bool isSet) + { + var typeExt = TypeExtension.GetTypeExtension(type, extensions); + var value = typeExt.Attributes["DatabaseName"].Value; + + if (value != null) + { + isSet = true; + return value.ToString(); + } + + return base.GetDatabaseName(type, extensions, out isSet); + } + + #endregion + + #region GetOwnerName + + public override string GetOwnerName(Type type, ExtensionList extensions, out bool isSet) + { + var typeExt = TypeExtension.GetTypeExtension(type, extensions); + var value = typeExt.Attributes["OwnerName"].Value; + + if (value != null) + { + isSet = true; + return value.ToString(); + } + + return base.GetOwnerName(type, extensions, out isSet); + } + + #endregion + + #region GetTableName + + public override string GetTableName(Type type, ExtensionList extensions, out bool isSet) + { + var typeExt = TypeExtension.GetTypeExtension(type, extensions); + var value = typeExt.Attributes["TableName"].Value; + + if (value != null) + { + isSet = true; + return value.ToString(); + } + + return base.GetTableName(type, extensions, out isSet); + } + + #endregion + + #region GetPrimaryKeyOrder + + public override int GetPrimaryKeyOrder(Type type, TypeExtension typeExt, MemberAccessor member, out bool isSet) + { + var value = typeExt[member.Name]["PrimaryKey"].Value; + + if (value != null) + { + isSet = true; + return (int)TypeExtension.ChangeType(value, typeof(int)); + } + + return base.GetPrimaryKeyOrder(type, typeExt, member, out isSet); + } + + #endregion + + #region GetNonUpdatableFlag + + public override NonUpdatableAttribute GetNonUpdatableAttribute(Type type, TypeExtension typeExt, MemberAccessor member, out bool isSet) + { + var value = typeExt[member.Name]["NonUpdatable"].Value; + + if (value != null) + { + isSet = true; + return (bool)TypeExtension.ChangeType(value, typeof(bool)) ? new NonUpdatableAttribute() : null; + } + + value = typeExt[member.Name]["Identity"].Value; + + if (value != null) + { + isSet = true; + return (bool)TypeExtension.ChangeType(value, typeof(bool)) ? new IdentityAttribute() : null; + } + + return base.GetNonUpdatableAttribute(type, typeExt, member, out isSet); + } + + #endregion + + #region GetSqlIgnore + + public override bool GetSqlIgnore(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + var value = GetValue(typeExtension, member, "SqlIgnore", out isSet); + + if (value != null) + return TypeExtension.ToBoolean(value); + + return base.GetSqlIgnore(typeExtension, member, out isSet); + } + + #endregion + + #region GetRelations + + public override List GetRelations(MappingSchema schema, ExtensionList typeExt, Type master, Type slave, out bool isSet) + { + var relations = new List(); + var ext = typeExt != null ? typeExt[master] : TypeExtension.Null; + + isSet = ext != TypeExtension.Null; + + if (!isSet) + return relations; + + var ta = TypeAccessor.GetAccessor(master); + + foreach (var mex in ext.Members.Values) + { + var relationInfos = mex.Attributes[TypeExtension.NodeName.Relation]; + + if (relationInfos == AttributeExtensionCollection.Null) + continue; + + var destinationTypeName = relationInfos[0][TypeExtension.AttrName.DestinationType, string.Empty].ToString(); + var destinationType = slave; + var ma = ta[mex.Name]; + var toMany = TypeHelper.IsSameOrParent(typeof(IEnumerable), ma.Type); + + if (destinationTypeName == string.Empty) + { + if (toMany) + throw new InvalidOperationException("Destination type should be set for enumerable relations: " + ma.Type.FullName + "." + ma.Name); + + destinationType = ma.Type; + } + else + { + if (!destinationTypeName.Contains(",")) + destinationTypeName += ", " + ta.OriginalType.Assembly.FullName; + + try + { + destinationType = Type.GetType(destinationTypeName, true); + } + catch (TypeLoadException ex) + { + throw new InvalidOperationException( + "Unable to load type by name: " + destinationTypeName + + "\n may be assembly is not specefied, please see Type.GetType(string typeName) documentation", + ex); + } + } + + if (slave != null && !TypeHelper.IsSameOrParent(slave, destinationType)) + continue; + + var masterIndexFields = new List(); + var slaveIndexFields = new List(); + + foreach (var ae in relationInfos[0].Attributes[TypeExtension.NodeName.MasterIndex]) + masterIndexFields.Add(ae[TypeExtension.AttrName.Name].ToString()); + + foreach (var ae in relationInfos[0].Attributes[TypeExtension.NodeName.SlaveIndex]) + slaveIndexFields.Add(ae[TypeExtension.AttrName.Name].ToString()); + + + if (slaveIndexFields.Count == 0) + { + var accessor = toMany ? ta : TypeAccessor.GetAccessor(destinationType); + var tex = TypeExtension.GetTypeExtension(accessor.Type, typeExt); + + slaveIndexFields = GetPrimaryKeyFields(schema, accessor, tex); + } + + if (slaveIndexFields.Count == 0) + throw new InvalidOperationException("Slave index is not set for relation: " + ma.Type.FullName + "." + ma.Name); + + var slaveIndex = new MapIndex(slaveIndexFields.ToArray()); + var masterIndex = masterIndexFields.Count > 0 ? new MapIndex(masterIndexFields.ToArray()) : slaveIndex; + var mapRelation = new MapRelationBase(destinationType, slaveIndex, masterIndex, mex.Name); + + relations.Add(mapRelation); + + } + + isSet = relations.Count > 0; + return relations; + } + + #endregion + + #region GetAssociation + + public override Association GetAssociation(TypeExtension typeExtension, MemberAccessor member) + { + if (typeExtension == TypeExtension.Null) + return null; + + var mex = typeExtension[member.Name]; + + if (mex == MemberExtension.Null) + return null; + + var attrs = mex.Attributes[TypeExtension.NodeName.Association]; + + if (attrs == AttributeExtensionCollection.Null) + return null; + + return new Association( + member, + Association.ParseKeys(attrs[0]["ThisKey", string.Empty].ToString()), + Association.ParseKeys(attrs[0]["OtherKey", string.Empty].ToString()), + attrs[0]["Storage", string.Empty].ToString(), + TypeExtension.ToBoolean(attrs[0]["Storage", "True"], true)); + } + + #endregion + + #region GetInheritanceMapping + + public override InheritanceMappingAttribute[] GetInheritanceMapping(Type type, TypeExtension typeExtension) + { + var extList = typeExtension.Attributes["InheritanceMapping"]; + + if (extList == AttributeExtensionCollection.Null) + return Array.Empty; + + var attrs = new InheritanceMappingAttribute[extList.Count]; + + for (var i = 0; i < extList.Count; i++) + { + var ext = extList[i]; + + attrs[i] = new InheritanceMappingAttribute + { + Code = ext["Code"], + IsDefault = TypeExtension.ToBoolean(ext["IsDefault", "False"], false), + Type = Type.GetType(Convert.ToString(ext["Type"])) + }; + } + + return attrs; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/MetadataProvider/LinqMetadataProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/MetadataProvider/LinqMetadataProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,239 @@ +using System; +using System.Data.Linq.Mapping; +using System.Linq; + +namespace BLToolkit.Reflection.MetadataProvider +{ + using DataAccess; + using Mapping; + using Extension; + + public class LinqMetadataProvider : MetadataProviderBase + { + #region Helpers + + private Type _type; + private bool? _isLinqObject; + readonly object _sync = new object(); + + void EnsureMapper(Type type) + { + if (_type != type) + { + _type = type; + _isLinqObject = null; + } + } + + bool IsLinqObject(Type type) + { + lock (_sync) + { + EnsureMapper(type); + + if (_isLinqObject == null) + { + var attrs = type.GetCustomAttributes(typeof(TableAttribute), true); + _isLinqObject = attrs.Length > 0; + } + + return _isLinqObject.Value; + } + } + + #endregion + + #region GetFieldName + + public override string GetFieldName(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + if (IsLinqObject(member.TypeAccessor.Type)) + { + var a = member.GetAttribute(); + + if (a != null && !string.IsNullOrEmpty(a.Name)) + { + isSet = true; + return a.Name; + } + } + + return base.GetFieldName(typeExtension, member, out isSet); + } + + #endregion + + #region GetFieldStorage + + public override string GetFieldStorage(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + if (IsLinqObject(member.TypeAccessor.Type)) + { + var a = member.GetAttribute(); + + if (a != null && !string.IsNullOrEmpty(a.Name)) + { + isSet = true; + return a.Storage; + } + } + + return base.GetFieldStorage(typeExtension, member, out isSet); + } + + #endregion + + #region GetInheritanceDiscriminator + + public override bool GetInheritanceDiscriminator(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + if (IsLinqObject(member.TypeAccessor.Type)) + { + var a = member.GetAttribute(); + + if (a != null && !string.IsNullOrEmpty(a.Name)) + { + isSet = true; + return a.IsDiscriminator; + } + } + + return base.GetInheritanceDiscriminator(typeExtension, member, out isSet); + } + + #endregion + + #region GetMapIgnore + + public override bool GetMapIgnore(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + if (member.GetAttribute() != null) + { + isSet = true; + return true; + } + + if (IsLinqObject(member.TypeAccessor.Type)) + { + isSet = true; + return member.GetAttribute() == null; + } + + return base.GetMapIgnore(typeExtension, member, out isSet); + } + + #endregion + + #region GetNullable + + public override bool GetNullable(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + if (IsLinqObject(member.TypeAccessor.Type)) + { + var attr = member.GetAttribute(); + + if (attr != null) + { + isSet = true; + return attr.CanBeNull; + } + } + + return base.GetNullable(mappingSchema, typeExtension, member, out isSet); + } + + #endregion + + #region GetTableName + + public override string GetTableName(Type type, ExtensionList extensions, out bool isSet) + { + if (IsLinqObject(type)) + { + isSet = true; + + var attrs = type.GetCustomAttributes(typeof(TableAttribute), true); + + return ((TableAttribute)attrs[0]).Name; + } + + return base.GetTableName(type, extensions, out isSet); + } + + #endregion + + #region GetPrimaryKeyOrder + + public override int GetPrimaryKeyOrder(Type type, TypeExtension typeExt, MemberAccessor member, out bool isSet) + { + if (IsLinqObject(type)) + { + ColumnAttribute a = member.GetAttribute(); + + if (a != null && a.IsPrimaryKey) + { + isSet = true; + return 0; + } + } + + return base.GetPrimaryKeyOrder(type, typeExt, member, out isSet); + } + + #endregion + + #region GetNonUpdatableFlag + + public override NonUpdatableAttribute GetNonUpdatableAttribute(Type type, TypeExtension typeExt, MemberAccessor member, out bool isSet) + { + if (IsLinqObject(member.TypeAccessor.Type)) + { + var a = member.GetAttribute(); + + if (a != null) + { + isSet = true; + return a.IsDbGenerated ? new IdentityAttribute() : null; + } + } + + return base.GetNonUpdatableAttribute(type, typeExt, member, out isSet); + } + + #endregion + + #region GetAssociation + + public override Association GetAssociation(TypeExtension typeExtension, MemberAccessor member) + { + if (IsLinqObject(member.TypeAccessor.Type)) + { + var a = member.GetAttribute(); + + if (a != null) + return new Association(member, Association.ParseKeys(a.ThisKey), Association.ParseKeys(a.OtherKey), a.Storage, true); + } + + return base.GetAssociation(typeExtension, member); + } + + #endregion + + #region GetInheritanceMapping + + public override InheritanceMappingAttribute[] GetInheritanceMapping(Type type,TypeExtension typeExtension) + { + if (IsLinqObject(type)) + { + var attrs = type.GetCustomAttributes(typeof(InheritanceMappingAttribute), true); + + if (attrs.Length > 0) + return attrs.Select(a => (InheritanceMappingAttribute)a).ToArray(); + } + + return base.GetInheritanceMapping(type, typeExtension); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/MetadataProvider/MetadataProviderBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/MetadataProvider/MetadataProviderBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,349 @@ +using System; +using System.Collections.Generic; + +using BLToolkit.Common; +using BLToolkit.DataAccess; + +namespace BLToolkit.Reflection.MetadataProvider +{ + using Extension; + using Mapping; + + public delegate void OnCreateProvider(MetadataProviderBase parentProvider); + public delegate MetadataProviderBase CreateProvider(); + public delegate MemberMapper EnsureMapperHandler(string mapName, string origName); + + public abstract class MetadataProviderBase + { + #region Provider Support + + public virtual void AddProvider(MetadataProviderBase provider) + { + } + + public virtual void InsertProvider(int index, MetadataProviderBase provider) + { + } + + public virtual MetadataProviderBase[] GetProviders() + { + return new MetadataProviderBase[0]; + } + + #endregion + + #region GetFieldName + + public virtual string GetFieldName(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + return member.Name; + } + + #endregion + + public virtual string GetSequenceName(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + return null; + } + + #region GetFieldStorage + + public virtual string GetFieldStorage(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + return null; + } + + #endregion + + #region GetInheritanceDiscriminator + + public virtual bool GetInheritanceDiscriminator(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + return false; + } + + #endregion + + #region EnsureMapper + + public virtual void EnsureMapper(TypeAccessor typeAccessor, MappingSchema mappingSchema, EnsureMapperHandler handler) + { + } + + #endregion + + #region GetMapIgnore + + public virtual bool GetMapIgnore(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + + return + TypeHelper.IsScalar(member.Type) == false;// || + //(member.MemberInfo is FieldInfo && ((FieldInfo)member.MemberInfo).IsLiteral); + } + + #endregion + + #region GetMapField + + public virtual MapFieldAttribute GetMapField(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + return null; + } + + #endregion + + #region GetDbType + + [CLSCompliant(false)] + public virtual DbTypeAttribute GetDbType(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + return null; + } + + #endregion + + #region GetPrimaryKey + + public virtual PrimaryKeyAttribute GetPrimaryKey(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + return null; + } + + #endregion + + #region GetTrimmable + + public virtual bool GetTrimmable(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = member.Type != typeof(string); + return isSet? false: TrimmableAttribute.Default.IsTrimmable; + } + + #endregion + + #region GetMapValues + + public virtual MapValue[] GetMapValues(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + return null; + } + + public virtual MapValue[] GetMapValues(TypeExtension typeExtension, Type type, out bool isSet) + { + isSet = false; + return null; + } + + #endregion + + #region GetDefaultValue + + public virtual object GetDefaultValue(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + return null; + } + + public virtual object GetDefaultValue(MappingSchema mappingSchema, TypeExtension typeExtension, Type type, out bool isSet) + { + isSet = false; + return null; + } + + #endregion + + #region GetNullable + + public virtual bool GetNullable(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + return + //member.Type.IsClass || + member.Type.IsGenericType && member.Type.GetGenericTypeDefinition() == typeof (Nullable<>) + /*|| + member.Type == typeof(System.Data.Linq.Binary) || + member.Type == typeof(byte[])*/; + } + + #endregion + + #region GetLazyInstance + + public virtual bool GetLazyInstance(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + return false; + } + + #endregion + + #region GetNullValue + + public virtual object GetNullValue(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + + if (member.Type.IsEnum) + return null; + + var value = mappingSchema.GetNullValue(member.Type); + + if (value is Type && (Type)value == typeof(DBNull)) + { + value = DBNull.Value; + + if (member.Type == typeof(string)) + value = null; + } + + return value; + } + + #endregion + + #region GetDbName + + public virtual string GetDatabaseName(Type type, ExtensionList extensions, out bool isSet) + { + isSet = false; + return null; + } + + #endregion + + #region GetOwnerName + + public virtual string GetOwnerName(Type type, ExtensionList extensions, out bool isSet) + { + isSet = false; + return null; + } + + #endregion + + #region GetTableName + + public virtual string GetTableName(Type type, ExtensionList extensions, out bool isSet) + { + isSet = false; + return + type.IsInterface && type.Name.StartsWith("I") + ? type.Name.Substring(1) + : type.Name; + } + + #endregion + + #region GetPrimaryKeyOrder + + public virtual int GetPrimaryKeyOrder(Type type, TypeExtension typeExt, MemberAccessor member, out bool isSet) + { + isSet = false; + return 0; + } + + #endregion + + #region GetNonUpdatableAttribute + + public virtual NonUpdatableAttribute GetNonUpdatableAttribute(Type type, TypeExtension typeExt, MemberAccessor member, out bool isSet) + { + isSet = false; + return null; + } + + #endregion + + #region GetSqlIgnore + + public virtual bool GetSqlIgnore(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + isSet = false; + return false; + } + + #endregion + + #region GetRelations + + public virtual List GetRelations(MappingSchema schema, ExtensionList typeExt, Type master, Type slave, out bool isSet) + { + isSet = false; + return new List(); + } + + protected static List GetPrimaryKeyFields(MappingSchema schema, TypeAccessor ta, TypeExtension tex) + { + var mdp = schema.MetadataProvider; + var keys = new List(); + + foreach (MemberAccessor sma in ta) + { + bool isSetFlag; + + mdp.GetPrimaryKeyOrder(ta.Type, tex, sma, out isSetFlag); + + if (isSetFlag) + { + var name = mdp.GetFieldName(tex, sma, out isSetFlag); + keys.Add(name); + } + } + + return keys; + } + + #endregion + + #region GetAssociation + + public virtual Association GetAssociation(TypeExtension typeExtension, MemberAccessor member) + { + return null; + } + + #endregion + + #region GetInheritanceMapping + + public virtual InheritanceMappingAttribute[] GetInheritanceMapping(Type type, TypeExtension typeExtension) + { + return Array.Empty; + } + + #endregion + + #region Static Members + + public static event OnCreateProvider OnCreateProvider; + + private static CreateProvider _createProvider = CreateInternal; + public static CreateProvider CreateProvider + { + get { return _createProvider; } + set { _createProvider = value ?? new CreateProvider(CreateInternal); } + } + + private static MetadataProviderBase CreateInternal() + { + var list = new MetadataProviderList(); + + if (OnCreateProvider != null) + OnCreateProvider(list); + + return list; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/MetadataProvider/MetadataProviderList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/MetadataProvider/MetadataProviderList.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,473 @@ +using System; +using System.Collections.Generic; + +namespace BLToolkit.Reflection.MetadataProvider +{ + using DataAccess; + using Extension; + using Mapping; + + public class MetadataProviderList : MetadataProviderBase + { + #region Init + + public MetadataProviderList() + { + AddProvider(new ExtensionMetadataProvider()); + AddProvider(new AttributeMetadataProvider()); +#if !SILVERLIGHT + AddProvider(new LinqMetadataProvider()); +#endif + } + + private readonly List _list = new List(3); + + #endregion + + #region Provider Support + + public override void AddProvider(MetadataProviderBase provider) + { + _list.Add(provider); + } + + public override void InsertProvider(int index, MetadataProviderBase provider) + { + _list.Insert(index, provider); + } + + public override MetadataProviderBase[] GetProviders() + { + return _list.ToArray(); + } + + #endregion + + #region GetFieldName + + public override string GetFieldName(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var name = p.GetFieldName(typeExtension, member, out isSet); + + if (isSet) + return name; + } + + return base.GetFieldName(typeExtension, member, out isSet); + } + + #endregion + + #region GetFieldStorage + + public override string GetFieldStorage(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var name = p.GetFieldStorage(typeExtension, member, out isSet); + + if (isSet) + return name; + } + + return base.GetFieldStorage(typeExtension, member, out isSet); + } + + #endregion + + #region GetInheritanceDiscriminator + + public override bool GetInheritanceDiscriminator(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetInheritanceDiscriminator(typeExtension, member, out isSet); + + if (isSet) + return value; + } + + return base.GetInheritanceDiscriminator(typeExtension, member, out isSet); + } + + #endregion + + #region EnsureMapper + + public override void EnsureMapper(TypeAccessor typeAccessor, MappingSchema mappingSchema, EnsureMapperHandler handler) + { + foreach (var p in _list) + p.EnsureMapper(typeAccessor, mappingSchema, handler); + } + + #endregion + + #region GetMapIgnore + + public override bool GetMapIgnore(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var ignore = p.GetMapIgnore(typeExtension, member, out isSet); + + if (isSet) + return ignore; + } + + return base.GetMapIgnore(typeExtension, member, out isSet); + } + + #endregion + + #region GetMapField + + public override MapFieldAttribute GetMapField(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var attr = p.GetMapField(typeExtension, member, out isSet); + + if (attr != null) + return attr; + } + + return base.GetMapField(typeExtension, member, out isSet); + } + + #endregion + + #region GetDbType + + [CLSCompliant(false)] + public override DbTypeAttribute GetDbType(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var attr = p.GetDbType(typeExtension, member, out isSet); + + if (attr != null) + return attr; + } + + return base.GetDbType(typeExtension, member, out isSet); + } + + #endregion + + #region GetPrimaryKey + + public override PrimaryKeyAttribute GetPrimaryKey(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var attr = p.GetPrimaryKey(typeExtension, member, out isSet); + + if (attr != null) + return attr; + } + + return base.GetPrimaryKey(typeExtension, member, out isSet); + } + + #endregion + + #region GetTrimmable + + public override bool GetTrimmable(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + if (member.Type == typeof(string)) + { + foreach (var p in _list) + { + var trimmable = p.GetTrimmable(typeExtension, member, out isSet); + + if (isSet) + return trimmable; + } + } + + return base.GetTrimmable(typeExtension, member, out isSet); + } + + #endregion + + #region GetMapValues + + public override MapValue[] GetMapValues(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetMapValues(typeExtension, member, out isSet); + + if (isSet) + return value; + } + + return base.GetMapValues(typeExtension, member, out isSet); + } + + public override MapValue[] GetMapValues(TypeExtension typeExt, Type type, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetMapValues(typeExt, type, out isSet); + + if (isSet) + return value; + } + + return base.GetMapValues(typeExt, type, out isSet); + } + + #endregion + + #region GetDefaultValue + + public override object GetDefaultValue(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetDefaultValue(mappingSchema, typeExtension, member, out isSet); + + if (isSet) + return value; + } + + return base.GetDefaultValue(mappingSchema, typeExtension, member, out isSet); + } + + public override object GetDefaultValue(MappingSchema mappingSchema, TypeExtension typeExtension, Type type, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetDefaultValue(mappingSchema, typeExtension, type, out isSet); + + if (isSet) + return value; + } + + return base.GetDefaultValue(mappingSchema, typeExtension, type, out isSet); + } + + #endregion + + #region GetNullable + + public override bool GetNullable(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetNullable(mappingSchema, typeExtension, member, out isSet); + + if (isSet) + return value; + } + + return base.GetNullable(mappingSchema, typeExtension, member, out isSet); + } + + #endregion + + #region GetLazyInstance + + public override bool GetLazyInstance(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetLazyInstance(mappingSchema, typeExtension, member, out isSet); + + if (isSet) + return value; + } + + return base.GetLazyInstance(mappingSchema, typeExtension, member, out isSet); + } + + #endregion + + #region GetNullValue + + public override object GetNullValue(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetNullValue(mappingSchema, typeExtension, member, out isSet); + + if (isSet) + return value; + } + + return base.GetNullValue(mappingSchema, typeExtension, member, out isSet); + } + + #endregion + + #region GetDbName + + public override string GetDatabaseName(Type type, ExtensionList extensions, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetDatabaseName(type, extensions, out isSet); + + if (isSet) + return value; + } + + return base.GetDatabaseName(type, extensions, out isSet); + } + + #endregion + + #region GetOwnerName + + public override string GetOwnerName(Type type, ExtensionList extensions, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetOwnerName(type, extensions, out isSet); + + if (isSet) + return value; + } + + return base.GetOwnerName(type, extensions, out isSet); + } + + #endregion + + #region GetTableName + + public override string GetTableName(Type type, ExtensionList extensions, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetTableName(type, extensions, out isSet); + + if (isSet) + return value; + } + + return base.GetTableName(type, extensions, out isSet); + } + + #endregion + + #region GetPrimaryKeyOrder + + public override int GetPrimaryKeyOrder(Type type, TypeExtension typeExt, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetPrimaryKeyOrder(type, typeExt, member, out isSet); + + if (isSet) + return value; + } + + return base.GetPrimaryKeyOrder(type, typeExt, member, out isSet); + } + + #endregion + + public override string GetSequenceName(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetSequenceName(typeExtension, member, out isSet); + + if (isSet) + return value; + } + + return base.GetSequenceName(typeExtension, member, out isSet); + } + + #region GetNonUpdatableFlag + + public override NonUpdatableAttribute GetNonUpdatableAttribute(Type type, TypeExtension typeExt, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var value = p.GetNonUpdatableAttribute(type, typeExt, member, out isSet); + + if (isSet) + return value; + } + + return base.GetNonUpdatableAttribute(type, typeExt, member, out isSet); + } + + #endregion + + #region GetSqlIgnore + + public override bool GetSqlIgnore(TypeExtension typeExtension, MemberAccessor member, out bool isSet) + { + foreach (var p in _list) + { + var ignore = p.GetSqlIgnore(typeExtension, member, out isSet); + + if (isSet) + return ignore; + } + + return base.GetSqlIgnore(typeExtension, member, out isSet); + } + + #endregion + + #region GetRelations + + public override List GetRelations(MappingSchema schema, ExtensionList typeExt, Type master, Type slave, out bool isSet) + { + foreach (var p in _list) + { + var relations = p.GetRelations(schema, typeExt, master, slave, out isSet); + + if (isSet) + return relations; + } + + return base.GetRelations(schema, typeExt, master, slave, out isSet); + } + + #endregion + + #region GetAssociation + + public override Association GetAssociation(TypeExtension typeExtension, MemberAccessor member) + { + foreach (var p in _list) + { + var attr = p.GetAssociation(typeExtension, member); + + if (attr != null) + return attr; + } + + return base.GetAssociation(typeExtension, member); + } + + #endregion + + #region GetInheritanceMapping + + public override InheritanceMappingAttribute[] GetInheritanceMapping(Type type, TypeExtension typeExtension) + { + foreach (var p in _list) + { + var attrs = p.GetInheritanceMapping(type, typeExtension); + + if (attrs.Length > 0) + return attrs; + } + + return base.GetInheritanceMapping(type, typeExtension); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/ObjectFactoryAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/ObjectFactoryAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,27 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace BLToolkit.Reflection +{ + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] + public class ObjectFactoryAttribute : Attribute + { + public ObjectFactoryAttribute(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + _objectFactory = Activator.CreateInstance(type) as IObjectFactory; + + if (_objectFactory == null) + throw new ArgumentException( + string.Format("Type '{0}' does not implement IObjectFactory interface.", type)); + } + + private readonly IObjectFactory _objectFactory; + public IObjectFactory ObjectFactory + { + get { return _objectFactory; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/TypeAccessor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/TypeAccessor.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1152 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Data.SqlTypes; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Reflection; + +using BLToolkit.Common; +#if !SILVERLIGHT && !DATA +using BLToolkit.ComponentModel; +using BLToolkit.EditableObjects; +#endif +using BLToolkit.Mapping; +using BLToolkit.TypeBuilder; +using BLToolkit.TypeBuilder.Builders; + +using JNotNull = JetBrains.Annotations.NotNullAttribute; + +namespace BLToolkit.Reflection +{ + public delegate object NullValueProvider(Type type); + public delegate bool IsNullHandler (object obj); + + [DebuggerDisplay("Type = {Type}, OriginalType = {OriginalType}")] + public abstract class TypeAccessor : ICollection +#if !SILVERLIGHT && !DATA + , ITypeDescriptionProvider +#endif + { + #region Protected Emit Helpers + + protected MemberInfo GetMember(int memberType, string memberName) + { + const BindingFlags allInstaceMembers = + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + MemberInfo mi; + + switch (memberType) + { + case 1: mi = Type.GetField (memberName, allInstaceMembers); break; + case 2: + mi = + Type. GetProperty(memberName, allInstaceMembers) ?? + OriginalType.GetProperty(memberName, allInstaceMembers); + break; + default: + throw new InvalidOperationException(); + } + + return mi; + } + + protected void AddMember(MemberAccessor member) + { + if (member == null) throw new ArgumentNullException("member"); + + _members.Add(member); + _memberNames.Add(member.MemberInfo.Name, member); + } + + #endregion + + #region CreateInstance + + [DebuggerStepThrough] + public virtual object CreateInstance() + { + throw new TypeBuilderException(string.Format( + "The '{0}' type must have public default or init constructor.", + OriginalType.Name)); + } + + [DebuggerStepThrough] + public virtual object CreateInstance(InitContext context) + { + return CreateInstance(); + } + + [DebuggerStepThrough] + public object CreateInstanceEx() + { + return _objectFactory != null? + _objectFactory.CreateInstance(this, null): CreateInstance((InitContext)null); + } + + [DebuggerStepThrough] + public object CreateInstanceEx(InitContext context) + { + return _objectFactory != null? _objectFactory.CreateInstance(this, context): CreateInstance(context); + } + + #endregion + + #region ObjectFactory + + private IObjectFactory _objectFactory; + public IObjectFactory ObjectFactory + { + get { return _objectFactory; } + set { _objectFactory = value; } + } + + #endregion + + #region Copy & AreEqual + + internal static object CopyInternal(object source, object dest, TypeAccessor ta) + { +#if !SILVERLIGHT && !DATA + var isDirty = false; + var sourceEditable = source as IMemberwiseEditable; + var destEditable = dest as IMemberwiseEditable; + + if (sourceEditable != null && destEditable != null) + { + foreach (MemberAccessor ma in ta) + { + ma.CloneValue(source, dest); + if (sourceEditable.IsDirtyMember(null, ma.MemberInfo.Name, ref isDirty) && !isDirty) + destEditable.AcceptMemberChanges(null, ma.MemberInfo.Name); + } + } + else +#endif + { + foreach (MemberAccessor ma in ta) + ma.CloneValue(source, dest); + } + + return dest; + } + + public static object Copy(object source, object dest) + { + if (source == null) throw new ArgumentNullException("source"); + if (dest == null) throw new ArgumentNullException("dest"); + + TypeAccessor ta; + + var sType = source.GetType(); + var dType = dest. GetType(); + + if (TypeHelper.IsSameOrParent(sType, dType)) ta = GetAccessor(sType); + else if (TypeHelper.IsSameOrParent(dType, sType)) ta = GetAccessor(dType); + else + throw new ArgumentException(); + + return CopyInternal(source, dest, ta); + } + + public static object Copy(object source) + { + if (source == null) throw new ArgumentNullException("source"); + + var ta = GetAccessor(source.GetType()); + + return CopyInternal(source, ta.CreateInstanceEx(), ta); + } + + public static bool AreEqual(object obj1, object obj2) + { + if (ReferenceEquals(obj1, obj2)) + return true; + + if (obj1 == null || obj2 == null) + return false; + + TypeAccessor ta; + + var sType = obj1.GetType(); + var dType = obj2.GetType(); + + if (TypeHelper.IsSameOrParent(sType, dType)) ta = GetAccessor(sType); + else if (TypeHelper.IsSameOrParent(dType, sType)) ta = GetAccessor(dType); + else + return false; + + foreach (MemberAccessor ma in ta) + if ((!Equals(ma.GetValue(obj1), ma.GetValue(obj2)))) + return false; + + return true; + } + + public static int GetHashCode(object obj) + { + if (obj == null) + throw new ArgumentNullException("obj"); + + var hash = 0; + object value; + + foreach (MemberAccessor ma in GetAccessor(obj.GetType())) + { + value = ma.GetValue(obj); + hash = ((hash << 5) + hash) ^ (value == null ? 0 : value.GetHashCode()); + } + + return hash; + } + + #endregion + + #region Abstract Members + + public abstract Type Type { get; } + public abstract Type OriginalType { get; } + + #endregion + + #region Items + + private readonly List _members = new List(); + private readonly Dictionary _memberNames = new Dictionary(); + + public MemberAccessor this[string memberName] + { + get + { + MemberAccessor ma; + return _memberNames.TryGetValue(memberName, out ma) ? ma : null; + } + } + + public MemberAccessor this[int index] + { + get { return _members[index]; } + } + + public MemberAccessor this[NameOrIndexParameter nameOrIndex] + { + get + { + return nameOrIndex.ByName ? _memberNames[nameOrIndex.Name] : _members[nameOrIndex.Index]; + } + } + + #endregion + + #region Static Members + + [Obsolete("Use TypeFactory.LoadTypes instead")] + public static bool LoadTypes + { + get { return TypeFactory.LoadTypes; } + set { TypeFactory.LoadTypes = value; } + } + + private static readonly Dictionary _accessors = new Dictionary(10); + + public static TypeAccessor GetAccessor(Type originalType) + { + if (originalType == null) throw new ArgumentNullException("originalType"); + + lock (_accessors) + { + TypeAccessor accessor; + + if (_accessors.TryGetValue(originalType, out accessor)) + return accessor; + + if (IsAssociatedType(originalType)) + return _accessors[originalType]; + + var instanceType = (IsClassBulderNeeded(originalType) ? null : originalType) ?? TypeFactory.GetType(originalType); + + var accessorType = TypeFactory.GetType(originalType, originalType, new TypeAccessorBuilder(instanceType, originalType)); + + accessor = (TypeAccessor)Activator.CreateInstance(accessorType); + + _accessors.Add(originalType, accessor); + + if (originalType != instanceType) + _accessors.Add(instanceType, accessor); + + return accessor; + } + } + + public static TypeAccessor GetAccessor([JNotNull] object obj) + { + if (obj == null) throw new ArgumentNullException("obj"); + return GetAccessor(obj.GetType()); + } + + public static TypeAccessor GetAccessor() + { + return TypeAccessor.Instance; + } + + private static bool IsClassBulderNeeded(Type type) + { + if (type.IsAbstract && !type.IsSealed) + { + if (!type.IsInterface) + { + if (TypeHelper.GetDefaultConstructor(type) != null) + return true; + + if (TypeHelper.GetConstructor(type, typeof(InitContext)) != null) + return true; + } + else + { + var attrs = TypeHelper.GetAttributes(type, typeof(AutoImplementInterfaceAttribute)); + + if (attrs != null && attrs.Length > 0) + return true; + } + } + + return false; + } + + internal static bool IsInstanceBuildable(Type type) + { + if (!type.IsInterface) + return true; + + lock (_accessors) + { + if (_accessors.ContainsKey(type)) + return true; + + if (IsAssociatedType(type)) + return true; + } + + var attrs = TypeHelper.GetAttributes(type, typeof(AutoImplementInterfaceAttribute)); + + return attrs != null && attrs.Length > 0; + } + + private static bool IsAssociatedType(Type type) + { + if (AssociatedTypeHandler != null) + { + var child = AssociatedTypeHandler(type); + + if (child != null) + { + AssociateType(type, child); + return true; + } + } + + return false; + } + + public static object CreateInstance(Type type) + { + return GetAccessor(type).CreateInstance(); + } + + public static object CreateInstance(Type type, InitContext context) + { + return GetAccessor(type).CreateInstance(context); + } + + public static object CreateInstanceEx(Type type) + { + return GetAccessor(type).CreateInstanceEx(); + } + + public static object CreateInstanceEx(Type type, InitContext context) + { + return GetAccessor(type).CreateInstance(context); + } + + public static T CreateInstance() + { + return TypeAccessor.CreateInstance(); + } + + public static T CreateInstance(InitContext context) + { + return TypeAccessor.CreateInstance(context); + } + + public static T CreateInstanceEx() + { + return TypeAccessor.CreateInstanceEx(); + } + + public static T CreateInstanceEx(InitContext context) + { + return TypeAccessor.CreateInstance(context); + } + + public static TypeAccessor AssociateType(Type parent, Type child) + { + if (!TypeHelper.IsSameOrParent(parent, child)) + throw new ArgumentException( + string.Format("'{0}' must be a base type of '{1}'", parent, child), + "child"); + + var accessor = GetAccessor(child); + + accessor = (TypeAccessor)Activator.CreateInstance(accessor.GetType()); + + lock (_accessors) + _accessors.Add(parent, accessor); + + return accessor; + } + + public delegate Type GetAssociatedType(Type parent); + public static event GetAssociatedType AssociatedTypeHandler; + + #endregion + + #region GetNullValue + + private static NullValueProvider _getNullValue = GetNullInternal; + public static NullValueProvider GetNullValue + { + get { return _getNullValue ?? (_getNullValue = GetNullInternal);} + set { _getNullValue = value; } + } + + private static object GetNullInternal(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + if (type.IsValueType) + { + if (type.IsEnum) + return GetEnumNullValue(type); + + if (type.IsPrimitive) + { + if (type == typeof(Int32)) return Common.Configuration.NullableValues.Int32; + if (type == typeof(Double)) return Common.Configuration.NullableValues.Double; + if (type == typeof(Int16)) return Common.Configuration.NullableValues.Int16; + if (type == typeof(Boolean)) return Common.Configuration.NullableValues.Boolean; + if (type == typeof(SByte)) return Common.Configuration.NullableValues.SByte; + if (type == typeof(Int64)) return Common.Configuration.NullableValues.Int64; + if (type == typeof(Byte)) return Common.Configuration.NullableValues.Byte; + if (type == typeof(UInt16)) return Common.Configuration.NullableValues.UInt16; + if (type == typeof(UInt32)) return Common.Configuration.NullableValues.UInt32; + if (type == typeof(UInt64)) return Common.Configuration.NullableValues.UInt64; + if (type == typeof(Single)) return Common.Configuration.NullableValues.Single; + if (type == typeof(Char)) return Common.Configuration.NullableValues.Char; + } + else + { + if (type == typeof(DateTime)) return Common.Configuration.NullableValues.DateTime; + if (type == typeof(DateTimeOffset)) return Common.Configuration.NullableValues.DateTimeOffset; + if (type == typeof(Decimal)) return Common.Configuration.NullableValues.Decimal; + if (type == typeof(Guid)) return Common.Configuration.NullableValues.Guid; + +#if !SILVERLIGHT + + if (type == typeof(SqlInt32)) return SqlInt32. Null; + if (type == typeof(SqlString)) return SqlString. Null; + if (type == typeof(SqlBoolean)) return SqlBoolean. Null; + if (type == typeof(SqlByte)) return SqlByte. Null; + if (type == typeof(SqlDateTime)) return SqlDateTime.Null; + if (type == typeof(SqlDecimal)) return SqlDecimal. Null; + if (type == typeof(SqlDouble)) return SqlDouble. Null; + if (type == typeof(SqlGuid)) return SqlGuid. Null; + if (type == typeof(SqlInt16)) return SqlInt16. Null; + if (type == typeof(SqlInt64)) return SqlInt64. Null; + if (type == typeof(SqlMoney)) return SqlMoney. Null; + if (type == typeof(SqlSingle)) return SqlSingle. Null; + if (type == typeof(SqlBinary)) return SqlBinary. Null; + +#endif + } + } + else + { + if (type == typeof(String)) return Common.Configuration.NullableValues.String; + if (type == typeof(DBNull)) return DBNull.Value; + if (type == typeof(Stream)) return Stream.Null; +#if !SILVERLIGHT + if (type == typeof(SqlXml)) return SqlXml.Null; +#endif + } + + return null; + } + + const FieldAttributes EnumField = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal; + + static readonly Dictionary _nullValues = new Dictionary(); + + static object GetEnumNullValue(Type type) + { + object nullValue; + + lock (_nullValues) + if (_nullValues.TryGetValue(type, out nullValue)) + return nullValue; + + var fields = type.GetFields(); + + foreach (var fi in fields) + { + if ((fi.Attributes & EnumField) == EnumField) + { + var attrs = Attribute.GetCustomAttributes(fi, typeof(NullValueAttribute)); + + if (attrs.Length > 0) + { + nullValue = Enum.Parse(type, fi.Name, false); + break; + } + } + } + + lock (_nullValues) + if (!_nullValues.ContainsKey(type)) + _nullValues.Add(type, nullValue); + + return nullValue; + } + + private static IsNullHandler _isNull = IsNullInternal; + public static IsNullHandler IsNull + { + get { return _isNull ?? (_isNull = IsNullInternal); } + set { _isNull = value; } + } + + private static bool IsNullInternal(object value) + { + if (value == null) + return true; + + var nullValue = GetNullValue(value.GetType()); + + return nullValue != null && value.Equals(nullValue); + } + + #endregion + + #region ICollection Members + + void ICollection.Add(MemberAccessor item) + { + _members.Add(item); + } + + void ICollection.Clear() + { + _members.Clear(); + } + + bool ICollection.Contains(MemberAccessor item) + { + return _members.Contains(item); + } + + void ICollection.CopyTo(MemberAccessor[] array, int arrayIndex) + { + _members.CopyTo(array, arrayIndex); + } + + bool ICollection.Remove(MemberAccessor item) + { + return _members.Remove(item); + } + + public int Count + { + get { return _members.Count; } + } + + bool ICollection.IsReadOnly + { + get { return ((ICollection)_members).IsReadOnly; } + } + + public int IndexOf(MemberAccessor ma) + { + return _members.IndexOf(ma); + } + + #endregion + + #region IEnumerable Members + + public IEnumerator GetEnumerator() + { + return _members.GetEnumerator(); + } + + #endregion + + #region IEnumerable Members + + IEnumerator IEnumerable.GetEnumerator() + { + foreach (MemberAccessor member in _members) + yield return member; + } + + #endregion + + #region Write Object Info + + public static void WriteDebug(object o) + { +#if DEBUG + Write(o, DebugWriteLine); +#endif + } + + private static void DebugWriteLine(string text) + { + Debug.WriteLine(text); + } + + public static void WriteConsole(object o) + { + Write(o, Console.WriteLine); + } + + [SuppressMessage("Microsoft.Performance", "CA1818:DoNotConcatenateStringsInsideLoops")] + private static string MapTypeName(Type type) + { + if (type.IsGenericType) + { + if (type.GetGenericTypeDefinition() == typeof(Nullable<>)) + return string.Format("{0}?", MapTypeName(Nullable.GetUnderlyingType(type))); + + var name = type.Name; + var idx = name.IndexOf('`'); + + if (idx >= 0) + name = name.Substring(0, idx); + + name += "<"; + + foreach (var t in type.GetGenericArguments()) + name += MapTypeName(t) + ','; + + if (name[name.Length - 1] == ',') + name = name.Substring(0, name.Length - 1); + + name += ">"; + + return name; + } + + if (type.IsPrimitive || + type == typeof(string) || + type == typeof(object) || + type == typeof(decimal)) + { + if (type == typeof(int)) return "int"; + if (type == typeof(bool)) return "bool"; + if (type == typeof(short)) return "short"; + if (type == typeof(long)) return "long"; + if (type == typeof(ushort)) return "ushort"; + if (type == typeof(uint)) return "uint"; + if (type == typeof(ulong)) return "ulong"; + if (type == typeof(float)) return "float"; + + return type.Name.ToLower(); + } + + return type.Name; + } + + public delegate void WriteLine(string text); + + [SuppressMessage("Microsoft.Usage", "CA2241:ProvideCorrectArgumentsToFormattingMethods")] + public static void Write(object o, WriteLine writeLine) + { + if (o == null) + { + writeLine("*** (null) ***"); + return; + } + + MemberAccessor ma; + + var ta = GetAccessor(o.GetType()); + var nameLen = 0; + var typeLen = 0; + + foreach (var de in ta._memberNames) + { + if (nameLen < de.Key.Length) + nameLen = de.Key.Length; + + ma = de.Value; + + if (typeLen < MapTypeName(ma.Type).Length) + typeLen = MapTypeName(ma.Type).Length; + } + + var text = "*** " + o.GetType().FullName + ": ***"; + + writeLine(text); + + var format = string.Format("{{0,-{0}}} {{1,-{1}}} : {{2}}", typeLen, nameLen); + + foreach (var de in ta._memberNames) + { + ma = de.Value; + + var value = ma.GetValue(o); + + if (value == null) + value = "(null)"; + else if (value is ICollection) + value = string.Format("(Count = {0})", ((ICollection)value).Count); + + text = string.Format(format, MapTypeName(ma.Type), de.Key, value); + + writeLine(text); + } + + writeLine("***"); + } + + #endregion + + #region TypeDescriptor + +#if !SILVERLIGHT && !DATA + + #region CustomTypeDescriptor + + private static readonly Hashtable _descriptors = new Hashtable(); + + public static ICustomTypeDescriptor GetCustomTypeDescriptor(Type type) + { + var descriptor = (ICustomTypeDescriptor)_descriptors[type]; + + if (descriptor == null) + { + lock (_descriptors.SyncRoot) + { + descriptor = (ICustomTypeDescriptor)_descriptors[type]; + + if (descriptor == null) + { + descriptor = new CustomTypeDescriptorImpl(type); + + _descriptors.Add(type, descriptor); + } + } + } + return descriptor; + } + + private ICustomTypeDescriptor _customTypeDescriptor; + public ICustomTypeDescriptor CustomTypeDescriptor + { + get { return _customTypeDescriptor ?? (_customTypeDescriptor = GetCustomTypeDescriptor(OriginalType)); } + } + + #endregion + + #region Property Descriptors + + private PropertyDescriptorCollection _propertyDescriptors; + public PropertyDescriptorCollection PropertyDescriptors + { + get + { + if (_propertyDescriptors == null) + { + if (TypeHelper.IsSameOrParent(typeof(ICustomTypeDescriptor), OriginalType)) + { + var descriptor = CreateInstance() as ICustomTypeDescriptor; + + if (descriptor != null) + _propertyDescriptors = descriptor.GetProperties(); + } + + if (_propertyDescriptors == null) + _propertyDescriptors = CreatePropertyDescriptors(); + } + + return _propertyDescriptors; + } + } + + public PropertyDescriptorCollection CreatePropertyDescriptors() + { + if (Data.DbManager.TraceSwitch.TraceInfo) + Data.DbManager.WriteTraceLine(OriginalType.FullName, "CreatePropertyDescriptors"); + + var pd = new PropertyDescriptor[Count]; + + var i = 0; + foreach (MemberAccessor ma in _members) + pd[i++] = ma.PropertyDescriptor; + + return new PropertyDescriptorCollection(pd); + } + + public PropertyDescriptorCollection CreateExtendedPropertyDescriptors( + Type objectViewType, + IsNullHandler isNull) + { + // This is definitely wrong. + // + //if (isNull == null) + // isNull = _isNull; + + var pdc = CreatePropertyDescriptors(); + + if (objectViewType != null) + { + var viewAccessor = GetAccessor(objectViewType); + var objectView = (IObjectView)viewAccessor.CreateInstanceEx(); + var list = new List(); + + var viewpdc = viewAccessor.PropertyDescriptors; + + foreach (PropertyDescriptor pd in viewpdc) + list.Add(new ObjectViewPropertyDescriptor(pd, objectView)); + + foreach (PropertyDescriptor pd in pdc) + if (viewpdc.Find(pd.Name, false) == null) + list.Add(pd); + + pdc = new PropertyDescriptorCollection(list.ToArray()); + } + + pdc = pdc.Sort(new PropertyDescriptorComparer()); + + pdc = GetExtendedProperties(pdc, OriginalType, String.Empty, Type.EmptyTypes, new PropertyDescriptor[0], isNull); + + return pdc; + } + + private static PropertyDescriptorCollection GetExtendedProperties( + PropertyDescriptorCollection pdc, + Type itemType, + string propertyPrefix, + Type[] parentTypes, + PropertyDescriptor[] parentAccessors, + IsNullHandler isNull) + { + var list = new ArrayList(pdc.Count); + var objects = new ArrayList(); + var isDataRow = itemType.IsSubclassOf(typeof(DataRow)); + + foreach (PropertyDescriptor p in pdc) + { + var propertyType = p.PropertyType; + + if (p.Attributes.Matches(BindableAttribute.No) || + //propertyType == typeof(Type) || + isDataRow && p.Name == "ItemArray") + continue; + + var isList = false; + var explicitlyBound = p.Attributes.Contains(BindableAttribute.Yes); + var pd = p; + + if (propertyType.GetInterface("IList") != null) + { + //if (!explicitlyBound) + // continue; + + isList = true; + pd = new ListPropertyDescriptor(pd); + } + + if (!isList && + !propertyType.IsValueType && + !propertyType.IsArray && + (!propertyType.FullName.StartsWith("System.") || explicitlyBound + || propertyType.IsGenericType) && + propertyType != typeof(Type) && + propertyType != typeof(string) && + propertyType != typeof(object) && + Array.IndexOf(parentTypes, propertyType) == -1) + { + var childParentTypes = new Type[parentTypes.Length + 1]; + + parentTypes.CopyTo(childParentTypes, 0); + childParentTypes[parentTypes.Length] = itemType; + + var childParentAccessors = new PropertyDescriptor[parentAccessors.Length + 1]; + + parentAccessors.CopyTo(childParentAccessors, 0); + childParentAccessors[parentAccessors.Length] = pd; + + var pdch = GetAccessor(propertyType).PropertyDescriptors; + + pdch = pdch.Sort(new PropertyDescriptorComparer()); + pdch = GetExtendedProperties( + pdch, + propertyType, + propertyPrefix + pd.Name + "+", + childParentTypes, + childParentAccessors, + isNull); + + objects.AddRange(pdch); + } + else + { + if (propertyPrefix.Length != 0 || isNull != null) + pd = new StandardPropertyDescriptor(pd, propertyPrefix, parentAccessors, isNull); + + list.Add(pd); + } + } + + list.AddRange(objects); + + return new PropertyDescriptorCollection( + (PropertyDescriptor[])list.ToArray(typeof(PropertyDescriptor))); + } + + #region PropertyDescriptorComparer + + class PropertyDescriptorComparer : IComparer + { + public int Compare(object x, object y) + { + return String.Compare(((PropertyDescriptor)x).Name, ((PropertyDescriptor)y).Name); + } + } + + #endregion + + #region ListPropertyDescriptor + + class ListPropertyDescriptor : PropertyDescriptorWrapper + { + public ListPropertyDescriptor(PropertyDescriptor descriptor) + : base(descriptor) + { + } + + public override object GetValue(object component) + { + var value = base.GetValue(component); + + if (value == null) + return value; + + if (value is IBindingList && value is ITypedList) + return value; + + return EditableArrayList.Adapter((IList)value); + } + } + + #endregion + + #region StandardPropertyDescriptor + + class StandardPropertyDescriptor : PropertyDescriptorWrapper + { + protected readonly PropertyDescriptor _descriptor; + protected readonly IsNullHandler _isNull; + + protected readonly string _prefixedName; + protected readonly PropertyDescriptor[] _chainAccessors; + + public StandardPropertyDescriptor( + PropertyDescriptor pd, + string namePrefix, + PropertyDescriptor[] chainAccessors, + IsNullHandler isNull) + : base(pd) + { + _descriptor = pd; + _isNull = isNull; + _prefixedName = namePrefix + pd.Name; + _chainAccessors = chainAccessors; + } + + protected object GetNestedComponent(object component) + { + for (var i = 0; + i < _chainAccessors.Length && component != null && !(component is DBNull); + i++) + { + component = _chainAccessors[i].GetValue(component); + } + + return component; + } + + public override void SetValue(object component, object value) + { + component = GetNestedComponent(component); + + if (component != null && !(component is DBNull)) + _descriptor.SetValue(component, value); + } + + public override object GetValue(object component) + { + component = GetNestedComponent(component); + + return CheckNull( + component != null && !(component is DBNull)? _descriptor.GetValue(component): null); + } + + public override string Name + { + get { return _prefixedName; } + } + + protected object CheckNull(object value) + { + if (_isNull != null && _isNull(value)) + { + switch (Common.Configuration.CheckNullReturnIfNull) + { + case Common.Configuration.NullEquivalent.DBNull: + return DBNull.Value; + case Common.Configuration.NullEquivalent.Null: + return null; + case Common.Configuration.NullEquivalent.Value: + return value; + } + + return DBNull.Value; + } + + return value; + } + } + + #endregion + + #region objectViewPropertyDescriptor + + class ObjectViewPropertyDescriptor : PropertyDescriptorWrapper + { + public ObjectViewPropertyDescriptor(PropertyDescriptor pd, IObjectView objectView) + : base(pd) + { + _objectView = objectView; + } + + private readonly IObjectView _objectView; + + public override object GetValue(object component) + { + _objectView.Object = component; + + return base.GetValue(_objectView); + } + + public override void SetValue(object component, object value) + { + _objectView.Object = component; + + base.SetValue(_objectView, value); + } + } + + #endregion + + #endregion + + #region ITypeDescriptionProvider Members + + string ITypeDescriptionProvider.ClassName + { + get { return OriginalType.Name; } + } + + string ITypeDescriptionProvider.ComponentName + { + get { return OriginalType.Name; } + } + + EventDescriptor ITypeDescriptionProvider.GetEvent(string name) + { + return new CustomEventDescriptor(OriginalType.GetEvent(name)); + } + + PropertyDescriptor ITypeDescriptionProvider.GetProperty(string name) + { + var ma = this[name]; + return ma != null ? ma.PropertyDescriptor : null; + } + + AttributeCollection ITypeDescriptionProvider.GetAttributes() + { + var attributesAsObj = new TypeHelper(OriginalType).GetAttributes(); + var attributes = new Attribute[attributesAsObj.Length]; + + for (var i = 0; i < attributesAsObj.Length; i++) + attributes[i] = attributesAsObj[i] as Attribute; + + return new AttributeCollection(attributes); + } + + EventDescriptorCollection ITypeDescriptionProvider.GetEvents() + { + var ei = OriginalType.GetEvents(); + var ed = new EventDescriptor[ei.Length]; + + for (var i = 0; i < ei.Length; i++) + ed[i] = new CustomEventDescriptor(ei[i]); + + return new EventDescriptorCollection(ed); + } + + PropertyDescriptorCollection ITypeDescriptionProvider.GetProperties() + { + return CreatePropertyDescriptors(); + } + + #region CustomEventDescriptor + + class CustomEventDescriptor : EventDescriptor + { + public CustomEventDescriptor(EventInfo eventInfo) + : base(eventInfo.Name, null) + { + _eventInfo = eventInfo; + } + + private readonly EventInfo _eventInfo; + + public override void AddEventHandler(object component, Delegate value) + { + _eventInfo.AddEventHandler(component, value); + } + + public override void RemoveEventHandler(object component, Delegate value) + { + _eventInfo.RemoveEventHandler(component, value); + } + + public override Type ComponentType { get { return _eventInfo.DeclaringType; } } + public override Type EventType { get { return _eventInfo.EventHandlerType; } } + public override bool IsMulticast { get { return _eventInfo.IsMulticast; } } + } + + #endregion + + #endregion + +#endif + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/TypeAccessorT.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/TypeAccessorT.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,103 @@ +using System; + +namespace BLToolkit.Reflection +{ + public static class TypeAccessor + { + #region CreateInstance + + [System.Diagnostics.DebuggerStepThrough] + public static T CreateInstance() + { + return (T)_instance.CreateInstance(); + } + + [System.Diagnostics.DebuggerStepThrough] + public static T CreateInstance(InitContext context) + { + return (T)_instance.CreateInstance(context); + } + + [System.Diagnostics.DebuggerStepThrough] + public static T CreateInstanceEx() + { + return (T)_instance.CreateInstanceEx(); + } + + [System.Diagnostics.DebuggerStepThrough] + public static T CreateInstanceEx(InitContext context) + { + return (T)_instance.CreateInstanceEx(context); + } + + #endregion + + #region Copy & AreEqual + + public static T Copy(T source, T dest) + { + if (source == null) throw new ArgumentNullException("source"); + if (dest == null) throw new ArgumentNullException("dest"); + + return (T)TypeAccessor.CopyInternal(source, dest, _instance); + } + + public static T Copy(T source) + { + if (source == null) return source; + + return (T)TypeAccessor.CopyInternal(source, CreateInstanceEx(), _instance); + } + + public static bool AreEqual(T obj1, T obj2) + { + if (ReferenceEquals(obj1, obj2)) + return true; + + if (obj1 == null || obj2 == null) + return false; + + foreach (MemberAccessor ma in _instance) + if ((!Equals(ma.GetValue(obj1), ma.GetValue(obj2)))) + return false; + + return true; + } + + #endregion + + public static IObjectFactory ObjectFactory + { + get { return _instance.ObjectFactory; } + set { _instance.ObjectFactory = value; } + } + + public static Type Type { get { return _instance.Type; } } + public static Type OriginalType { get { return _instance.OriginalType; } } + + private static readonly TypeAccessor _instance; + public static TypeAccessor Instance + { + [System.Diagnostics.DebuggerStepThrough] + get { return _instance; } + } + + static TypeAccessor() + { + // Explicitly typed type constructor to prevent 'BeforeFieldInit' jit optimization. + // See http://blogs.msdn.com/davidnotario/archive/2005/02/08/369593.aspx for details. + // + // For us, this means that + // + // TypeFactory.SetGlobalAssembly(); + // SomeObject o = TypeAccessor.CreateInstance(); + // + // May be executed in reverse order. Usually, there is no problem, + // but sometimes the order is important. + // See UnitTests\CS\TypeBuilder\InternalTypesTest.cs for an example. + // + _instance = TypeAccessor.GetAccessor(typeof(T)); + } + } +} + diff -r 000000000000 -r f990fcb411a9 Source/Reflection/TypeHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/TypeHelper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1692 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Xml; + +#if !SILVERLIGHT +using System.Xml.Linq; +#endif + +namespace BLToolkit.Reflection +{ +#if !SILVERLIGHT && !DATA + using EditableObjects; +#endif + using DataAccess; + using TypeBuilder; + + /// + /// A wrapper around the class. + /// + [System.Diagnostics.DebuggerDisplay("Type = {Type}")] + public class TypeHelper + { + /// + /// Initializes a new instance of the class. + /// + /// The Type to wrap. + public TypeHelper(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + Type = type; + } + + /// + /// Gets associated Type. + /// + public Type Type { get; private set; } + + /// + /// Converts the supplied to a . + /// + /// The Type. + /// A TypeHelper. + public static implicit operator TypeHelper(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + return new TypeHelper(type); + } + + /// + /// Converts the supplied to a . + /// + /// The TypeHelper. + /// A Type. + public static implicit operator Type(TypeHelper typeHelper) + { + if (typeHelper == null) throw new ArgumentNullException("typeHelper"); + + return typeHelper.Type; + } + + #region GetAttributes + + /// + /// Returns an array of custom attributes identified by Type. + /// + /// The type of attribute to search for. + /// Only attributes that are assignable to this type are returned. + /// Specifies whether to search this member's inheritance chain + /// to find the attributes. + /// An array of custom attributes defined on this reflected member, + /// or an array with zero (0) elements if no attributes are defined. + public object[] GetCustomAttributes(Type attributeType, bool inherit) + { + return Type.GetCustomAttributes(attributeType, inherit); + } + + /// + /// Returns an array of custom attributes identified by Type + /// including attribute's inheritance chain. + /// + /// The type of attribute to search for. + /// Only attributes that are assignable to this type are returned. + /// An array of custom attributes defined on this reflected member, + /// or an array with zero (0) elements if no attributes are defined. + public object[] GetCustomAttributes(Type attributeType) + { + return Type.GetCustomAttributes(attributeType, true); + } + + + /// + /// Returns an array of all of the custom attributes. + /// + /// Specifies whether to search this member's inheritance chain + /// to find the attributes. + /// An array of custom attributes defined on this reflected member, + /// or an array with zero (0) elements if no attributes are defined. + public object[] GetCustomAttributes(bool inherit) + { + return Type.GetCustomAttributes(inherit); + } + + /// + /// Returns an array of all of the custom attributes including attributes' inheritance chain. + /// + /// An array of custom attributes defined on this reflected member, + /// or an array with zero (0) elements if no attributes are defined. + public object[] GetCustomAttributes() + { + return Type.GetCustomAttributes(true); + } + + /// + /// Returns an array of all custom attributes identified by Type including type's + /// inheritance chain. + /// + /// The type of attribute to search for. + /// Only attributes that are assignable to this type are returned. + /// An array of custom attributes defined on this reflected member, + /// or an array with zero (0) elements if no attributes are defined. + public object[] GetAttributes(Type attributeType) + { + return GetAttributes(Type, attributeType); + } + + /// + /// Returns an array of all custom attributes including type's inheritance chain. + /// + /// An array of custom attributes defined on this reflected member, + /// or an array with zero (0) elements if no attributes are defined. + public object[] GetAttributes() + { + return GetAttributesInternal(); + } + + #region Attributes cache + + object[] GetAttributesInternal() + { + lock (_typeAttributes) + { + var key = Type.FullName; + + object[] attrs; + + if (!_typeAttributes.TryGetValue(key, out attrs)) + { + var list = new List(); + + GetAttributesInternal(list, Type); + + _typeAttributes.Add(key, attrs = list.ToArray()); + } + + return attrs; + } + } + + static readonly Dictionary _typeAttributesTopInternal = new Dictionary(10); + + static void GetAttributesInternal(List list, Type type) + { + object[] attrs; + + if (_typeAttributesTopInternal.TryGetValue(type, out attrs)) + list.AddRange(attrs); + else + { + GetAttributesTreeInternal(list, type); + _typeAttributesTopInternal.Add(type, list.ToArray()); + } + } + + static readonly Dictionary _typeAttributesInternal = new Dictionary(10); + + static void GetAttributesTreeInternal(List list, Type type) + { + object[] attrs; + + if (!_typeAttributesInternal.TryGetValue(type, out attrs)) + _typeAttributesInternal.Add(type, attrs = type.GetCustomAttributes(false)); + + if (Common.Configuration.FilterOutBaseEqualAttributes) + { + foreach (var t in attrs) + if (!list.Contains(t)) + list.Add(t); + } + else + list.AddRange(attrs); + + if (type.IsInterface) + return; + + // Reflection returns interfaces for the whole inheritance chain. + // So, we are going to get some hemorrhoid here to restore the inheritance sequence. + // + var interfaces = type.GetInterfaces(); + var nBaseInterfaces = type.BaseType != null? type.BaseType.GetInterfaces().Length: 0; + + for (var i = 0; i < interfaces.Length; i++) + { + var intf = interfaces[i]; + + if (i < nBaseInterfaces) + { + var getAttr = false; + + foreach (var mi in type.GetInterfaceMap(intf).TargetMethods) + { + // Check if the interface is reimplemented. + // + if (mi.DeclaringType == type) + { + getAttr = true; + break; + } + } + + if (getAttr == false) + continue; + } + + GetAttributesTreeInternal(list, intf); + } + + if (type.BaseType != null && type.BaseType != typeof(object)) + GetAttributesTreeInternal(list, type.BaseType); + } + + static readonly Dictionary _typeAttributes = new Dictionary(10); + + #endregion + + /// + /// Returns an array of custom attributes applied to a type. + /// + /// A type instance. + /// The type of attribute to search for. + /// Only attributes that are assignable to this type are returned. + /// An array of custom attributes applied to this type, + /// or an array with zero (0) elements if no attributes have been applied. + public static object[] GetAttributes(Type type, Type attributeType) + { + if (type == null) throw new ArgumentNullException("type"); + if (attributeType == null) throw new ArgumentNullException("attributeType"); + + lock (_typeAttributes) + { + var key = type.FullName + "#" + attributeType.FullName; + + object[] attrs; + + if (!_typeAttributes.TryGetValue(key, out attrs)) + { + var list = new List(); + + GetAttributesInternal(list, type); + + for (var i = 0; i < list.Count; i++) + if (attributeType.IsInstanceOfType(list[i]) == false) + list.RemoveAt(i--); + + _typeAttributes.Add(key, attrs = list.ToArray()); + } + + return attrs; + } + } + + /// + /// Retrieves a custom attribute applied to a type. + /// + /// A type instance. + /// The type of attribute to search for. + /// Only attributes that are assignable to this type are returned. + /// A reference to the first custom attribute of type + /// that is applied to element, or null if there is no such attribute. + public static Attribute GetFirstAttribute(Type type, Type attributeType) + { + var attrs = new TypeHelper(type).GetAttributes(attributeType); + + return attrs.Length > 0? (Attribute)attrs[0]: null; + } + + /// + /// Retrieves a custom attribute applied to a type. + /// + /// A type instance. + /// The type of attribute to search for. + /// Only attributes that are assignable to this type are returned. + /// A reference to the first custom attribute of type attributeType + /// that is applied to element, or null if there is no such attribute. + public static T GetFirstAttribute(Type type) where T : Attribute + { + var attrs = new TypeHelper(type).GetAttributes(typeof(T)); + + return attrs.Length > 0? (T)attrs[0]: null; + } + + #endregion + + #region Property Wrappers + + /// + /// Gets the fully qualified name of the Type, including the namespace of the Type. + /// + public string FullName + { + get { return Type.FullName; } + } + + /// + /// Gets the name of the Type. + /// + public string Name + { + get { return Type.Name; } + } + + /// + /// Gets a value indicating whether the Type is abstract and must be overridden. + /// + public bool IsAbstract + { + get { return Type.IsAbstract; } + } + + /// + /// Gets a value indicating whether the System.Type is an array. + /// + public bool IsArray + { + get { return Type.IsArray; } + } + + /// + /// Gets a value indicating whether the Type is a value type. + /// + public bool IsValueType + { + get { return Type.IsValueType; } + } + + /// + /// Gets a value indicating whether the Type is a class; that is, not a value type or interface. + /// + public bool IsClass + { + get { return Type.IsClass; } + } + + /// + /// Gets a value indicating whether the System.Type is an interface; that is, not a class or a value type. + /// + public bool IsInterface + { + get { return Type.IsInterface; } + } + + /// + /// Indicates whether the Type is serializable. + /// + public bool IsSerializable + { + get + { +#if SILVERLIGHT + return false; +#else + return Type.IsSerializable; +#endif + } + } + + #endregion + + #region GetMethods + + /// + /// Returns all the methods of the current Type. + /// + /// An array of objects representing all methods + /// defined for the current Type. + public MethodInfo[] GetMethods() + { + return Type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + } + + /// + /// Returns all the public methods of the current Type. + /// + /// An array of objects representing all the public methods + /// defined for the current Type. + public MethodInfo[] GetPublicMethods() + { + return Type.GetMethods(BindingFlags.Instance | BindingFlags.Public); + } + + /// + /// Searches for the methods defined for the current Type, + /// using the specified binding constraints. + /// + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// An array of objects representing all methods defined + /// for the current Type that match the specified binding constraints. + public MethodInfo[] GetMethods(BindingFlags flags) + { + return Type.GetMethods(flags); + } + + /// + /// Returns all the generic or non-generic methods of the current Type. + /// + /// True to return all generic methods, false to return all non-generic. + /// An array of objects representing all methods + /// defined for the current Type. + public MethodInfo[] GetMethods(bool generic) + { + return GetMethods(Type, generic, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + } + + /// + /// Returns all the public and non-generic methods of the current Type. + /// + /// True to return all generic methods, false to return all non-generic. + /// An array of objects representing all the public methods + /// defined for the current Type. + public MethodInfo[] GetPublicMethods(bool generic) + { + return GetMethods(Type, generic, BindingFlags.Instance | BindingFlags.Public); + } + + /// + /// Searches for the generic methods defined for the current Type, + /// using the specified binding constraints. + /// + /// True to return all generic methods, false to return all non-generic. + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// An array of objects representing all methods defined + /// for the current Type that match the specified binding constraints. + public MethodInfo[] GetMethods(bool generic, BindingFlags flags) + { + return GetMethods(Type, generic, flags); + } + + #endregion + + #region GetMethod + + /// + /// Searches for the specified instance method (public or non-public), using the specified name. + /// + /// The String containing the name of the method to get. + /// A object representing the method + /// that matches the specified name, if found; otherwise, null. + public MethodInfo GetMethod(string methodName) + { + return Type.GetMethod(methodName, + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + } + + /// + /// Searches for the specified public instance method, using the specified name. + /// + /// The String containing the name of the method to get. + /// A object representing the method + /// that matches the specified name, if found; otherwise, null. + public MethodInfo GetPublicMethod(string methodName) + { + return Type.GetMethod(methodName, + BindingFlags.Instance | BindingFlags.Public); + } + + /// + /// Searches for the specified method, using the specified name and binding flags. + /// + /// The String containing the name of the method to get. + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public MethodInfo GetMethod(string methodName, BindingFlags flags) + { + return Type.GetMethod(methodName, flags); + } + + /// + /// Searches for the specified public instance method, using the specified name. + /// + /// The String containing the name of the method to get. + /// An array of objects representing + /// the number, order, and type of the parameters for the method to get.-or- + /// An empty array of the type (for example, ) + /// to get a method that takes no parameters. + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public MethodInfo GetPublicMethod(string methodName, params Type[] types) + { + return Type.GetMethod( + methodName, + BindingFlags.Instance | BindingFlags.Public, + null, + types, + null); + } + + /// + /// Searches for the specified instance method (public or non-public), + /// using the specified name and argument types. + /// + /// The String containing the name of the method to get. + /// An array of objects representing + /// the number, order, and type of the parameters for the method to get.-or- + /// An empty array of the type (for example, ) + /// to get a method that takes no parameters. + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public MethodInfo GetMethod(string methodName, params Type[] types) + { + return Type.GetMethod( + methodName, + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, + null, + types, + null); + } + + /// + /// Searches for the specified method, using the specified name, + /// binding flags and argument types. + /// + /// The String containing the name of the method to get. + /// An array of objects representing + /// the number, order, and type of the parameters for the method to get.-or- + /// An empty array of the type (for example, ) + /// to get a method that takes no parameters. + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public MethodInfo GetMethod(string methodName, BindingFlags flags, params Type[] types) + { + return Type.GetMethod(methodName, flags, null, types, null); + } + + /// + /// Searches for the specified instance method (public or non-public), using the specified name. + /// + /// The String containing the name of the method to get. + /// True to search only for a generic method, or + /// False to search only for non-generic method. + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public MethodInfo GetMethod(bool generic, string methodName) + { + return GetMethod(Type, generic, methodName, + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + } + + /// + /// Searches for the specified public instance method, using the specified name. + /// + /// The String containing the name of the method to get. + /// True to search only for a generic method, or + /// False to search only for non-generic method. + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public MethodInfo GetPublicMethod(bool generic, string methodName) + { + return GetMethod(Type, generic, methodName, + BindingFlags.Instance | BindingFlags.Public); + } + + /// + /// Searches for the specified method, using the specified name and binding flags. + /// + /// The String containing the name of the method to get. + /// True to search only for a generic method, or + /// False to search only for non-generic method. + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public MethodInfo GetMethod(bool generic, string methodName, BindingFlags flags) + { + return GetMethod(Type, generic, methodName, flags); + } + + /// + /// Searches for the specified public instance method, using the specified name and argument types. + /// + /// The String containing the name of the method to get. + /// True to search only for a generic method, or + /// False to search only for non-generic method. + /// An array of objects representing + /// the number, order, and type of the parameters for the method to get.-or- + /// An empty array of the type (for example, ) + /// to get a method that takes no parameters. + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public MethodInfo GetPublicMethod(bool generic, string methodName, params Type[] types) + { + return Type.GetMethod(methodName, + BindingFlags.Instance | BindingFlags.Public, + generic ? GenericBinder.Generic : GenericBinder.NonGeneric, + types, null); + } + + /// + /// Searches for the specified instance method (public or non-public), + /// using the specified name and argument types. + /// + /// The String containing the name of the method to get. + /// True to search only for a generic method, or + /// False to search only for non-generic method. + /// An array of objects representing + /// the number, order, and type of the parameters for the method to get.-or- + /// An empty array of the type (for example, ) + /// to get a method that takes no parameters. + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public MethodInfo GetMethod(bool generic, string methodName, params Type[] types) + { + return Type.GetMethod(methodName, + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, + generic ? GenericBinder.Generic : GenericBinder.NonGeneric, + types, null); + } + + /// + /// Searches for the specified method using the specified name, binding flags and argument types. + /// + /// The String containing the name of the method to get. + /// True to search only for a generic method, or + /// False to search only for non-generic method. + /// An array of objects representing + /// the number, order, and type of the parameters for the method to get.-or- + /// An empty array of the type (for example, ) + /// to get a method that takes no parameters. + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public MethodInfo GetMethod(bool generic, string methodName, BindingFlags flags, params Type[] types) + { + return Type.GetMethod(methodName, + flags, + generic ? GenericBinder.Generic : GenericBinder.NonGeneric, + types, null); + } + + #endregion + + #region GetFields + + /// + /// Returns all the public fields of the current Type. + /// + /// An array of objects representing + /// all the public fields defined for the current Type. + public FieldInfo[] GetFields() + { + return Type.GetFields(); + } + + /// + /// Searches for the fields of the current Type, using the specified binding constraints. + /// + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// An array of objects representing + /// all fields of the current Type + /// that match the specified binding constraints. + public FieldInfo[] GetFields(BindingFlags bindingFlags) + { + return Type.GetFields(bindingFlags); + } + + /// + /// Searches for the public field with the specified name. + /// + /// The String containing the name of the public field to get. + /// A object representing the public field with the specified name, + /// if found; otherwise, a null reference. + public FieldInfo GetField(string name) + { + return Type.GetField( + name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + } + + #endregion + + #region GetProperties + + /// + /// Returns all the public properties of the current Type. + /// + /// An array of objects representing + /// all public properties of the current Type. + public PropertyInfo[] GetProperties() + { + return Type.GetProperties(); + } + + /// + /// Searches for the properties of the current Type, using the specified binding constraints. + /// + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// An array of objects representing + /// all properties of the current Type + /// that match the specified binding constraints. + public PropertyInfo[] GetProperties(BindingFlags bindingFlags) + { + return Type.GetProperties(bindingFlags); + } + + /// + /// Searches for the public property with the specified name. + /// + /// The String containing the name of the public property to get. + /// A object representing the public property with the specified name, + /// if found; otherwise, a null reference. + public PropertyInfo GetProperty(string name) + { + return Type.GetProperty( + name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + } + + #endregion + + #region GetInterfaces + + /* + private Type[] _interfaces; + + /// + /// Gets all the interfaces implemented or inherited by the current . + /// + /// An array of Type objects representing all the interfaces implemented or + /// inherited by the current Type, + /// if found; otherwise, an empty array. + public Type[] GetInterfaces() + { + if (_interfaces == null) + _interfaces = _type.GetInterfaces(); + + return _interfaces; + } + + /// + /// Gets a specific interface implemented or inherited by the current . + /// + /// The type of the interface to get. + /// A Type object representing the interface of the specified type, if found; + /// otherwise, a null reference (Nothing in Visual Basic). + public Type GetInterface(Type interfaceType) + { + foreach (Type intf in GetInterfaces()) + if (intf == interfaceType) + return null; + + _type.IsSubclassOf(interfaceType); + + return null; + } + */ + + /// + /// Returns an interface mapping for the current . + /// + /// The + /// of the interface of which to retrieve a mapping. + /// An object representing the interface + /// mapping for . + public InterfaceMapping GetInterfaceMap(Type interfaceType) + { + return Type.GetInterfaceMap(interfaceType); + } + + #endregion + + #region GetConstructor + + /// + /// Searches for a public instance constructor whose parameters match + /// the types in the specified array. + /// + /// An array of Type objects representing the number, + /// order, and type of the parameters for the constructor to get. + /// A object representing the + /// public instance constructor whose parameters match the types in + /// the parameter type array, if found; otherwise, a null reference. + public ConstructorInfo GetPublicConstructor(params Type[] types) + { + return Type.GetConstructor(types); + } + + /// + /// Searches for an instance constructor (public or non-public) whose + /// parameters match the types in the specified array. + /// + /// Type object representing type of the + /// parameter for the constructor to get. + /// A object representing the constructor + /// whose parameters match the types in the parameter type array, if found; + /// otherwise, a null reference. + public ConstructorInfo GetConstructor(Type parameterType) + { + return GetConstructor(Type, parameterType); + } + + /// + /// Searches for an instance constructor (public or non-public) whose + /// parameters match the types in the specified array. + /// + /// An instance of to search constructor for. + /// An array of Type objects representing the number, + /// order, and type of the parameters for the constructor to get. + /// A object representing the constructor + /// whose parameters match the types in the parameter type array, if found; + /// otherwise, a null reference. + public static ConstructorInfo GetConstructor(Type type, params Type[] types) + { + if (type == null) throw new ArgumentNullException("type"); + + return type.GetConstructor( + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, + null, + types, + null); + } + + /// + /// Searches for a public default constructor. + /// + /// A object representing the constructor. + public ConstructorInfo GetPublicDefaultConstructor() + { + return Type.GetConstructor(Type.EmptyTypes); + } + + /// + /// Searches for a default constructor. + /// + /// A object representing the constructor. + public ConstructorInfo GetDefaultConstructor() + { + return GetDefaultConstructor(Type); + } + + /// + /// Searches for a default constructor. + /// + /// An instance of to search constructor for. + /// A object representing the constructor. + public static ConstructorInfo GetDefaultConstructor(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + return type.GetConstructor( + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, + null, + Type.EmptyTypes, + null); + } + + /// + /// Searches for a public constructors. + /// + /// An array of objects + /// representing all the type public constructors, if found; otherwise, an empty array. + public ConstructorInfo[] GetPublicConstructors() + { + return Type.GetConstructors(); + } + + /// + /// Searches for all constructors (except type constructors). + /// + /// An array of objects + /// representing all the type constructors, if found; otherwise, an empty array. + public ConstructorInfo[] GetConstructors() + { + return Type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + } + + #endregion + + #region Static Members + + /// + /// Gets a value indicating whether a type (or type's element type) + /// instance can be null in the underlying data store. + /// + /// A instance. + /// True, if the type parameter is a closed generic nullable type; otherwise, False. + /// Arrays of Nullable types are treated as Nullable types. + public static bool IsNullable(Type type) + { + while (type.IsArray) + type = type.GetElementType(); + + return (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)); + } + + public static bool IsNullableType(Type type) + { + return (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)); + } + + public static bool IsNullableEnum(Type type) + { + return IsNullableType(type) && type.GetGenericArguments()[0].IsEnum; + } + + public static bool IsEnumOrNullableEnum(Type type) + { + return type.IsEnum || IsNullableEnum(type); + } + + public static Type ToNullable(Type type) + { + if (!IsNullable(type) && type.IsValueType) + { + var nullable = typeof(Nullable<>); + var typeArguments = nullable.GetGenericArguments(); + if (typeArguments != null && typeArguments.Length == 1) + { + type = nullable.MakeGenericType(type); + } + } + return type; + } + + /// + /// Returns the underlying type argument of the specified type. + /// + /// A instance. + /// + /// The type argument of the type parameter, + /// if the type parameter is a closed generic nullable type. + /// The underlying Type if the type parameter is an enum type. + /// Otherwise, the type itself. + /// + /// + public static Type GetUnderlyingType(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + if (IsNullableType(type)) + type = type.GetGenericArguments()[0]; + + if (type.IsEnum) + type = Enum.GetUnderlyingType(type); + + return type; + } + + public static Type UnwrapNullableType(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + return IsNullableType(type) ? type.GetGenericArguments()[0] : type; + } + + public static IEnumerable GetDefiningTypes(Type child, MemberInfo member) + { + if (member.MemberType == MemberTypes.Property) + { + var prop = (PropertyInfo)member; + member = prop.GetGetMethod(); + } + + foreach (var inf in child.GetInterfaces()) + { + var pm = child.GetInterfaceMap(inf); + + for (var i = 0; i < pm.TargetMethods.Length; i++) + { + var method = pm.TargetMethods[i]; + + if (method == member || (method.DeclaringType == member.DeclaringType && method.Name == member.Name)) + yield return inf; + } + } + + yield return member.DeclaringType; + } + + public static bool IsAbstractClass(Type type) + { + return type.IsClass && type.IsAbstract; + } + + /// + /// Determines whether the specified types are considered equal. + /// + /// A instance. + /// A type possible derived from the parent type + /// True, when an object instance of the type child + /// can be used as an object of the type parent; otherwise, false. + /// Note that nullable types does not have a parent-child relation to it's underlying type. + /// For example, the 'int?' type (nullable int) and the 'int' type + /// aren't a parent and it's child. + public static bool IsSameOrParent([JetBrains.Annotations.NotNull] Type parent, [JetBrains.Annotations.NotNull] Type child) + { + if (parent == null) throw new ArgumentNullException("parent"); + if (child == null) throw new ArgumentNullException("child"); + + if (parent == child || + child.IsEnum && Enum.GetUnderlyingType(child) == parent || + child.IsSubclassOf(parent)) + { + return true; + } + + if (parent.IsGenericTypeDefinition) + for (var t = child; t != typeof(object) && t != null; t = t.BaseType) + if (t.IsGenericType && t.GetGenericTypeDefinition() == parent) + return true; + + if (parent.IsInterface) + { + var interfaces = child.GetInterfaces(); + + foreach (var t in interfaces) + { + if (parent.IsGenericTypeDefinition) + { + if (t.IsGenericType && t.GetGenericTypeDefinition() == parent) + return true; + } + else if (t == parent) + return true; + } + } + + return false; + } + + public static Type GetGenericType([JetBrains.Annotations.NotNull] Type genericType, Type type) + { + if (genericType == null) throw new ArgumentNullException("genericType"); + + while (type != null && type != typeof(object)) + { + if (type.IsGenericType && type.GetGenericTypeDefinition() == genericType) + return type; + + if (genericType.IsInterface) + { + foreach (var interfaceType in type.GetInterfaces()) + { + var gType = GetGenericType(genericType, interfaceType); + + if (gType != null) + return gType; + } + } + + type = type.BaseType; + } + + return null; + } + + /// + /// Searches for the method defined for a , + /// using the specified name and binding flags. + /// + /// The String containing the name of the method to get. + /// True to search only for a generic method, or + /// False to search only for non-generic method. + /// A instance. + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public static MethodInfo GetMethod([JetBrains.Annotations.NotNull] Type type, bool generic, string methodName, BindingFlags flags) + { + if (type == null) throw new ArgumentNullException("type"); + + foreach (var method in type.GetMethods(flags)) + if (method.IsGenericMethodDefinition == generic && method.Name == methodName) + return method; + + return null; + } + + /// + /// Searches for the methods defined for a , + /// using the specified name and binding flags. + /// + /// A instance. + /// True to return all generic methods, false to return all non-generic. + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// An array of objects representing all methods defined + /// for the current Type that match the specified binding constraints. + public static MethodInfo[] GetMethods(Type type, bool generic, BindingFlags flags) + { + if (type == null) throw new ArgumentNullException("type"); + + return type.GetMethods(flags).Where(method => method.IsGenericMethodDefinition == generic).ToArray(); + } + + /// + /// Searches for the method defined for a , + /// using the specified name and binding flags. + /// + /// A instance. + /// The String containing the name of the method to get. + /// Number of required (non optional) + /// parameter types. + /// A bitmask comprised of one or more + /// that specify how the search is conducted. + /// An array of objects representing + /// the number, order, and type of the parameters for the method to get.-or- + /// An empty array of the type (for example, ) + /// to get a method that takes no parameters. + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public static MethodInfo GetMethod( + Type type, + string methodName, + BindingFlags bindingFlags, + int requiredParametersCount, + params Type[] parameterTypes) + { + while (parameterTypes.Length >= requiredParametersCount) + { + var method = type.GetMethod(methodName, parameterTypes); + + if (null != method) + return method; + + if (parameterTypes.Length == 0) + break; + + Array.Resize(ref parameterTypes, parameterTypes.Length - 1); + } + + return null; + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public static object[] GetPropertyParameters(PropertyInfo propertyInfo) + { + if (propertyInfo == null) throw new ArgumentNullException("propertyInfo"); + + var attrs = propertyInfo.GetCustomAttributes(typeof(ParameterAttribute), true); + + if (attrs != null && attrs.Length > 0) + return ((ParameterAttribute)attrs[0]).Parameters; + + attrs = propertyInfo.GetCustomAttributes(typeof(InstanceTypeAttribute), true); + + if (attrs.Length > 0) + return ((InstanceTypeAttribute)attrs[0]).Parameters; + + attrs = new TypeHelper( + propertyInfo.DeclaringType).GetAttributes(typeof(GlobalInstanceTypeAttribute)); + + foreach (GlobalInstanceTypeAttribute attr in attrs) + if (IsSameOrParent(attr.PropertyType, propertyInfo.PropertyType)) +// if (attr.PropertyType == propertyInfo.PropertyType) + return attr.Parameters; + + return null; + } + + /// + /// Searches for the property defined for a , + /// using the specified name and parameter types. + /// + /// A instance. + /// The String containing the name of the method to get. + /// An array of Type objects representing the number, + /// order, and type of the parameters for the constructor to get. + /// The property return . + /// A object representing the method + /// that matches the specified requirements, if found; otherwise, null. + public static PropertyInfo GetPropertyInfo( + Type type, string propertyName, Type returnType, Type[] types) + { + if (type == null) throw new ArgumentNullException("type"); + + return type.GetProperty( + propertyName, + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, + null, + returnType, + types, + null); + } + + /// + /// Gets the Type of a list item. + /// + /// A instance. + ///The Type instance that represents the exact runtime type of a list item. + public static Type GetListItemType(object list) + { + var typeOfObject = typeof(object); + + if (list == null) + return typeOfObject; + +#if !SILVERLIGHT && !DATA + + if (list is EditableArrayList) + return ((EditableArrayList)list).ItemType; + +#endif + + if (list is Array) + return list.GetType().GetElementType(); + + var type = list.GetType(); + + // object[] attrs = type.GetCustomAttributes(typeof(DefaultMemberAttribute), true); + // string itemMemberName = (attrs.Length == 0)? "Item": ((DefaultMemberAttribute)attrs[0]).MemberName; + + if (list is IList +#if !SILVERLIGHT + || list is ITypedList || list is IListSource +#endif + ) + { + PropertyInfo last = null; + + foreach (var pi in type.GetProperties()) + { + if (pi.GetIndexParameters().Length > 0 && pi.PropertyType != typeOfObject) + { + if (pi.Name == "Item") + return pi.PropertyType; + + last = pi; + } + } + + if (last != null) + return last.PropertyType; + } + + try + { + if (list is IList) + { + foreach (var o in (IList)list) + if (o != null && o.GetType() != typeOfObject) + return o.GetType(); + } + else if (list is IEnumerable) + { + foreach (var o in (IEnumerable)list) + if (o != null && o.GetType() != typeOfObject) + return o.GetType(); + } + } + catch + { + } + + return typeOfObject; + } + + /// + /// Gets the Type of a list item. + /// + /// A instance. + ///The Type instance that represents the exact runtime type of a list item. + public static Type GetListItemType(Type listType) + { + if (listType.IsGenericType) + { + var elementTypes = GetGenericArguments(listType, typeof(IList)); + + if (elementTypes != null) + return elementTypes[0]; + } + + if (IsSameOrParent(typeof(IList), listType) +#if !SILVERLIGHT + || IsSameOrParent(typeof(ITypedList), listType) + || IsSameOrParent(typeof(IListSource), listType) +#endif + ) + { + var elementType = listType.GetElementType(); + + if (elementType != null) + return elementType; + + PropertyInfo last = null; + + foreach (var pi in listType.GetProperties()) + { + if (pi.GetIndexParameters().Length > 0 && pi.PropertyType != typeof(object)) + { + if (pi.Name == "Item") + return pi.PropertyType; + + last = pi; + } + } + + if (last != null) + return last.PropertyType; + } + + return typeof(object); + } + + public static Type GetElementType(Type type) + { + if (type == null) + return null; + + if (type == typeof(object)) + return type.HasElementType ? type.GetElementType(): null; + + if (type.IsArray) + return type.GetElementType(); + + if (type.IsGenericType) + foreach (var aType in type.GetGenericArguments()) + if (typeof(IEnumerable<>).MakeGenericType(new[] { aType }).IsAssignableFrom(type)) + return aType; + + var interfaces = type.GetInterfaces(); + + if (interfaces != null && interfaces.Length > 0) + { + foreach (var iType in interfaces) + { + var eType = GetElementType(iType); + + if (eType != null) + return eType; + } + } + + return GetElementType(type.BaseType); + } + + /// + /// Gets a value indicating whether a type can be used as a db primitive. + /// + /// A instance. + /// True, if the type parameter is a primitive type; otherwise, False. + /// . . + /// . . are specially handled by the library + /// and, therefore, can be treated as scalar types. + public static bool IsScalar(Type type) + { + while (type.IsArray) + type = type.GetElementType(); + + return type.IsValueType + || type == typeof(string) + || type == typeof(System.Data.Linq.Binary) + || type == typeof(Stream) + || type == typeof(XmlReader) + || type.GetCustomAttributes(typeof(ScalarAttribute),true).Any() // If the type is a UDT pass it as is +#if !SILVERLIGHT + || type == typeof(XmlDocument) + || type == typeof(XElement) +#endif + ; + } + + /// + /// Returns an array of Type objects that represent the type arguments + /// of a generic type or the type parameters of a generic type definition. + /// + /// A instance. + ///Non generic base type. + ///An array of Type objects that represent the type arguments + /// of a generic type. Returns an empty array if the current type is not a generic type. + public static Type[] GetGenericArguments(Type type, Type baseType) + { + var baseTypeName = baseType.Name; + + for (var t = type; t != typeof(object) && t != null; t = t.BaseType) + { + if (t.IsGenericType) + { + if (baseType.IsGenericTypeDefinition) + { + if (t.GetGenericTypeDefinition() == baseType) + return t.GetGenericArguments(); + } + else if (baseTypeName == null || t.Name.Split('`')[0] == baseTypeName) + { + return t.GetGenericArguments(); + } + } + } + + foreach (var t in type.GetInterfaces()) + { + if (t.IsGenericType) + { + if (baseType.IsGenericTypeDefinition) + { + if (t.GetGenericTypeDefinition() == baseType) + return t.GetGenericArguments(); + } + else if (baseTypeName == null || t.Name.Split('`')[0] == baseTypeName) + { + return t.GetGenericArguments(); + } + } + } + + return null; + } + + /// + /// Substitutes the elements of an array of types for the type parameters + /// of the current generic type definition and returns a Type object + /// representing the resulting constructed type. + /// + /// A instance. + /// An array of types to be substituted for + /// the type parameters of the current generic type. + /// A Type representing the constructed type formed by substituting + /// the elements of for the type parameters + /// of the current generic type. + /// + public static Type TranslateGenericParameters(Type type, Type[] typeArguments) + { + // 'T paramName' case + // + if (type.IsGenericParameter) + return typeArguments[type.GenericParameterPosition]; + + // 'List paramName' or something like that. + // + if (type.IsGenericType && type.ContainsGenericParameters) + { + var genArgs = type.GetGenericArguments(); + + for (var i = 0; i < genArgs.Length; ++i) + genArgs[i] = TranslateGenericParameters(genArgs[i], typeArguments); + + return type.GetGenericTypeDefinition().MakeGenericType(genArgs); + } + + // Non-generic type. + // + return type; + } + + public static bool CompareParameterTypes(Type goal, Type probe) + { + if (goal == probe) + return true; + + if (goal.IsGenericParameter) + return CheckConstraints(goal, probe); + if (goal.IsGenericType && probe.IsGenericType) + return CompareGenericTypes(goal, probe); + + return false; + } + + public static bool CheckConstraints(Type goal, Type probe) + { + var constraints = goal.GetGenericParameterConstraints(); + + for (var i = 0; i < constraints.Length; i++) + if (!constraints[i].IsAssignableFrom(probe)) + return false; + + return true; + } + + public static bool CompareGenericTypes(Type goal, Type probe) + { + var genArgs = goal.GetGenericArguments(); + var specArgs = probe.GetGenericArguments(); + var match = (genArgs.Length == specArgs.Length); + + for (var i = 0; match && i < genArgs.Length; i++) + { + if (genArgs[i] == specArgs[i]) + continue; + + if (genArgs[i].IsGenericParameter) + match = CheckConstraints(genArgs[i], specArgs[i]); + else if (genArgs[i].IsGenericType && specArgs[i].IsGenericType) + match = CompareGenericTypes(genArgs[i], specArgs[i]); + else + match = false; + } + + return match; + } + + public static PropertyInfo GetPropertyByMethod(MethodInfo method) + { + if (method != null) + { + var type = method.DeclaringType; + var attr = BindingFlags.NonPublic | BindingFlags.Public | (method.IsStatic ? BindingFlags.Static : BindingFlags.Instance); + + foreach (var info in type.GetProperties(attr)) + { + if (info.CanRead && method == info.GetGetMethod(true)) + return info; + + if (info.CanWrite && method == info.GetSetMethod(true)) + return info; + } + } + + return null; + } + + public static Type GetMemberType(MemberInfo memberInfo) + { + switch (memberInfo.MemberType) + { + case MemberTypes.Property : return ((PropertyInfo) memberInfo).PropertyType; + case MemberTypes.Field : return ((FieldInfo) memberInfo).FieldType; + case MemberTypes.Method : return ((MethodInfo) memberInfo).ReturnType; + case MemberTypes.Constructor : return ((ConstructorInfo)memberInfo).DeclaringType; + } + + throw new InvalidOperationException(); + } + + public static bool IsFloatType(Type type) + { + if (IsNullableType(type)) + type = type.GetGenericArguments()[0]; + + switch (Type.GetTypeCode(type)) + { + case TypeCode.Single : + case TypeCode.Double : + case TypeCode.Decimal : return true; + } + + return false; + } + + public static bool IsIntegerType(Type type) + { + if (IsNullableType(type)) + type = type.GetGenericArguments()[0]; + + switch (Type.GetTypeCode(type)) + { + case TypeCode.SByte : + case TypeCode.Byte : + case TypeCode.Int16 : + case TypeCode.UInt16 : + case TypeCode.Int32 : + case TypeCode.UInt32 : + case TypeCode.Int64 : + case TypeCode.UInt64 : return true; + } + + return false; + } + + public static bool IsNullableValueMember(MemberInfo member) + { + return + member.Name == "Value" && + member.DeclaringType.IsGenericType && + member.DeclaringType.GetGenericTypeDefinition() == typeof(Nullable<>); + } + + public static bool IsNullableHasValueMember(MemberInfo member) + { + return + member.Name == "HasValue" && + member.DeclaringType.IsGenericType && + member.DeclaringType.GetGenericTypeDefinition() == typeof(Nullable<>); + } + + public static bool Equals(MemberInfo member1, MemberInfo member2) + { + return Equals(member1, member2, null); + } + + public static bool Equals(MemberInfo member1, MemberInfo member2, Type declaringType) + { + if (ReferenceEquals(member1, member2)) + return true; + + if (member1 == null || member2 == null) + return false; + + if (member1.Name == member2.Name) + { + if (member1.DeclaringType == member2.DeclaringType) + return true; + + if (member1 is PropertyInfo) + { + var isSubclass = + IsSameOrParent(member1.DeclaringType, member2.DeclaringType) || + IsSameOrParent(member2.DeclaringType, member1.DeclaringType); + + if (isSubclass) + return true; + + if (declaringType != null && member2.DeclaringType.IsInterface) + { + var getter1 = ((PropertyInfo)member1).GetGetMethod(); + var getter2 = ((PropertyInfo)member2).GetGetMethod(); + + var map = declaringType.GetInterfaceMap(member2.DeclaringType); + + for (var i = 0; i < map.InterfaceMethods.Length; i++) + if (getter2.Name == map.InterfaceMethods[i].Name && getter2.DeclaringType == map.InterfaceMethods[i].DeclaringType && + getter1.Name == map.TargetMethods [i].Name && getter1.DeclaringType == map.TargetMethods [i].DeclaringType) + return true; + } + } + } + + if (member2.DeclaringType.IsInterface && member1.Name.EndsWith(member2.Name)) + { + if (member1 is PropertyInfo) + { + var isSubclass = member2.DeclaringType.IsAssignableFrom(member1.DeclaringType); + + if (isSubclass) + { + var getter1 = ((PropertyInfo)member1).GetGetMethod(); + var getter2 = ((PropertyInfo)member2).GetGetMethod(); + + var map = member1.DeclaringType.GetInterfaceMap(member2.DeclaringType); + + for (var i = 0; i < map.InterfaceMethods.Length; i++) + if ((getter2 == null || (getter2.Name == map.InterfaceMethods[i].Name && getter2.DeclaringType == map.InterfaceMethods[i].DeclaringType)) + && + (getter1 == null || (getter1.Name == map.InterfaceMethods[i].Name && getter1.DeclaringType == map.InterfaceMethods[i].DeclaringType)) + ) + { + return true; + } + } + } + } + + return false; + } + + interface IGetDefaultValueHelper + { + object GetDefaultValue(); + } + + class GetDefaultValueHelper : IGetDefaultValueHelper + { + public object GetDefaultValue() + { + return default(T); + } + } + + public static object GetDefaultValue(Type type) + { + var dtype = typeof(GetDefaultValueHelper<>).MakeGenericType(type); + var helper = (IGetDefaultValueHelper)Activator.CreateInstance(dtype); + + return helper.GetDefaultValue(); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Reflection/XmlIncludeAbstractAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Reflection/XmlIncludeAbstractAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ +using System; +using System.Xml.Serialization; + +namespace BLToolkit.Reflection +{ + /// + /// Allows the to recognize a type generated + /// by the BLToolkit when it serializes or deserializes an object. + /// + public class XmlIncludeAbstractAttribute : XmlIncludeAttribute + { + /// + /// Initializes a new instance of the class. + /// + /// The of an abstract class to + /// include its BLToolkit extensions. + public XmlIncludeAbstractAttribute(Type type) + : base(TypeBuilder.TypeFactory.GetType(type)) + { + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/Async/ILinqService.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/Async/ILinqService.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +using System; +using System.ServiceModel; + +namespace BLToolkit.ServiceModel.Async +{ + [ServiceContract] + [ServiceKnownType(typeof(LinqServiceQuery))] + [ServiceKnownType(typeof(LinqServiceResult))] + public interface ILinqService + { + [OperationContract(AsyncPattern = true, Action = "http://tempuri.org/ILinqService/GetSqlProviderType", ReplyAction = "http://tempuri.org/ILinqService/GetSqlProviderTypeResponse")] + IAsyncResult BeginGetSqlProviderType(AsyncCallback callback, object asyncState); + + string EndGetSqlProviderType(IAsyncResult result); + + [OperationContract(AsyncPattern = true, Action = "http://tempuri.org/ILinqService/ExecuteNonQuery", ReplyAction = "http://tempuri.org/ILinqService/ExecuteNonQueryResponse")] + IAsyncResult BeginExecuteNonQuery(string queryData, AsyncCallback callback, object asyncState); + + int EndExecuteNonQuery(IAsyncResult result); + + [OperationContract(AsyncPattern = true, Action = "http://tempuri.org/ILinqService/ExecuteScalar", ReplyAction = "http://tempuri.org/ILinqService/ExecuteScalarResponse")] + IAsyncResult BeginExecuteScalar(string queryData, AsyncCallback callback, object asyncState); + + object EndExecuteScalar(IAsyncResult result); + + [OperationContract(AsyncPattern = true, Action = "http://tempuri.org/ILinqService/ExecuteReader", ReplyAction = "http://tempuri.org/ILinqService/ExecuteReaderResponse")] + IAsyncResult BeginExecuteReader(string queryData, AsyncCallback callback, object asyncState); + + string EndExecuteReader(IAsyncResult result); + + [OperationContract(AsyncPattern = true, Action = "http://tempuri.org/ILinqService/ExecuteBatch", ReplyAction = "http://tempuri.org/ILinqService/ExecuteBatchResponse")] + IAsyncResult BeginExecuteBatch(string queryData, AsyncCallback callback, object asyncState); + + int EndExecuteBatch(IAsyncResult result); + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/Async/ILinqSoapService.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/Async/ILinqSoapService.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,36 @@ +using System; +using System.ServiceModel; + +namespace BLToolkit.ServiceModel.Async +{ + [ServiceContract] + [ServiceKnownType(typeof(LinqServiceQuery))] + [ServiceKnownType(typeof(LinqServiceResult))] + public interface ILinqSoapService + { + [OperationContract(AsyncPattern = true, Action = "http://tempuri.org/GetSqlProviderType", ReplyAction = "http://tempuri.org/GetSqlProviderTypeResponse")] + IAsyncResult BeginGetSqlProviderType(AsyncCallback callback, object asyncState); + + string EndGetSqlProviderType(IAsyncResult result); + + [OperationContract(AsyncPattern = true, Action = "http://tempuri.org/ExecuteNonQuery", ReplyAction = "http://tempuri.org/ExecuteNonQueryResponse")] + IAsyncResult BeginExecuteNonQuery(string queryData, AsyncCallback callback, object asyncState); + + int EndExecuteNonQuery(IAsyncResult result); + + [OperationContract(AsyncPattern = true, Action = "http://tempuri.org/ExecuteScalar", ReplyAction = "http://tempuri.org/ExecuteScalarResponse")] + IAsyncResult BeginExecuteScalar(string queryData, AsyncCallback callback, object asyncState); + + object EndExecuteScalar(IAsyncResult result); + + [OperationContract(AsyncPattern = true, Action = "http://tempuri.org/ExecuteReader", ReplyAction = "http://tempuri.org/ExecuteReaderResponse")] + IAsyncResult BeginExecuteReader(string queryData, AsyncCallback callback, object asyncState); + + string EndExecuteReader(IAsyncResult result); + + [OperationContract(AsyncPattern = true, Action = "http://tempuri.org/ExecuteBatch", ReplyAction = "http://tempuri.org/ExecuteBatchResponse")] + IAsyncResult BeginExecuteBatch(string queryData, AsyncCallback callback, object asyncState); + + int EndExecuteBatch(IAsyncResult result); + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/DataService.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/DataService.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,467 @@ +using System; +using System.Collections.Generic; +using System.Data.Services.Providers; +using System.Linq; +using System.Linq.Expressions; + +namespace BLToolkit.ServiceModel +{ + using Data.Linq; + using Data.Sql; + using Mapping; + + public class DataService : System.Data.Services.DataService, IServiceProvider + where T : IDataContext + { + #region Init + + public DataService() + { + if (_defaultMetadata == null) + _defaultMetadata = Tuple.Create(default(T), new MetadataInfo(Map.DefaultSchema)); + + _metadata = new MetadataProvider(_defaultMetadata.Item2); + _query = new QueryProvider (_defaultMetadata.Item2); + _update = new UpdateProvider (_defaultMetadata.Item2, _metadata, _query); + } + + static Tuple _defaultMetadata; + + public DataService(MappingSchema mappingSchema) + { + lock (_cache) + { + Tuple data; + + if (!_cache.TryGetValue(mappingSchema, out data)) + data = Tuple.Create(default(T), new MetadataInfo(mappingSchema)); + + _metadata = new MetadataProvider(data.Item2); + _query = new QueryProvider (data.Item2); + _update = new UpdateProvider (data.Item2, _metadata, _query); + } + } + + readonly static Dictionary> _cache = + new Dictionary>(); + + readonly MetadataProvider _metadata; + readonly QueryProvider _query; + readonly UpdateProvider _update; + + #endregion + + #region Public Members + + public object GetService(Type serviceType) + { + if (serviceType == typeof(IDataServiceMetadataProvider)) return _metadata; + if (serviceType == typeof(IDataServiceQueryProvider)) return _query; + if (serviceType == typeof(IDataServiceUpdateProvider)) return _update; + + return null; + } + + #endregion + + #region MetadataInfo + + class TypeInfo + { + public ResourceType Type; + public SqlTable Table; + public ObjectMapper Mapper; + } + + class MetadataInfo + { + public MetadataInfo(MappingSchema mappingSchema) + { + _mappingSchema = mappingSchema; + LoadMetadata(); + } + + readonly MappingSchema _mappingSchema; + + readonly public Dictionary TypeDic = new Dictionary(); + readonly public Dictionary Types = new Dictionary(); + readonly public Dictionary Sets = new Dictionary(); + readonly public Dictionary> RootGetters = new Dictionary>(); + + void LoadMetadata() + { + var n = 0; + var list = + ( + from p in typeof(T).GetProperties() + let t = p.PropertyType + where t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Table<>) + let tt = t.GetGenericArguments()[0] + let tbl = new SqlTable(_mappingSchema, tt) + where tbl.Fields.Values.Any(f => f.IsPrimaryKey) + let m = _mappingSchema.GetObjectMapper(tt) + select new + { + p.Name, + ID = n++, + Type = tt, + Table = tbl, + Mapper = m + } + ).ToList(); + + var baseTypes = new Dictionary(); + + foreach (var item in list) + foreach (var m in item.Mapper.InheritanceMapping) + if (!baseTypes.ContainsKey(m.Type)) + baseTypes.Add(m.Type, item.Type); + + list.Sort((x,y) => + { + Type baseType; + + if (baseTypes.TryGetValue(x.Type, out baseType)) + if (y.Type == baseType) + return 1; + + if (baseTypes.TryGetValue(y.Type, out baseType)) + if (x.Type == baseType) + return -1; + + return x.ID - y.ID; + }); + + foreach (var item in list) + { + Type baseType; + baseTypes.TryGetValue(item.Type, out baseType); + + var type = GetTypeInfo(item.Type, baseType, item.Table, item.Mapper); + var set = new ResourceSet(item.Name, type.Type); + + set.SetReadOnly(); + + Sets.Add(set.Name, set); + } + + foreach (var item in list) + { + foreach (var m in item.Mapper.InheritanceMapping) + { + if (!TypeDic.ContainsKey(m.Type)) + { + GetTypeInfo( + m.Type, + item.Type, + new SqlTable(_mappingSchema, item.Type), + _mappingSchema.GetObjectMapper(item.Type)); + } + } + } + } + + TypeInfo GetTypeInfo(Type type, Type baseType, SqlTable table, ObjectMapper mapper) + { + TypeInfo typeInfo; + + if (!TypeDic.TryGetValue(type, out typeInfo)) + { + var baseInfo = baseType != null ? TypeDic[baseType] : null; + + typeInfo = new TypeInfo + { + Type = new ResourceType( + type, + ResourceTypeKind.EntityType, + baseInfo != null ? baseInfo.Type : null, + type.Namespace, + type.Name, + type.IsAbstract), + Table = table, + Mapper = mapper, + }; + + foreach (var field in table.Fields.Values) + { + if (baseType != null && baseInfo.Table.Fields.ContainsKey(field.Name)) + continue; + + var kind = ResourcePropertyKind.Primitive; + var ptype = ResourceType.GetPrimitiveResourceType(field.SystemType); + + if (baseType == null && field.IsPrimaryKey) + kind |= ResourcePropertyKind.Key; + + var p = new ResourceProperty(field.Name, kind, ptype); + + typeInfo.Type.AddProperty(p); + } + + typeInfo.Type.SetReadOnly(); + + Types. Add(typeInfo.Type.FullName, typeInfo.Type); + TypeDic.Add(type, typeInfo); + } + + return typeInfo; + } + + public object CreateInstance(Type type) + { + return TypeDic[type].Mapper.CreateInstance(); + } + } + + #endregion + + #region MetadataProvider + + class MetadataProvider : IDataServiceMetadataProvider + { + public MetadataProvider(MetadataInfo data) + { + _data = data; + } + + readonly MetadataInfo _data; + + public bool TryResolveResourceSet(string name, out ResourceSet resourceSet) + { + return _data.Sets.TryGetValue(name, out resourceSet); + } + + public ResourceAssociationSet GetResourceAssociationSet(ResourceSet resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) + { + throw new InvalidOperationException(); + } + + public bool TryResolveResourceType(string name, out ResourceType resourceType) + { + return _data.Types.TryGetValue(name, out resourceType); + } + + public IEnumerable GetDerivedTypes(ResourceType resourceType) + { + return _data.TypeDic[resourceType.InstanceType].Mapper.InheritanceMapping.Select(m => _data.TypeDic[m.Type].Type); + } + + public bool HasDerivedTypes(ResourceType resourceType) + { + return _data.TypeDic[resourceType.InstanceType].Mapper.InheritanceMapping.Count > 0; + } + + public bool TryResolveServiceOperation(string name, out ServiceOperation serviceOperation) + { + serviceOperation = null; + return false; + } + + public string ContainerNamespace { get { return typeof(T).Namespace; } } + public string ContainerName { get { return typeof(T).Name; } } + public IEnumerable ResourceSets { get { return _data.Sets.Values; } } + public IEnumerable Types { get { return _data.Types.Values; } } + public IEnumerable ServiceOperations { get { yield break; } } + } + + #endregion + + #region QueryProvider + + class QueryProvider : IDataServiceQueryProvider + { + public QueryProvider(MetadataInfo data) + { + _data = data; + } + + readonly MetadataInfo _data; + + public IQueryable GetQueryRootForResourceSet(ResourceSet resourceSet) + { + Func func; + + lock (_data.RootGetters) + { + if (!_data.RootGetters.TryGetValue(resourceSet.Name, out func)) + { + var p = Expression.Parameter(typeof(object), "p"); + var l = Expression.Lambda>( + Expression.PropertyOrField( + Expression.Convert(p, typeof(T)), + resourceSet.Name), + p); + + func = l.Compile(); + + _data.RootGetters.Add(resourceSet.Name, func); + } + } + + return func(CurrentDataSource); + } + + public ResourceType GetResourceType(object target) + { + return _data.TypeDic[target.GetType()].Type; + } + + public object GetPropertyValue(object target, ResourceProperty resourceProperty) + { + throw new InvalidOperationException(); + } + + public object GetOpenPropertyValue(object target, string propertyName) + { + throw new InvalidOperationException(); + } + + public IEnumerable> GetOpenPropertyValues(object target) + { + throw new InvalidOperationException(); + } + + public object InvokeServiceOperation(ServiceOperation serviceOperation, object[] parameters) + { + throw new InvalidOperationException(); + } + + public object CurrentDataSource { get; set; } + public bool IsNullPropagationRequired { get { return true; } } + } + + #endregion + + #region UpdateProvider + + abstract class ResourceAction + { + public object Resource; + + public class Create : ResourceAction {} + public class Delete : ResourceAction {} + public class Reset : ResourceAction {} + + public class Update : ResourceAction + { + public string Property; + public object Value; + } + + } + + class UpdateProvider : IDataServiceUpdateProvider + { + #region Init + + public UpdateProvider(MetadataInfo data, MetadataProvider metadata, QueryProvider query) + { + _data = data; + _metadata = metadata; + _query = query; + } + + readonly MetadataInfo _data; + readonly MetadataProvider _metadata; + readonly QueryProvider _query; + readonly List _actions = new List(); + + #endregion + + #region IDataServiceUpdateProvider + + public void SetConcurrencyValues(object resourceCookie, bool? checkForEquality, IEnumerable> concurrencyValues) + { + throw new InvalidOperationException(); + } + + public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded) + { + throw new InvalidOperationException(); + } + + public void ClearChanges() + { + _actions.Clear(); + } + + public object CreateResource(string containerName, string fullTypeName) + { + ResourceType type; + + if (_metadata.TryResolveResourceType(fullTypeName, out type)) + { + var resource = _data.CreateInstance(type.InstanceType); + _actions.Add(new ResourceAction.Create { Resource = resource }); + return resource; + } + + throw new Exception(string.Format("Type '{0}' not found", fullTypeName)); + } + + public void DeleteResource(object targetResource) + { + _actions.Add(new ResourceAction.Delete { Resource = targetResource }); + } + + public object GetResource(IQueryable query, string fullTypeName) + { + object resource = null; + + foreach (var item in query) + { + if (resource != null) + throw new LinqException("Resource not uniquely identified"); + resource = item; + } + + return resource; + } + + public object GetValue(object targetResource, string propertyName) + { + var m = _data.TypeDic[targetResource.GetType()].Mapper; + return m[propertyName, true].GetValue(targetResource); + } + + public void RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved) + { + throw new InvalidOperationException(); + } + + public object ResetResource(object resource) + { + _actions.Add(new ResourceAction.Reset { Resource = resource }); + return resource; + } + + public object ResolveResource(object resource) + { + return resource; + } + + public void SaveChanges() + { + throw new InvalidOperationException(); + } + + public void SetReference(object targetResource, string propertyName, object propertyValue) + { + throw new InvalidOperationException(); + } + + public void SetValue(object targetResource, string propertyName, object propertyValue) + { + var m = _data.TypeDic[targetResource.GetType()].Mapper; + + m[propertyName, true].SetValue(targetResource, propertyValue); + + _actions.Add(new ResourceAction.Update { Resource = targetResource, Property = propertyName, Value = propertyValue }); + } + + #endregion + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/ILinqService.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/ILinqService.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +using System; +using System.ServiceModel; + +namespace BLToolkit.ServiceModel +{ + [ServiceContract] + public interface ILinqService + { + [OperationContract] string GetSqlProviderType(); + [OperationContract] int ExecuteNonQuery(string queryData); + [OperationContract] object ExecuteScalar (string queryData); + [OperationContract] string ExecuteReader (string queryData); + [OperationContract] int ExecuteBatch (string queryData); + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/ILinqSoapService.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/ILinqSoapService.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +using System; +using System.ServiceModel; + +namespace BLToolkit.ServiceModel +{ + [ServiceContract] + public interface ILinqSoapService + { + [OperationContract] string GetSqlProviderType(); + [OperationContract] int ExecuteNonQuery(string queryData); + [OperationContract] object ExecuteScalar (string queryData); + [OperationContract] string ExecuteReader (string queryData); + [OperationContract] int ExecuteBatch (string queryData); + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/LinqService.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/LinqService.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.ServiceModel; +using System.Web.Services; + +namespace BLToolkit.ServiceModel +{ + using Data; + using Data.Linq; + using Data.Sql; + + [ServiceBehavior (InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] + [WebService (Namespace = "http://tempuri.org/")] + [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] + public class LinqService : ILinqService + { + public LinqService() + { + } + + public LinqService(string configuration) + { + Configuration = configuration; + } + + public string Configuration { get; set; } + public bool AllowUpdates { get; set; } + + public static Func TypeResolver = _ => null; + + public virtual IDataContext CreateDataContext() + { + return Settings.CreateDefaultDataContext(Configuration); + } + + protected virtual void ValidateQuery(LinqServiceQuery query) + { + if (AllowUpdates == false && !query.Query.IsSelect) + throw new LinqException("Insert/Update/Delete requests are not allowed by the service policy."); + } + + protected virtual void HandleException(Exception exception) + { + } + + #region ILinqService Members + + public Type SqlProviderType { get; set; } + + [WebMethod] + public virtual string GetSqlProviderType() + { + try + { + if (SqlProviderType == null) + using (var ctx = CreateDataContext()) + SqlProviderType = ctx.CreateSqlProvider().GetType(); + + return SqlProviderType.FullName; + } + catch (Exception exception) + { + HandleException(exception); + throw; + } + } + + class QueryContext : IQueryContext + { + public SqlQuery SqlQuery { get; set; } + public object Context { get; set; } + public SqlParameter[] Parameters { get; set; } + + public SqlParameter[] GetParameters() + { + return Parameters; + } + } + + [WebMethod] + public int ExecuteNonQuery(string queryData) + { + try + { + var query = LinqServiceSerializer.Deserialize(queryData); + + ValidateQuery(query); + + using (var db = CreateDataContext()) + { + var obj = db.SetQuery(new QueryContext { SqlQuery = query.Query, Parameters = query.Parameters }); + return db.ExecuteNonQuery(obj); + } + } + catch (Exception exception) + { + HandleException(exception); + throw; + } + } + + [WebMethod] + public object ExecuteScalar(string queryData) + { + try + { + var query = LinqServiceSerializer.Deserialize(queryData); + + ValidateQuery(query); + + using (var db = CreateDataContext()) + { + var obj = db.SetQuery(new QueryContext { SqlQuery = query.Query, Parameters = query.Parameters }); + return db.ExecuteScalar(obj); + } + } + catch (Exception exception) + { + HandleException(exception); + throw; + } + } + + [WebMethod] + public string ExecuteReader(string queryData) + { + try + { + var query = LinqServiceSerializer.Deserialize(queryData); + + ValidateQuery(query); + + using (var db = CreateDataContext()) + { + var obj = db.SetQuery(new QueryContext { SqlQuery = query.Query, Parameters = query.Parameters }); + + using (var rd = db.ExecuteReader(obj)) + { + var ret = new LinqServiceResult + { + QueryID = Guid.NewGuid(), + FieldCount = rd.FieldCount, + FieldNames = new string[rd.FieldCount], + FieldTypes = new Type [rd.FieldCount], + Data = new List(), + }; + + for (var i = 0; i < ret.FieldCount; i++) + { + ret.FieldNames[i] = rd.GetName(i); + ret.FieldTypes[i] = rd.GetFieldType(i); + } + + var varyingTypes = new List(); + + while (rd.Read()) + { + var data = new string [rd.FieldCount]; + var codes = new TypeCode[rd.FieldCount]; + + for (var i = 0; i < ret.FieldCount; i++) + codes[i] = Type.GetTypeCode(ret.FieldTypes[i]); + + ret.RowCount++; + + for (var i = 0; i < ret.FieldCount; i++) + { + if (!rd.IsDBNull(i)) + { + var code = codes[i]; + var type = rd.GetFieldType(i); + var idx = -1; + + if (type != ret.FieldTypes[i]) + { + code = Type.GetTypeCode(type); + idx = varyingTypes.IndexOf(type); + + if (idx < 0) + { + varyingTypes.Add(type); + idx = varyingTypes.Count - 1; + } + } + + switch (code) + { + case TypeCode.Decimal : data[i] = rd.GetDecimal (i).ToString(CultureInfo.InvariantCulture); break; + case TypeCode.Double : data[i] = rd.GetDouble (i).ToString(CultureInfo.InvariantCulture); break; + case TypeCode.Single : data[i] = rd.GetFloat (i).ToString(CultureInfo.InvariantCulture); break; + case TypeCode.DateTime : data[i] = rd.GetDateTime(i).ToString("o"); break; + default : + { + if (type == typeof(DateTimeOffset)) + { + var dt = rd.GetValue(i); + + if (dt is DateTime) + data[i] = ((DateTime)dt).ToString("o"); + else if (dt is DateTimeOffset) + data[i] = ((DateTimeOffset)dt).ToString("o"); + else + data[i] = rd.GetValue(i).ToString(); + } + else if (ret.FieldTypes[i] == typeof(byte[])) + data[i] = Convert.ToBase64String((byte[])rd.GetValue(i)); + else + data[i] = (rd.GetValue(i) ?? "").ToString(); + + break; + } + } + + if (idx >= 0) + data[i] = "\0" + (char)idx + data[i]; + } + } + + ret.Data.Add(data); + } + + ret.VaryingTypes = varyingTypes.ToArray(); + + return LinqServiceSerializer.Serialize(ret); + } + } + } + catch (Exception exception) + { + HandleException(exception); + throw; + } + } + + [WebMethod] + public int ExecuteBatch(string queryData) + { + try + { + var data = LinqServiceSerializer.DeserializeStringArray(queryData); + var queries = data.Select(LinqServiceSerializer.Deserialize).ToArray(); + + foreach (var query in queries) + ValidateQuery(query); + + using (var db = CreateDataContext()) + { + if (db is DbManager) ((DbManager)db).BeginTransaction(); + + foreach (var query in queries) + { + var obj = db.SetQuery(new QueryContext { SqlQuery = query.Query, Parameters = query.Parameters }); + db.ExecuteNonQuery(obj); + } + + if (db is DbManager) ((DbManager)db).CommitTransaction(); + + return queryData.Length; + } + } + catch (Exception exception) + { + HandleException(exception); + throw; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/LinqServiceClient.Silverlight.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/LinqServiceClient.Silverlight.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,150 @@ +using System; +using System.ServiceModel; + +namespace BLToolkit.ServiceModel +{ + class LinqServiceClient : ClientBase, ILinqService, IDisposable + { + #region Init + + public LinqServiceClient(string endpointConfigurationName) : base(endpointConfigurationName) { } + public LinqServiceClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } + public LinqServiceClient(string endpointConfigurationName, EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } + public LinqServiceClient(System.ServiceModel.Channels.Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) { } + + #endregion + + #region ILinqService Members + + public string GetSqlProviderType() + { + var async = Channel.BeginGetSqlProviderType(null, null); + return Channel.EndGetSqlProviderType(async); + } + + public int ExecuteNonQuery(string queryData) + { + var async = Channel.BeginExecuteNonQuery(queryData, null, null); + return Channel.EndExecuteNonQuery(async); + } + + public object ExecuteScalar(string queryData) + { + var async = Channel.BeginExecuteScalar(queryData, null, null); + return Channel.EndExecuteScalar(async); + } + + public string ExecuteReader(string queryData) + { + var async = Channel.BeginExecuteReader(queryData, null, null); + return Channel.EndExecuteReader(async); + } + + public int ExecuteBatch(string queryData) + { + var async = Channel.BeginExecuteBatch(queryData, null, null); + return Channel.EndExecuteBatch(async); + } + + #endregion + + #region IDisposable Members + + void IDisposable.Dispose() + { + try + { + if (State != CommunicationState.Faulted) + ((ICommunicationObject)this).Close(); + else + Abort(); + } + catch (CommunicationException) + { + Abort(); + } + catch (TimeoutException) + { + Abort(); + } + catch (Exception) + { + Abort(); + throw; + } + } + + #endregion + + #region Overrides + + protected override Async.ILinqService CreateChannel() + { + return new LinqServiceClientChannel(this); + } + + #endregion + + #region Channel + + class LinqServiceClientChannel : ChannelBase, Async.ILinqService + { + public LinqServiceClientChannel(ClientBase client) : + base(client) + { + } + + public IAsyncResult BeginGetSqlProviderType(AsyncCallback callback, object asyncState) + { + return BeginInvoke("GetSqlProviderType", new object[0], callback, asyncState); + } + + public string EndGetSqlProviderType(IAsyncResult result) + { + return (string)EndInvoke("GetSqlProviderType", new object[0], result); + } + + public IAsyncResult BeginExecuteNonQuery(string queryData, AsyncCallback callback, object asyncState) + { + return BeginInvoke("ExecuteNonQuery", new object[] { queryData }, callback, asyncState); + } + + public int EndExecuteNonQuery(IAsyncResult result) + { + return (int)EndInvoke("ExecuteNonQuery", new object[0], result); + } + + public IAsyncResult BeginExecuteScalar(string queryData, AsyncCallback callback, object asyncState) + { + return BeginInvoke("ExecuteScalar", new object[] { queryData }, callback, asyncState); + } + + public object EndExecuteScalar(IAsyncResult result) + { + return EndInvoke("ExecuteScalar", new object[0], result); + } + + public IAsyncResult BeginExecuteReader(string queryData, AsyncCallback callback, object asyncState) + { + return BeginInvoke("ExecuteReader", new object[] { queryData }, callback, asyncState); + } + + public string EndExecuteReader(IAsyncResult result) + { + return (string)EndInvoke("ExecuteReader", new object[0], result); + } + + public IAsyncResult BeginExecuteBatch(string queryData, AsyncCallback callback, object asyncState) + { + return BeginInvoke("ExecuteBatch", new object[] { queryData }, callback, asyncState); + } + + public int EndExecuteBatch(IAsyncResult result) + { + return (int)EndInvoke("ExecuteBatch", new object[0], result); + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/LinqServiceClient.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/LinqServiceClient.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,81 @@ +using System; +using System.ServiceModel; +using System.ServiceModel.Channels; + +namespace BLToolkit.ServiceModel +{ + class LinqServiceClient : ClientBase, ILinqService, IDisposable + { + #region Init + + //public LinqServiceClient() {} + public LinqServiceClient(string endpointConfigurationName) : base(endpointConfigurationName) { } + public LinqServiceClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } + public LinqServiceClient(string endpointConfigurationName, EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } + public LinqServiceClient(Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) { } + //public LinqServiceClient(InstanceContext callbackInstance) : base(callbackInstance) { } + //public LinqServiceClient(InstanceContext callbackInstance, string endpointConfigurationName) : base(callbackInstance, endpointConfigurationName) { } + //public LinqServiceClient(InstanceContext callbackInstance, string endpointConfigurationName, string remoteAddress) : base(callbackInstance, endpointConfigurationName, remoteAddress) { } + //public LinqServiceClient(InstanceContext callbackInstance, string endpointConfigurationName, EndpointAddress remoteAddress) : base(callbackInstance, endpointConfigurationName, remoteAddress) { } + //public LinqServiceClient(InstanceContext callbackInstance, Binding binding, EndpointAddress remoteAddress) : base(callbackInstance, binding, remoteAddress) { } + + #endregion + + #region ILinqService Members + + public string GetSqlProviderType() + { + return Channel.GetSqlProviderType(); + } + + public int ExecuteNonQuery(string queryData) + { + return Channel.ExecuteNonQuery(queryData); + } + + public object ExecuteScalar(string queryData) + { + return Channel.ExecuteScalar(queryData); + } + + public string ExecuteReader(string queryData) + { + return Channel.ExecuteReader(queryData); + } + + public int ExecuteBatch(string queryData) + { + return Channel.ExecuteBatch(queryData); + } + + #endregion + + #region IDisposable Members + + void IDisposable.Dispose() + { + try + { + if (State != CommunicationState.Faulted) + ((ICommunicationObject)this).Close(); + else + Abort(); + } + catch (CommunicationException) + { + Abort(); + } + catch (TimeoutException) + { + Abort(); + } + catch (Exception) + { + Abort(); + throw; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/LinqServiceQuery.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/LinqServiceQuery.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using System; + +namespace BLToolkit.ServiceModel +{ + using Data.Sql; + + public class LinqServiceQuery + { + public SqlQuery Query { get; set; } + public SqlParameter[] Parameters { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/LinqServiceResult.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/LinqServiceResult.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; + +namespace BLToolkit.ServiceModel +{ + public class LinqServiceResult + { + public int FieldCount { get; set; } + public int RowCount { get; set; } + public Guid QueryID { get; set; } + public string[] FieldNames { get; set; } + public Type[] FieldTypes { get; set; } + public Type[] VaryingTypes { get; set; } + public List Data { get; set; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/LinqServiceSerializer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/LinqServiceSerializer.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1699 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace BLToolkit.ServiceModel +{ + using Data.Sql; + using Data.Sql.SqlProvider; + using Mapping; + using Reflection; + + static class LinqServiceSerializer + { + #region Public Members + + public static string Serialize(SqlQuery query, SqlParameter[] parameters) + { + return new QuerySerializer().Serialize(query, parameters); + } + + public static LinqServiceQuery Deserialize(string str) + { + return new QueryDeserializer().Deserialize(str); + } + + public static string Serialize(LinqServiceResult result) + { + return new ResultSerializer().Serialize(result); + } + + public static LinqServiceResult DeserializeResult(string str) + { + return new ResultDeserializer().DeserializeResult(str); + } + + public static string Serialize(string[] data) + { + return new StringArraySerializer().Serialize(data); + } + + public static string[] DeserializeStringArray(string str) + { + return new StringArrayDeserializer().Deserialize(str); + } + + #endregion + + #region SerializerBase + + const int _paramIndex = -1; + const int _typeIndex = -2; + const int _typeArrayIndex = -3; + + class SerializerBase + { + protected readonly StringBuilder Builder = new StringBuilder(); + protected readonly Dictionary Dic = new Dictionary(); + protected int Index; + + string ConvertToString(Type type, object value) + { + switch (Type.GetTypeCode(type)) + { + case TypeCode.Decimal : return ((decimal) value).ToString(CultureInfo.InvariantCulture); + case TypeCode.Double : return ((double) value).ToString(CultureInfo.InvariantCulture); + case TypeCode.Single : return ((float) value).ToString(CultureInfo.InvariantCulture); + case TypeCode.DateTime : return ((DateTime)value).ToString("o"); + } + + if (type == typeof(DateTimeOffset)) + return ((DateTimeOffset)value).ToString("o"); + + return Common.Convert.ToString(value); + } + + protected void Append(Type type, object value) + { + Append(type); + + if (value == null) + Append((string)null); + else if (!type.IsArray) + { + Append(ConvertToString(type, value)); + } + else + { + var elementType = type.GetElementType(); + + Builder.Append(' '); + + var len = Builder.Length; + var cnt = 0; + + if (elementType.IsArray) + foreach (var val in (IEnumerable)value) + { + Append(elementType, val); + cnt++; + } + else + foreach (var val in (IEnumerable)value) + { + if (val == null) + Append((string)null); + else + Append(ConvertToString(val.GetType(), val)); + cnt++; + } + + Builder.Insert(len, cnt.ToString(CultureInfo.CurrentCulture)); + } + } + + protected void Append(int value) + { + Builder.Append(' ').Append(value); + } + + protected void Append(Type value) + { + Builder.Append(' ').Append(value == null ? 0 : GetType(value)); + } + + protected void Append(bool value) + { + Builder.Append(' ').Append(value ? '1' : '0'); + } + + protected void Append(IQueryElement element) + { + Builder.Append(' ').Append(element == null ? 0 : Dic[element]); + } + + protected void Append(string str) + { + Builder.Append(' '); + + if (str == null) + { + Builder.Append('-'); + } + else if (str.Length == 0) + { + Builder.Append('0'); + } + else + { + Builder + .Append(str.Length) + .Append(':') + .Append(str); + } + } + + protected int GetType(Type type) + { + if (type == null) + return 0; + + int idx; + + if (!Dic.TryGetValue(type, out idx)) + { + if (type.IsArray) + { + var elementType = GetType(type.GetElementType()); + + Dic.Add(type, idx = ++Index); + + Builder + .Append(idx) + .Append(' ') + .Append(_typeArrayIndex) + .Append(' ') + .Append(elementType); + } + else + { + Dic.Add(type, idx = ++Index); + + Builder + .Append(idx) + .Append(' ') + .Append(_typeIndex); + + Append(type.FullName); + } + + Builder.AppendLine(); + } + + return idx; + } + } + + #endregion + + #region DeserializerBase + + public class DeserializerBase + { + protected readonly Dictionary Dic = new Dictionary(); + + protected string Str; + protected int Pos; + + protected char Peek() + { + return Str[Pos]; + } + + char Next() + { + return Str[++Pos]; + } + + protected bool Get(char c) + { + if (Peek() == c) + { + Pos++; + return true; + } + + return false; + } + + protected int ReadInt() + { + Get(' '); + + var minus = Get('-'); + var value = 0; + + for (var c = Peek(); char.IsDigit(c); c = Next()) + value = value * 10 + (c - '0'); + + return minus ? -value : value; + } + + protected int? ReadCount() + { + Get(' '); + + if (Get('-')) + return null; + + var value = 0; + + for (var c = Peek(); char.IsDigit(c); c = Next()) + value = value * 10 + (c - '0'); + + return value; + } + + protected string ReadString() + { + Get(' '); + + var c = Peek(); + + if (c == '-') + { + Pos++; + return null; + } + + if (c == '0') + { + Pos++; + return string.Empty; + } + + var len = ReadInt(); + var value = Str.Substring(++Pos, len); + + Pos += len; + + return value; + } + + protected bool ReadBool() + { + Get(' '); + + var value = Peek() == '1'; + + Pos++; + + return value; + } + + protected T Read() + where T : class + { + var idx = ReadInt(); + return idx == 0 ? null : (T)Dic[idx]; + } + + protected T[] ReadArray() + where T : class + { + var count = ReadCount(); + + if (count == null) + return null; + + var items = new T[count.Value]; + + for (var i = 0; i < count; i++) + items[i] = Read(); + + return items; + } + + protected List ReadList() + where T : class + { + var count = ReadCount(); + + if (count == null) + return null; + + var items = new List(count.Value); + + for (var i = 0; i < count; i++) + items.Add(Read()); + + return items; + } + + protected void NextLine() + { + while (Pos < Str.Length && (Peek() == '\n' || Peek() == '\r')) + Pos++; + } + + interface IDeserializerHelper + { + object GetArray(DeserializerBase deserializer); + } + + class DeserializerHelper : IDeserializerHelper + { + public object GetArray(DeserializerBase deserializer) + { + var count = deserializer.ReadCount(); + + if (count == null) + return null; + + var arr = new T[count.Value]; + var type = typeof(T); + + for (var i = 0; i < count.Value; i++) + arr[i] = (T)deserializer.ReadValue(type); + + return arr; + } + } + + static readonly Dictionary> _arrayDeserializers = + new Dictionary>(); + + protected object ReadValue(Type type) + { + if (type == null) + return ReadString(); + + if (type.IsArray) + { + var elem = type.GetElementType(); + + Func deserializer; + + lock (_arrayDeserializers) + { + if (!_arrayDeserializers.TryGetValue(elem, out deserializer)) + { + var helper = (IDeserializerHelper)Activator.CreateInstance(typeof(DeserializerHelper<>).MakeGenericType(elem)); + _arrayDeserializers.Add(elem, deserializer = helper.GetArray); + } + } + + return deserializer(this); + } + + var str = ReadString(); + + switch (Type.GetTypeCode(type)) + { + case TypeCode.Decimal : return decimal. Parse(str, CultureInfo.InvariantCulture); + case TypeCode.Double : return double. Parse(str, CultureInfo.InvariantCulture); + case TypeCode.Single : return float. Parse(str, CultureInfo.InvariantCulture); + case TypeCode.DateTime : return DateTime.ParseExact(str, "o", CultureInfo.InvariantCulture); + } + + if (type == typeof(DateTimeOffset)) + return DateTimeOffset.ParseExact(str, "o", CultureInfo.InvariantCulture); + + return Common.Convert.ChangeTypeFromString(str, type); + } + + protected readonly List UnresolvedTypes = new List(); + + protected Type ResolveType(string str) + { + if (str == null) + return null; + + var type = Type.GetType(str, false); + + if (type == null) + { + if (str == "System.Data.Linq.Binary") + return typeof(System.Data.Linq.Binary); + +#if !SILVERLIGHT + + type = LinqService.TypeResolver(str); + +#endif + + if (type == null) + { + UnresolvedTypes.Add(str); + + Debug.WriteLine( + string.Format("Type '{0}' cannot be resolved. Use LinqService.TypeResolver to resolve unknown types.", str), + "LinqServiceSerializer"); + } + } + + return type; + } + } + + #endregion + + #region QuerySerializer + + class QuerySerializer : SerializerBase + { + public string Serialize(SqlQuery query, SqlParameter[] parameters) + { + var visitor = new QueryVisitor(); + + visitor.Visit(query, Visit); + + foreach (var parameter in parameters) + if (!Dic.ContainsKey(parameter)) + Visit(parameter); + + Builder + .Append(++Index) + .Append(' ') + .Append(_paramIndex); + + Append(parameters.Length); + + foreach (var parameter in parameters) + Append(parameter); + + Builder.AppendLine(); + + return Builder.ToString(); + } + + void Visit(IQueryElement e) + { + switch (e.ElementType) + { + case QueryElementType.SqlField : + { + var fld = (SqlField)e; + + if (fld != fld.Table.All) + { + GetType(fld.SystemType); + + if (fld.MemberMapper != null) + GetType(fld.MemberMapper.MemberAccessor.TypeAccessor.OriginalType); + } + + break; + } + + case QueryElementType.SqlParameter : + { + var p = (SqlParameter)e; + var t = p.Value == null ? p.SystemType : p.Value.GetType(); + + if (p.Value == null || t.IsArray || t == typeof(string) || !(p.Value is IEnumerable)) + { + GetType(t); + } + else + { + var elemType = TypeHelper.GetElementType(t); + GetType(GetArrayType(elemType)); + } + + //if (p.EnumTypes != null) + // foreach (var type in p.EnumTypes) + // GetType(type); + + break; + } + + case QueryElementType.SqlFunction : GetType(((SqlFunction) e).SystemType); break; + case QueryElementType.SqlExpression : GetType(((SqlExpression) e).SystemType); break; + case QueryElementType.SqlBinaryExpression : GetType(((SqlBinaryExpression)e).SystemType); break; + case QueryElementType.SqlDataType : GetType(((SqlDataType) e).Type); break; + case QueryElementType.SqlValue : GetType(((SqlValue) e).SystemType); break; + case QueryElementType.SqlTable : GetType(((SqlTable) e).ObjectType); break; + } + + Dic.Add(e, ++Index); + + Builder + .Append(Index) + .Append(' ') + .Append((int)e.ElementType); + + switch (e.ElementType) + { + case QueryElementType.SqlField : + { + var elem = (SqlField)e; + + Append(elem.SystemType); + Append(elem.Name); + Append(elem.PhysicalName); + Append(elem.Nullable); + Append(elem.PrimaryKeyOrder); + Append(elem.IsIdentity); + Append(elem.IsUpdatable); + Append(elem.IsInsertable); + Append(elem.MemberMapper == null ? null : elem.MemberMapper.MemberAccessor.TypeAccessor.OriginalType); + Append(elem.MemberMapper == null ? null : elem.MemberMapper.Name); + + break; + } + + case QueryElementType.SqlFunction : + { + var elem = (SqlFunction)e; + + Append(elem.SystemType); + Append(elem.Name); + Append(elem.Precedence); + Append(elem.Parameters); + + break; + } + + case QueryElementType.SqlParameter : + { + var elem = (SqlParameter)e; + + Append(elem.Name); + Append(elem.IsQueryParameter); + Append((int)elem.DbType); + Append(elem.DbSize); + + var type = elem.Value == null ? elem.SystemType : elem.Value.GetType(); + + if (elem.Value == null || type.IsArray || type == typeof(string) || !(elem.Value is IEnumerable)) + { + Append(type, elem.Value); + } + else + { + var elemType = TypeHelper.GetElementType(type); + var value = ConvertIEnumerableToArray(elem.Value, elemType); + + Append(GetArrayType(elemType), value); + } + + break; + } + + case QueryElementType.SqlExpression : + { + var elem = (SqlExpression)e; + + Append(elem.SystemType); + Append(elem.Expr); + Append(elem.Precedence); + Append(elem.Parameters); + + break; + } + + case QueryElementType.SqlBinaryExpression : + { + var elem = (SqlBinaryExpression)e; + + Append(elem.SystemType); + Append(elem.Expr1); + Append(elem.Operation); + Append(elem.Expr2); + Append(elem.Precedence); + + break; + } + + case QueryElementType.SqlValue : + { + var elem = (SqlValue)e; + Append(elem.SystemType, elem.Value); + break; + } + + case QueryElementType.SqlDataType : + { + var elem = (SqlDataType)e; + + Append((int)elem.SqlDbType); + Append(elem.Type); + Append(elem.Length); + Append(elem.Precision); + Append(elem.Scale); + + break; + } + + case QueryElementType.SqlTable : + { + var elem = (SqlTable)e; + + Append(elem.SourceID); + Append(elem.Name); + Append(elem.Alias); + Append(elem.Database); + Append(elem.Owner); + Append(elem.PhysicalName); + Append(elem.ObjectType); + + if (elem.SequenceAttributes == null) + Builder.Append(" -"); + else + { + Append(elem.SequenceAttributes.Length); + + foreach (var a in elem.SequenceAttributes) + { + Append(a.ProviderName); + Append(a.SequenceName); + } + } + + Append(Dic[elem.All]); + Append(elem.Fields.Count); + + foreach (var field in elem.Fields) + Append(Dic[field.Value]); + + Append((int)elem.SqlTableType); + + if (elem.SqlTableType != SqlTableType.Table) + { + if (elem.TableArguments == null) + Append(0); + else + { + Append(elem.TableArguments.Length); + + foreach (var expr in elem.TableArguments) + Append(Dic[expr]); + } + } + + break; + } + + case QueryElementType.ExprPredicate : + { + var elem = (SqlQuery.Predicate.Expr)e; + + Append(elem.Expr1); + Append(elem.Precedence); + + break; + } + + case QueryElementType.NotExprPredicate : + { + var elem = (SqlQuery.Predicate.NotExpr)e; + + Append(elem.Expr1); + Append(elem.IsNot); + Append(elem.Precedence); + + break; + } + + case QueryElementType.ExprExprPredicate : + { + var elem = (SqlQuery.Predicate.ExprExpr)e; + + Append(elem.Expr1); + Append((int)elem.Operator); + Append(elem.Expr2); + + break; + } + + case QueryElementType.LikePredicate : + { + var elem = (SqlQuery.Predicate.Like)e; + + Append(elem.Expr1); + Append(elem.IsNot); + Append(elem.Expr2); + Append(elem.Escape); + + break; + } + + case QueryElementType.BetweenPredicate : + { + var elem = (SqlQuery.Predicate.Between)e; + + Append(elem.Expr1); + Append(elem.IsNot); + Append(elem.Expr2); + Append(elem.Expr3); + + break; + } + + case QueryElementType.IsNullPredicate : + { + var elem = (SqlQuery.Predicate.IsNull)e; + + Append(elem.Expr1); + Append(elem.IsNot); + + break; + } + + case QueryElementType.InSubQueryPredicate : + { + var elem = (SqlQuery.Predicate.InSubQuery)e; + + Append(elem.Expr1); + Append(elem.IsNot); + Append(elem.SubQuery); + + break; + } + + case QueryElementType.InListPredicate : + { + var elem = (SqlQuery.Predicate.InList)e; + + Append(elem.Expr1); + Append(elem.IsNot); + Append(elem.Values); + + break; + } + + case QueryElementType.FuncLikePredicate : + { + var elem = (SqlQuery.Predicate.FuncLike)e; + Append(elem.Function); + break; + } + + case QueryElementType.SqlQuery : + { + var elem = (SqlQuery)e; + + Append(elem.SourceID); + Append((int)elem.QueryType); + Append(elem.From); + + var appendInsert = false; + var appendUpdate = false; + var appendDelete = false; + var appendSelect = false; + + switch (elem.QueryType) + { + case QueryType.InsertOrUpdate : + appendUpdate = true; + appendInsert = true; + break; + + case QueryType.Update : + appendUpdate = true; + break; + + case QueryType.Delete : + appendDelete = true; + appendSelect = true; + break; + + case QueryType.Insert : + appendInsert = true; + if (elem.From.Tables.Count != 0) + appendSelect = true; + break; + + default : + appendSelect = true; + break; + } + + Append(appendInsert); if (appendInsert) Append(elem.Insert); + Append(appendUpdate); if (appendUpdate) Append(elem.Update); + Append(appendDelete); if (appendDelete) Append(elem.Delete); + Append(appendSelect); if (appendSelect) Append(elem.Select); + + Append(elem.Where); + Append(elem.GroupBy); + Append(elem.Having); + Append(elem.OrderBy); + Append(elem.ParentSql == null ? 0 : elem.ParentSql.SourceID); + Append(elem.IsParameterDependent); + + if (!elem.HasUnion) + Builder.Append(" -"); + else + Append(elem.Unions); + + Append(elem.Parameters); + + if (Dic.ContainsKey(elem.All)) + Append(Dic[elem.All]); + else + Builder.Append(" -"); + + break; + } + + case QueryElementType.Column : + { + var elem = (SqlQuery.Column) e; + + Append(elem.Parent.SourceID); + Append(elem.Expression); + Append(elem._alias); + + break; + } + + case QueryElementType.SearchCondition : + Append(((SqlQuery.SearchCondition)e).Conditions); + break; + + case QueryElementType.Condition : + { + var elem = (SqlQuery.Condition)e; + + Append(elem.IsNot); + Append(elem.Predicate); + Append(elem.IsOr); + + break; + } + + case QueryElementType.TableSource : + { + var elem = (SqlQuery.TableSource)e; + + Append(elem.Source); + Append(elem._alias); + Append(elem.Joins); + + break; + } + + case QueryElementType.JoinedTable : + { + var elem = (SqlQuery.JoinedTable)e; + + Append((int)elem.JoinType); + Append(elem.Table); + Append(elem.IsWeak); + Append(elem.Condition); + + break; + } + + case QueryElementType.SelectClause : + { + var elem = (SqlQuery.SelectClause)e; + + Append(elem.IsDistinct); + Append(elem.SkipValue); + Append(elem.TakeValue); + Append(elem.Columns); + + break; + } + + case QueryElementType.InsertClause : + { + var elem = (SqlQuery.InsertClause)e; + + Append(elem.Items); + Append(elem.Into); + Append(elem.WithIdentity); + + break; + } + + case QueryElementType.UpdateClause : + { + var elem = (SqlQuery.UpdateClause)e; + + Append(elem.Items); + Append(elem.Keys); + Append(elem.Table); + + break; + } + + case QueryElementType.DeleteClause : + { + var elem = (SqlQuery.DeleteClause)e; + Append(elem.Table); + break; + } + + case QueryElementType.SetExpression : + { + var elem = (SqlQuery.SetExpression)e; + + Append(elem.Column); + Append(elem.Expression); + + break; + } + + case QueryElementType.FromClause : Append(((SqlQuery.FromClause) e).Tables); break; + case QueryElementType.WhereClause : Append(((SqlQuery.WhereClause) e).SearchCondition); break; + case QueryElementType.GroupByClause : Append(((SqlQuery.GroupByClause)e).Items); break; + case QueryElementType.OrderByClause : Append(((SqlQuery.OrderByClause)e).Items); break; + + case QueryElementType.OrderByItem : + { + var elem = (SqlQuery.OrderByItem)e; + + Append(elem.Expression); + Append(elem.IsDescending); + + break; + } + + case QueryElementType.Union : + { + var elem = (SqlQuery.Union)e; + + Append(elem.SqlQuery); + Append(elem.IsAll); + + break; + } + } + + Builder.AppendLine(); + } + + void Append(ICollection exprs) + where T : IQueryElement + { + if (exprs == null) + Builder.Append(" -"); + else + { + Append(exprs.Count); + + foreach (var e in exprs) + Append(Dic[e]); + } + } + } + + #endregion + + #region QueryDeserializer + + public class QueryDeserializer : DeserializerBase + { + SqlQuery _query; + SqlParameter[] _parameters; + + readonly Dictionary _queries = new Dictionary(); + readonly List _actions = new List(); + + public LinqServiceQuery Deserialize(string str) + { + Str = str; + + while (Parse()) {} + + foreach (var action in _actions) + action(); + + return new LinqServiceQuery { Query = _query, Parameters = _parameters }; + } + + bool Parse() + { + NextLine(); + + if (Pos >= Str.Length) + return false; + + var obj = null as object; + var idx = ReadInt(); Pos++; + var type = ReadInt(); Pos++; + + switch ((QueryElementType)type) + { + case (QueryElementType)_paramIndex : obj = _parameters = ReadArray(); break; + case (QueryElementType)_typeIndex : obj = ResolveType(ReadString()); break; + case (QueryElementType)_typeArrayIndex : obj = GetArrayType(Read()); break; + + case QueryElementType.SqlField : + { + var systemType = Read(); + var name = ReadString(); + var physicalName = ReadString(); + var nullable = ReadBool(); + var primaryKeyOrder = ReadInt(); + var isIdentity = ReadBool(); + var isUpdatable = ReadBool(); + var isInsertable = ReadBool(); + var memberMapperType = Read(); + var memberMapperName = ReadString(); + var memberMapper = memberMapperType == null ? null : Map.GetObjectMapper(memberMapperType)[memberMapperName]; + + obj = new SqlField( + systemType, + name, + physicalName, + nullable, + primaryKeyOrder, + isIdentity + ? new DataAccess.IdentityAttribute() + : isInsertable || isUpdatable + ? new DataAccess.NonUpdatableAttribute(isInsertable, isUpdatable, false) + : null, + memberMapper); + + break; + } + + case QueryElementType.SqlFunction : + { + var systemType = Read(); + var name = ReadString(); + var precedence = ReadInt(); + var parameters = ReadArray(); + + obj = new SqlFunction(systemType, name, precedence, parameters); + + break; + } + + case QueryElementType.SqlParameter : + { + var name = ReadString(); + var isQueryParameter = ReadBool(); + var dbType = (DbType)ReadInt(); + var dbSize = ReadInt(); + var systemType = Read(); + var value = ReadValue(systemType); + //var enumTypes = ReadList(); + //var takeValues = null as List; + + /* + var count = ReadCount(); + + if (count != null) + { + takeValues = new List(count.Value); + + for (var i = 0; i < count; i++) + takeValues.Add(ReadInt()); + } + + var likeStart = ReadString(); + var likeEnd = ReadString(); + */ + + obj = new SqlParameter(systemType, name, value, (MappingSchema)null) + { + IsQueryParameter = isQueryParameter, + DbType = dbType, + DbSize = dbSize, + //EnumTypes = enumTypes, + //TakeValues = takeValues, + //LikeStart = likeStart, + //LikeEnd = likeEnd, + }; + + /* + if (enumTypes != null && UnresolvedTypes.Count > 0) + foreach (var et in enumTypes) + if (et == null) + throw new LinqException( + "Query cannot be deserialized. The possible reason is that the deserializer could not resolve the following types: {0}. Use LinqService.TypeResolver to resolve types.", + string.Join(", ", UnresolvedTypes.Select(_ => "'" + _ + "'").ToArray())); + */ + + break; + } + + case QueryElementType.SqlExpression : + { + var systemType = Read(); + var expr = ReadString(); + var precedence = ReadInt(); + var parameters = ReadArray(); + + obj = new SqlExpression(systemType, expr, precedence, parameters); + + break; + } + + case QueryElementType.SqlBinaryExpression : + { + var systemType = Read(); + var expr1 = Read(); + var operation = ReadString(); + var expr2 = Read(); + var precedence = ReadInt(); + + obj = new SqlBinaryExpression(systemType, expr1, operation, expr2, precedence); + + break; + } + + case QueryElementType.SqlValue : + { + var systemType = Read(); + var value = ReadValue(systemType); + + obj = new SqlValue(systemType, value); + + break; + } + + case QueryElementType.SqlDataType : + { + var dbType = (SqlDbType)ReadInt(); + var systemType = Read(); + var length = ReadInt(); + var precision = ReadInt(); + var scale = ReadInt(); + + obj = new SqlDataType(dbType, systemType, length, precision, scale); + + break; + } + + case QueryElementType.SqlTable : + { + var sourceID = ReadInt(); + var name = ReadString(); + var alias = ReadString(); + var database = ReadString(); + var owner = ReadString(); + var physicalName = ReadString(); + var objectType = Read(); + var sequenceAttributes = null as SequenceNameAttribute[]; + + var count = ReadCount(); + + if (count != null) + { + sequenceAttributes = new SequenceNameAttribute[count.Value]; + + for (var i = 0; i < count.Value; i++) + sequenceAttributes[i] = new SequenceNameAttribute(ReadString(), ReadString()); + } + + var all = Read(); + var fields = ReadArray(); + var flds = new SqlField[fields.Length + 1]; + + flds[0] = all; + Array.Copy(fields, 0, flds, 1, fields.Length); + + var sqlTableType = (SqlTableType)ReadInt(); + var tableArgs = sqlTableType == SqlTableType.Table ? null : ReadArray(); + + obj = new SqlTable( + sourceID, name, alias, database, owner, physicalName, objectType, sequenceAttributes, flds, + sqlTableType, tableArgs); + + break; + } + + case QueryElementType.ExprPredicate : + { + var expr1 = Read(); + var precedence = ReadInt(); + + obj = new SqlQuery.Predicate.Expr(expr1, precedence); + + break; + } + + case QueryElementType.NotExprPredicate : + { + var expr1 = Read(); + var isNot = ReadBool(); + var precedence = ReadInt(); + + obj = new SqlQuery.Predicate.NotExpr(expr1, isNot, precedence); + + break; + } + + case QueryElementType.ExprExprPredicate : + { + var expr1 = Read(); + var @operator = (SqlQuery.Predicate.Operator)ReadInt(); + var expr2 = Read(); + + obj = new SqlQuery.Predicate.ExprExpr(expr1, @operator, expr2); + + break; + } + + case QueryElementType.LikePredicate : + { + var expr1 = Read(); + var isNot = ReadBool(); + var expr2 = Read(); + var escape = Read(); + + obj = new SqlQuery.Predicate.Like(expr1, isNot, expr2, escape); + + break; + } + + case QueryElementType.BetweenPredicate : + { + var expr1 = Read(); + var isNot = ReadBool(); + var expr2 = Read(); + var expr3 = Read(); + + obj = new SqlQuery.Predicate.Between(expr1, isNot, expr2, expr3); + + break; + } + + case QueryElementType.IsNullPredicate : + { + var expr1 = Read(); + var isNot = ReadBool(); + + obj = new SqlQuery.Predicate.IsNull(expr1, isNot); + + break; + } + + case QueryElementType.InSubQueryPredicate : + { + var expr1 = Read(); + var isNot = ReadBool(); + var subQuery = Read(); + + obj = new SqlQuery.Predicate.InSubQuery(expr1, isNot, subQuery); + + break; + } + + case QueryElementType.InListPredicate : + { + var expr1 = Read(); + var isNot = ReadBool(); + var values = ReadList(); + + obj = new SqlQuery.Predicate.InList(expr1, isNot, values); + + break; + } + + case QueryElementType.FuncLikePredicate : + { + var func = Read(); + obj = new SqlQuery.Predicate.FuncLike(func); + break; + } + + case QueryElementType.SqlQuery : + { + var sid = ReadInt(); + var queryType = (QueryType)ReadInt(); + var from = Read(); + var readInsert = ReadBool(); + var insert = readInsert ? Read() : null; + var readUpdate = ReadBool(); + var update = readUpdate ? Read() : null; + var readDelete = ReadBool(); + var delete = readDelete ? Read() : null; + var readSelect = ReadBool(); + var select = readSelect ? Read() : new SqlQuery.SelectClause(null); + var where = Read(); + var groupBy = Read(); + var having = Read(); + var orderBy = Read(); + var parentSql = ReadInt(); + var parameterDependent = ReadBool(); + var unions = ReadArray(); + var parameters = ReadArray(); + + var query = _query = new SqlQuery(sid) { QueryType = queryType }; + + query.Init( + insert, + update, + delete, + select, + from, + where, + groupBy, + having, + orderBy, + unions == null ? null : unions.ToList(), + null, + parameterDependent, + parameters.ToList()); + + _queries.Add(sid, _query); + + if (parentSql != 0) + _actions.Add(() => + { + SqlQuery sql; + if (_queries.TryGetValue(parentSql, out sql)) + query.ParentSql = sql; + }); + + query.All = Read(); + + obj = query; + + break; + } + + case QueryElementType.Column : + { + var sid = ReadInt(); + var expression = Read(); + var alias = ReadString(); + + var col = new SqlQuery.Column(null, expression, alias); + + _actions.Add(() => col.Parent = _queries[sid]); + + obj = col; + + break; + } + + case QueryElementType.SearchCondition : + obj = new SqlQuery.SearchCondition(ReadArray()); + break; + + case QueryElementType.Condition : + obj = new SqlQuery.Condition(ReadBool(), Read(), ReadBool()); + break; + + case QueryElementType.TableSource : + { + var source = Read(); + var alias = ReadString(); + var joins = ReadArray(); + + obj = new SqlQuery.TableSource(source, alias, joins); + + break; + } + + case QueryElementType.JoinedTable : + { + var joinType = (SqlQuery.JoinType)ReadInt(); + var table = Read(); + var isWeak = ReadBool(); + var condition = Read(); + + obj = new SqlQuery.JoinedTable(joinType, table, isWeak, condition); + + break; + } + + case QueryElementType.SelectClause : + { + var isDistinct = ReadBool(); + var skipValue = Read(); + var takeValue = Read(); + var columns = ReadArray(); + + obj = new SqlQuery.SelectClause(isDistinct, takeValue, skipValue, columns); + + break; + } + + case QueryElementType.InsertClause : + { + var items = ReadArray(); + var into = Read(); + var wid = ReadBool(); + + var c = new SqlQuery.InsertClause { Into = into, WithIdentity = wid }; + + c.Items.AddRange(items); + obj = c; + + break; + } + + case QueryElementType.UpdateClause : + { + var items = ReadArray(); + var keys = ReadArray(); + var table = Read(); + //var wid = ReadBool(); + + var c = new SqlQuery.UpdateClause { Table = table }; + + c.Items.AddRange(items); + c.Keys. AddRange(keys); + obj = c; + + break; + } + + case QueryElementType.DeleteClause : + { + var table = Read(); + obj = new SqlQuery.DeleteClause { Table = table }; + break; + } + + case QueryElementType.SetExpression : obj = new SqlQuery.SetExpression(Read(), Read()); break; + case QueryElementType.FromClause : obj = new SqlQuery.FromClause(ReadArray()); break; + case QueryElementType.WhereClause : obj = new SqlQuery.WhereClause(Read()); break; + case QueryElementType.GroupByClause : obj = new SqlQuery.GroupByClause(ReadArray()); break; + case QueryElementType.OrderByClause : obj = new SqlQuery.OrderByClause(ReadArray()); break; + + case QueryElementType.OrderByItem : + { + var expression = Read(); + var isDescending = ReadBool(); + + obj = new SqlQuery.OrderByItem(expression, isDescending); + + break; + } + + case QueryElementType.Union : + { + var sqlQuery = Read(); + var isAll = ReadBool(); + + obj = new SqlQuery.Union(sqlQuery, isAll); + + break; + } + } + + Dic.Add(idx, obj); + + return true; + } + } + + #endregion + + #region ResultSerializer + + class ResultSerializer : SerializerBase + { + public string Serialize(LinqServiceResult result) + { + Append(result.FieldCount); + Append(result.VaryingTypes.Length); + Append(result.RowCount); + Append(result.QueryID.ToString()); + + Builder.AppendLine(); + + foreach (var name in result.FieldNames) + { + Append(name); + Builder.AppendLine(); + } + + foreach (var type in result.FieldTypes) + { + Append(type.FullName); + Builder.AppendLine(); + } + + foreach (var type in result.VaryingTypes) + { + Append(type.FullName); + Builder.AppendLine(); + } + + foreach (var data in result.Data) + { + foreach (var str in data) + { + if (result.VaryingTypes.Length > 0 && !string.IsNullOrEmpty(str) && str[0] == '\0') + { + Builder.Append('*'); + Append((int)str[1]); + Append(str.Substring(2)); + } + else + Append(str); + } + + Builder.AppendLine(); + } + + return Builder.ToString(); + } + } + + #endregion + + #region ResultDeserializer + + class ResultDeserializer : DeserializerBase + { + public LinqServiceResult DeserializeResult(string str) + { + Str = str; + + var fieldCount = ReadInt(); + var varTypesLen = ReadInt(); + + var result = new LinqServiceResult + { + FieldCount = fieldCount, + RowCount = ReadInt(), + VaryingTypes = new Type[varTypesLen], + QueryID = new Guid(ReadString()), + FieldNames = new string[fieldCount], + FieldTypes = new Type [fieldCount], + Data = new List(), + }; + + NextLine(); + + for (var i = 0; i < fieldCount; i++) { result.FieldNames [i] = ReadString(); NextLine(); } + for (var i = 0; i < fieldCount; i++) { result.FieldTypes [i] = ResolveType(ReadString()); NextLine(); } + for (var i = 0; i < varTypesLen; i++) { result.VaryingTypes[i] = ResolveType(ReadString()); NextLine(); } + + for (var n = 0; n < result.RowCount; n++) + { + var data = new string[fieldCount]; + + for (var i = 0; i < fieldCount; i++) + { + if (varTypesLen > 0) + { + Get(' '); + + if (Get('*')) + { + var idx = ReadInt(); + data[i] = "\0" + (char)idx + ReadString(); + } + else + data[i] = ReadString(); + } + else + data[i] = ReadString(); + } + + result.Data.Add(data); + + NextLine(); + } + + return result; + } + } + + #endregion + + #region StringArraySerializer + + class StringArraySerializer : SerializerBase + { + public string Serialize(string[] data) + { + Append(data.Length); + + foreach (var str in data) + Append(str); + + Builder.AppendLine(); + + return Builder.ToString(); + } + } + + #endregion + + #region StringArrayDeserializer + + class StringArrayDeserializer : DeserializerBase + { + public string[] Deserialize(string str) + { + Str = str; + + var data = new string[ReadInt()]; + + for (var i = 0; i < data.Length; i++) + data[i] = ReadString(); + + return data; + } + } + + #endregion + + #region Helpers + + interface IArrayHelper + { + Type GetArrayType(); + object ConvertToArray(object list); + } + + class ArrayHelper : IArrayHelper + { + public Type GetArrayType() + { + return typeof(T[]); + } + + public object ConvertToArray(object list) + { + return ((IEnumerable)list).ToArray(); + } + } + + static readonly Dictionary _arrayTypes = new Dictionary(); + static readonly Dictionary> _arrayConverters = new Dictionary>(); + + static Type GetArrayType(Type elementType) + { + Type arrayType; + + lock (_arrayTypes) + { + if (!_arrayTypes.TryGetValue(elementType, out arrayType)) + { + var helper = (IArrayHelper)Activator.CreateInstance(typeof(ArrayHelper<>).MakeGenericType(elementType)); + _arrayTypes.Add(elementType, arrayType = helper.GetArrayType()); + } + } + + return arrayType; + } + + static object ConvertIEnumerableToArray(object list, Type elementType) + { + Func converter; + + lock (_arrayConverters) + { + if (!_arrayConverters.TryGetValue(elementType, out converter)) + { + var helper = (IArrayHelper)Activator.CreateInstance(typeof(ArrayHelper<>).MakeGenericType(elementType)); + _arrayConverters.Add(elementType, converter = helper.ConvertToArray); + } + } + + return converter(list); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/LinqSoapServiceClient.Silverlight.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/LinqSoapServiceClient.Silverlight.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,150 @@ +using System; +using System.ServiceModel; + +namespace BLToolkit.ServiceModel +{ + class LinqSoapServiceClient : ClientBase, ILinqService, IDisposable + { + #region Init + + public LinqSoapServiceClient(string endpointConfigurationName) : base(endpointConfigurationName) { } + public LinqSoapServiceClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } + public LinqSoapServiceClient(string endpointConfigurationName, EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } + public LinqSoapServiceClient(System.ServiceModel.Channels.Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) { } + + #endregion + + #region ILinqService Members + + public string GetSqlProviderType() + { + var async = Channel.BeginGetSqlProviderType(null, null); + return Channel.EndGetSqlProviderType(async); + } + + public int ExecuteNonQuery(string queryData) + { + var async = Channel.BeginExecuteNonQuery(queryData, null, null); + return Channel.EndExecuteNonQuery(async); + } + + public object ExecuteScalar(string queryData) + { + var async = Channel.BeginExecuteScalar(queryData, null, null); + return Channel.EndExecuteScalar(async); + } + + public string ExecuteReader(string queryData) + { + var async = Channel.BeginExecuteReader(queryData, null, null); + return Channel.EndExecuteReader(async); + } + + public int ExecuteBatch(string queryData) + { + var async = Channel.BeginExecuteBatch(queryData, null, null); + return Channel.EndExecuteBatch(async); + } + + #endregion + + #region IDisposable Members + + void IDisposable.Dispose() + { + try + { + if (State != CommunicationState.Faulted) + ((ICommunicationObject)this).Close(); + else + Abort(); + } + catch (CommunicationException) + { + Abort(); + } + catch (TimeoutException) + { + Abort(); + } + catch (Exception) + { + Abort(); + throw; + } + } + + #endregion + + #region Overrides + + protected override Async.ILinqSoapService CreateChannel() + { + return new LinqSoapServiceClientChannel(this); + } + + #endregion + + #region Channel + + class LinqSoapServiceClientChannel : ChannelBase, Async.ILinqSoapService + { + public LinqSoapServiceClientChannel(ClientBase client) : + base(client) + { + } + + public IAsyncResult BeginGetSqlProviderType(AsyncCallback callback, object asyncState) + { + return BeginInvoke("GetSqlProviderType", new object[0], callback, asyncState); + } + + public string EndGetSqlProviderType(IAsyncResult result) + { + return (string)EndInvoke("GetSqlProviderType", new object[0], result); + } + + public IAsyncResult BeginExecuteNonQuery(string queryData, AsyncCallback callback, object asyncState) + { + return BeginInvoke("ExecuteNonQuery", new object[] { queryData }, callback, asyncState); + } + + public int EndExecuteNonQuery(IAsyncResult result) + { + return (int)EndInvoke("ExecuteNonQuery", new object[0], result); + } + + public IAsyncResult BeginExecuteScalar(string queryData, AsyncCallback callback, object asyncState) + { + return BeginInvoke("ExecuteScalar", new object[] { queryData }, callback, asyncState); + } + + public object EndExecuteScalar(IAsyncResult result) + { + return EndInvoke("ExecuteScalar", new object[0], result); + } + + public IAsyncResult BeginExecuteReader(string queryData, AsyncCallback callback, object asyncState) + { + return BeginInvoke("ExecuteReader", new object[] { queryData }, callback, asyncState); + } + + public string EndExecuteReader(IAsyncResult result) + { + return (string)EndInvoke("ExecuteReader", new object[0], result); + } + + public IAsyncResult BeginExecuteBatch(string queryData, AsyncCallback callback, object asyncState) + { + return BeginInvoke("ExecuteBatch", new object[] { queryData }, callback, asyncState); + } + + public int EndExecuteBatch(IAsyncResult result) + { + return (int)EndInvoke("ExecuteBatch", new object[0], result); + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/LinqSoapServiceClient.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/LinqSoapServiceClient.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,75 @@ +using System; +using System.ServiceModel; +using System.ServiceModel.Channels; + +namespace BLToolkit.ServiceModel +{ + class LinqSoapServiceClient : ClientBase, ILinqService, IDisposable + { + #region Init + + public LinqSoapServiceClient(string endpointConfigurationName) : base(endpointConfigurationName) { } + public LinqSoapServiceClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } + public LinqSoapServiceClient(string endpointConfigurationName, EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } + public LinqSoapServiceClient(Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) { } + + #endregion + + #region ILinqService Members + + public string GetSqlProviderType() + { + return Channel.GetSqlProviderType(); + } + + public int ExecuteNonQuery(string queryData) + { + return Channel.ExecuteNonQuery(queryData); + } + + public object ExecuteScalar(string queryData) + { + return Channel.ExecuteScalar(queryData); + } + + public string ExecuteReader(string queryData) + { + return Channel.ExecuteReader(queryData); + } + + public int ExecuteBatch(string queryData) + { + return Channel.ExecuteBatch(queryData); + } + + #endregion + + #region IDisposable Members + + void IDisposable.Dispose() + { + try + { + if (State != CommunicationState.Faulted) + ((ICommunicationObject)this).Close(); + else + Abort(); + } + catch (CommunicationException) + { + Abort(); + } + catch (TimeoutException) + { + Abort(); + } + catch (Exception) + { + Abort(); + throw; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/RemoteDataContextBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/RemoteDataContextBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,276 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq.Expressions; +using System.Text; + +namespace BLToolkit.ServiceModel +{ + using Data.Linq; + using Data.Sql.SqlProvider; + using Mapping; + + public abstract class RemoteDataContextBase : IDataContext + { + protected abstract ILinqService GetClient(); + protected abstract IDataContext Clone (); + protected abstract string ContextIDPrefix { get; } + + string _contextID; + string IDataContext.ContextID + { + get { return _contextID ?? (_contextID = ContextIDPrefix + SqlProviderType.Name.Replace("SqlProvider", "")); } + } + + private MappingSchema _mappingSchema; + public MappingSchema MappingSchema + { + get + { + if (_mappingSchema == null) + { + var sp = ((IDataContext)this).CreateSqlProvider(); + _mappingSchema = sp is IMappingSchemaProvider ? ((IMappingSchemaProvider)sp).MappingSchema : Map.DefaultSchema; + } + + return _mappingSchema; + } + + set { _mappingSchema = value; } + } + + private Type _sqlProviderType; + public virtual Type SqlProviderType + { + get + { + if (_sqlProviderType == null) + { + var client = GetClient(); + + try + { + var type = client.GetSqlProviderType(); + _sqlProviderType = Type.GetType(type); + } + finally + { + ((IDisposable)client).Dispose(); + } + } + + return _sqlProviderType; + } + + set { _sqlProviderType = value; } + } + + public bool IsMarsEnabled + { + get { return false; } + } + + static readonly Dictionary> _sqlProviders = new Dictionary>(); + + Func _createSqlProvider; + + Func IDataContext.CreateSqlProvider + { + get + { + if (_createSqlProvider == null) + { + var type = SqlProviderType; + + if (!_sqlProviders.TryGetValue(type, out _createSqlProvider)) + lock (_sqlProviderType) + if (!_sqlProviders.TryGetValue(type, out _createSqlProvider)) + _sqlProviders.Add(type, _createSqlProvider = Expression.Lambda>(Expression.New(type)).Compile()); + } + + return _createSqlProvider; + } + } + + List _queryBatch; + int _batchCounter; + + public void BeginBatch() + { + _batchCounter++; + + if (_queryBatch == null) + _queryBatch = new List(); + } + + public void CommitBatch() + { + if (_batchCounter == 0) + throw new InvalidOperationException(); + + _batchCounter--; + + if (_batchCounter == 0) + { + var client = GetClient(); + + try + { + var data = LinqServiceSerializer.Serialize(_queryBatch.ToArray()); + client.ExecuteBatch(data); + } + finally + { + ((IDisposable)client).Dispose(); + _queryBatch = null; + } + } + } + + class QueryContext + { + public IQueryContext Query; + public ILinqService Client; + } + + object IDataContext.SetQuery(IQueryContext queryContext) + { + return new QueryContext { Query = queryContext }; + } + + int IDataContext.ExecuteNonQuery(object query) + { + var ctx = (QueryContext)query; + var q = ctx.Query.SqlQuery.ProcessParameters(); + var data = LinqServiceSerializer.Serialize(q, q.IsParameterDependent ? q.Parameters.ToArray() : ctx.Query.GetParameters()); + + if (_batchCounter > 0) + { + _queryBatch.Add(data); + return -1; + } + + ctx.Client = GetClient(); + + return ctx.Client.ExecuteNonQuery(data); + } + + object IDataContext.ExecuteScalar(object query) + { + if (_batchCounter > 0) + throw new LinqException("Incompatible batch operation."); + + var ctx = (QueryContext)query; + + ctx.Client = GetClient(); + + var q = ctx.Query.SqlQuery.ProcessParameters(); + + return ctx.Client.ExecuteScalar( + LinqServiceSerializer.Serialize(q, q.IsParameterDependent ? q.Parameters.ToArray() : ctx.Query.GetParameters())); + } + + IDataReader IDataContext.ExecuteReader(object query) + { + if (_batchCounter > 0) + throw new LinqException("Incompatible batch operation."); + + var ctx = (QueryContext)query; + + ctx.Client = GetClient(); + + var q = ctx.Query.SqlQuery.ProcessParameters(); + var ret = ctx.Client.ExecuteReader( + LinqServiceSerializer.Serialize(q, q.IsParameterDependent ? q.Parameters.ToArray() : ctx.Query.GetParameters())); + var result = LinqServiceSerializer.DeserializeResult(ret); + + return new ServiceModelDataReader(result); + } + + public void ReleaseQuery(object query) + { + var ctx = (QueryContext)query; + + if (ctx.Client != null) + ((IDisposable)ctx.Client).Dispose(); + } + + string IDataContext.GetSqlText(object query) + { + var ctx = (QueryContext)query; + var sqlProvider = ((IDataContext)this).CreateSqlProvider(); + var sb = new StringBuilder(); + + sb + .Append("-- ") + .Append("ServiceModel") + .Append(' ') + .Append(((IDataContext)this).ContextID) + .Append(' ') + .Append(sqlProvider.Name) + .AppendLine(); + + if (ctx.Query.SqlQuery.Parameters != null && ctx.Query.SqlQuery.Parameters.Count > 0) + { + foreach (var p in ctx.Query.SqlQuery.Parameters) + sb + .Append("-- DECLARE ") + .Append(p.Name) + .Append(' ') + .Append(p.Value == null ? p.SystemType.ToString() : p.Value.GetType().Name) + .AppendLine(); + + sb.AppendLine(); + + foreach (var p in ctx.Query.SqlQuery.Parameters) + { + var value = p.Value; + + if (value is string || value is char) + value = "'" + value.ToString().Replace("'", "''") + "'"; + + sb + .Append("-- SET ") + .Append(p.Name) + .Append(" = ") + .Append(value) + .AppendLine(); + } + + sb.AppendLine(); + } + + var cc = sqlProvider.CommandCount(ctx.Query.SqlQuery); + var commands = new string[cc]; + + for (var i = 0; i < cc; i++) + { + sb.Length = 0; + + sqlProvider.BuildSql(i, ctx.Query.SqlQuery, sb, 0, 0, false); + commands[i] = sb.ToString(); + } + + if (!ctx.Query.SqlQuery.IsParameterDependent) + ctx.Query.Context = commands; + + foreach (var command in commands) + sb.AppendLine(command); + + return sb.ToString(); + } + + IDataContext IDataContext.Clone(bool forNestedQuery) + { + return Clone(); + } + + public event EventHandler OnClosing; + + public void Dispose() + { + if (OnClosing != null) + OnClosing(this, EventArgs.Empty); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/ServiceModelDataContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/ServiceModelDataContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,102 @@ +using System; +using System.ServiceModel; +using System.ServiceModel.Channels; + +using JetBrains.Annotations; + +namespace BLToolkit.ServiceModel +{ + using Data.Linq; + + using NotNullAttribute = NotNullAttribute; + + public class ServiceModelDataContext : RemoteDataContextBase + { + #region Init + + ServiceModelDataContext() + { + } + + public ServiceModelDataContext([NotNull] string endpointConfigurationName) + : this() + { + if (endpointConfigurationName == null) throw new ArgumentNullException("endpointConfigurationName"); + + _endpointConfigurationName = endpointConfigurationName; + } + + public ServiceModelDataContext([NotNull] string endpointConfigurationName, [NotNull] string remoteAddress) + : this() + { + if (endpointConfigurationName == null) throw new ArgumentNullException("endpointConfigurationName"); + if (remoteAddress == null) throw new ArgumentNullException("remoteAddress"); + + _endpointConfigurationName = endpointConfigurationName; + _remoteAddress = remoteAddress; + } + + public ServiceModelDataContext([NotNull] string endpointConfigurationName, [NotNull] EndpointAddress endpointAddress) + : this() + { + if (endpointConfigurationName == null) throw new ArgumentNullException("endpointConfigurationName"); + if (endpointAddress == null) throw new ArgumentNullException("endpointAddress"); + + _endpointConfigurationName = endpointConfigurationName; + _endpointAddress = endpointAddress; + } + + public ServiceModelDataContext([NotNull] Binding binding, [NotNull] EndpointAddress endpointAddress) + : this() + { + if (binding == null) throw new ArgumentNullException("binding"); + if (endpointAddress == null) throw new ArgumentNullException("endpointAddress"); + + Binding = binding; + _endpointAddress = endpointAddress; + } + + string _endpointConfigurationName; + string _remoteAddress; + EndpointAddress _endpointAddress; + + public Binding Binding { get; private set; } + + #endregion + + #region Overrides + + protected override ILinqService GetClient() + { + if (Binding != null) + return new LinqServiceClient(Binding, _endpointAddress); + + if (_endpointAddress != null) + return new LinqServiceClient(_endpointConfigurationName, _endpointAddress); + + if (_remoteAddress != null) + return new LinqServiceClient(_endpointConfigurationName, _remoteAddress); + + return new LinqServiceClient(_endpointConfigurationName); + } + + protected override IDataContext Clone() + { + return new ServiceModelDataContext + { + MappingSchema = MappingSchema, + Binding = Binding, + _endpointConfigurationName = _endpointConfigurationName, + _remoteAddress = _remoteAddress, + _endpointAddress = _endpointAddress, + }; + } + + protected override string ContextIDPrefix + { + get { return "LinqService_"; } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/ServiceModelDataReader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/ServiceModelDataReader.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,247 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Globalization; + +namespace BLToolkit.ServiceModel +{ + using Common; + + class ServiceModelDataReader : IDataReader + { + public ServiceModelDataReader(LinqServiceResult result) + { + _result = result; + + for (var i = 0; i < result.FieldNames.Length; i++) + _ordinal.Add(result.FieldNames[i], i); + } + + readonly LinqServiceResult _result; + readonly Dictionary _ordinal = new Dictionary(); + + string[] _data; + int _current = -1; + + #region IDataReader Members + + public void Close() + { + } + + public int Depth + { + get { return 0; } + } + +#if !SILVERLIGHT + + public DataTable GetSchemaTable() + { + throw new InvalidOperationException(); + } + +#endif + + public bool IsClosed + { + get { throw new InvalidOperationException(); } + } + + public bool NextResult() + { + throw new InvalidOperationException(); + } + + public bool Read() + { + if (++_current < _result.RowCount) + { + _data = _result.Data[_current]; + + return true; + } + + _data = null; + + return false; + } + + public int RecordsAffected + { + get { throw new InvalidOperationException(); } + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + } + + #endregion + + #region IDataRecord Members + + public int FieldCount + { + get { return _result.FieldCount; } + } + + public bool GetBoolean(int i) + { + return bool.Parse(_data[i]); + } + + public byte GetByte(int i) + { + return byte.Parse(_data[i]); + } + + public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) + { + throw new InvalidOperationException(); + } + + public char GetChar(int i) + { + return _data[i][0]; + } + + public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) + { + throw new InvalidOperationException(); + } + + public IDataReader GetData(int i) + { + throw new InvalidOperationException(); + } + + public string GetDataTypeName(int i) + { + return _result.FieldTypes[i].FullName; + } + + public DateTime GetDateTime(int i) + { + return DateTime.Parse(_data[i], CultureInfo.InvariantCulture); + } + + public decimal GetDecimal(int i) + { + return decimal.Parse(_data[i], CultureInfo.InvariantCulture); + } + + public double GetDouble(int i) + { + return double.Parse(_data[i], CultureInfo.InvariantCulture); + } + + public Type GetFieldType(int i) + { + return _result.FieldTypes[i]; + } + + public float GetFloat(int i) + { + return float.Parse(_data[i], CultureInfo.InvariantCulture); + } + + public Guid GetGuid(int i) + { + return new Guid(_data[i]); + } + + public short GetInt16(int i) + { + return short.Parse(_data[i]); + } + + public int GetInt32(int i) + { + return int.Parse(_data[i]); + } + + public long GetInt64(int i) + { + return long.Parse(_data[i]); + } + + public string GetName(int i) + { + return _result.FieldNames[i]; + } + + public int GetOrdinal(string name) + { + return _ordinal[name]; + } + + public string GetString(int i) + { + return _data[i]; + } + + public object GetValue(int i) + { + var type = _result.FieldTypes[i]; + var value = _data[i]; + + if (_result.VaryingTypes.Length > 0 && !string.IsNullOrEmpty(value) && value[0] == '\0') + { + type = _result.VaryingTypes[value[1]]; + value = value.Substring(2); + } + + if (value == null) + return null; + + if (type.IsArray && type == typeof(byte[])) + return System.Convert.FromBase64String(value); + + switch (Type.GetTypeCode(type)) + { + case TypeCode.String : return value; + case TypeCode.Double : return double. Parse(value, CultureInfo.InvariantCulture); + case TypeCode.Decimal : return decimal. Parse(value, CultureInfo.InvariantCulture); + case TypeCode.Single : return float. Parse(value, CultureInfo.InvariantCulture); + case TypeCode.DateTime : return DateTime.Parse(value, CultureInfo.InvariantCulture); + case TypeCode.Object : + if (type == typeof(double?)) return double. Parse(value, CultureInfo.InvariantCulture); + if (type == typeof(decimal?)) return decimal. Parse(value, CultureInfo.InvariantCulture); + if (type == typeof(float?)) return float. Parse(value, CultureInfo.InvariantCulture); + if (type == typeof(DateTime?)) return DateTime. Parse(value, CultureInfo.InvariantCulture); + + if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?)) + return DateTimeOffset.Parse(value, CultureInfo.InvariantCulture); + break; + } + + return Convert.ChangeTypeFromString(value, type); + } + + public int GetValues(object[] values) + { + throw new InvalidOperationException(); + } + + public bool IsDBNull(int i) + { + return _data[i] == null; + } + + public object this[string name] + { + get { return GetValue(GetOrdinal(name)); } + } + + public object this[int i] + { + get { return GetValue(i); } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/ServiceModel/SoapDataContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ServiceModel/SoapDataContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,102 @@ +using System; +using System.ServiceModel; +using System.ServiceModel.Channels; + +using JetBrains.Annotations; + +namespace BLToolkit.ServiceModel +{ + using Data.Linq; + + using NotNullAttribute = NotNullAttribute; + + public class SoapDataContext : RemoteDataContextBase + { + #region Init + + SoapDataContext() + { + } + + public SoapDataContext([NotNull] string endpointConfigurationName) + : this() + { + if (endpointConfigurationName == null) throw new ArgumentNullException("endpointConfigurationName"); + + _endpointConfigurationName = endpointConfigurationName; + } + + public SoapDataContext([NotNull] string endpointConfigurationName, [NotNull] string remoteAddress) + : this() + { + if (endpointConfigurationName == null) throw new ArgumentNullException("endpointConfigurationName"); + if (remoteAddress == null) throw new ArgumentNullException("remoteAddress"); + + _endpointConfigurationName = endpointConfigurationName; + _remoteAddress = remoteAddress; + } + + public SoapDataContext([NotNull] string endpointConfigurationName, [NotNull] EndpointAddress endpointAddress) + : this() + { + if (endpointConfigurationName == null) throw new ArgumentNullException("endpointConfigurationName"); + if (endpointAddress == null) throw new ArgumentNullException("endpointAddress"); + + _endpointConfigurationName = endpointConfigurationName; + _endpointAddress = endpointAddress; + } + + public SoapDataContext([NotNull] Binding binding, [NotNull] EndpointAddress endpointAddress) + : this() + { + if (binding == null) throw new ArgumentNullException("binding"); + if (endpointAddress == null) throw new ArgumentNullException("endpointAddress"); + + Binding = binding; + _endpointAddress = endpointAddress; + } + + string _endpointConfigurationName; + string _remoteAddress; + EndpointAddress _endpointAddress; + + public Binding Binding { get; private set; } + + #endregion + + #region Overrides + + protected override ILinqService GetClient() + { + if (Binding != null) + return new LinqSoapServiceClient(Binding, _endpointAddress); + + if (_endpointAddress != null) + return new LinqSoapServiceClient(_endpointConfigurationName, _endpointAddress); + + if (_remoteAddress != null) + return new LinqSoapServiceClient(_endpointConfigurationName, _remoteAddress); + + return new LinqSoapServiceClient(_endpointConfigurationName); + } + + protected override IDataContext Clone() + { + return new SoapDataContext + { + MappingSchema = MappingSchema, + Binding = Binding, + _endpointConfigurationName = _endpointConfigurationName, + _remoteAddress = _remoteAddress, + _endpointAddress = _endpointAddress, + }; + } + + protected override string ContextIDPrefix + { + get { return "LinqSoapService_"; } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Templates/BLT4Toolkit.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/BLT4Toolkit.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +<#@ include file="T4Toolbox.tt" #> +<# + + var customToolNamespace = TransformationContext.FindProjectItem(Host.TemplateFile).Properties.Item("CustomToolNamespace").Value; + + if (customToolNamespace != null) + Namespace = customToolNamespace.ToString(); + + if (string.IsNullOrEmpty(Namespace)) + Namespace = TransformationContext.DefaultNamespace; + + if (string.IsNullOrEmpty(DataContextName)) + DataContextName = System.IO.Path.GetFileNameWithoutExtension(Host.TemplateFile); + +#> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Templates/BLToolkit.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/BLToolkit.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,643 @@ +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Data" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.IO" #> +<# + AppDomain.CurrentDomain.AssemblyResolve += (_,args) => + { + foreach (var a in Assemblies) + if (args.Name.ToLower().IndexOf(a.Key.ToLower()) >= 0) + return System.Reflection.Assembly.LoadFile(a.Value); + + if (DataProviderAssembly != null && args.Name.Split(',')[0] == System.IO.Path.GetFileNameWithoutExtension(DataProviderAssembly)) + return System.Reflection.Assembly.LoadFile(DataProviderAssembly); + + return null; + }; +#><#+ + +static Dictionary Assemblies = new Dictionary(); + +static Action WriteComment = (tt,s) => tt.WriteLine("//{0}", s); +static Action WriteSummary = (tt,s) => +{ + if (!string.IsNullOrWhiteSpace(s)) + { + tt.WriteLine("/// "); + tt.WriteLine("/// {0}", s); + tt.WriteLine("/// "); + } +}; +static Action WriteUsing = (tt,s) => tt.WriteLine("using {0};", s); +static Action WriteBeginNamespace = (tt,s) => { tt.WriteLine("namespace {0}", s); tt.WriteLine("{"); }; +static Action WriteEndNamespace = tt => tt.WriteLine("}"); +static Action WriteBeginClass = (tt,cl,bc) => +{ + tt.Write("public partial class {0}", cl); + if (!string.IsNullOrEmpty(bc)) + tt.Write(" : {0}", bc); + tt.WriteLine(""); + tt.WriteLine("{"); +}; +static Action WriteEndClass = tt => tt.WriteLine("}"); +static Func MakeGenericType = (c,t) => string.Format("{0}<{1}>", c, t); +static Func MakeType = t => t; + +delegate void WriteTablePropertyAction(GeneratedTextTransformation tt, string name, string pname, int maxlen, int maxplen, string desc); + +static WriteTablePropertyAction WriteTableProperty = (tt,name,pname,maxlen,maxplen,desc) => +{ + WriteSummary(tt,desc); + tt.WriteLine("public Table<{0}>{1} {2}{3} {{ get {{ return this.GetTable<{0}>();{1} }} }}", name, tt.LenDiff(maxlen, name), pname, tt.LenDiff(maxplen, pname)); +}; +static Action WriteAttribute = (tt,a) => tt.Write("[{0}]", a); +static Action WriteAttributeLine = tt => tt.WriteLine(""); + +static string ConnectionString; +static string ConnectionType; +static string DataProviderAssembly = null; + +string DatabaseName = null; +string DataContextName = null; +string Namespace = "DataModel"; +string BaseDataContextClass = "DbManager"; +string BaseEntityClass = null; +string OneToManyAssociationType = "IEnumerable<{0}>"; + +string OwnerToInclude = null; +string[] DatabaseQuote = null; + +bool RenderField = false; +bool RenderBackReferences = true; +bool RenderForeignKeys = true; + +bool IsMetadataLoaded; + +int MaxColumnTypeLen; +int MaxColumnMemberLen; + +static Action RenderColumn = (tt,c,maxLens,attrs) => +{ + WriteSummary(tt,c.Description); + + if (maxLens.Sum() > 0) + { + if (attrs.Any(_ => _ != null)) + { + tt.Write("["); + + for (var i = 0; i < attrs.Length; i++) + { + if (attrs[i] != null) + { + tt.Write(attrs[i]); + tt.WriteSpace(maxLens[i] - attrs[i].Length); + + if (attrs.Skip(i + 1).Any(_ => _ != null)) + tt.Write(", "); + else if (maxLens.Skip(i + 1).Any(_ => _ > 0)) + tt.WriteSpace(2); + } + else if (maxLens[i] > 0) + { + tt.WriteSpace(maxLens[i]); + + if (maxLens.Skip(i + 1).Any(_ => _ > 0)) + tt.WriteSpace(2); + } + } + + tt.Write("] "); + } + else + { + tt.WriteSpace(maxLens.Sum() + (maxLens.Where(_ => _ > 0).Count() - 1) * 2 + 3); + } + } + + tt.Write("public {0}{1} {2}", c.Type, tt.LenDiff(tt.MaxColumnTypeLen, c.Type), c.MemberName); + + if (tt.RenderField) + { + tt.Write(";"); + if (c.ColumnType != null) + tt.Write(tt.LenDiff(tt.MaxColumnMemberLen, c.MemberName)); + } + else + tt.Write("{0} {{ get; set; }}", tt.LenDiff(tt.MaxColumnMemberLen, c.MemberName)); + + if (c.ColumnType != null) + { + tt.Write(" // {0}", c.ColumnType); + + if (c.Length != 0) + tt.Write("({0})", c.Length); + + if (c.Precision != 0) + { + if (c.Scale == 0) + tt.Write("({0})", c.Precision); + else + tt.Write("({0},{1})", c.Precision, c.Scale); + } + } + + tt.WriteLine(""); +}; + +static Action RenderForeignKey = (tt,key) => +{ + WriteComment(tt, " " + key.KeyName); + tt.WriteLine("[Association(ThisKey=\"{0}\", OtherKey=\"{1}\", CanBeNull={2})]", + string.Join(", ", (from c in key.ThisColumns select c.MemberName).ToArray()), + string.Join(", ", (from c in key.OtherColumns select c.MemberName).ToArray()), + key.CanBeNull ? "true" : "false"); + + if (key.Attributes.Count > 0) + { + WriteAttribute(tt, string.Join(", ", key.Attributes.Distinct().ToArray())); + WriteAttributeLine(tt); + } + + tt.Write("public "); + + if (key.AssociationType == AssociationType.OneToMany) + tt.Write(tt.OneToManyAssociationType, key.OtherTable.ClassName); + else + tt.Write(key.OtherTable.ClassName); + + tt.Write(" "); + tt.Write(key.MemberName); + + if (tt.RenderField) + tt.WriteLine(";"); + else + tt.WriteLine(" { get; set; }"); +}; + +static Action RenderTable = (tt,t, renderForeignKeys) => +{ + WriteSummary(tt,t.Description); + + if (t.IsView) + { + WriteComment(tt, " View"); + } + + RenderTableAttributes(tt, t); + + WriteBeginClass(tt, t.ClassName, t.BaseClassName); + + tt.PushIndent("\t"); + + if (t.Columns.Count > 0) + { + tt.MaxColumnTypeLen = t.Columns.Values.Max(_ => _.Type.Length); + tt.MaxColumnMemberLen = t.Columns.Values.Max(_ => _.MemberName.Length); + + var maxLens = new int[] + { + t.Columns.Values.Max(_ => _.MemberName == _.ColumnName ? 0 : "MapField('')".Length + _.ColumnName.Length), + t.Columns.Values.Max(_ => _.IsNullable ? "Nullable".Length : _.IsIdentity ? "Identity".Length : 0), + t.Columns.Values.Max(_ => _.IsIdentity && _.IsNullable ? "Identity".Length : 0), + t.Columns.Values.Max(_ => _.IsPrimaryKey ? string.Format("PrimaryKey({0})", _.PKIndex).Length : 0), + t.Columns.Values.Max(_ => _.Attributes.Count == 0 ? 0 : string.Join(", ", _.Attributes.Distinct().ToArray()).Length), + }; + + foreach (var c in from c in t.Columns.Values orderby c.ID select c) + { + var attrs = new string[] + { + c.MemberName == c.ColumnName ? null : string.Format("MapField(\"{0}\")", c.ColumnName), + c.IsNullable ? "Nullable" : c.IsIdentity ? "Identity" : null, + c.IsIdentity && c.IsNullable ? "Identity" : null, + c.IsPrimaryKey ? string.Format("PrimaryKey({0})", c.PKIndex) : null, + c.Attributes.Count == 0 ? null : string.Join(", ", c.Attributes.Distinct().ToArray()), + }; + + RenderColumn(tt, c, maxLens, attrs); + } + } + + if (renderForeignKeys && t.ForeignKeys.Count > 0) + { + foreach (var key in t.ForeignKeys.Values.Where(k => tt.RenderBackReferences || k.BackReference != null)) + { + tt.WriteLine(""); + RenderForeignKey(tt, key); + } + } + + tt.PopIndent(); + WriteEndClass(tt); +}; + +static Action RenderTableAttributes = (tt,t) => +{ + if (t.Attributes.Count > 0) + { + WriteAttribute(tt, string.Join(", ", t.Attributes.Distinct().ToArray())); + WriteAttributeLine(tt); + } + + string tbl = "TableName("; + + if (!string.IsNullOrEmpty(tt.DatabaseName)) + tbl += string.Format("Database=\"{0}\", ", tt.DatabaseName); + + if (!string.IsNullOrEmpty(t.Owner)) + tbl += string.Format("Owner=\"{0}\", ", t.Owner); + + tbl += string.Format("Name=\"{0}\")", t.TableName); + + WriteAttribute(tt, tbl); + WriteAttributeLine(tt); +}; + +List Usings = new List() +{ + "System", + "BLToolkit.Data", + "BLToolkit.Data.Linq", + "BLToolkit.DataAccess", + "BLToolkit.Mapping", +}; + +static Action RenderUsing = tt => +{ + var q = + from ns in tt.Usings.Distinct() + group ns by ns.Split('.')[0]; + + var groups = + (from ns in q where ns.Key == "System" select ns).Concat + (from ns in q where ns.Key != "System" orderby ns.Key select ns); + + foreach (var gr in groups) + { + foreach (var ns in from s in gr orderby s select s) + WriteUsing(tt, ns); + + tt.WriteLine(""); + } +}; + +Action BeforeGenerateModel = _ => {}; +Action AfterGenerateModel = _ => {}; + +Action BeforeWriteTableProperty = _ => {}; +Action AfterWriteTableProperty = _ => {}; + +void GenerateModel() +{ + if (ConnectionString != null) ConnectionString = ConnectionString.Trim(); + if (DataContextName != null) DataContextName = DataContextName. Trim(); + + if (string.IsNullOrEmpty(ConnectionString)) { Error("ConnectionString cannot be empty."); return; } + + if (string.IsNullOrEmpty(DataContextName)) + DataContextName = "DataContext"; + + LoadMetadata(); + + BeforeGenerateModel(this); + + WriteComment(this, "---------------------------------------------------------------------------------------------------"); + WriteComment(this, " "); + WriteComment(this, " This code was generated by BLToolkit template for T4."); + WriteComment(this, " Changes to this file may cause incorrect behavior and will be lost if the code is regenerated."); + WriteComment(this, " "); + WriteComment(this, "---------------------------------------------------------------------------------------------------"); + + RenderUsing(this); + + WriteBeginNamespace(this, Namespace); + PushIndent("\t"); + + WriteBeginClass(this, DataContextName, BaseDataContextClass); + + var tlist = (from t in Tables.Values orderby t.TableName select t).ToList(); + var maxlen = tlist.Max(_ => _.ClassName.Length); + var maxplen = tlist.Max(_ => (_.DataContextPropertyName ?? _.ClassName).Length); + + PushIndent("\t"); + + BeforeWriteTableProperty(this); + + foreach (var t in tlist) + WriteTableProperty(this, t.ClassName, t.DataContextPropertyName ?? t.ClassName, maxlen, maxplen, t.Description); + + AfterWriteTableProperty(this); + + PopIndent(); + + WriteEndClass(this); + + foreach (var t in tlist) + { + WriteLine(""); + RenderTable(this, t, RenderForeignKeys); + } + + PopIndent(); + WriteEndNamespace(this); + + AfterGenerateModel(this); +} + +string LenDiff(int max, string str) +{ + var s = ""; + + while (max-- > str.Length) + s += " "; + + return s; +} + +void WriteSpace(int len) +{ + while (len-- > 0) + Write(" "); +} + +List CreateList(T item) +{ + return new List(); +} + +Func GetConnectionObject = () => +{ + Type connType = null; + + if (DataProviderAssembly != null) + { + try + { + var assembly = System.Reflection.Assembly.LoadFile(DataProviderAssembly); + connType = assembly.GetType(ConnectionType) + ?? assembly.GetType(ConnectionType.Substring(0, ConnectionType.IndexOf(","))); + } + catch + { + } + } + + if (connType == null) + connType = Type.GetType(ConnectionType); + + return (System.Data.IDbConnection)Activator.CreateInstance(connType); +}; + +System.Data.IDbConnection GetConnection() +{ + var conn = GetConnectionObject(); + + conn.ConnectionString = ConnectionString; + conn.Open(); + + return conn; +} + +void LoadMetadata() +{ + if (IsMetadataLoaded) + return; + + IsMetadataLoaded = true; + + if (!string.IsNullOrEmpty(DataProviderAssembly) && !DataProviderAssembly.Contains(":") && DataProviderAssembly.Contains("..")) + { + try + { + string path = this.Host.ResolvePath(""); + DataProviderAssembly = Path.GetFullPath(Path.Combine(path, DataProviderAssembly)); + } + catch + { + } + } + + BeforeLoadMetadata(this); + LoadServerMetadata(); + + if (DatabaseQuote != null) + { + foreach (var t in Tables.Values) + { + t.TableName = string.Format("{1}{0}{2}", t.TableName, DatabaseQuote.FirstOrDefault(), DatabaseQuote.Skip(1).FirstOrDefault() ?? DatabaseQuote.FirstOrDefault()); + foreach (var c in t.Columns.Values) + { + c.ColumnName = string.Format("{1}{0}{2}", c.ColumnName, DatabaseQuote.FirstOrDefault(), DatabaseQuote.Skip(1).FirstOrDefault() ?? DatabaseQuote.FirstOrDefault()); + } + } + } + + foreach (var t in Tables.Values) + { + if (t.ClassName.Contains(" ")) + { + var ss = t.ClassName.Split(' ').Where(_ => _.Trim().Length > 0).Select(_ => char.ToUpper(_[0]) + _.Substring(1)); + t.ClassName = string.Join("", ss.ToArray()); + } + } + + foreach (var t in Tables.Values) + foreach (var key in t.ForeignKeys.Values.ToList()) + if (!key.KeyName.EndsWith("_BackReference")) + key.OtherTable.ForeignKeys.Add(key.KeyName + "_BackReference", key.BackReference = new ForeignKey + { + KeyName = key.KeyName + "_BackReference", + MemberName = key.MemberName + "_BackReference", + AssociationType = AssociationType.Auto, + OtherTable = t, + ThisColumns = key.OtherColumns, + OtherColumns = key.ThisColumns, + }); + + foreach (var t in Tables.Values) + { + foreach (var key in t.ForeignKeys.Values) + { + if (key.BackReference != null && key.AssociationType == AssociationType.Auto) + { + if (key.ThisColumns.All(_ => _.IsPrimaryKey)) + { + if (t.Columns.Values.Count(_ => _.IsPrimaryKey) == key.ThisColumns.Count) + key.AssociationType = AssociationType.OneToOne; + else + key.AssociationType = AssociationType.ManyToOne; + } + else + key.AssociationType = AssociationType.ManyToOne; + + key.CanBeNull = key.ThisColumns.All(_ => _.IsNullable); + } + } + } + + foreach (var t in Tables.Values) + { + foreach (var key in t.ForeignKeys.Values) + { + var name = key.MemberName; + + if (key.BackReference != null && key.ThisColumns.Count == 1 && key.ThisColumns[0].MemberName.ToLower().EndsWith("id")) + { + name = key.ThisColumns[0].MemberName; + name = name.Substring(0, name.Length - "id".Length); + + if (!t.ForeignKeys.Values.Select(_ => _.MemberName).Concat( + t.Columns. Values.Select(_ => _.MemberName)).Concat( + new[] { t.ClassName }).Any(_ => _ == name)) + { + name = key.MemberName;; + } + } + + if (name == key.MemberName) + { + if (name.StartsWith("FK_")) + name = name.Substring(3); + + if (name.EndsWith("_BackReference")) + name = name.Substring(0, name.Length - "_BackReference".Length); + + name = string.Join("", name.Split('_').Where(_ => _.Length > 0 && _ != t.TableName).ToArray()); + + if (name.Length > 0) + name = key.AssociationType == AssociationType.OneToMany ? PluralizeAssociationName(name) : SingularizeAssociationName(name); + } + + if (name.Length != 0 && + !t.ForeignKeys.Values.Select(_ => _.MemberName).Concat( + t.Columns. Values.Select(_ => _.MemberName)).Concat( + new[] { t.ClassName }).Any(_ => _ == name)) + { + key.MemberName = name; + } + } + } + + if (Tables.Values.SelectMany(_ => _.ForeignKeys.Values).Any(_ => _.AssociationType == AssociationType.OneToMany)) + Usings.Add("System.Collections.Generic"); + + var keyWords = new HashSet + { + "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", + "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", + "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", + "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "new", + "null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly", + "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "struct", "switch", + "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", + "using", "virtual", "volatile", "void", "while" + }; + + foreach (var t in Tables.Values) + { + if (keyWords.Contains(t.ClassName)) + t.ClassName = "@" + t.ClassName; + + if (keyWords.Contains(t.DataContextPropertyName)) + t.DataContextPropertyName = "@" + t.DataContextPropertyName; + + foreach (var col in t.Columns.Values) + if (keyWords.Contains(col.MemberName)) + col.MemberName = "@" + col.MemberName; + } + + + AfterLoadMetadata(this); +} + +Func PluralizeAssociationName = _ => _ + "s"; +Func SingularizeAssociationName = _ => _; + +Action BeforeLoadMetadata = _ => {}; +Action AfterLoadMetadata = _ => {}; + +Dictionary Tables = new Dictionary(); + +public partial class Table +{ + public string Owner; + public string TableName; + public string ClassName; + public string DataContextPropertyName; + public string BaseClassName; + public bool IsView; + public string Description; + public List Attributes = new List(); + + public Dictionary Columns = new Dictionary(); + public Dictionary ForeignKeys = new Dictionary(); +} + +public partial class Column +{ + public int ID; + public string ColumnName; // Column name in database + public string MemberName; // Member name of the generated class + public bool IsNullable; + public bool IsIdentity; + public string Type; // Type of the generated member + public string ColumnType; // Type of the column in database + public bool IsClass; + public DbType DbType; + public SqlDbType SqlDbType; + public long Length; + public int Precision; + public int Scale; + public string Description; + + public int PKIndex = -1; + public List Attributes = new List(); + + public bool IsPrimaryKey { get { return PKIndex >= 0; } } +} + +public enum AssociationType +{ + Auto, + OneToOne, + OneToMany, + ManyToOne, +} + +public partial class ForeignKey +{ + public string KeyName; + public string MemberName; + public Table OtherTable; + public List ThisColumns = new List(); + public List OtherColumns = new List(); + public List Attributes = new List(); + public bool CanBeNull = true; + public ForeignKey BackReference; + + private AssociationType _associationType = AssociationType.Auto; + public AssociationType AssociationType + { + get { return _associationType; } + set + { + _associationType = value; + + if (BackReference != null) + { + switch (value) + { + case AssociationType.Auto : BackReference.AssociationType = AssociationType.Auto; break; + case AssociationType.OneToOne : BackReference.AssociationType = AssociationType.OneToOne; break; + case AssociationType.OneToMany : BackReference.AssociationType = AssociationType.ManyToOne; break; + case AssociationType.ManyToOne : BackReference.AssociationType = AssociationType.OneToMany; break; + } + } + } + } +} + +#> diff -r 000000000000 -r f990fcb411a9 Source/Templates/BLToolkitConstants.Revision.cs.template --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/BLToolkitConstants.Revision.cs.template Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +// Autogenerated. Do not modify! + +namespace BLToolkit +{ + partial class BLToolkitConstants + { + // + // Revision component of version. + // + public const string Revision = "$WCREV$"; + } +} diff -r 000000000000 -r f990fcb411a9 Source/Templates/MSSQL.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/MSSQL.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,424 @@ +<# + ConnectionType = typeof(System.Data.SqlClient.SqlConnection).AssemblyQualifiedName; +#><#+ +private void LoadServerMetadata() +{ + var tables = CreateList(new { ID = "", Table = new Table() }); + var columns = CreateList(new { ID = "", Column = new Column() }); + + using (var conn = GetConnection()) + using (var cmd = conn.CreateCommand()) + { + // Load tables & views. + // + string s = @" + SELECT + TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME AS TABLE_FULLNAME, + TABLE_SCHEMA, + TABLE_NAME, + TABLE_TYPE, + ISNULL(CONVERT(varchar(8000), x.Value), '') AS TABLE_DESC + FROM + INFORMATION_SCHEMA.TABLES s + LEFT JOIN + sys.tables t + ON + OBJECT_ID(TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME) = t.object_id + LEFT JOIN + sys.extended_properties x + ON + OBJECT_ID(TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME) = x.major_id AND + x.minor_id = 0 AND + x.name = 'MS_Description' + WHERE {0} + ( + t.object_id IS NULL OR + t.is_ms_shipped <> 1 AND + ( + SELECT + major_id + FROM + sys.extended_properties + WHERE + major_id = t.object_id and + minor_id = 0 and + class = 1 and + name = N'microsoft_database_tools_support' + ) IS NULL + )"; + + if (string.IsNullOrWhiteSpace(OwnerToInclude)) + cmd.CommandText = string.Format(s, ""); + else + cmd.CommandText = string.Format(s, " TABLE_SCHEMA = '" + OwnerToInclude + "' AND "); + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var t = new + { + ID = Convert.ToString(rd[0]), + Table = new Table + { + Owner = rd[1].ToString(), + TableName = rd[2].ToString(), + ClassName = rd[2].ToString(), + IsView = rd[3].ToString() == "VIEW", + BaseClassName = BaseEntityClass, + Description = Convert.ToString(rd[4]), + } + }; + + tables.Add(t); + } + } + + // Load columns. + // + s = @" + SELECT + (TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME) as id, + (CASE WHEN IS_NULLABLE = 'YES' THEN 1 ELSE 0 END) as isNullable, + ORDINAL_POSITION as colid, + COLUMN_NAME as name, + c.DATA_TYPE as dataType, + CHARACTER_MAXIMUM_LENGTH as length, + ISNULL(NUMERIC_PRECISION, DATETIME_PRECISION) AS prec, + NUMERIC_SCALE as scale, + COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') as isIdentity, + ISNULL(CONVERT(varchar(8000), x.Value), '') AS COLUMN_DESC + FROM + INFORMATION_SCHEMA.COLUMNS c + LEFT JOIN + sys.extended_properties x + ON + OBJECT_ID(TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME) = x.major_id AND + ORDINAL_POSITION = x.minor_id AND + x.name = 'MS_Description' + {0}"; + + if(string.IsNullOrWhiteSpace(OwnerToInclude)) + cmd.CommandText = string.Format(s, ""); + else + cmd.CommandText = string.Format(s, "WHERE TABLE_SCHEMA = '" + OwnerToInclude + "' "); + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var col = new + { + ID = Convert.ToString(rd["id"]), + Column = new Column + { + ID = Convert.ToInt16 (rd["colid"]), + ColumnName = Convert.ToString (rd["name"]), + MemberName = Convert.ToString (rd["name"]), + ColumnType = Convert.ToString (rd["dataType"]), + IsNullable = Convert.ToBoolean(rd["isNullable"]), + IsIdentity = Convert.ToBoolean(rd["isIdentity"]), + Length = rd.IsDBNull(rd.GetOrdinal("length")) ? 0 : Convert.ToInt64(rd["length"]), + Precision = rd.IsDBNull(rd.GetOrdinal("prec")) ? 0 : Convert.ToInt32(rd["prec"]), + Scale = rd.IsDBNull(rd.GetOrdinal("scale")) ? 0 : Convert.ToInt32(rd["scale"]), + Description = Convert.ToString(rd["COLUMN_DESC"]), + } + }; + + var c = col.Column; + + switch (c.ColumnType) + { + case "image" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Image; break; + case "text" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.Text; break; + case "binary" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Binary; break; + case "tinyint" : c.Type = "byte"; c.DbType = DbType.Byte; c.SqlDbType = SqlDbType.TinyInt; break; + case "date" : c.Type = "DateTime"; c.DbType = DbType.Date; c.SqlDbType = SqlDbType.Date; break; + case "time" : c.Type = "DateTime"; c.DbType = DbType.Time; c.SqlDbType = SqlDbType.Time; break; + case "bit" : c.Type = "bool"; c.DbType = DbType.Boolean; c.SqlDbType = SqlDbType.Bit; break; + case "smallint" : c.Type = "short"; c.DbType = DbType.Int16; c.SqlDbType = SqlDbType.SmallInt; break; + case "decimal" : c.Type = "decimal"; c.DbType = DbType.Decimal; c.SqlDbType = SqlDbType.Decimal; break; + case "int" : c.Type = "int"; c.DbType = DbType.Int32; c.SqlDbType = SqlDbType.Int; break; + case "smalldatetime" : c.Type = "DateTime"; c.DbType = DbType.DateTime; c.SqlDbType = SqlDbType.SmallDateTime; break; + case "real" : c.Type = "float"; c.DbType = DbType.Single; c.SqlDbType = SqlDbType.Real; break; + case "money" : c.Type = "decimal"; c.DbType = DbType.Currency; c.SqlDbType = SqlDbType.Money; break; + case "datetime" : c.Type = "DateTime"; c.DbType = DbType.DateTime; c.SqlDbType = SqlDbType.DateTime; break; + case "float" : c.Type = "double"; c.DbType = DbType.Double; c.SqlDbType = SqlDbType.Float; break; + case "numeric" : c.Type = "decimal"; c.DbType = DbType.Decimal; c.SqlDbType = SqlDbType.Decimal; break; + case "smallmoney" : c.Type = "decimal"; c.DbType = DbType.Currency; c.SqlDbType = SqlDbType.SmallMoney; break; + case "datetime2" : c.Type = "DateTime"; c.DbType = DbType.DateTime2; c.SqlDbType = SqlDbType.DateTime2; break; + case "bigint" : c.Type = "long"; c.DbType = DbType.Int64; c.SqlDbType = SqlDbType.BigInt; break; + case "varbinary" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.VarBinary; break; + case "timestamp" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Timestamp; break; + case "sysname" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.NVarChar; break; + case "nvarchar" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.NVarChar; break; + case "varchar" : c.Type = "string"; c.DbType = DbType.AnsiString; c.SqlDbType = SqlDbType.VarChar; break; + case "ntext" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.NText; break; + case "uniqueidentifier" : c.Type = "Guid"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.UniqueIdentifier; break; + case "datetimeoffset" : c.Type = "DateTimeOffset"; c.DbType = DbType.DateTimeOffset; c.SqlDbType = SqlDbType.DateTimeOffset; break; + case "sql_variant" : c.Type = "object"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Variant; break; + case "xml" : c.Type = "string"; c.DbType = DbType.Xml; c.SqlDbType = SqlDbType.Xml; break; + + case "char" : + c.Type = Convert.ToInt32 (rd["length"]) == 1 ? "char" : "string"; + c.DbType = DbType.AnsiStringFixedLength; + c.SqlDbType = SqlDbType.Char; + break; + + case "nchar" : + c.Type = Convert.ToInt32 (rd["length"]) == 1 ? "char" : "string"; + c.DbType = DbType.StringFixedLength; + c.SqlDbType = SqlDbType.NChar; + break; + + //hierarchyid + //geometry + //geography + default : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Binary; break; + } + + switch (c.Type) + { + case "string" : + case "object" : + case "byte[]" : c.IsClass = true; break; + } + + if (c.IsNullable && !c.IsClass) + c.Type += "?"; + + columns.Add(col); + } + } + + // Load PKs. + // + s = @" + SELECT + (k.TABLE_CATALOG + '.' + k.TABLE_SCHEMA + '.' + k.TABLE_NAME) as id, + k.CONSTRAINT_NAME as name, + k.COLUMN_NAME as colname, + k.ORDINAL_POSITION as colid + FROM + INFORMATION_SCHEMA.KEY_COLUMN_USAGE k + JOIN + INFORMATION_SCHEMA.TABLE_CONSTRAINTS c + ON + k.CONSTRAINT_CATALOG = c.CONSTRAINT_CATALOG AND + k.CONSTRAINT_SCHEMA = c.CONSTRAINT_SCHEMA AND + k.CONSTRAINT_NAME = c.CONSTRAINT_NAME + WHERE + c.CONSTRAINT_TYPE='PRIMARY KEY' + {0}"; + + if (string.IsNullOrWhiteSpace(OwnerToInclude)) + cmd.CommandText = string.Format(s, ""); + else + cmd.CommandText = string.Format(s, "AND k.TABLE_SCHEMA = '" + OwnerToInclude + "' "); + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var id = Convert.ToString(rd["id"]); + var colid = Convert.ToInt32 (rd["colid"]); + var colname = Convert.ToString(rd["colname"]); + + columns.Single(_ => _.ID == id && _.Column.ColumnName == colname).Column.PKIndex = colid; + } + } + + // Load FKs. + // + s = @" + SELECT + rc.CONSTRAINT_NAME as Name, + fk.TABLE_CATALOG + '.' + fk.TABLE_SCHEMA + '.' + fk.TABLE_NAME as ThisTable, + fk.COLUMN_NAME as ThisColumn, + pk.TABLE_CATALOG + '.' + pk.TABLE_SCHEMA + '.' + pk.TABLE_NAME as OtherTable, + pk.COLUMN_NAME as OtherColumn, + cu.ORDINAL_POSITION as Ordinal + FROM + INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc + JOIN + INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE fk + ON + rc.CONSTRAINT_CATALOG = fk.CONSTRAINT_CATALOG AND + rc.CONSTRAINT_SCHEMA = fk.CONSTRAINT_SCHEMA AND + rc.CONSTRAINT_NAME = fk.CONSTRAINT_NAME + JOIN + INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE pk + ON + rc.UNIQUE_CONSTRAINT_CATALOG = pk.CONSTRAINT_CATALOG AND + rc.UNIQUE_CONSTRAINT_SCHEMA = pk.CONSTRAINT_SCHEMA AND + rc.UNIQUE_CONSTRAINT_NAME = pk.CONSTRAINT_NAME + JOIN + INFORMATION_SCHEMA.KEY_COLUMN_USAGE cu + ON + rc.CONSTRAINT_CATALOG = cu.CONSTRAINT_CATALOG AND + rc.CONSTRAINT_SCHEMA = cu.CONSTRAINT_SCHEMA AND + rc.CONSTRAINT_NAME = cu.CONSTRAINT_NAME + {0} + ORDER BY + ThisTable, + Ordinal"; + + if (string.IsNullOrWhiteSpace(OwnerToInclude)) + cmd.CommandText = string.Format(s, ""); + else + cmd.CommandText = string.Format(s, "WHERE fk.TABLE_SCHEMA = '" + OwnerToInclude + "' "); + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var name = Convert.ToString(rd["Name"]); + var thisTableID = Convert.ToString(rd["ThisTable"]); + var otherTableID = Convert.ToString(rd["OtherTable"]); + var thisColumnName = Convert.ToString(rd["ThisColumn"]); + var otherColumnName = Convert.ToString(rd["OtherColumn"]); + + var thisTable = (from t in tables where t.ID == thisTableID select t.Table).Single(); + var otherTable = (from t in tables where t.ID == otherTableID select t.Table).Single(); + var thisColumn = (from c in columns where c.ID == thisTableID && c.Column.ColumnName == thisColumnName select c.Column).Single(); + var otherColumn = (from c in columns where c.ID == otherTableID && c.Column.ColumnName == otherColumnName select c.Column).Single(); + + if (thisTable.ForeignKeys.ContainsKey(name) == false) + thisTable.ForeignKeys.Add(name, new ForeignKey { KeyName = name, MemberName = name, OtherTable = otherTable }); + + var key = thisTable.ForeignKeys[name]; + + key.ThisColumns. Add(thisColumn); + key.OtherColumns.Add(otherColumn); + } + } + } + + var qc = + from c in columns + group c by c.ID into gr + join t in tables on gr.Key equals t.ID + select new { t.Table, gr }; + + foreach (var c in qc) + { + foreach (var col in from col in c.gr orderby col.Column.ID select col.Column) + c.Table.Columns.Add(col.ColumnName, col); + + if (c.Table.Owner == "dbo") + { + c.Table.Owner = null; + Tables.Add(c.Table.TableName, c.Table); + } + else + { + Tables.Add(c.Table.Owner + "." + c.Table.TableName, c.Table); + } + } + + { + Usings.Add("System.Collections.Generic"); + Usings.Add("System.Linq"); + Usings.Add("System.Linq.Expressions"); + Usings.Add("System.Reflection"); + Usings.Add("System.Text"); + Usings.Add("BLToolkit.Data.DataProvider"); + Usings.Add("BLToolkit.Data.Sql"); + Usings.Add("BLToolkit.Data.Sql.SqlProvider"); + + var mssqlAfterWriteTableProperty = AfterWriteTableProperty; + + AfterWriteTableProperty = tt => + { + mssqlAfterWriteTableProperty(tt); + + tt.WriteLine(@" +#region FreeTextTable + +public class FreeTextKey +{ + public T Key; + public int Rank; +} + +class FreeTextTableExpressionAttribute : TableExpressionAttribute +{ + public FreeTextTableExpressionAttribute() + : base("""") + { + } + + public override void SetTable(SqlTable table, MemberInfo member, IEnumerable expArgs, IEnumerable sqlArgs) + { + var aargs = sqlArgs.ToArray(); + var arr = ConvertArgs(member, aargs).ToList(); + var method = (MethodInfo)member; + var sp = new MsSql2008SqlProvider(); + + { + var ttype = method.GetGenericArguments()[0]; + var tbl = new SqlTable(ttype); + + var database = tbl.Database == null ? null : sp.Convert(tbl.Database, ConvertType.NameToDatabase). ToString(); + var owner = tbl.Owner == null ? null : sp.Convert(tbl.Owner, ConvertType.NameToOwner). ToString(); + var physicalName = tbl.PhysicalName == null ? null : sp.Convert(tbl.PhysicalName, ConvertType.NameToQueryTable).ToString(); + + var name = sp.BuildTableName(new StringBuilder(), database, owner, physicalName); + + arr.Add(new SqlExpression(name.ToString(), Precedence.Primary)); + } + + { + var field = ((ConstantExpression)expArgs.First()).Value; + + if (field is string) + { + arr[0] = new SqlExpression(field.ToString(), Precedence.Primary); + } + else if (field is LambdaExpression) + { + var body = ((LambdaExpression)field).Body; + + if (body is MemberExpression) + { + var name = ((MemberExpression)body).Member.Name; + + name = sp.Convert(name, ConvertType.NameToQueryField).ToString(); + + arr[0] = new SqlExpression(name, Precedence.Primary); + } + } + } + + table.SqlTableType = SqlTableType.Expression; + table.Name = ""FREETEXTTABLE({6}, {2}, {3}) {1}""; + table.TableArguments = arr.ToArray(); + } +} + +[FreeTextTableExpressionAttribute] +public Table> FreeTextTable(string field, string text) +{ + return this.GetTable>( + this, + ((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)), + field, + text); +} + +[FreeTextTableExpressionAttribute] +public Table> FreeTextTable(Expression> fieldSelector, string text) +{ + return this.GetTable>( + this, + ((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)), + fieldSelector, + text); +} + +#endregion"); + + }; + } +} +#> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Templates/MySql.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/MySql.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,307 @@ +<# + ConnectionType = "MySql.Data.MySqlClient.MySqlConnection, MySql.Data"; +#><#+ + +private void LoadServerMetadata() +{ + var tables = CreateList(new { ID = "", Table = new Table() }); + var columns = CreateList(new { ID = "", Column = new Column() }); + + using (var conn = GetConnection()) + using (var cmd = conn.CreateCommand()) + { + string schemasToSkip = "'information_schema', 'cr_debug', 'mysql'"; + + // Load tables & views. + // + + cmd.CommandText = "SELECT DATABASE()"; + _databaseName = Convert.ToString(cmd.ExecuteScalar()); + + cmd.CommandText = string.Format(@" + SELECT + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME), + TABLE_SCHEMA, + TABLE_NAME, + TABLE_TYPE + FROM + INFORMATION_SCHEMA.tables + WHERE + TABLE_SCHEMA NOT IN ({0}) AND + TABLE_TYPE IN ('BASE TABLE', 'VIEW') + {1}", + schemasToSkip, + GetDatabaseSqlFilter("")); + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var t = new + { + ID = Convert.ToString(rd[0]), + Table = new Table + { + Owner = null, // there is no concept of table owner in MySql + TableName = rd[2].ToString(), + ClassName = rd[2].ToString(), + DataContextPropertyName = rd[2].ToString(), + IsView = rd[3].ToString() == "VIEW", + BaseClassName = BaseEntityClass, + } + }; + + tables.Add(t); + } + } + + cmd.CommandText = "SELECT @@session.sql_mode"; + string sqlMode = Convert.ToString(cmd.ExecuteScalar()); + + // Load columns. + // + cmd.CommandText = string.Format(@" + SELECT + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) as id, + CASE WHEN IS_NULLABLE = 'YES' THEN 1 ELSE 0 END as isNullable, + ORDINAL_POSITION as colid, + COLUMN_NAME as name, + c.DATA_TYPE as dataType, + CHARACTER_MAXIMUM_LENGTH as length, + NUMERIC_PRECISION as prec, + NUMERIC_SCALE as scale, + EXTRA = 'auto_increment' as isIdentity, + c.COLUMN_TYPE as columnType, + COLUMN_DEFAULT as columnDefault, + EXTRA as extra + FROM + INFORMATION_SCHEMA.COLUMNS c + WHERE + TABLE_SCHEMA NOT IN ({0}) + {1}", + schemasToSkip, + GetDatabaseSqlFilter("")); + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var col = new + { + ID = Convert.ToString(rd["id"]), + Column = new Column + { + ID = Convert.ToInt16 (rd["colid"]), + ColumnName = Convert.ToString (rd["name"]), + MemberName = Convert.ToString (rd["name"]), + ColumnType = Convert.ToString (rd["dataType"]), + IsNullable = Convert.ToBoolean(rd["isNullable"]), + IsIdentity = Convert.ToBoolean(rd["isIdentity"]), + Length = rd.IsDBNull(rd.GetOrdinal("length")) ? 0 : Convert.ToInt64(rd["length"]), + Precision = rd.IsDBNull(rd.GetOrdinal("prec")) ? 0 : Convert.ToInt32(rd["prec"]), + Scale = rd.IsDBNull(rd.GetOrdinal("scale")) ? 0 : Convert.ToInt32(rd["scale"]), + ColumnDefault = Convert.ToString(rd["columnDefault"]), + Extra = Convert.ToString(rd["extra"]).ToUpper() + } + }; + + var c = col.Column; + var columnType = Convert.ToString(rd["columnType"]).ToLower(); + var unsigned = columnType.Contains("unsigned"); + var realAsFloat = sqlMode.ToLower().Contains("real_as_float"); + + switch (c.ColumnType) + { + case "longtext" : + case "mediumtext" : + case "tinytext" : + case "text" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.Text; break; + case "binary" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Binary; break; + case "date" : c.Type = "DateTime"; c.DbType = DbType.Date; c.SqlDbType = SqlDbType.Date; break; + case "time" : c.Type = "DateTime"; c.DbType = DbType.Time; c.SqlDbType = SqlDbType.Time; break; + case "bit" : c.Type = "bool"; c.DbType = DbType.Boolean; c.SqlDbType = SqlDbType.Bit; break; + case "numeric" : + case "decimal" : + case "dec" : + case "fixed" : c.Type = "decimal"; c.DbType = DbType.Decimal; c.SqlDbType = SqlDbType.Decimal; break; + case "datetime" : c.Type = "DateTime"; c.DbType = DbType.DateTime; c.SqlDbType = SqlDbType.DateTime; break; + case "float" : c.Type = "float"; c.DbType = DbType.Single; c.SqlDbType = SqlDbType.Float; break; + case "double" : c.Type = "double"; c.DbType = DbType.Double; c.SqlDbType = SqlDbType.Float; break; + case "varbinary" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.VarBinary; break; + case "varchar" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.VarChar; break; + case "year" : c.Type = "DateTime"; c.DbType = DbType.Date; c.SqlDbType = SqlDbType.Date; break; + case "enum" : + case "set" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.VarChar; break; + case "bool" : + case "boolean" : c.Type = "bool"; c.DbType = DbType.Boolean; c.SqlDbType = SqlDbType.Bit; break; + case "serial" : c.Type = "ulong"; c.DbType = DbType.UInt64; c.SqlDbType = SqlDbType.BigInt; break; + case "mediumblob" : + case "longblob" : + case "blob" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Image; break; + case "tinyblob" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Binary; break; + + case "smallint" : c.Type = unsigned ? "ushort" : "short"; c.DbType = unsigned ? DbType.UInt16 : DbType.Int16; c.SqlDbType = SqlDbType.SmallInt; break; + case "mediumint" : + case "int" : + case "integer" : c.Type = unsigned ? "uint" : "int"; c.DbType = unsigned ? DbType.UInt32 : DbType.Int32; c.SqlDbType = SqlDbType.Int; break; + case "real" : c.Type = realAsFloat ? "float" : "double"; c.DbType = realAsFloat ? DbType.Single : DbType.Double; c.SqlDbType = SqlDbType.Real; break; + case "bigint" : c.Type = unsigned ? "ulong" : "long"; c.DbType = unsigned ? DbType.UInt64 : DbType.Int64; c.SqlDbType = SqlDbType.BigInt; break; + case "char" : c.Type = "string"; c.DbType = DbType.StringFixedLength; c.SqlDbType = SqlDbType.Char; break; + case "timestamp" : + c.Type = "DateTime"; + c.DbType = DbType.DateTime; + c.SqlDbType = SqlDbType.Timestamp; + + if(c.ColumnDefault == "CURRENT_TIMESTAMP" || c.Extra.Contains("ON UPDATE CURRENT_TIMESTAMP")) + { + c.Attributes.Add(string.Format( + "NonUpdatable(OnInsert = {0}, OnUpdate = {1})", + c.ColumnDefault == "CURRENT_TIMESTAMP" ? "true" : "false", + c.Extra.Contains("ON UPDATE CURRENT_TIMESTAMP") ? "true" : "false")); + } + break; + case "tinyint" : + if(columnType == "tinyint(1)") + { + c.Type = "bool"; + c.DbType = DbType.Boolean; + c.SqlDbType = SqlDbType.Bit; + } + else + { + c.Type = unsigned ? "byte" : "sbyte"; + c.DbType = unsigned ? DbType.Byte : DbType.SByte; + c.SqlDbType = SqlDbType.TinyInt; + } + break; + default : + throw new System.IO.InvalidDataException(string.Format("Unknown column type: {0}.", c.ColumnType)); + } + + switch (c.Type) + { + case "string" : + case "byte[]" : c.IsClass = true; break; + } + + if (c.IsNullable && !c.IsClass) + c.Type += "?"; + + columns.Add(col); + } + } + + // Load PKs. + // + cmd.CommandText = string.Format(@" + SELECT + CONCAT(k.TABLE_SCHEMA, '.', k.TABLE_NAME) as id, + k.CONSTRAINT_NAME as name, + k.COLUMN_NAME as colname, + k.ORDINAL_POSITION as colid + FROM + INFORMATION_SCHEMA.KEY_COLUMN_USAGE k + JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS c ON k.CONSTRAINT_NAME = c.CONSTRAINT_NAME + WHERE + c.CONSTRAINT_TYPE='PRIMARY KEY' AND + k.TABLE_SCHEMA NOT IN ({0}) + {1} + GROUP BY id, colid", + schemasToSkip, + GetDatabaseSqlFilter("k")); + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var id = Convert.ToString(rd["id"]); + var colid = Convert.ToInt32 (rd["colid"]); + var colname = Convert.ToString(rd["colname"]); + + columns.Single(_ => _.ID == id && _.Column.ColumnName == colname).Column.PKIndex = colid; + } + } + + // Load FKs. + // + cmd.CommandText = string.Format(@" + SELECT + CONSTRAINT_NAME as Name, + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) as ThisTable, + COLUMN_NAME as ThisColumn, + CONCAT(REFERENCED_TABLE_SCHEMA, '.', REFERENCED_TABLE_NAME) as OtherTable, + REFERENCED_COLUMN_NAME as OtherColumn, + ORDINAL_POSITION as Ordinal + FROM + INFORMATION_SCHEMA.key_column_usage + WHERE + TABLE_SCHEMA NOT IN ({0}) AND + REFERENCED_TABLE_NAME IS NOT NULL AND + REFERENCED_COLUMN_NAME IS NOT NULL + {1} + ORDER BY + ThisTable, + Ordinal", + schemasToSkip, + GetDatabaseSqlFilter("")); + + if(!string.IsNullOrEmpty(DatabaseName)) + cmd.CommandText += string.Format(" AND TABLE_SCHEMA = '{0}' ", DatabaseName); + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var name = Convert.ToString(rd["Name"]); + var thisTableID = Convert.ToString(rd["ThisTable"]); + var otherTableID = Convert.ToString(rd["OtherTable"]); + var thisColumnName = Convert.ToString(rd["ThisColumn"]); + var otherColumnName = Convert.ToString(rd["OtherColumn"]); + + var thisTable = (from t in tables where t.ID == thisTableID select t.Table).Single(); + var otherTable = (from t in tables where t.ID == otherTableID select t.Table).Single(); + var thisColumn = (from c in columns where c.ID == thisTableID && c.Column.ColumnName == thisColumnName select c.Column).Single(); + var otherColumn = (from c in columns where c.ID == otherTableID && c.Column.ColumnName == otherColumnName select c.Column).Single(); + + if (thisTable.ForeignKeys.ContainsKey(name) == false) + thisTable.ForeignKeys.Add(name, new ForeignKey { KeyName = name, MemberName = name, OtherTable = otherTable }); + + var key = thisTable.ForeignKeys[name]; + + key.ThisColumns. Add(thisColumn); + key.OtherColumns.Add(otherColumn); + } + } + } + + var qc = + from c in columns + group c by c.ID into gr + join t in tables on gr.Key equals t.ID + select new { t.Table, gr }; + + foreach (var c in qc) + { + foreach (var col in from col in c.gr orderby col.Column.ID select col.Column) + c.Table.Columns.Add(col.ColumnName, col); + + // there is no concept of table owner in MySql so we just use table name + Tables.Add(c.Table.TableName, c.Table); + } +} + +private string _databaseName; +private string GetDatabaseSqlFilter(string optionalTablePrefix) +{ + if(string.IsNullOrEmpty(_databaseName)) return ""; + string tablePrefix = string.IsNullOrEmpty(optionalTablePrefix) ? "" : optionalTablePrefix + "."; + return string.Format(" AND {0}TABLE_SCHEMA = '{1}' ", tablePrefix, _databaseName); +} + +public partial class Column +{ + public string ColumnDefault; + public string Extra; +} + +#> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Templates/PluralSingular.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/PluralSingular.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,556 @@ +<#@ import namespace="System" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Text.RegularExpressions" #> +<# + { + var psPrevAfterLoadMetadata = AfterLoadMetadata; + + AfterLoadMetadata = _ => + { + psPrevAfterLoadMetadata(_); + + if (PluralizeDataContextPropertyNames || SingularizeDataContextPropertyNames) + { + foreach (var t in Tables.Values) + { + var propName = t.DataContextPropertyName ?? t.ClassName ?? t.TableName; + var newName = PluralizeDataContextPropertyNames ? ToPlural(propName) : ToSingular(propName); + + t.DataContextPropertyName = newName; + } + } + + if (PluralizeClassNames || SingularizeClassNames) + { + foreach (var t in Tables.Values) + { + var className = t.ClassName ?? t.TableName; + var newName = PluralizeClassNames ? ToPlural(className) : ToSingular(className); + + t.ClassName = newName; + } + } + }; + + PluralizeAssociationName = ToPlural; + SingularizeAssociationName = ToSingular; + } + +#><#+ + +bool PluralizeClassNames = false; +bool SingularizeClassNames = true; +bool PluralizeDataContextPropertyNames = true; +bool SingularizeDataContextPropertyNames = false; + +string ToPlural(string str) +{ + var word = GetLastWord(str); + var newWord = Plurals.ToPlural(word); + + if (word != newWord) + { + if (char.IsUpper(word[0])) + newWord = char.ToUpper(newWord[0]) + newWord.Substring(1, newWord.Length - 1); + + return word == str ? newWord : str.Substring(0, str.Length - word.Length) + newWord; + } + + return str; +} + +string ToSingular(string str) +{ + var word = GetLastWord(str); + var newWord = Plurals.ToSingular(word); + + if (word != newWord) + { + if (char.IsUpper(word[0])) + newWord = char.ToUpper(newWord[0]) + newWord.Substring(1, newWord.Length - 1); + + return word == str ? newWord : str.Substring(0, str.Length - word.Length) + newWord; + } + + return str; +} + +string GetLastWord(string word) +{ + if (string.IsNullOrEmpty(word)) + return word; + + var len = word.Length; + var n = len - 1; + + if (char.IsLower(word[n])) + { + for (; n > 0 && char.IsLower(word[n]); n--); + } + else + { + for (; n > 0 && char.IsUpper(word[n]); n--); + if (char.IsLower(word[n])) + n++; + } + + return n > 0 ? word.Substring(n) : word; +} + +// Shamelessly jacked from http://www.bennysutton.com/C-sharp/Plural-Singular-Words.aspx with little modifications. +// + +//using System; +//using System.Collections.Generic; +//using System.Text; +//using System.Text.RegularExpressions; + +/// +/// Convert words to and from singulars/plurals +/// Copyright www.BennySutton.com 2008 +/// You may reuse this code BUT not for sale AND ONLY with credit to www.BennySutton.com +/// +public sealed class Plurals +{ + /// + /// Store irregular plurals in a dictionary + /// + private static Dictionary _dictionary = new Dictionary(); + + #region Constructors + + /// + /// The singleton instance (thanks to dotnetpearls.com for help here) + /// + static readonly Plurals _instance = new Plurals(); + /// + /// Get an instance of the structure singleton. This effectively caches the dictionary + /// + public static Plurals Instance + { + get + { + // Fastest solution that avoids null check and is thread-safe + // because of readonly keyword. + return _instance; + } + } + + /// + /// Run initialization on this singleton class + /// + private Plurals() + { + Initialize(); + } + + private void Initialize() + { + //to test that this class only initializes once uncomment next line + //System.Web.HttpContext.Current.Response.Write("initializing singleton
"); + // irregular plurals + _dictionary.Add("access", "accesses"); + _dictionary.Add("afterlife", "afterlives"); + _dictionary.Add("alga", "algae"); + _dictionary.Add("alumna", "alumnae"); + _dictionary.Add("alumnus", "alumni"); + _dictionary.Add("analysis", "analyses"); + _dictionary.Add("antenna", "antennae"); + _dictionary.Add("appendix", "appendices"); + _dictionary.Add("axis", "axes"); + _dictionary.Add("bacillus", "bacilli"); + _dictionary.Add("basis", "bases"); + _dictionary.Add("Bedouin", "Bedouin"); + _dictionary.Add("cactus", "cacti"); + _dictionary.Add("calf", "calves"); + _dictionary.Add("cherub", "cherubim"); + _dictionary.Add("child", "children"); + _dictionary.Add("cod", "cod"); + _dictionary.Add("cookie", "cookies"); + _dictionary.Add("criterion", "criteria"); + _dictionary.Add("curriculum", "curricula"); + _dictionary.Add("data", "data"); + _dictionary.Add("deer", "deer"); + _dictionary.Add("diagnosis", "diagnoses"); + _dictionary.Add("die", "dice"); + _dictionary.Add("dormouse", "dormice"); + _dictionary.Add("elf", "elves"); + _dictionary.Add("elk", "elk"); + _dictionary.Add("erratum", "errata"); + _dictionary.Add("esophagus", "esophagi"); + _dictionary.Add("fauna", "faunae"); + _dictionary.Add("fish", "fish"); + _dictionary.Add("flora", "florae"); + _dictionary.Add("focus", "foci"); + _dictionary.Add("foot", "feet"); + _dictionary.Add("formula", "formulae"); + _dictionary.Add("fundus", "fundi"); + _dictionary.Add("fungus", "fungi"); + _dictionary.Add("genie", "genii"); + _dictionary.Add("genus", "genera"); + _dictionary.Add("goose", "geese"); + _dictionary.Add("grouse", "grouse"); + _dictionary.Add("hake", "hake"); + _dictionary.Add("half", "halves"); + _dictionary.Add("headquarters", "headquarters"); + _dictionary.Add("hippo", "hippos"); + _dictionary.Add("hippopotamus", "hippopotami"); + _dictionary.Add("hoof", "hooves"); + _dictionary.Add("housewife", "housewives"); + _dictionary.Add("hypothesis", "hypotheses"); + _dictionary.Add("index", "indices"); + _dictionary.Add("jackknife", "jackknives"); + _dictionary.Add("knife", "knives"); + _dictionary.Add("labium", "labia"); + _dictionary.Add("larva", "larvae"); + _dictionary.Add("leaf", "leaves"); + _dictionary.Add("life", "lives"); + _dictionary.Add("loaf", "loaves"); + _dictionary.Add("louse", "lice"); + _dictionary.Add("magus", "magi"); + _dictionary.Add("man", "men"); + _dictionary.Add("memorandum", "memoranda"); + _dictionary.Add("midwife", "midwives"); + _dictionary.Add("millennium", "millennia"); + _dictionary.Add("moose", "moose"); + _dictionary.Add("mouse", "mice"); + _dictionary.Add("nebula", "nebulae"); + _dictionary.Add("neurosis", "neuroses"); + _dictionary.Add("nova", "novas"); + _dictionary.Add("nucleus", "nuclei"); + _dictionary.Add("oesophagus", "oesophagi"); + _dictionary.Add("offspring", "offspring"); + _dictionary.Add("ovum", "ova"); + _dictionary.Add("ox", "oxen"); + _dictionary.Add("papyrus", "papyri"); + _dictionary.Add("passerby", "passersby"); + _dictionary.Add("penknife", "penknives"); + _dictionary.Add("person", "people"); + _dictionary.Add("phenomenon", "phenomena"); + _dictionary.Add("placenta", "placentae"); + _dictionary.Add("pocketknife", "pocketknives"); + _dictionary.Add("process", "processes"); + _dictionary.Add("pupa", "pupae"); + _dictionary.Add("radius", "radii"); + _dictionary.Add("reindeer", "reindeer"); + _dictionary.Add("retina", "retinae"); + _dictionary.Add("rhinoceros", "rhinoceros"); + _dictionary.Add("roe", "roe"); + _dictionary.Add("salmon", "salmon"); + _dictionary.Add("scarf", "scarves"); + _dictionary.Add("self", "selves"); + _dictionary.Add("seraph", "seraphim"); + _dictionary.Add("series", "series"); + _dictionary.Add("sheaf", "sheaves"); + _dictionary.Add("sheep", "sheep"); + _dictionary.Add("shelf", "shelves"); + _dictionary.Add("species", "species"); + _dictionary.Add("spectrum", "spectra"); + _dictionary.Add("status", "status"); + _dictionary.Add("stimulus", "stimuli"); + _dictionary.Add("stratum", "strata"); + _dictionary.Add("supernova", "supernovas"); + _dictionary.Add("swine", "swine"); + _dictionary.Add("terminus", "termini"); + _dictionary.Add("thesaurus", "thesauri"); + _dictionary.Add("thesis", "theses"); + _dictionary.Add("thief", "thieves"); + _dictionary.Add("trout", "trout"); + _dictionary.Add("vulva", "vulvae"); + _dictionary.Add("wife", "wives"); + _dictionary.Add("wildebeest", "wildebeest"); + _dictionary.Add("wolf", "wolves"); + _dictionary.Add("woman", "women"); + _dictionary.Add("yen", "yen"); + } + + #endregion //Constructors + + #region Methods + + /// + /// Call this method to get the properly pluralized + /// English version of the word. + /// + /// The word needing conditional pluralization. + /// The number of items the word refers to. + /// The pluralized word + static public string ToPlural(string word) + { + word = word.ToLower(); + + if (_dictionary.ContainsKey(word)) + //it's an irregular plural, use the word from the dictionary + { + return _dictionary[word]; + } + + if (TestIsPlural(word) == true) + { + return word; //it's already a plural + } + + if (word.Length <= 2) + { + return word; //not a word that can be pluralised! + } + + ////1. If the word ends in a consonant plus -y, change the -y into + ///-ie and add an -s to form the plural + ///e.g. enemy--enemies baby--babies + switch (word.Substring(word.Length - 2)) + { + case "by": + case "cy": + case "dy": + case "fy": + case "gy": + case "hy": + case "jy": + case "ky": + case "ly": + case "my": + case "ny": + case "py": + case "ry": + case "sy": + case "ty": + case "vy": + case "wy": + case "xy": + case "zy": + { + return word.Substring(0, word.Length - 1) + "ies"; + } + + //2. For words that end in -is, change the -is to -es to make the plural form. + //synopsis--synopses + //thesis--theses + case "is": + { + return word.Substring(0, word.Length - 1) + "es"; + } + + //3. For words that end in a "hissing" sound (s,z,x,ch,sh), add an -es to form the plural. + //box--boxes + //church--churches + case "ch": + case "sh": + { + return word + "es"; + } + default: + { + switch (word.Substring(word.Length - 1)) + { + case "s": + case "z": + case "x": + { + return word + "es"; + } + default: + { + //4. Assume add an -s to form the plural of most words. + return word + "s"; + } + } + } + } + } + + /// + /// Call this method to get the singular + /// version of a plural English word. + /// + /// The word to turn into a singular + /// The singular word + static public string ToSingular(string word) + { + word = word.ToLower(); + + if (_dictionary.ContainsKey(word)) + return word; + + if (_dictionary.ContainsValue(word)) + { + foreach (KeyValuePair kvp in _dictionary) + { + if (kvp.Value == word) return kvp.Key; + } + } + + if (word.Substring(word.Length - 1) != "s") + { + return word; // not a plural word if it doesn't end in S + } + + if (word.Length <= 2) + { + return word; // not a word that can be made singular if only two letters! + } + + if (word.Length >= 4) + { + // 1. If the word ends in a consonant plus -y, change the -y into -ie and add an -s to form the plural – so reverse engineer it to get the singular + // e.g. enemy--enemies baby--babies family--families + switch (word.Substring(word.Length - 4)) + { + case "bies": + case "cies": + case "dies": + case "fies": + case "gies": + case "hies": + case "jies": + case "kies": + case "lies": + case "mies": + case "nies": + case "pies": + case "ries": + case "sies": + case "ties": + case "vies": + case "wies": + case "xies": + case "zies": + { + return word.Substring(0, word.Length - 3) + "y"; + } + //3. For words that end in a "hissing" sound (s,z,x,ch,sh), add an -es to form the plural. + //church--churches + case "ches": + case "shes": + { + return word.Substring(0, word.Length - 2); + } + } + } + + if (word.Length >= 3) + { + switch (word.Substring(word.Length - 3)) + { + //box--boxes + case "ses": + //NOTE some false positives here - For words that end in -is, change the -is to -es to make the plural form. + //synopsis--synopses + //thesis--theses + case "zes": + case "xes": + { + return word.Substring(0, word.Length - 2); + } + } + } + + if (word.Length >= 3) + { + switch (word.Substring(word.Length - 2)) + { + case "es": + { + return word.Substring(0, word.Length - 1); // + "is"; + } + //4. Assume add an -s to form the plural of most words. + default: + { + return word.Substring(0, word.Length - 1); + } + } + } + + return word; + } + + /// + /// test if a word is plural + /// + /// word to test + /// true if a word is plural + static public bool TestIsPlural(string word) + { + word = word.ToLower(); + + if (word.Length <= 2) + { + return false; // not a word that can be made singular if only two letters! + } + + if (_dictionary.ContainsValue(word)) + { + return true; //it's definitely already a plural + } + + if (word.Length >= 4) + { + //1. If the word ends in a consonant plus -y, change the -y into -ie and add an -s to form the plural + // e.g. enemy--enemies baby--babies family--families + switch (word.Substring(word.Length - 4)) + { + case "bies": + case "cies": + case "dies": + case "fies": + case "gies": + case "hies": + case "jies": + case "kies": + case "lies": + case "mies": + case "nies": + case "pies": + case "ries": + case "sies": + case "ties": + case "vies": + case "wies": + case "xies": + case "zies": + case "ches": + case "shes": + { + return true; + } + } + } + + if (word.Length >= 3) + { + switch (word.Substring(word.Length - 3)) + { + //box--boxes + case "ses": + case "zes": + case "xes": + { + return true; + } + } + } + + if (word.Length >= 3) + { + switch (word.Substring(word.Length - 2)) + { + case "es": + { + return true; + } + } + } + + if (word.Substring(word.Length - 1) != "s") + { + return false; // not a plural word if it doesn't end in S + } + + return true; + } + + #endregion +} + +#> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Templates/PostgreSQL.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/PostgreSQL.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,297 @@ +<# + ConnectionType = "Npgsql.NpgsqlConnection, Npgsql"; +#><#+ +private void LoadServerMetadata() +{ + var tables = CreateList(new { ID = 0, Table = new Table() }); + var columns = CreateList(new { ID = 0, Column = new Column() }); + + if (!string.IsNullOrEmpty(DataProviderAssembly)) + { + System.Reflection.Assembly.LoadFile(DataProviderAssembly.Replace("Npgsql.dll", "Mono.Security.dll")); + } + + using (var conn = GetConnection()) + using (var cmd = conn.CreateCommand()) + { + // Load tables & vies. + // + cmd.CommandText = @" + SELECT + pg_class.oid, + pg_namespace.nspname, + pg_class.relname, + pg_class.relkind + FROM + pg_class + INNER JOIN pg_user ON (pg_class.relowner = pg_user.usesysid) + INNER JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid) + WHERE + pg_class.relkind IN ('r','v') + AND pg_namespace.nspname NOT IN ('pg_catalog','information_schema')"; + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var t = new + { + ID = Convert.ToInt32(rd[0]), + Table = new Table + { + Owner = rd[1].ToString(), + TableName = rd[2].ToString(), + ClassName = rd[2].ToString(), + IsView = rd[3].ToString() == "v", + BaseClassName = BaseEntityClass, + } + }; + + tables.Add(t); + } + } + + // Load columns. + // + cmd.CommandText = @" + SELECT + pg_attribute.attrelid as id, + pg_attribute.attnum as colid, + pg_attribute.attname as name, + 0 as status, + 0 as usertype, + pg_attribute.atttypid as type, + COALESCE(CAST(substring(format_type(pg_attribute.atttypid, pg_attribute.atttypmod) from '[0-9]{1,}') as INTEGER),0) as lenght, + CASE WHEN pg_attribute.atttypid = 1700 AND format_type(pg_attribute.atttypid, pg_attribute.atttypmod) != 'numeric' THEN + COALESCE(CAST(regexp_replace(regexp_replace(format_type(pg_attribute.atttypid, pg_attribute.atttypmod),'[^,]*,',''),'[)]$','') as INTEGER),0) + ELSE + 0 + END as prec, + format_type(pg_attribute.atttypid, pg_attribute.atttypmod) as typename, + CASE WHEN CAST(pg_attribute.atttypid AS TEXT) IN ('17','25','1042','1043') THEN + false + ELSE + NOT pg_attribute.attnotnull + END as isnullable, + COALESCE(pg_attrdef.adsrc ~* 'nextval',FALSE) as isidentity + FROM + pg_attribute + LEFT JOIN pg_attrdef ON (pg_attribute.attrelid = pg_attrdef.adrelid AND + pg_attribute.attnum = pg_attrdef.adnum) + INNER JOIN pg_class ON (pg_attribute.attrelid = pg_class.oid) + INNER JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid) + WHERE + pg_class.relkind IN ('r','v') AND + pg_namespace.nspname NOT IN ('pg_catalog','information_schema') AND + pg_attribute.attnum > 0 AND + NOT pg_attribute.attisdropped"; + + bool addNpgsqlTypes = false; + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var col = new + { + ID = Convert.ToInt32(rd["id"]), + Column = new Column + { + ID = Convert.ToInt16(rd["colid"]), + ColumnName = Convert.ToString (rd["name"]), + MemberName = Convert.ToString (rd["name"]), + ColumnType = Convert.ToString (rd["typename"]), + IsNullable = Convert.ToBoolean(rd["isnullable"]), + IsIdentity = Convert.ToBoolean(rd["isidentity"]), + Length = rd.IsDBNull(rd.GetOrdinal("lenght")) ? 0 : Convert.ToInt64(rd["lenght"]), + Precision = rd.IsDBNull(rd.GetOrdinal("prec")) ? 0 : Convert.ToInt32(rd["prec"]), + //Scale = rd.IsDBNull(rd.GetOrdinal("scale")) ? 0 : Convert.ToInt32(rd["scale"]), + } + }; + + var c = col.Column; + var oid = Convert.ToInt32(rd["type"]); + + c.Type = "object"; + c.DbType = DbType.Object; + c.SqlDbType = SqlDbType.Variant; + + switch (oid) + { + case 16 /* bool */ : c.Type = "Boolean"; c.DbType = DbType.Boolean; c.SqlDbType = SqlDbType.Bit; break; + case 17 /* bytea */ : c.Type = "Byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Binary; break; + case 20 /* int8 */ : c.Type = "Int64"; c.DbType = DbType.Int64; c.SqlDbType = SqlDbType.BigInt; break; + case 21 /* int2 */ : c.Type = "Int16"; c.DbType = DbType.Int16; c.SqlDbType = SqlDbType.SmallInt; break; + case 23 /* int4 */ : c.Type = "Int32"; c.DbType = DbType.Int32; c.SqlDbType = SqlDbType.Int; break; + case 25 /* text */ : c.Type = "String"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.Text; break; + case 142 /* xml */ : c.Type = "String"; c.DbType = DbType.Xml; c.SqlDbType = SqlDbType.Xml; break; + case 600 /* point */ : c.Type = "NpgsqlPoint"; addNpgsqlTypes = true; break; + case 601 /* lseg */ : c.Type = "NpgsqlLSeg"; addNpgsqlTypes = true; break; + case 602 /* path */ : c.Type = "NpgsqlPath"; addNpgsqlTypes = true; break; + case 603 /* box */ : c.Type = "NpgsqlBox"; addNpgsqlTypes = true; break; + case 604 /* polygon */ : c.Type = "NpgsqlPolygon"; addNpgsqlTypes = true; break; + case 700 /* float4 */ : c.Type = "Single"; c.DbType = DbType.Single; c.SqlDbType = SqlDbType.Real; break; + case 701 /* float8 */ : c.Type = "Double"; c.DbType = DbType.Double; c.SqlDbType = SqlDbType.Float; break; + case 718 /* circle */ : c.Type = "NpgsqlCircle"; addNpgsqlTypes = true; break; + case 790 /* money */ : c.Type = "Decimal"; c.DbType = DbType.Decimal; c.SqlDbType = SqlDbType.Money; break; + case 829 /* macaddr */ : c.Type = "NpgsqlMacAddress"; addNpgsqlTypes = true; break; + case 869 /* inet */ : c.Type = "NpgsqlInet"; addNpgsqlTypes = true; break; + case 1042 /* char */ : c.Type = "String"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.Char; break; + case 1043 /* varchar */ : c.Type = "String"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.VarChar; break; + case 1082 /* date */ : c.Type = "DateTime"; c.DbType = DbType.Date; c.SqlDbType = SqlDbType.Date; break; + case 1083 /* time */ : c.Type = "DateTime"; c.DbType = DbType.Time; c.SqlDbType = SqlDbType.Time; break; + case 1114 /* datetime */ : c.Type = "DateTime"; c.DbType = DbType.DateTime; c.SqlDbType = SqlDbType.DateTime; break; + case 1560 /* bit */ : c.Type = "BitString"; addNpgsqlTypes = true; break; + case 1700 /* numeric */ : c.Type = "Decimal"; c.DbType = DbType.Decimal; c.SqlDbType = SqlDbType.Decimal; break; + case 1186 /* interval */ : c.Type = "NpgsqlInterval"; addNpgsqlTypes = true; break; + case 1184 /* timestamp with time zone */ : + case 1266 /* timestamp with time zone */ : c.Type = "DateTime"; c.DbType = DbType.DateTime2; c.SqlDbType = SqlDbType.DateTime2; break; + case 2950 /* Guid */ : c.Type = "Guid"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.UniqueIdentifier; break; + default: + if (oid < 100000) + throw new Exception(string.Format("Type '{0}' ({1}) is not expected in PostgreSQL.tt", rd["typename"], rd["type"])); + break; + } + + switch (c.Type) + { + case "object" : + case "String" : + case "byte[]" : c.IsClass = true; break; + } + + if (c.IsNullable && !c.IsClass) + c.Type += "?"; + + columns.Add(col); + } + } + + if (addNpgsqlTypes) + Usings.Add("NpgsqlTypes"); + + // Load PKs. + // + cmd.CommandText = @" + SELECT + pg_constraint.conrelid as id, + pg_constraint.conname as ""name"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[1]) as colname, + pg_constraint.conkey[1] as ""order"", + pg_constraint.conkey[1] as colid + FROM + pg_constraint + WHERE + pg_constraint.contype = 'p'"; + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var id = Convert.ToInt32(rd["id"]); + var colid = Convert.ToInt32(rd["colid"]); + + columns.Single(_ => _.ID == id && _.Column.ID == colid).Column.PKIndex = colid; + } + } + + // Load FKs. + // + cmd.CommandText = @" + SELECT + pg_constraint.conname as ""Name"", + pg_constraint.conrelid as ""ThisTable"", + pg_constraint.confrelid as ""OtherTable"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[01]) as ""ThisColumn1"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[02]) as ""ThisColumn2"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[03]) as ""ThisColumn3"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[04]) as ""ThisColumn4"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[05]) as ""ThisColumn5"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[06]) as ""ThisColumn6"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[07]) as ""ThisColumn7"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[08]) as ""ThisColumn8"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[09]) as ""ThisColumn9"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[10]) as ""ThisColumn10"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[11]) as ""ThisColumn11"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[12]) as ""ThisColumn12"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[13]) as ""ThisColumn13"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[14]) as ""ThisColumn14"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[15]) as ""ThisColumn15"", + (select attname from pg_attribute where attrelid = pg_constraint.conrelid and attnum = pg_constraint.conkey[16]) as ""ThisColumn16"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[01]) as ""OtherColumn1"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[02]) as ""OtherColumn2"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[03]) as ""OtherColumn3"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[04]) as ""OtherColumn4"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[05]) as ""OtherColumn5"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[06]) as ""OtherColumn6"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[07]) as ""OtherColumn7"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[08]) as ""OtherColumn8"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[09]) as ""OtherColumn9"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[10]) as ""OtherColumn10"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[11]) as ""OtherColumn11"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[12]) as ""OtherColumn12"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[13]) as ""OtherColumn13"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[14]) as ""OtherColumn14"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[15]) as ""OtherColumn15"", + (select attname from pg_attribute where attrelid = pg_constraint.confrelid and attnum = pg_constraint.confkey[16]) as ""OtherColumn16"" + FROM + pg_constraint + WHERE + pg_constraint.contype = 'f'"; + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var name = Convert.ToString(rd["Name"]); + var thisTableID = Convert.ToInt32 (rd["ThisTable"]); + var otherTableID = Convert.ToInt32 (rd["OtherTable"]); + + var thisTable = (from t in tables where t.ID == thisTableID select t.Table).Single(); + var otherTable = (from t in tables where t.ID == otherTableID select t.Table).Single(); + + thisTable.ForeignKeys.Add(name, new ForeignKey { KeyName = name, MemberName = name, OtherTable = otherTable }); + + for (int i = 1; i <= 16; i++) + { + if (rd.IsDBNull(rd.GetOrdinal("ThisColumn" + i))) + break; + + var thisColumnName = Convert.ToString(rd["ThisColumn" + i]); + var otherColumnName = Convert.ToString(rd["OtherColumn" + i]); + + var thisColumn = (from c in columns where c.ID == thisTableID && c.Column.ColumnName == thisColumnName select c.Column).Single(); + var otherColumn = (from c in columns where c.ID == otherTableID && c.Column.ColumnName == otherColumnName select c.Column).Single(); + + var key = thisTable.ForeignKeys[name]; + + key.ThisColumns. Add(thisColumn); + key.OtherColumns.Add(otherColumn); + } + } + } + } + + var qc = + from c in columns + group c by c.ID into gr + join t in tables on gr.Key equals t.ID + select new { t.Table, gr }; + + foreach (var c in qc) + { + foreach (var col in from col in c.gr orderby col.Column.ID select col.Column) + c.Table.Columns.Add(col.ColumnName, col); + + if (c.Table.Owner == "postgres") + { + c.Table.Owner = null; + Tables.Add(c.Table.TableName, c.Table); + } + else + { + Tables.Add(c.Table.Owner + "." + c.Table.TableName, c.Table); + } + } +} +#> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Templates/Renamer.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/Renamer.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,38 @@ +<# +//Rename tables and fields according to the .NET style, i.e. "booking_number" to "BookingNumber" + { + var fieldsPrevBeforeGenerateModel = BeforeGenerateModel; + + Func getNetStyleName = (string name) => + { + if(!string.IsNullOrEmpty(name)) + { + var chars = new System.Text.StringBuilder(name); + for(int i=1; i + { + fieldsPrevBeforeGenerateModel(tt); + Dictionary remapper = new Dictionary() { { "Exception", "Exceptions" } }; + + foreach (var t in Tables.Values) + { + t.ClassName = getNetStyleName(t.ClassName); + string className; + if(remapper.TryGetValue(t.ClassName, out className)) + t.ClassName = className; + foreach (var c in t.Columns.Values) + c.MemberName = getNetStyleName(c.MemberName); + } + }; + } + + +#> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Templates/Sybase.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/Sybase.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,444 @@ +<# + ConnectionType = "Sybase.Data.AseClient.AseConnection, Sybase.AdoNet2.AseClient"; +#><#+ + +bool GenerateSybaseSystemTables = false; + +private void LoadServerMetadata() +{ + var tables = CreateList(new { ID = 0, Table = new Table() }); + var columns = CreateList(new { ID = 0, Column = new Column() }); + + using (var conn = GetConnection()) + using (var cmd = conn.CreateCommand()) + { + // Load tables & vies. + // + cmd.CommandText = @" + SELECT + id, + USER_NAME(uid), + name, + type + FROM + sysobjects + WHERE + type IN ('U','V')"; + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var t = new + { + ID = Convert.ToInt32(rd[0]), + Table = new Table + { + Owner = rd[1].ToString(), + TableName = rd[2].ToString(), + ClassName = rd[2].ToString(), + IsView = rd[3].ToString()[0] == 'V', + BaseClassName = BaseEntityClass, + } + }; + + tables.Add(t); + } + } + + // Load columns. + // + cmd.CommandText = @" + SELECT + o.id, + c.colid, + c.name, + c.status, + c.usertype, + t.type, + c.length, + c.prec, + c.scale, + t.name as typename, + Convert(bit, c.status & 0x08) isNullable, + Convert(bit, c.status & 0x80) isIdentity + FROM + syscolumns c + JOIN sysobjects o ON c.id = o.id + JOIN systypes t ON c.usertype = t.usertype + WHERE + o.type IN ('U','V')"; + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var col = new + { + ID = Convert.ToInt32(rd["id"]), + Column = new Column + { + ID = Convert.ToInt16 (rd["colid"]), + ColumnName = Convert.ToString (rd["name"]), + MemberName = Convert.ToString (rd["name"]), + ColumnType = Convert.ToString (rd["typename"]), + IsNullable = Convert.ToBoolean(rd["isNullable"]), + IsIdentity = Convert.ToBoolean(rd["isIdentity"]), + Length = rd.IsDBNull(rd.GetOrdinal("length")) ? 0 : Convert.ToInt64(rd["length"]), + Precision = rd.IsDBNull(rd.GetOrdinal("prec")) ? 0 : Convert.ToInt32(rd["prec"]), + Scale = rd.IsDBNull(rd.GetOrdinal("scale")) ? 0 : Convert.ToInt32(rd["scale"]), + } + }; + + var c = col.Column; + + switch (Convert.ToInt32(rd["type"])) + { + case 34 /* image */ : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Image; break; + case 35 /* text */ : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.Text; break; + case 45 /* binary */ : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Binary; break; + case 48 /* tinyint */ : c.Type = "byte"; c.DbType = DbType.Byte; c.SqlDbType = SqlDbType.TinyInt; break; + case 49 /* date */ : c.Type = "DateTime"; c.DbType = DbType.Date; c.SqlDbType = SqlDbType.Date; break; + case 50 /* bit */ : c.Type = "bool"; c.DbType = DbType.Boolean; c.SqlDbType = SqlDbType.Bit; break; + case 51 /* time */ : c.Type = "DateTime"; c.DbType = DbType.Time; c.SqlDbType = SqlDbType.Time; break; + case 52 /* smallint */ : c.Type = "short"; c.DbType = DbType.Int16; c.SqlDbType = SqlDbType.SmallInt; break; + case 55 /* decimal */ : c.Type = "decimal"; c.DbType = DbType.Decimal; c.SqlDbType = SqlDbType.Decimal; break; + case 56 /* int */ : c.Type = "int"; c.DbType = DbType.Int32; c.SqlDbType = SqlDbType.Int; break; + case 58 /* smalldatetime */ : c.Type = "DateTime"; c.DbType = DbType.DateTime; c.SqlDbType = SqlDbType.SmallDateTime; break; + case 59 /* real */ : c.Type = "float"; c.DbType = DbType.Single; c.SqlDbType = SqlDbType.Real; break; + case 60 /* money */ : c.Type = "decimal"; c.DbType = DbType.Currency; c.SqlDbType = SqlDbType.Money; break; + case 61 /* datetime */ : c.Type = "DateTime"; c.DbType = DbType.DateTime; c.SqlDbType = SqlDbType.DateTime; break; + case 62 /* float */ : c.Type = "double"; c.DbType = DbType.Double; c.SqlDbType = SqlDbType.Float; break; + case 63 /* numeric */ : c.Type = "decimal"; c.DbType = DbType.Decimal; c.SqlDbType = SqlDbType.Decimal; break; + case 65 /* usmallint */ : c.Type = "ushort"; c.DbType = DbType.UInt16; c.SqlDbType = SqlDbType.SmallInt; break; + case 66 /* uint */ : c.Type = "uint"; c.DbType = DbType.UInt32; c.SqlDbType = SqlDbType.Int; break; + case 67 /* ubigint */ : c.Type = "ulong"; c.DbType = DbType.UInt64; c.SqlDbType = SqlDbType.BigInt; break; + case 122 /* smallmoney */ : c.Type = "decimal"; c.DbType = DbType.Currency; c.SqlDbType = SqlDbType.SmallMoney; break; + case 174 /* unitext */ : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.NText; break; + case 189 /* bigdatetime */ : c.Type = "DateTime"; c.DbType = DbType.DateTime2; c.SqlDbType = SqlDbType.DateTime2; break; + case 190 /* bigtime */ : c.Type = "DateTime"; c.DbType = DbType.DateTime2; c.SqlDbType = SqlDbType.DateTime2; break; + case 191 /* bigint */ : c.Type = "long"; c.DbType = DbType.Int64; c.SqlDbType = SqlDbType.BigInt; break; + + case 37 /* varbinary */ + /* timestamp */ : + c.Type = "byte[]"; + c.DbType = DbType.Binary; + c.SqlDbType = Convert.ToString(rd["typename"]) == "timestamp" ? SqlDbType.Timestamp : SqlDbType.VarBinary; + break; + + case 39 /* sysname */ + /* longsysname */ + /* varchar */ + /* nvarchar */ : + + c.Type = "string"; + + if (Convert.ToString(rd["typename"]) == "nvarchar") + { + c.DbType = DbType.String; + c.SqlDbType = SqlDbType.NVarChar; + } + else + { + c.DbType = DbType.AnsiString; + c.SqlDbType = SqlDbType.VarChar; + } + + break; + + case 47 /* char */ + /* nchar */ : + + c.Type = Convert.ToInt32 (rd["length"]) == 1 ? "char" : "string"; + c.DbType = Convert.ToString(rd["typename"]) == "char" ? DbType.AnsiStringFixedLength : DbType.StringFixedLength; + c.SqlDbType = Convert.ToString(rd["typename"]) == "char" ? SqlDbType.Char : SqlDbType.NChar; + break; + + case 135 /* unichar */ : + c.Type = Convert.ToInt32 (rd["length"]) == 1 ? "char" : "string"; + c.DbType = DbType.StringFixedLength; + c.SqlDbType = SqlDbType.NChar; + break; + + case 155 /* univarchar */ : + c.Type = Convert.ToInt32 (rd["length"]) == 1 ? "char" : "string"; + c.DbType = DbType.String; + c.SqlDbType = SqlDbType.NVarChar; + break; + + case 36 /* extended type */ : + case 38 /* intn */ : + case 68 /* uintn */ : + case 106 /* decimaln */ : + case 108 /* numericn */ : + case 109 /* floatn */ : + case 110 /* moneyn */ : + case 111 /* datetimn */ : + case 123 /* daten */ : + case 147 /* timen */ : + case 187 /* bigdatetimen */ : + case 188 /* bigtimen */ : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Binary; break; + } + + switch (c.Type) + { + case "string" : + case "byte[]" : c.IsClass = true; break; + } + + if (c.IsNullable && !c.IsClass) + c.Type += "?"; + + columns.Add(col); + } + } + + // Load PKs. + // + cmd.CommandText = @" + SELECT + i.id, + i.name, + INDEX_COL(USER_NAME(o.uid) + '.' + o.name, i.indid, c.colid) AS colname, + INDEX_COLORDER(USER_NAME(o.uid) + '.' + o.name, i.indid, c.colid) AS [order], + c.colid + FROM + sysindexes i + JOIN sysobjects o ON i.id = o.id + JOIN syscolumns c ON i.id = c.id + WHERE + i.status2 & 2 = 2 AND + i.status & 2048 = 2048 AND + i.indid > 0 AND + c.colid < i.keycnt + CASE WHEN i.indid = 1 THEN 1 ELSE 0 END"; + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var id = Convert.ToInt32 (rd["id"]); + var colid = Convert.ToInt32 (rd["colid"]); + var colname = Convert.ToString(rd["colname"]); + + columns.Single(_ => _.ID == id && _.Column.ColumnName == colname).Column.PKIndex = colid; + } + } + + // Load FKs. + // + cmd.CommandText = @" + SELECT + o.name as Name, + c.tableid as ThisTable, + r.reftabid as OtherTable, + COL_NAME(c.tableid, r.fokey1) as ThisColumn1, + COL_NAME(c.tableid, r.fokey2) as ThisColumn2, + COL_NAME(c.tableid, r.fokey3) as ThisColumn3, + COL_NAME(c.tableid, r.fokey4) as ThisColumn4, + COL_NAME(c.tableid, r.fokey5) as ThisColumn5, + COL_NAME(c.tableid, r.fokey6) as ThisColumn6, + COL_NAME(c.tableid, r.fokey7) as ThisColumn7, + COL_NAME(c.tableid, r.fokey8) as ThisColumn8, + COL_NAME(c.tableid, r.fokey9) as ThisColumn9, + COL_NAME(c.tableid, r.fokey10) as ThisColumn10, + COL_NAME(c.tableid, r.fokey11) as ThisColumn11, + COL_NAME(c.tableid, r.fokey12) as ThisColumn12, + COL_NAME(c.tableid, r.fokey13) as ThisColumn13, + COL_NAME(c.tableid, r.fokey14) as ThisColumn14, + COL_NAME(c.tableid, r.fokey15) as ThisColumn15, + COL_NAME(c.tableid, r.fokey16) as ThisColumn16, + COL_NAME(r.reftabid, r.refkey1) as OtherColumn1, + COL_NAME(r.reftabid, r.refkey2) as OtherColumn2, + COL_NAME(r.reftabid, r.refkey3) as OtherColumn3, + COL_NAME(r.reftabid, r.refkey4) as OtherColumn4, + COL_NAME(r.reftabid, r.refkey5) as OtherColumn5, + COL_NAME(r.reftabid, r.refkey6) as OtherColumn6, + COL_NAME(r.reftabid, r.refkey7) as OtherColumn7, + COL_NAME(r.reftabid, r.refkey8) as OtherColumn8, + COL_NAME(r.reftabid, r.refkey9) as OtherColumn9, + COL_NAME(r.reftabid, r.refkey10) as OtherColumn10, + COL_NAME(r.reftabid, r.refkey11) as OtherColumn11, + COL_NAME(r.reftabid, r.refkey12) as OtherColumn12, + COL_NAME(r.reftabid, r.refkey13) as OtherColumn13, + COL_NAME(r.reftabid, r.refkey14) as OtherColumn14, + COL_NAME(r.reftabid, r.refkey15) as OtherColumn15, + COL_NAME(r.reftabid, r.refkey16) as OtherColumn16 + FROM + sysreferences r + JOIN sysconstraints c ON r.constrid = c.constrid + JOIN sysobjects o ON c.constrid = o.id + JOIN sysobjects o3 ON c.tableid = o3.id + LEFT JOIN sysobjects o2 ON r.reftabid = o2.id + JOIN sysreferences r2 ON r.constrid = r2.constrid + LEFT JOIN sysindexes i ON r2.indexid = i.indid AND r2.reftabid = i.id + WHERE + c.status = 64"; + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var name = Convert.ToString(rd["Name"]); + var thisTableID = Convert.ToInt32 (rd["ThisTable"]); + var otherTableID = Convert.ToInt32 (rd["OtherTable"]); + + var thisTable = (from t in tables where t.ID == thisTableID select t.Table).Single(); + var otherTable = (from t in tables where t.ID == otherTableID select t.Table).Single(); + + thisTable.ForeignKeys.Add(name, new ForeignKey { KeyName = name, MemberName = name, OtherTable = otherTable }); + + for (int i = 1; i <= 16; i++) + { + if (rd.IsDBNull(rd.GetOrdinal("ThisColumn" + i))) + break; + + var thisColumnName = Convert.ToString(rd["ThisColumn" + i]); + var otherColumnName = Convert.ToString(rd["OtherColumn" + i]); + + var thisColumn = (from c in columns where c.ID == thisTableID && c.Column.ColumnName == thisColumnName select c.Column).Single(); + var otherColumn = (from c in columns where c.ID == otherTableID && c.Column.ColumnName == otherColumnName select c.Column).Single(); + + var key = thisTable.ForeignKeys[name]; + + key.ThisColumns. Add(thisColumn); + key.OtherColumns.Add(otherColumn); + } + } + } + } + + var qc = + from c in columns + group c by c.ID into gr + join t in tables on gr.Key equals t.ID + select new { t.Table, gr }; + + foreach (var c in qc) + { + foreach (var col in from col in c.gr orderby col.Column.ID select col.Column) + c.Table.Columns.Add(col.ColumnName, col); + + if (c.Table.Owner == "dbo") + { + c.Table.Owner = null; + Tables.Add(c.Table.TableName, c.Table); + } + else + { + Tables.Add(c.Table.Owner + "." + c.Table.TableName, c.Table); + } + } + + if (GenerateSybaseSystemTables) + { + Tables.Add("sysobjects", new Table + { + TableName = "sysobjects", + ClassName = "SysObject", + BaseClassName = BaseEntityClass, + Columns = + { + { "name", new VarCharColumn { ColumnName = "name", Length = 255 }}, + { "id", new IntColumn { ColumnName = "id" }}, + { "uid", new IntColumn { ColumnName = "uid" }}, + { "type", new Column { + ColumnName = "type", + Type = "string", + ColumnType = "char", + DbType = DbType.AnsiStringFixedLength, + SqlDbType = SqlDbType.Char, + Length = 2, + }}, + { "userstat", new SmallIntColumn { ColumnName = "userstat" }}, + { "sysstat", new SmallIntColumn { ColumnName = "sysstat" }}, + { "indexdel", new SmallIntColumn { ColumnName = "indexdel" }}, + { "schemacnt", new SmallIntColumn { ColumnName = "schemacnt" }}, + { "sysstat2", new IntColumn { ColumnName = "sysstat2" }}, + { "crdate", new DateTimeColumn { ColumnName = "crdate" }}, + { "expdate", new DateTimeColumn { ColumnName = "expdate" }}, + { "deltrig", new IntColumn { ColumnName = "deltrig" }}, + { "instrig", new IntColumn { ColumnName = "instrig" }}, + { "updtrig", new IntColumn { ColumnName = "updtrig" }}, + { "seltrig", new IntColumn { ColumnName = "seltrig" }}, + { "ckfirst", new IntColumn { ColumnName = "ckfirst" }}, + { "cache", new SmallIntColumn { ColumnName = "cache" }}, + { "audflags", new IntColumn { ColumnName = "audflags", IsNullable = true }}, + { "objspare", new IntColumn { ColumnName = "objspare" }}, + { "versionts", new Column { + ColumnName = "versionts", + IsNullable = true, + Type = "byte[]", + ColumnType = "binary", + IsClass = true, + DbType = DbType.Binary, + SqlDbType = SqlDbType.Binary, + Length = 6, + }}, + { "loginame", new VarCharColumn { ColumnName = "loginame", Length = 30 }}, + } + }); + + int n = 1; + + foreach (var col in Tables["sysobjects"].Columns) + { + var c = col.Value; + + c.ID = n++; + c.MemberName = c.ColumnName; + + if (c.IsNullable && !c.IsClass) + c.Type = c.Type + "?"; + } + } +} + +class VarCharColumn : Column +{ + public VarCharColumn() + { + Type = "string"; + ColumnType = "varchar"; + IsClass = true; + DbType = DbType.AnsiString; + SqlDbType = SqlDbType.VarChar; + } +} + +class IntColumn : Column +{ + public IntColumn() + { + Type = "int"; + ColumnType = "int"; + DbType = DbType.Int32; + SqlDbType = SqlDbType.Int; + Length = 4; + } +} + +class SmallIntColumn : Column +{ + public SmallIntColumn() + { + Type = "short"; + ColumnType = "smallint"; + DbType = DbType.Int16; + SqlDbType = SqlDbType.SmallInt; + Length = 2; + } +} + +class DateTimeColumn : Column +{ + public DateTimeColumn() + { + Type = "DateTime"; + ColumnType = "datetime"; + DbType = DbType.DateTime; + SqlDbType = SqlDbType.DateTime; + Length = 8; + } +} + +#> diff -r 000000000000 -r f990fcb411a9 Source/Templates/VB.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/VB.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,117 @@ +<# + +OneToManyAssociationType = OneToManyAssociationType.Replace("<", "(Of ").Replace(">", ")"); + +WriteComment = (tt,s) => WriteLine("'{0}", s); +WriteUsing = (tt,s) => WriteLine("Imports {0}", s); +WriteBeginNamespace = (tt,s) => { WriteLine("Namespace {0}", s); WriteLine(""); }; +WriteEndNamespace = tt => { WriteLine(""); WriteLine("End Namespace"); }; +WriteBeginClass = (tt,cl,bc) => +{ + WriteLine("Public Partial Class {0}", cl); + if (!string.IsNullOrEmpty(bc)) + WriteLine("\tInherits {0}", bc); +}; +WriteEndClass = tt => WriteLine("End Class"); +MakeGenericType = (c,t) => string.Format("{0}(Of {1})", c, t); +WriteTableProperty = (tt,name,pname,maxlen,maxplen) => +{ + WriteLine(""); + WriteLine("Public ReadOnly Property {0}(){1} As Table(Of {2})", pname, LenDiff(maxplen, pname), name); + WriteLine("\tGet"); + WriteLine("\t\tReturn Me.GetTable(Of {0})()", name); + WriteLine("\tEnd Get"); + WriteLine("End Property"); +}; +WriteAttribute = (tt,a) => WriteLine("<{0}> _", a.Replace("=", ":=")); +WriteAttributeLine = tt => {}; + +RenderColumn = (tt,c,maxLens,attrs) => +{ + WriteLine(""); + + var type = MakeType(c.Type); + + if (!tt.RenderField) + WriteLine("Private _{0} As {1}", c.MemberName, type); + + attrs = attrs.Where(_ => _ != null).ToArray(); + + if (attrs.Length > 0) + WriteLine("<{0}> _", string.Join(", ", attrs).Replace("=", ":=")); + + if (tt.RenderField) + WriteLine("Public {0} As {1}", c.MemberName, type); + else + { + WriteLine("Public Property {0} As {1}", c.MemberName, type); + WriteLine("\tGet"); + WriteLine("\t\tReturn Me._{0}", c.MemberName); + WriteLine("\tEnd Get"); + WriteLine("\tSet"); + WriteLine("\t\tMe._{0} = value", c.MemberName); + WriteLine("\tEnd Set"); + WriteLine("End Property"); + } +}; + +RenderForeignKey = (tt,key) => +{ + WriteComment(tt, " " + key.KeyName); + + var type = "" ; + if (key.AssociationType == AssociationType.OneToMany) + type = string.Format(OneToManyAssociationType, key.OtherTable.ClassName); + else + type = key.OtherTable.ClassName ; + + if (!RenderField) + WriteLine("Private _{0} As {1}", key.MemberName, type); + + WriteLine(" _", + string.Join(", ", (from c in key.ThisColumns select c.MemberName).ToArray()), + string.Join(", ", (from c in key.OtherColumns select c.MemberName).ToArray())); + + if (RenderField) + WriteLine("Public {0} As {1}", key.MemberName, type); + else + { + WriteLine("Public Property {0} As {1}", key.MemberName, type); + WriteLine("\tGet"); + WriteLine("\t\tReturn Me._{0}", key.MemberName); + WriteLine("\tEnd Get"); + WriteLine("\tSet"); + WriteLine("\t\tMe._{0} = value", key.MemberName); + WriteLine("\tEnd Set"); + WriteLine("End Property"); + } +}; + +MakeType = t => +{ + switch (t) + { + case "byte[]" : return "Byte()"; + case "string" : return "String"; + case "byte" : return "Byte"; + case "byte?" : return "Byte?"; + case "bool" : return "Boolean"; + case "bool?" : return "Boolean?"; + case "object" : return "Object"; + case "short" : return "Short"; + case "short?" : return "Short?"; + case "decimal" : return "Decimal"; + case "decimal?" : return "Decimal?"; + case "int" : return "Integer"; + case "int?" : return "Integer?"; + case "float" : return "Single"; + case "float?" : return "Single?"; + case "double" : return "Double"; + case "double?" : return "Double?"; + case "long" : return "Long"; + case "long?" : return "Long?"; + } + + return t; +}; +#> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Templates/ValidationAttributes.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/ValidationAttributes.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,32 @@ +<# + { + var validationPrevBeforeGenerateModel = BeforeGenerateModel; + + BeforeGenerateModel = tt => + { + validationPrevBeforeGenerateModel(tt); + + Usings.Add("BLToolkit.Validation"); + + foreach (var t in Tables.Values) + { + var maxLength = t.Columns.Values + .Where (x => x.Type == "string") + .Select(x => x.Length) + .OrderByDescending(x => x) + .FirstOrDefault() + // Get exponent slowly + .ToString().Length; + + foreach (var c in t.Columns.Values) + { + if (c.Type == "string" && c.Length > 0) + c.Attributes.Add(string.Format("MaxLength({0," + maxLength + "})", c.Length)); + + if (!c.IsNullable) + c.Attributes.Add("Required"); + } + } + }; + } +#> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/Templates/WCFAttributes.ttinclude --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/WCFAttributes.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +<# + { + var wcfPrevBeforeGenerateModel = BeforeGenerateModel; + + BeforeGenerateModel = tt => + { + wcfPrevBeforeGenerateModel(tt); + + Usings.Add("System.Runtime.Serialization"); + + foreach (var t in Tables.Values) + t.Attributes.AddRange(new[] + { + "Serializable", + "DataContract" + (DataContractNamespace == null ? "" : "(Namespace=\"" + DataContractNamespace + "\")") + }); + + foreach (var t in Tables.Values) + foreach (var c in t.Columns.Values) + c.Attributes.Add("DataMember"); + }; + } +#><#+ +string DataContractNamespace = null; +#> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/AutoImplementInterfaceAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/AutoImplementInterfaceAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.Interface)] + public class AutoImplementInterfaceAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/BLToolkitGeneratedAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/BLToolkitGeneratedAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.All)] + public sealed class BLToolkitGeneratedAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/AbstractClassBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/AbstractClassBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,746 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Diagnostics.CodeAnalysis; + +namespace BLToolkit.TypeBuilder.Builders +{ + using Properties; + using Reflection; + using Reflection.Emit; + + internal class AbstractClassBuilder : ITypeBuilder + { + public AbstractClassBuilder(Type sourceType) + { + _sourceType = sourceType; + } + + readonly Type _sourceType; + + public string AssemblyNameSuffix + { + get { return TypeBuilderConsts.AssemblyNameSuffix; } + } + + public Type Build(AssemblyBuilderHelper assemblyBuilder) + { + _context = new BuildContext(_sourceType); + _builders = new AbstractTypeBuilderList(); + + _context.TypeBuilders = GetBuilderList(_context.Type); + _context.AssemblyBuilder = assemblyBuilder; + + _builders.AddRange(_context.TypeBuilders); + _builders.Add(_defaultTypeBuilder); + + return Build(); + } + + internal static string GetTypeFullName(Type type) + { + var name = type.FullName; + + if (type.IsGenericType) + { + name = name.Split('`')[0]; + + foreach (var t in type.GetGenericArguments()) + name += "_" + GetTypeFullName(t).Replace('+', '_').Replace('.', '_'); + } + + return name; + } + + internal static string GetTypeShortName(Type type) + { + var name = type.Name; + + if (type.IsGenericType) + { + name = name.Split('`')[0]; + + foreach (var t in type.GetGenericArguments()) + name += "_" + GetTypeFullName(t).Replace('+', '_').Replace('.', '_'); + } + + return name; + } + + public string GetTypeName() + { + var typeFullName = _sourceType.FullName; + var typeShortName = _sourceType.Name; + + if (_sourceType.IsGenericType) + { + typeFullName = GetTypeFullName (_sourceType); + typeShortName = GetTypeShortName(_sourceType); + } + + typeFullName = typeFullName. Replace('+', '.'); + typeShortName = typeShortName.Replace('+', '.'); + + typeFullName = typeFullName.Substring(0, typeFullName.Length - typeShortName.Length); + typeFullName = typeFullName + "BLToolkitExtension." + typeShortName; + + return typeFullName; + } + + public Type GetBuildingType() + { + return _sourceType; + } + + private static AbstractTypeBuilderList GetBuilderList(TypeHelper type) + { + var attrs = type.GetAttributes(typeof(AbstractTypeBuilderAttribute)); + var builders = new AbstractTypeBuilderList(attrs.Length); + + foreach (AbstractTypeBuilderAttribute attr in attrs) + { + var builder = attr.TypeBuilder; + + if (builder != null) + { + builder.TargetElement = type; + builders.Add(builder); + } + } + + return builders; + } + + private static readonly DefaultTypeBuilder _defaultTypeBuilder = new DefaultTypeBuilder(); + + private BuildContext _context; + private AbstractTypeBuilderList _builders; + + private Type Build() + { + DefineNonAbstractType(); + + SetID(_builders); + + _context.BuildElement = BuildElement.Type; + + Build(BuildStep.Before, _builders); + Build(BuildStep.Build, _builders); + + var ids = _builders.ToDictionary(builder => builder, builder => builder.ID); + + DefineAbstractProperties(); + DefineAbstractMethods(); + OverrideVirtualProperties(); + OverrideVirtualMethods(); + DefineInterfaces(); + + foreach (var builder in ids.Keys) + builder.ID = ids[builder]; + + _context.BuildElement = BuildElement.Type; + + Build(BuildStep.After, _builders); + + var initMethod = _context.Type.GetMethod("InitInstance", typeof(InitContext)); + + // Finalize constructors. + // + if (_context.TypeBuilder.IsDefaultConstructorDefined) + { + if (initMethod != null) + _context.TypeBuilder.DefaultConstructor.Emitter + .ldarg_0 + .ldnull + .callvirt (initMethod) + ; + + _context.TypeBuilder.DefaultConstructor.Emitter.ret(); + } + + if (_context.TypeBuilder.IsInitConstructorDefined) + { + if (initMethod != null) + _context.TypeBuilder.InitConstructor.Emitter + .ldarg_0 + .ldarg_1 + .callvirt (initMethod) + ; + + _context.TypeBuilder.InitConstructor.Emitter.ret(); + } + + if (_context.TypeBuilder.IsTypeInitializerDefined) + _context.TypeBuilder.TypeInitializer.Emitter.ret(); + + // Create the type. + // + return _context.TypeBuilder.Create(); + } + + private static int _idCounter; + + private static void SetID(AbstractTypeBuilderList builders) + { + foreach (var builder in builders) + builder.ID = ++_idCounter; + } + + private static void CheckCompatibility(BuildContext context, AbstractTypeBuilderList builders) + { + for (var i = 0; i < builders.Count; i++) + { + var cur = builders[i]; + + if (cur == null) + continue; + + for (var j = 0; j < builders.Count; j++) + { + var test = builders[j]; + + if (i == j || test == null) + continue; + + if (cur.IsCompatible(context, test) == false) + builders[j] = null; + } + } + + for (var i = 0; i < builders.Count; i++) + if (builders[i] == null) + builders.RemoveAt(i--); + } + + private void DefineNonAbstractType() + { + var interfaces = new List(); + + if (_context.Type.IsInterface) + { + interfaces.Add(_context.Type); + _context.InterfaceMap.Add(_context.Type, null); + } + + foreach (var tb in _builders) + { + var types = tb.GetInterfaces(); + + if (types != null) + { + foreach (var t in types) + { + if (t == null) + continue; + + if (!t.IsInterface) + { + throw new InvalidOperationException( + string.Format(Resources.AbstractClassBuilder_TypeIsNotAnInterface, t.FullName)); + } + + if (interfaces.Contains(t) == false) + { + interfaces.Add(t); + _context.InterfaceMap.Add(t, tb); + } + } + } + } + + var typeName = GetTypeName(); + + _context.TypeBuilder = _context.AssemblyBuilder.DefineType( + typeName, + TypeAttributes.Public | TypeAttributes.BeforeFieldInit | (TypeFactory.SealTypes? TypeAttributes.Sealed: 0), + _context.Type.IsInterface? typeof(object): (Type)_context.Type, + interfaces.ToArray()); + + if (_context.Type.IsSerializable) + _context.TypeBuilder.SetCustomAttribute(typeof(SerializableAttribute)); + } + + class BuilderComparer : IComparer + { + public BuilderComparer(BuildContext context) + { + _context = context; + } + + readonly BuildContext _context; + + [SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")] + public int Compare(IAbstractTypeBuilder x, IAbstractTypeBuilder y) + { + return y.GetPriority(_context) - x.GetPriority(_context); + } + } + + private void Build(BuildStep step, AbstractTypeBuilderList builders) + { + _context.Step = step; + _context.TypeBuilders.Clear(); + + foreach (var builder in builders) + if (builder.IsApplied(_context, builders)) + _context.TypeBuilders.Add(builder); + + if (_context.IsVirtualMethod || _context.IsVirtualProperty) + _context.TypeBuilders.Add(_defaultTypeBuilder); + + if (_context.TypeBuilders.Count == 0) + return; + + CheckCompatibility(_context, _context.TypeBuilders); + + _context.TypeBuilders.Sort(new BuilderComparer(_context)); + + for (var i = 0; i < _context.TypeBuilders.Count; i++) + { + var builder = _context.TypeBuilders[i]; + + builder.Build(_context); + } + } + + private void BeginEmitMethod(MethodInfo method) + { + _context.CurrentMethod = method; + _context.MethodBuilder = _context.TypeBuilder.DefineMethod(method); + + var emit = _context.MethodBuilder.Emitter; + + // Label right before return and catch block. + // + _context.ReturnLabel = emit.DefineLabel(); + + // Create return value. + // + if (method.ReturnType != typeof(void)) + { + _context.ReturnValue = _context.MethodBuilder.Emitter.DeclareLocal(method.ReturnType); + emit.Init(_context.ReturnValue); + } + + // Initialize out parameters. + // + var parameters = method.GetParameters(); + + if (parameters != null) + emit.InitOutParameters(parameters); + } + + private void EmitMethod( + AbstractTypeBuilderList builders, MethodInfo methdoInfo, BuildElement buildElement) + { + SetID(builders); + + _context.BuildElement = buildElement; + + var isCatchBlockRequired = false; + var isFinallyBlockRequired = false; + + foreach (var builder in builders) + { + isCatchBlockRequired = isCatchBlockRequired || IsApplied(builder, builders, BuildStep.Catch); + isFinallyBlockRequired = isFinallyBlockRequired || IsApplied(builder, builders, BuildStep.Finally); + } + + BeginEmitMethod(methdoInfo); + + Build(BuildStep.Begin, builders); + + var emit = _context.MethodBuilder.Emitter; + var returnLabel = _context.ReturnLabel; + + // Begin catch block. + // + + if (isCatchBlockRequired || isFinallyBlockRequired) + { + _context.ReturnLabel = emit.DefineLabel(); + emit.BeginExceptionBlock(); + } + + Build(BuildStep.Before, builders); + Build(BuildStep.Build, builders); + Build(BuildStep.After, builders); + + if (isCatchBlockRequired || isFinallyBlockRequired) + { + emit.MarkLabel(_context.ReturnLabel); + _context.ReturnLabel = returnLabel; + } + + // End catch block. + // + if (isCatchBlockRequired) + { + emit + .BeginCatchBlock(typeof(Exception)); + + _context.ReturnLabel = emit.DefineLabel(); + _context.Exception = emit.DeclareLocal(typeof(Exception)); + + emit + .stloc (_context.Exception); + + Build(BuildStep.Catch, builders); + + emit + .rethrow + .end(); + + emit.MarkLabel(_context.ReturnLabel); + _context.ReturnLabel = returnLabel; + _context.Exception = null; + } + + if (isFinallyBlockRequired) + { + emit.BeginFinallyBlock(); + _context.ReturnLabel = emit.DefineLabel(); + + Build(BuildStep.Finally, builders); + + emit.MarkLabel(_context.ReturnLabel); + _context.ReturnLabel = returnLabel; + } + + if (isCatchBlockRequired || isFinallyBlockRequired) + emit.EndExceptionBlock(); + + Build(BuildStep.End, builders); + + EndEmitMethod(); + } + + private void EndEmitMethod() + { + var emit = _context.MethodBuilder.Emitter; + + // Prepare return. + // + emit.MarkLabel(_context.ReturnLabel); + + if (_context.ReturnValue != null) + emit.ldloc(_context.ReturnValue); + + emit.ret(); + + // Cleanup the context. + // + _context.ReturnValue = null; + _context.CurrentMethod = null; + _context.MethodBuilder = null; + } + + private static AbstractTypeBuilderList GetBuilders(object[] attributes, object target) + { + var builders = new AbstractTypeBuilderList(attributes.Length); + + foreach (AbstractTypeBuilderAttribute attr in attributes) + { + var builder = attr.TypeBuilder; + + builder.TargetElement = target; + builders.Add(builder); + } + + return builders; + } + + private static AbstractTypeBuilderList GetBuilders(MemberInfo memberInfo) + { + return GetBuilders( + memberInfo.GetCustomAttributes(typeof(AbstractTypeBuilderAttribute), true), memberInfo); + } + + private static AbstractTypeBuilderList GetBuilders(ParameterInfo parameterInfo) + { + return GetBuilders( + parameterInfo.GetCustomAttributes(typeof(AbstractTypeBuilderAttribute), true), parameterInfo); + } + + private static AbstractTypeBuilderList GetBuilders(ParameterInfo[] parameters) + { + var builders = new AbstractTypeBuilderList(); + + foreach (var pi in parameters) + { + var attributes = pi.GetCustomAttributes(typeof(AbstractTypeBuilderAttribute), true); + + foreach (AbstractTypeBuilderAttribute attr in attributes) + { + var builder = attr.TypeBuilder; + + builder.TargetElement = pi; + builders.Add(builder); + } + } + + return builders; + } + + private static AbstractTypeBuilderList Combine(params AbstractTypeBuilderList[] builders) + { + var list = new AbstractTypeBuilderList(); + + foreach (var l in builders) + list.AddRange(l); + + return list; + } + + private bool IsApplied(IAbstractTypeBuilder builder, AbstractTypeBuilderList builders, BuildStep buildStep) + { + _context.Step = buildStep; + return builder.IsApplied(_context, builders); + } + + private bool IsApplied(BuildElement element, AbstractTypeBuilderList builders) + { + _context.BuildElement = element; + + foreach (var builder in builders) + { + if (IsApplied(builder, builders, BuildStep.Before)) return true; + if (IsApplied(builder, builders, BuildStep.Build)) return true; + if (IsApplied(builder, builders, BuildStep.After)) return true; + if (IsApplied(builder, builders, BuildStep.Catch)) return true; + if (IsApplied(builder, builders, BuildStep.Finally)) return true; + } + + return false; + } + + private static void GetAbstractProperties(Type type, List props) + { + if (props.FirstOrDefault(mi => mi.DeclaringType == type) == null) + { + props.AddRange( + type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)); + + if (type.IsInterface) + foreach (var t in type.GetInterfaces()) + GetAbstractProperties(t, props); + } + } + + private void DefineAbstractProperties() + { + var props = new List(); + + GetAbstractProperties(_context.Type, props); + + foreach (var pi in props) + { + _context.CurrentProperty = pi; + + var propertyBuilders = GetBuilders(pi); + + var getter = pi.GetGetMethod(true); + var setter = pi.GetSetMethod(true); + + if (getter != null && getter.IsAbstract || + setter != null && setter.IsAbstract) + { + DefineAbstractGetter(pi, getter, propertyBuilders); + DefineAbstractSetter(pi, setter, propertyBuilders); + } + } + + _context.CurrentProperty = null; + } + + private void DefineAbstractGetter( + PropertyInfo propertyInfo, MethodInfo getter, AbstractTypeBuilderList propertyBuilders) + { + // Getter can be not defined. We will generate it anyway. + // + if (getter == null) +#if SILVERLIGHT + return; +#else + getter = new FakeGetter(propertyInfo); +#endif + + var builders = Combine( + GetBuilders(getter.GetParameters()), + GetBuilders(getter.ReturnParameter), + GetBuilders(getter), + propertyBuilders, + _builders); + + EmitMethod(builders, getter, BuildElement.AbstractGetter); + } + + private void DefineAbstractSetter( + PropertyInfo propertyInfo, + MethodInfo setter, + AbstractTypeBuilderList propertyBuilders) + { + // Setter can be not defined. We will generate it anyway. + // + if (setter == null) +#if SILVERLIGHT + return; +#else + setter = new FakeSetter(propertyInfo); +#endif + + var builders = Combine( + GetBuilders(setter.GetParameters()), + GetBuilders(setter.ReturnParameter), + GetBuilders(setter), + propertyBuilders, + _builders); + + EmitMethod(builders, setter, BuildElement.AbstractSetter); + } + + private static void GetAbstractMethods(Type type, List methods) + { + if (!methods.Exists(mi => mi.DeclaringType == type)) + { + methods.AddRange( + type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)); + + if (type.IsInterface) + foreach (var t in type.GetInterfaces()) + GetAbstractMethods(t, methods); + } + } + + private void DefineAbstractMethods() + { + var methods = new List(); + + GetAbstractMethods(_context.Type, methods); + + foreach (var method in methods) + { + if (method.IsAbstract && (method.Attributes & MethodAttributes.SpecialName) == 0) + { + var builders = Combine( + GetBuilders(method.GetParameters()), + GetBuilders(method.ReturnParameter), + GetBuilders(method), + _builders); + + EmitMethod(builders, method, BuildElement.AbstractMethod); + } + } + } + + private void OverrideVirtualProperties() + { + var props = _context.Type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + + foreach (var pi in props) + { + _context.CurrentProperty = pi; + + var propertyBuilders = GetBuilders(pi); + + var getter = pi.GetGetMethod(true); + + if (getter != null && getter.IsVirtual && !getter.IsAbstract && !getter.IsFinal) + OverrideGetter(getter, propertyBuilders); + + var setter = pi.GetSetMethod(true); + + if (setter != null && setter.IsVirtual && !setter.IsAbstract && !setter.IsFinal) + OverrideSetter(setter, propertyBuilders); + } + + _context.CurrentProperty = null; + } + + private void OverrideGetter(MethodInfo getter, AbstractTypeBuilderList propertyBuilders) + { + var builders = Combine( + GetBuilders(getter.GetParameters()), + GetBuilders(getter.ReturnParameter), + GetBuilders(getter), + propertyBuilders, + _builders); + + if (IsApplied(BuildElement.VirtualGetter, builders)) + EmitMethod(builders, getter, BuildElement.VirtualGetter); + } + + private void OverrideSetter(MethodInfo setter, AbstractTypeBuilderList propertyBuilders) + { + var builders = Combine( + GetBuilders(setter.GetParameters()), + GetBuilders(setter.ReturnParameter), + GetBuilders(setter), + propertyBuilders, + _builders); + + if (IsApplied(BuildElement.VirtualSetter, builders)) + EmitMethod(builders, setter, BuildElement.VirtualSetter); + } + + private void OverrideVirtualMethods() + { + var methods = _context.Type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + + foreach (var method in methods) + { + if (method.IsVirtual && + method.IsAbstract == false && + method.IsFinal == false && + (method.Attributes & MethodAttributes.SpecialName) == 0 && + method.DeclaringType != typeof(object)) + { + var builders = Combine( + GetBuilders(method.GetParameters()), + GetBuilders(method.ReturnParameter), + GetBuilders(method), + _builders); + + if (IsApplied(BuildElement.VirtualMethod, builders)) + EmitMethod(builders, method, BuildElement.VirtualMethod); + } + } + } + + private void DefineInterfaces() + { + foreach (var de in _context.InterfaceMap) + { + _context.CurrentInterface = de.Key; + + var interfaceMethods = _context.CurrentInterface.GetMethods(); + + foreach (var m in interfaceMethods) + { + if (_context.TypeBuilder.OverriddenMethods.ContainsKey(m)) + continue; + + BeginEmitMethod(m); + + // Call builder to build the method. + // + var builder = de.Value; + + if (builder != null) + { + builder.ID = ++_idCounter; + + _context.BuildElement = BuildElement.InterfaceMethod; + _context.Step = BuildStep.Build; + builder.Build(_context); + } + + EndEmitMethod(); + } + + _context.CurrentInterface = null; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/AbstractTypeBuilderBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/AbstractTypeBuilderBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,428 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using System.Reflection.Emit; +using System.Diagnostics; + +using BLToolkit.Reflection; +using BLToolkit.Reflection.Emit; + +namespace BLToolkit.TypeBuilder.Builders +{ + public abstract class AbstractTypeBuilderBase : IAbstractTypeBuilder + { + public virtual Type[] GetInterfaces() + { + return null; + } + + private int _id; + public int ID + { + get { return _id; } + set { _id = value; } + } + + private object _targetElement; + public object TargetElement + { + get { return _targetElement; } + set { _targetElement = value; } + } + + private BuildContext _context; + public BuildContext Context + { + [DebuggerStepThrough] get { return _context; } + [DebuggerStepThrough] set { _context = value; } + } + + public virtual bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder) + { + return true; + } + + protected bool IsRelative(IAbstractTypeBuilder typeBuilder) + { + if (typeBuilder == null) throw new ArgumentNullException("typeBuilder"); + + return GetType().IsInstanceOfType(typeBuilder) || typeBuilder.GetType().IsInstanceOfType(this); + } + + public virtual bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + return false; + } + + public virtual int GetPriority(BuildContext context) + { + return TypeBuilderConsts.Priority.Normal; + } + + public virtual void Build(BuildContext context) + { + if (context == null) throw new ArgumentNullException("context"); + + Context = context; + + switch (context.Step) + { + case BuildStep.Begin: BeginMethodBuild(); return; + case BuildStep.End: EndMethodBuild(); return; + } + + switch (context.BuildElement) + { + case BuildElement.Type: + switch (context.Step) + { + case BuildStep.Before: BeforeBuildType(); break; + case BuildStep.Build: BuildType(); break; + case BuildStep.After: AfterBuildType(); break; + case BuildStep.Catch: CatchBuildType(); break; + case BuildStep.Finally: FinallyBuildType(); break; + } + + break; + + case BuildElement.AbstractGetter: + switch (context.Step) + { + case BuildStep.Before: BeforeBuildAbstractGetter(); break; + case BuildStep.Build: BuildAbstractGetter(); break; + case BuildStep.After: AfterBuildAbstractGetter(); break; + case BuildStep.Catch: CatchBuildAbstractGetter(); break; + case BuildStep.Finally: FinallyBuildAbstractGetter(); break; + } + + break; + + case BuildElement.AbstractSetter: + switch (context.Step) + { + case BuildStep.Before: BeforeBuildAbstractSetter(); break; + case BuildStep.Build: BuildAbstractSetter(); break; + case BuildStep.After: AfterBuildAbstractSetter(); break; + case BuildStep.Catch: CatchBuildAbstractSetter(); break; + case BuildStep.Finally: FinallyBuildAbstractSetter(); break; + } + + break; + + case BuildElement.AbstractMethod: + switch (context.Step) + { + case BuildStep.Before: BeforeBuildAbstractMethod(); break; + case BuildStep.Build: BuildAbstractMethod(); break; + case BuildStep.After: AfterBuildAbstractMethod(); break; + case BuildStep.Catch: CatchBuildAbstractMethod(); break; + case BuildStep.Finally: FinallyBuildAbstractMethod(); break; + } + + break; + + case BuildElement.VirtualGetter: + switch (context.Step) + { + case BuildStep.Before: BeforeBuildVirtualGetter(); break; + case BuildStep.Build: BuildVirtualGetter(); break; + case BuildStep.After: AfterBuildVirtualGetter(); break; + case BuildStep.Catch: CatchBuildVirtualGetter(); break; + case BuildStep.Finally: FinallyBuildVirtualGetter(); break; + } + + break; + + case BuildElement.VirtualSetter: + switch (context.Step) + { + case BuildStep.Before: BeforeBuildVirtualSetter(); break; + case BuildStep.Build: BuildVirtualSetter(); break; + case BuildStep.After: AfterBuildVirtualSetter(); break; + case BuildStep.Catch: CatchBuildVirtualSetter(); break; + case BuildStep.Finally: FinallyBuildVirtualSetter(); break; + } + + break; + + case BuildElement.VirtualMethod: + switch (context.Step) + { + case BuildStep.Before: BeforeBuildVirtualMethod(); break; + case BuildStep.Build: BuildVirtualMethod(); break; + case BuildStep.After: AfterBuildVirtualMethod(); break; + case BuildStep.Catch: CatchBuildVirtualMethod(); break; + case BuildStep.Finally: FinallyBuildVirtualMethod(); break; + } + + break; + + case BuildElement.InterfaceMethod: + BuildInterfaceMethod(); + break; + } + } + + protected virtual void BeforeBuildType () {} + protected virtual void BuildType () {} + protected virtual void AfterBuildType () {} + protected virtual void CatchBuildType () {} + protected virtual void FinallyBuildType () {} + + protected virtual void BeforeBuildAbstractGetter() {} + protected virtual void BuildAbstractGetter() {} + protected virtual void AfterBuildAbstractGetter() {} + protected virtual void CatchBuildAbstractGetter() {} + protected virtual void FinallyBuildAbstractGetter() {} + + protected virtual void BeforeBuildAbstractSetter() {} + protected virtual void BuildAbstractSetter() {} + protected virtual void AfterBuildAbstractSetter() {} + protected virtual void CatchBuildAbstractSetter() {} + protected virtual void FinallyBuildAbstractSetter() {} + + protected virtual void BeforeBuildAbstractMethod() {} + protected virtual void BuildAbstractMethod() {} + protected virtual void AfterBuildAbstractMethod() {} + protected virtual void CatchBuildAbstractMethod() {} + protected virtual void FinallyBuildAbstractMethod() {} + + protected virtual void BeforeBuildVirtualGetter () {} + protected virtual void BuildVirtualGetter () {} + protected virtual void AfterBuildVirtualGetter () {} + protected virtual void CatchBuildVirtualGetter () {} + protected virtual void FinallyBuildVirtualGetter () {} + + protected virtual void BeforeBuildVirtualSetter () {} + protected virtual void BuildVirtualSetter () {} + protected virtual void AfterBuildVirtualSetter () {} + protected virtual void CatchBuildVirtualSetter () {} + protected virtual void FinallyBuildVirtualSetter () {} + + protected virtual void BeforeBuildVirtualMethod () {} + protected virtual void BuildVirtualMethod () {} + protected virtual void AfterBuildVirtualMethod () {} + protected virtual void CatchBuildVirtualMethod () {} + protected virtual void FinallyBuildVirtualMethod () {} + + protected virtual void BuildInterfaceMethod () {} + + protected virtual void BeginMethodBuild () {} + protected virtual void EndMethodBuild () {} + + #region Helpers + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + protected bool CallLazyInstanceInsurer(FieldBuilder field) + { + if (field == null) throw new ArgumentNullException("field"); + + MethodBuilderHelper ensurer = Context.GetFieldInstanceEnsurer(field.Name); + + if (ensurer != null) + { + Context.MethodBuilder.Emitter + .ldarg_0 + .call (ensurer); + } + + return ensurer != null; + } + + [SuppressMessage("Microsoft.Performance", "CA1818:DoNotConcatenateStringsInsideLoops")] + protected virtual string GetFieldName(PropertyInfo propertyInfo) + { + string name = propertyInfo.Name; + + if (char.IsUpper(name[0]) && name.Length > 1 && char.IsLower(name[1])) + name = char.ToLower(name[0]) + name.Substring(1, name.Length - 1); + + name = "_" + name; + + foreach (ParameterInfo p in propertyInfo.GetIndexParameters()) + name += "." + p.ParameterType.FullName;//.Replace(".", "_").Replace("+", "_"); + + return name; + } + + protected string GetFieldName() + { + return GetFieldName(Context.CurrentProperty); + } + + protected FieldBuilder GetPropertyInfoField(PropertyInfo property) + { + string fieldName = GetFieldName(property) + "_$propertyInfo"; + FieldBuilder field = Context.GetField(fieldName); + + if (field == null) + { + field = Context.CreatePrivateStaticField(fieldName, typeof(PropertyInfo)); + + EmitHelper emit = Context.TypeBuilder.TypeInitializer.Emitter; + + ParameterInfo[] index = property.GetIndexParameters(); + + emit + .LoadType (Context.Type) + .ldstr (property.Name) + .LoadType (property.PropertyType) + ; + + if (index.Length == 0) + { + emit + .ldsfld (typeof(Type).GetField("EmptyTypes")) + ; + } + else + { + emit + .ldc_i4 (index.Length) + .newarr (typeof(Type)) + ; + + for (int i = 0; i < index.Length; i++) + emit + .dup + .ldc_i4 (i) + .LoadType (index[i].ParameterType) + .stelem_ref + .end() + ; + } + + emit + .call (typeof(TypeHelper).GetMethod("GetPropertyInfo")) + .stsfld (field) + ; + } + + return field; + } + + protected FieldBuilder GetPropertyInfoField() + { + return GetPropertyInfoField(Context.CurrentProperty); + } + + protected FieldBuilder GetParameterField() + { + string fieldName = GetFieldName() + "_$parameters"; + FieldBuilder field = Context.GetField(fieldName); + + if (field == null) + { + field = Context.CreatePrivateStaticField(fieldName, typeof(object[])); + + FieldBuilder piField = GetPropertyInfoField(); + EmitHelper emit = Context.TypeBuilder.TypeInitializer.Emitter; + + emit + .ldsfld (piField) + .call (typeof(TypeHelper).GetMethod("GetPropertyParameters")) + .stsfld (field) + ; + } + + return field; + } + + protected FieldBuilder GetTypeAccessorField() + { + string fieldName = "_" + GetObjectType().FullName + "_$typeAccessor"; + FieldBuilder field = Context.GetField(fieldName); + + if (field == null) + { + field = Context.CreatePrivateStaticField(fieldName, typeof(TypeAccessor)); + + EmitHelper emit = Context.TypeBuilder.TypeInitializer.Emitter; + + emit + .LoadType (GetObjectType()) + .call (typeof(TypeAccessor), "GetAccessor", typeof(Type)) + .stsfld (field) + ; + } + + return field; + } + + protected FieldBuilder GetArrayInitializer(Type arrayType) + { + string fieldName = "_array_of_$_" + arrayType.FullName; + FieldBuilder field = Context.GetField(fieldName); + + if (field == null) + { + field = Context.CreatePrivateStaticField(fieldName, arrayType); + + EmitHelper emit = Context.TypeBuilder.TypeInitializer.Emitter; + + int rank = arrayType.GetArrayRank(); + + if (rank > 1) + { + Type[] parameters = new Type[rank]; + + for (int i = 0; i < parameters.Length; i++) + { + parameters[i] = typeof(int); + emit.ldc_i4_0.end(); + } + + ConstructorInfo ci = TypeHelper.GetConstructor(arrayType, parameters); + + emit + .newobj (ci) + .stsfld (field) + ; + } + else + { + emit + .ldc_i4_0 + .newarr (arrayType.GetElementType()) + .stsfld (field) + ; + } + } + + return field; + } + + protected FieldBuilder GetArrayInitializer() + { + return GetArrayInitializer(Context.CurrentProperty.PropertyType); + } + + protected virtual Type GetFieldType() + { + var pi = Context.CurrentProperty; + var index = pi.GetIndexParameters(); + + switch (index.Length) + { + case 0: return pi.PropertyType; + case 1: return typeof(Dictionary); + default: + throw new InvalidOperationException(); + } + } + + protected virtual Type GetObjectType() + { + return GetFieldType(); + } + + protected virtual bool IsObjectHolder + { + get { return false; } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/AbstractTypeBuilderList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/AbstractTypeBuilderList.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace BLToolkit.TypeBuilder.Builders +{ + public class AbstractTypeBuilderList : List + { + public AbstractTypeBuilderList() + { + } + + public AbstractTypeBuilderList(int capacity) + : base(capacity) + { + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/BuildContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/BuildContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; +using System.Diagnostics; + +using BLToolkit.Reflection; +using BLToolkit.Reflection.Emit; + +namespace BLToolkit.TypeBuilder.Builders +{ + [DebuggerStepThrough] + public class BuildContext + { + public BuildContext(Type type) + { + Type = type; + Items = new Dictionary(10); + } + + public TypeHelper Type { get; private set; } + public AssemblyBuilderHelper AssemblyBuilder { get; set; } + public TypeBuilderHelper TypeBuilder { get; set; } + public Dictionary Items { get; private set; } + + public T GetItem(string key) + { + object value; + return Items.TryGetValue(key, out value) ? (T)value : default(T); + } + + private Dictionary _fields; + public Dictionary Fields + { + get { return _fields ?? (_fields = new Dictionary(10)); } + } + + private IDictionary _interfaceMap; + public IDictionary InterfaceMap + { + get { return _interfaceMap ?? (_interfaceMap = new Dictionary()); } + } + + public TypeHelper CurrentInterface { get; set; } + public MethodBuilderHelper MethodBuilder { get; set; } + public LocalBuilder ReturnValue { get; set; } + public LocalBuilder Exception { get; set; } + public Label ReturnLabel { get; set; } + + #region BuildElement + + public BuildElement BuildElement { get; set; } + + public bool IsAbstractGetter { get { return BuildElement == BuildElement.AbstractGetter; } } + public bool IsAbstractSetter { get { return BuildElement == BuildElement.AbstractSetter; } } + public bool IsAbstractProperty { get { return IsAbstractGetter || IsAbstractSetter; } } + public bool IsAbstractMethod { get { return BuildElement == BuildElement.AbstractMethod; } } + public bool IsVirtualGetter { get { return BuildElement == BuildElement.VirtualGetter; } } + public bool IsVirtualSetter { get { return BuildElement == BuildElement.VirtualSetter; } } + public bool IsVirtualProperty { get { return IsVirtualGetter || IsVirtualSetter; } } + public bool IsVirtualMethod { get { return BuildElement == BuildElement.VirtualMethod; } } + public bool IsGetter { get { return IsAbstractGetter || IsVirtualGetter; } } + public bool IsSetter { get { return IsAbstractSetter || IsVirtualSetter; } } + public bool IsProperty { get { return IsGetter || IsSetter; } } + public bool IsMethod { get { return IsAbstractMethod || IsVirtualMethod; } } + public bool IsMethodOrProperty { get { return IsMethod || IsProperty; } } + + #endregion + + #region BuildStep + + public BuildStep Step { get; set; } + + public bool IsBeginStep { get { return Step == BuildStep.Begin; } } + public bool IsBeforeStep { get { return Step == BuildStep.Before; } } + public bool IsBuildStep { get { return Step == BuildStep.Build; } } + public bool IsAfterStep { get { return Step == BuildStep.After; } } + public bool IsCatchStep { get { return Step == BuildStep.Catch; } } + public bool IsFinallyStep { get { return Step == BuildStep.Finally; } } + public bool IsEndStep { get { return Step == BuildStep.End; } } + + public bool IsBeforeOrBuildStep + { + get { return Step == BuildStep.Before || Step == BuildStep.Build; } + } + + #endregion + + public AbstractTypeBuilderList TypeBuilders { get; set; } + public PropertyInfo CurrentProperty { get; set; } + public MethodInfo CurrentMethod { get; set; } + + #region Internal Methods + + public FieldBuilder GetField(string fieldName) + { + return GetItem("$BLToolkit.Field." + fieldName); + } + + public FieldBuilder CreateField(string fieldName, Type type, FieldAttributes attributes) + { + var field = TypeBuilder.DefineField(fieldName, type, attributes); + + field.SetCustomAttribute(MethodBuilder.Type.Assembly.BLToolkitAttribute); + + Items.Add("$BLToolkit.Field." + fieldName, field); + + return field; + } + + public FieldBuilder CreatePrivateField(string fieldName, Type type) + { + return CreateField(fieldName, type, FieldAttributes.Private); + } + + public FieldBuilder CreatePrivateField(PropertyInfo propertyInfo, string fieldName, Type type) + { + var field = CreateField(fieldName, type, FieldAttributes.Private); + + if (propertyInfo != null) + Fields.Add(propertyInfo, field); + + return field; + } + + public FieldBuilder CreatePrivateStaticField(string fieldName, Type type) + { + return CreateField(fieldName, type, FieldAttributes.Private | FieldAttributes.Static); + } + + public MethodBuilderHelper GetFieldInstanceEnsurer(string fieldName) + { + return GetItem("$BLToolkit.FieldInstanceEnsurer." + fieldName); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/BuildElement.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/BuildElement.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,14 @@ +namespace BLToolkit.TypeBuilder.Builders +{ + public enum BuildElement + { + Type, + AbstractGetter, + AbstractSetter, + AbstractMethod, + VirtualGetter, + VirtualSetter, + VirtualMethod, + InterfaceMethod + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/BuildStep.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/BuildStep.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +namespace BLToolkit.TypeBuilder.Builders +{ + public enum BuildStep + { + Begin, + Before, + Build, + After, + Catch, + Finally, + End + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/DefaultTypeBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/DefaultTypeBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1064 @@ +using System; +using System.Collections; +using System.Reflection; +using System.Reflection.Emit; +using System.Collections.Generic; + +namespace BLToolkit.TypeBuilder.Builders +{ + using Properties; + using Reflection; + using Reflection.Emit; + + public class DefaultTypeBuilder : AbstractTypeBuilderBase + { + #region Interface Overrides + + public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder) + { + return IsRelative(typeBuilder) == false; + } + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + if (context == null) throw new ArgumentNullException("context"); + + if (context.IsAbstractProperty && context.IsBeforeOrBuildStep) + { + return context.CurrentProperty.GetIndexParameters().Length <= 1; + } + + return context.BuildElement == BuildElement.Type && context.IsAfterStep; + } + + #endregion + + #region Get/Set Implementation + + protected override void BuildAbstractGetter() + { + var field = GetField(); + var index = Context.CurrentProperty.GetIndexParameters(); + + switch (index.Length) + { + case 0: + Context.MethodBuilder.Emitter + .ldarg_0 + .ldfld (field) + .stloc (Context.ReturnValue) + ; + break; + + case 1: + Context.MethodBuilder.Emitter + .ldarg_0 + .ldfld (field) + .ldarg_1 + .boxIfValueType (index[0].ParameterType) + .callvirt (typeof(Dictionary), "get_Item", typeof(object)) + .castType (Context.CurrentProperty.PropertyType) + .stloc (Context.ReturnValue) + ; + break; + } + } + + protected override void BuildAbstractSetter() + { + var field = GetField(); + var index = Context.CurrentProperty.GetIndexParameters(); + + switch (index.Length) + { + case 0: + Context.MethodBuilder.Emitter + .ldarg_0 + .ldarg_1 + .stfld (field) + ; + //Context.MethodBuilder.Emitter.AddMaxStackSize(6); + break; + + case 1: + Context.MethodBuilder.Emitter + .ldarg_0 + .ldfld (field) + .ldarg_1 + .boxIfValueType (index[0].ParameterType) + .ldarg_2 + .boxIfValueType (Context.CurrentProperty.PropertyType) + .callvirt (typeof(Dictionary), "set_Item", typeof(object), typeof(object)) + ; + break; + } + } + + #endregion + + #region Call Base Method + + protected override void BuildVirtualGetter() + { + CallBaseMethod(); + } + + protected override void BuildVirtualSetter() + { + CallBaseMethod(); + } + + protected override void BuildVirtualMethod() + { + CallBaseMethod(); + } + + private void CallBaseMethod() + { + var emit = Context.MethodBuilder.Emitter; + var method = Context.MethodBuilder.OverriddenMethod; + var ps = method.GetParameters(); + + emit.ldarg_0.end(); + + for (var i = 0; i < ps.Length; i++) + emit.ldarg(i + 1); + + emit.call(method); + + if (Context.ReturnValue != null) + emit.stloc(Context.ReturnValue); + } + + #endregion + + #region Properties + + private static TypeHelper _initContextType; + protected static TypeHelper InitContextType + { + get { return _initContextType ?? (_initContextType = new TypeHelper(typeof(InitContext))); } + } + + #endregion + + #region Field Initialization + + #region Overrides + + protected override void BeforeBuildAbstractGetter() + { + CallLazyInstanceInsurer(GetField()); + } + + protected override void BeforeBuildAbstractSetter() + { + var field = GetField(); + + if (field.FieldType != Context.CurrentProperty.PropertyType) + CallLazyInstanceInsurer(field); + } + + #endregion + + #region Common + + protected FieldBuilder GetField() + { + var propertyInfo = Context.CurrentProperty; + var fieldName = GetFieldName(); + var fieldType = GetFieldType(); + var field = Context.GetField(fieldName); + + if (field == null) + { + field = Context.CreatePrivateField(propertyInfo, fieldName, fieldType); + + if (TypeAccessor.IsInstanceBuildable(fieldType)) + { + var noInstance = propertyInfo.GetCustomAttributes(typeof(NoInstanceAttribute), true).Length > 0; + + if (IsObjectHolder && noInstance) + { + BuildHolderInstance(Context.TypeBuilder.DefaultConstructor.Emitter); + BuildHolderInstance(Context.TypeBuilder.InitConstructor.Emitter); + } + else if (!noInstance) + { + if (fieldType.IsClass && IsLazyInstance(fieldType)) + { + BuildLazyInstanceEnsurer(); + } + else + { + BuildDefaultInstance(); + BuildInitContextInstance(); + } + } + } + } + + return field; + } + + #endregion + + #region Build + + private void BuildHolderInstance(EmitHelper emit) + { + var fieldName = GetFieldName(); + var field = Context.GetField(fieldName); + var fieldType = new TypeHelper(field.FieldType); + var objectType = new TypeHelper(GetObjectType()); + + var ci = fieldType.GetPublicDefaultConstructor(); + + if (ci != null) + { + emit + .ldarg_0 + .newobj (ci) + .stfld (field) + ; + } + else + { + if (!CheckObjectHolderCtor(fieldType, objectType)) + return; + + emit + .ldarg_0 + .ldnull + .newobj (fieldType, objectType) + .stfld (field) + ; + } + } + + private void CreateDefaultInstance( + FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit) + { + if (!CheckObjectHolderCtor(fieldType, objectType)) + return; + + if (objectType.Type == typeof(string)) + { + emit + .ldarg_0 + .LoadInitValue (objectType) + ; + } + else if (objectType.IsArray) + { + var initializer = GetArrayInitializer(objectType); + + emit + .ldarg_0 + .ldsfld (initializer) + ; + } + else + { + var ci = objectType.GetPublicDefaultConstructor(); + + if (ci == null) + { + if (objectType.Type.IsValueType) + return; + + var message = string.Format( + Resources.TypeBuilder_PropertyTypeHasNoPublicDefaultCtor, + Context.CurrentProperty.Name, + Context.Type.FullName, + objectType.FullName); + + emit + .ldstr (message) + .newobj (typeof(TypeBuilderException), typeof(string)) + .@throw + .end() + ; + + return; + } + + emit + .ldarg_0 + .newobj (ci) + ; + } + + if (IsObjectHolder) + { + emit + .newobj (fieldType, objectType) + ; + } + + emit + .stfld (field) + ; + } + + private void CreateParametrizedInstance( + FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters) + { + if (!CheckObjectHolderCtor(fieldType, objectType)) + return; + + Stack genericNestedConstructors; + if (parameters.Length == 1) + { + var o = parameters[0]; + + if (o == null) + { + if (objectType.IsValueType == false) + emit + .ldarg_0 + .ldnull + .end() + ; + + if (IsObjectHolder) + { + emit + .newobj (fieldType, objectType) + ; + } + else + { + if (objectType.Type.IsGenericType) + { + Type nullableType = null; + genericNestedConstructors = GetGenericNestedConstructors( + objectType, + typeHelper => + typeHelper.IsValueType == false || + (typeHelper.Type.IsGenericType && typeHelper.Type.GetGenericTypeDefinition() == typeof (Nullable<>)), + typeHelper => { nullableType = typeHelper.Type; }, + () => nullableType != null); + + if (nullableType == null) + throw new Exception("Cannot find nullable type in generic types chain"); + + if (nullableType.IsValueType == false) + { + emit + .ldarg_0 + .ldnull + .end() + ; + } + else + { + var nullable = emit.DeclareLocal(nullableType); + + emit + .ldloca(nullable) + .initobj(nullableType) + .ldarg_0 + .ldloc(nullable) + ; + + if (genericNestedConstructors != null) + { + while (genericNestedConstructors.Count != 0) + { + emit + .newobj(genericNestedConstructors.Pop()) + ; + } + } + } + } + } + + emit + .stfld (field) + ; + + return; + } + + if (objectType.Type == o.GetType()) + { + if (objectType.Type == typeof(string)) + { + emit + .ldarg_0 + .ldstr ((string)o) + .stfld (field) + ; + + return; + } + + if (objectType.IsValueType) + { + emit.ldarg_0.end(); + + if (emit.LoadWellKnownValue(o) == false) + { + emit + .ldsfld (GetParameterField()) + .ldc_i4_0 + .ldelem_ref + .end() + ; + } + + emit.stfld(field); + + return; + } + } + } + + var types = new Type[parameters.Length]; + + for (var i = 0; i < parameters.Length; i++) + { + if (parameters[i] != null) + { + var t = parameters[i].GetType(); + + types[i] = (t.IsEnum) ? Enum.GetUnderlyingType(t) : t; + } + else + types[i] = typeof(object); + } + + // Do some heuristics for Nullable and EditableValue + // + ConstructorInfo objectCtor = null; + genericNestedConstructors = GetGenericNestedConstructors( + objectType, + typeHelper => true, + typeHelper => { objectCtor = typeHelper.GetPublicConstructor(types); }, + () => objectCtor != null); + + if (objectCtor == null) + { + if (objectType.IsValueType) + return; + + throw new TypeBuilderException( + string.Format(types.Length == 0? + Resources.TypeBuilder_PropertyTypeHasNoPublicDefaultCtor: + Resources.TypeBuilder_PropertyTypeHasNoPublicCtor, + Context.CurrentProperty.Name, + Context.Type.FullName, + objectType.FullName)); + } + + var pi = objectCtor.GetParameters(); + + emit.ldarg_0.end(); + + for (var i = 0; i < parameters.Length; i++) + { + var o = parameters[i]; + var oType = o.GetType(); + + if (emit.LoadWellKnownValue(o)) + { + if (oType.IsValueType) + { + if (!pi[i].ParameterType.IsValueType) + emit.box(oType); + else if (Type.GetTypeCode(oType) != Type.GetTypeCode(pi[i].ParameterType)) + emit.conv(pi[i].ParameterType); + } + } + else + { + emit + .ldsfld (GetParameterField()) + .ldc_i4 (i) + .ldelem_ref + .CastFromObject (types[i]) + ; + + if (oType.IsValueType && !pi[i].ParameterType.IsValueType) + emit.box(oType); + } + } + + emit + .newobj (objectCtor) + ; + + if (genericNestedConstructors != null) + { + while (genericNestedConstructors.Count != 0) + { + emit + .newobj(genericNestedConstructors.Pop()) + ; + } + } + + if (IsObjectHolder) + { + emit + .newobj (fieldType, objectType) + ; + } + + emit + .stfld (field) + ; + } + + private Stack GetGenericNestedConstructors(TypeHelper objectType, + Predicate isActionable, + Action action, + Func isBreakCondition) + { + Stack genericNestedConstructors = null; + + if (isActionable(objectType)) + action(objectType); + + while (objectType.Type.IsGenericType && !isBreakCondition()) + { + var typeArgs = objectType.Type.GetGenericArguments(); + + if (typeArgs.Length == 1) + { + var genericCtor = objectType.GetPublicConstructor(typeArgs[0]); + + if (genericCtor != null) + { + if (genericNestedConstructors == null) + genericNestedConstructors = new Stack(); + + genericNestedConstructors.Push(genericCtor); + objectType = typeArgs[0]; + + if (isActionable(objectType)) + action(objectType); + } + } + else + { + throw new TypeBuilderException( + string.Format(Resources.TypeBuilder_GenericShouldBeSingleTyped, + Context.CurrentProperty.Name, + Context.Type.FullName, + objectType.FullName)); + } + } + + return genericNestedConstructors; + } + + #endregion + + #region Build InitContext Instance + + private void BuildInitContextInstance() + { + var fieldName = GetFieldName(); + var field = Context.GetField(fieldName); + var fieldType = new TypeHelper(field.FieldType); + var objectType = new TypeHelper(GetObjectType()); + + var emit = Context.TypeBuilder.InitConstructor.Emitter; + + var parameters = TypeHelper.GetPropertyParameters(Context.CurrentProperty); + var ci = objectType.GetPublicConstructor(typeof(InitContext)); + + if (ci != null && ci.GetParameters()[0].ParameterType != typeof(InitContext)) + ci = null; + + if (ci != null || objectType.IsAbstract) + CreateAbstractInitContextInstance(field, fieldType, objectType, emit, parameters); + else if (parameters == null) + CreateDefaultInstance(field, fieldType, objectType, emit); + else + CreateParametrizedInstance(field, fieldType, objectType, emit, parameters); + } + + private void CreateAbstractInitContextInstance( + FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters) + { + if (!CheckObjectHolderCtor(fieldType, objectType)) + return; + + var memberParams = InitContextType.GetProperty("MemberParameters").GetSetMethod(); + var parentField = Context.GetItem("$BLToolkit.InitContext.Parent"); + + if (parentField == null) + { + Context.Items.Add("$BLToolkit.InitContext.Parent", parentField = emit.DeclareLocal(typeof(object))); + + var label = emit.DefineLabel(); + + emit + .ldarg_1 + .brtrue_s (label) + + .newobj (InitContextType.GetPublicDefaultConstructor()) + .starg (1) + + .ldarg_1 + .ldc_i4_1 + .callvirt (InitContextType.GetProperty("IsInternal").GetSetMethod()) + + .MarkLabel (label) + + .ldarg_1 + .callvirt (InitContextType.GetProperty("Parent").GetGetMethod()) + .stloc (parentField) + ; + } + + emit + .ldarg_1 + .ldarg_0 + .callvirt (InitContextType.GetProperty("Parent").GetSetMethod()) + ; + + var isDirty = Context.GetItem("$BLToolkit.InitContext.DirtyParameters"); + + if (parameters != null) + { + emit + .ldarg_1 + .ldsfld (GetParameterField()) + .callvirt (memberParams) + ; + } + else if (isDirty != null && (bool)isDirty) + { + emit + .ldarg_1 + .ldnull + .callvirt (memberParams) + ; + } + + if (Context.Items.ContainsKey("$BLToolkit.InitContext.DirtyParameters")) + Context.Items["$BLToolkit.InitContext.DirtyParameters"] = (bool?)(parameters != null); + else + Context.Items.Add("$BLToolkit.InitContext.DirtyParameters", (bool?)(parameters != null)); + + if (objectType.IsAbstract) + { + emit + .ldarg_0 + .ldsfld (GetTypeAccessorField()) + .ldarg_1 + .callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType) + .isinst (objectType) + ; + } + else + { + emit + .ldarg_0 + .ldarg_1 + .newobj (objectType.GetPublicConstructor(typeof(InitContext))) + ; + } + + if (IsObjectHolder) + { + emit + .newobj (fieldType, objectType) + ; + } + + emit + .stfld (field) + ; + } + + #endregion + + #region Build Default Instance + + private void BuildDefaultInstance() + { + var fieldName = GetFieldName(); + var field = Context.GetField(fieldName); + var fieldType = new TypeHelper(field.FieldType); + var objectType = new TypeHelper(GetObjectType()); + + var emit = Context.TypeBuilder.DefaultConstructor.Emitter; + var ps = TypeHelper.GetPropertyParameters(Context.CurrentProperty); + var ci = objectType.GetPublicConstructor(typeof(InitContext)); + + if (ci != null && ci.GetParameters()[0].ParameterType != typeof(InitContext)) + ci = null; + + if (ci != null || objectType.IsAbstract) + CreateInitContextDefaultInstance( + "$BLToolkit.DefaultInitContext.", field, fieldType, objectType, emit, ps); + else if (ps == null) + CreateDefaultInstance(field, fieldType, objectType, emit); + else + CreateParametrizedInstance(field, fieldType, objectType, emit, ps); + } + + private bool CheckObjectHolderCtor(TypeHelper fieldType, TypeHelper objectType) + { + if (IsObjectHolder) + { + var holderCi = fieldType.GetPublicConstructor(objectType); + + if (holderCi == null) + { + var message = string.Format( + Resources.TypeBuilder_PropertyTypeHasNoCtorWithParamType, + Context.CurrentProperty.Name, + Context.Type.FullName, + fieldType.FullName, + objectType.FullName); + + Context.TypeBuilder.DefaultConstructor.Emitter + .ldstr (message) + .newobj (typeof(TypeBuilderException), typeof(string)) + .@throw + .end() + ; + + return false; + } + } + + return true; + } + + private void CreateInitContextDefaultInstance( + string initContextName, + FieldBuilder field, + TypeHelper fieldType, + TypeHelper objectType, + EmitHelper emit, + object[] parameters) + { + if (!CheckObjectHolderCtor(fieldType, objectType)) + return; + + var initField = GetInitContextBuilder(initContextName, emit); + var memberParams = InitContextType.GetProperty("MemberParameters").GetSetMethod(); + + if (parameters != null) + { + emit + .ldloc (initField) + .ldsfld (GetParameterField()) + .callvirt (memberParams) + ; + } + else if ((bool)Context.Items["$BLToolkit.Default.DirtyParameters"]) + { + emit + .ldloc (initField) + .ldnull + .callvirt (memberParams) + ; + } + + Context.Items["$BLToolkit.Default.DirtyParameters"] = parameters != null; + + if (objectType.IsAbstract) + { + emit + .ldarg_0 + .ldsfld (GetTypeAccessorField()) + .ldloc (initField) + .callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType) + .isinst (objectType) + ; + } + else + { + emit + .ldarg_0 + .ldloc (initField) + .newobj (objectType.GetPublicConstructor(typeof(InitContext))) + ; + } + + if (IsObjectHolder) + { + emit + .newobj (fieldType, objectType) + ; + } + + emit + .stfld (field) + ; + } + + private LocalBuilder GetInitContextBuilder( + string initContextName, EmitHelper emit) + { + var initField = Context.GetItem(initContextName); + + if (initField == null) + { + Context.Items.Add(initContextName, initField = emit.DeclareLocal(InitContextType)); + + emit + .newobj (InitContextType.GetPublicDefaultConstructor()) + + .dup + .ldarg_0 + .callvirt (InitContextType.GetProperty("Parent").GetSetMethod()) + + .dup + .ldc_i4_1 + .callvirt (InitContextType.GetProperty("IsInternal").GetSetMethod()) + + .stloc (initField) + ; + + Context.Items.Add("$BLToolkit.Default.DirtyParameters", false); + } + + return initField; + } + + #endregion + + #region Build Lazy Instance + + private bool IsLazyInstance(Type type) + { + var attrs = Context.CurrentProperty.GetCustomAttributes(typeof(LazyInstanceAttribute), true); + + if (attrs.Length > 0) + return ((LazyInstanceAttribute)attrs[0]).IsLazy; + + attrs = Context.Type.GetAttributes(typeof(LazyInstancesAttribute)); + + foreach (LazyInstancesAttribute a in attrs) + if (a.Type == typeof(object) || type == a.Type || type.IsSubclassOf(a.Type)) + return a.IsLazy; + + return false; + } + + private void BuildLazyInstanceEnsurer() + { + var fieldName = GetFieldName(); + var field = Context.GetField(fieldName); + var fieldType = new TypeHelper(field.FieldType); + var objectType = new TypeHelper(GetObjectType()); + var ensurer = Context.TypeBuilder.DefineMethod( + string.Format("$EnsureInstance{0}", fieldName), + MethodAttributes.Private | MethodAttributes.HideBySig); + + var emit = ensurer.Emitter; + var end = emit.DefineLabel(); + + emit + .ldarg_0 + .ldfld (field) + .brtrue_s (end) + ; + + var parameters = TypeHelper.GetPropertyParameters(Context.CurrentProperty); + var ci = objectType.GetPublicConstructor(typeof(InitContext)); + + if (ci != null || objectType.IsAbstract) + CreateInitContextLazyInstance(field, fieldType, objectType, emit, parameters); + else if (parameters == null) + CreateDefaultInstance(field, fieldType, objectType, emit); + else + CreateParametrizedInstance(field, fieldType, objectType, emit, parameters); + + emit + .MarkLabel(end) + .ret() + ; + + Context.Items.Add("$BLToolkit.FieldInstanceEnsurer." + fieldName, ensurer); + } + + private void CreateInitContextLazyInstance( + FieldBuilder field, + TypeHelper fieldType, + TypeHelper objectType, + EmitHelper emit, + object[] parameters) + { + if (!CheckObjectHolderCtor(fieldType, objectType)) + return; + + var initField = emit.DeclareLocal(InitContextType); + + emit + .newobj (InitContextType.GetPublicDefaultConstructor()) + + .dup + .ldarg_0 + .callvirt (InitContextType.GetProperty("Parent").GetSetMethod()) + + .dup + .ldc_i4_1 + .callvirt (InitContextType.GetProperty("IsInternal").GetSetMethod()) + + .dup + .ldc_i4_1 + .callvirt (InitContextType.GetProperty("IsLazyInstance").GetSetMethod()) + + ; + + if (parameters != null) + { + emit + .dup + .ldsfld (GetParameterField()) + .callvirt (InitContextType.GetProperty("MemberParameters").GetSetMethod()) + ; + } + + emit + .stloc (initField); + + if (objectType.IsAbstract) + { + emit + .ldarg_0 + .ldsfld (GetTypeAccessorField()) + .ldloc (initField) + .callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType) + .isinst (objectType) + ; + } + else + { + emit + .ldarg_0 + .ldloc (initField) + .newobj (objectType.GetPublicConstructor(typeof(InitContext))) + ; + } + + if (IsObjectHolder) + { + emit + .newobj (fieldType, objectType) + ; + } + + emit + .stfld (field) + ; + } + + #endregion + + #region Finalize Type + + protected override void AfterBuildType() + { + var isDirty = Context.GetItem("$BLToolkit.InitContext.DirtyParameters"); + + if (isDirty != null && isDirty.Value) + { + Context.TypeBuilder.InitConstructor.Emitter + .ldarg_1 + .ldnull + .callvirt (InitContextType.GetProperty("MemberParameters").GetSetMethod()) + ; + } + + var localBuilder = Context.GetItem("$BLToolkit.InitContext.Parent"); + + if (localBuilder != null) + { + Context.TypeBuilder.InitConstructor.Emitter + .ldarg_1 + .ldloc (localBuilder) + .callvirt (InitContextType.GetProperty("Parent").GetSetMethod()) + ; + } + + FinalizeDefaultConstructors(); + FinalizeInitContextConstructors(); + } + + private void FinalizeDefaultConstructors() + { + var ci = Context.Type.GetDefaultConstructor(); + + if (ci == null || Context.TypeBuilder.IsDefaultConstructorDefined) + { + var emit = Context.TypeBuilder.DefaultConstructor.Emitter; + + if (ci != null) + { + emit.ldarg_0.call(ci); + } + else + { + ci = Context.Type.GetConstructor(typeof(InitContext)); + + if (ci != null) + { + var initField = GetInitContextBuilder("$BLToolkit.DefaultInitContext.", emit); + + emit + .ldarg_0 + .ldloc (initField) + .call (ci); + } + else + { + if (Context.Type.GetConstructors().Length > 0) + throw new TypeBuilderException(string.Format( + Resources.TypeBuilder_NoDefaultCtor, + Context.Type.FullName)); + } + } + } + } + + private void FinalizeInitContextConstructors() + { + var ci = Context.Type.GetConstructor(typeof(InitContext)); + + if (ci != null || Context.TypeBuilder.IsInitConstructorDefined) + { + var emit = Context.TypeBuilder.InitConstructor.Emitter; + + if (ci != null) + { + emit + .ldarg_0 + .ldarg_1 + .call (ci); + } + else + { + ci = Context.Type.GetDefaultConstructor(); + + if (ci != null) + { + emit.ldarg_0.call(ci); + } + else + { + if (Context.Type.GetConstructors().Length > 0) + throw new TypeBuilderException( + string.Format(Resources.TypeBuilder_NoDefaultCtor, + Context.Type.FullName)); + } + } + } + } + + #endregion + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/DuckTypeBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/DuckTypeBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,282 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +using BLToolkit.Patterns; +using BLToolkit.Properties; +using BLToolkit.Reflection.Emit; + +namespace BLToolkit.TypeBuilder.Builders +{ + class DuckTypeBuilder : ITypeBuilder + { + public DuckTypeBuilder(MustImplementAttribute defaultAttribute, Type interfaceType, Type[] objectTypes) + { + _interfaceType = interfaceType; + _objectTypes = objectTypes; + _defaultAttribute = defaultAttribute; + } + + private readonly Type _interfaceType; + private readonly Type[] _objectTypes; + private TypeBuilderHelper _typeBuilder; + private readonly MustImplementAttribute _defaultAttribute; + + #region ITypeBuilder Members + + public string AssemblyNameSuffix + { + get { return "DuckType." + AbstractClassBuilder.GetTypeFullName(_interfaceType).Replace('+', '.'); } + } + + public Type Build(AssemblyBuilderHelper assemblyBuilder) + { + _typeBuilder = assemblyBuilder.DefineType(GetTypeName(), typeof(DuckType), _interfaceType); + + if (!BuildMembers(_interfaceType)) + return null; + + foreach (Type t in _interfaceType.GetInterfaces()) + if (!BuildMembers(t)) + return null; + + return _typeBuilder.Create(); + } + + public string GetTypeName() + { + string name = String.Empty; + + foreach (Type t in _objectTypes) + { + if (t != null) + name += AbstractClassBuilder.GetTypeFullName(t).Replace('+', '.'); + name += "$"; + } + + return name + AssemblyNameSuffix; + } + + public Type GetBuildingType() + { + return _interfaceType; + } + + #endregion + + private static bool CompareMethodSignature(MethodInfo m1, MethodInfo m2) + { + if (m1 == m2) + return true; + + if (m1.Name != m2.Name) + return false; + + if (m1.ReturnType != m2.ReturnType) + return false; + + ParameterInfo[] ps1 = m1.GetParameters(); + ParameterInfo[] ps2 = m2.GetParameters(); + + if (ps1.Length != ps2.Length) + return false; + + for (int i = 0; i < ps1.Length; i++) + { + ParameterInfo p1 = ps1[i]; + ParameterInfo p2 = ps2[i]; + + if (p1.ParameterType != p2.ParameterType || +#if !SILVERLIGHT + p1.IsIn != p2.IsIn || +#endif + p1.IsOut != p2.IsOut) + return false; + } + + return true; + } + + private bool BuildMembers(Type interfaceType) + { + FieldInfo objectsField = typeof(DuckType).GetField("_objects", BindingFlags.NonPublic | BindingFlags.Instance); + BindingFlags flags = BindingFlags.Public | BindingFlags.Instance + | (DuckTyping.AllowStaticMembers? BindingFlags.Static | BindingFlags.FlattenHierarchy: 0); + + foreach (MethodInfo interfaceMethod in interfaceType.GetMethods(BindingFlags.Public | BindingFlags.Instance)) + { + MethodInfo targetMethod = null; + int typeIndex = 0; + + for (; typeIndex < _objectTypes.Length; typeIndex++) + { + if (_objectTypes[typeIndex] == null) + continue; + + foreach (MethodInfo mi in _objectTypes[typeIndex].GetMethods(flags)) + { + if (CompareMethodSignature(interfaceMethod, mi)) + { + targetMethod = mi; + break; + } + } + + if (targetMethod == null) + { + foreach (Type intf in _objectTypes[typeIndex].GetInterfaces()) + { + if (intf.IsPublic || intf.IsNestedPublic) + { + foreach (MethodInfo mi in intf.GetMethods(flags)) + { + if (CompareMethodSignature(interfaceMethod, mi)) + { + targetMethod = mi; + break; + } + } + + if (targetMethod != null) + break; + } + } + } + + if (targetMethod != null) + break; + } + + ParameterInfo[] ips = interfaceMethod.GetParameters(); + MethodBuilderHelper builder = _typeBuilder.DefineMethod(interfaceMethod); + EmitHelper emit = builder.Emitter; + + if (targetMethod != null) + { + Type targetType = targetMethod.DeclaringType; + + if (!targetMethod.IsStatic) + { + emit + .ldarg_0 + .ldfld (objectsField) + .ldc_i4 (typeIndex) + .ldelem_ref + .end() + ; + + if (targetType.IsValueType) + { + // For value types we have to use stack. + // + LocalBuilder obj = emit.DeclareLocal(targetType); + + emit + .unbox_any (targetType) + .stloc (obj) + .ldloca (obj) + ; + } + else + emit + .castclass (targetType) + ; + } + + foreach (ParameterInfo p in ips) + emit.ldarg(p); + + if (targetMethod.IsStatic || targetMethod.IsFinal || targetMethod.DeclaringType.IsSealed) + emit + .call (targetMethod) + .ret(); + else + emit + .callvirt (targetMethod) + .ret(); + } + else + { + // Method or property was not found. + // Insert an empty stub or stub that throws the NotImplementedException. + // + MustImplementAttribute attr = (MustImplementAttribute) + Attribute.GetCustomAttribute(interfaceMethod, typeof (MustImplementAttribute)); + + if (attr == null) + { + attr = (MustImplementAttribute)Attribute.GetCustomAttribute( + interfaceMethod.DeclaringType, typeof (MustImplementAttribute)); + if (attr == null) + attr = _defaultAttribute; + } + + // When the member is marked as 'Required' throw a build-time exception. + // + if (attr.Implement) + { + if (attr.ThrowException) + { + throw new TypeBuilderException(string.Format( + Resources.TypeBuilder_PublicMethodMustBeImplemented, + _objectTypes.Length > 0 && _objectTypes[0] != null ? _objectTypes[0].FullName : "???", + interfaceMethod)); + } + else + { + // Implement == true, but ThrowException == false. + // In this case the null pointer will be returned. + // This mimics the 'as' operator behaviour. + // + return false; + } + } + + if (attr.ThrowException) + { + string message = attr.ExceptionMessage; + + if (message == null) + { + message = string.Format(Resources.TypeBuilder_PublicMethodNotImplemented, + _objectTypes.Length > 0 && _objectTypes[0] != null ? _objectTypes[0].FullName : "???", + interfaceMethod); + } + + emit + .ldstr (message) + .newobj (typeof(InvalidOperationException), typeof(string)) + .@throw + .end(); + } + else + { + // Emit a 'do nothing' stub. + // + LocalBuilder returnValue = null; + + if (interfaceMethod.ReturnType != typeof(void)) + { + returnValue = emit.DeclareLocal(interfaceMethod.ReturnType); + emit.Init(returnValue); + } + + // Initialize out parameters. + // + ParameterInfo[] parameters = ips; + + if (parameters != null) + emit.InitOutParameters(parameters); + + if (returnValue != null) + emit.ldloc(returnValue); + + emit.ret(); + } + } + } + + return true; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/FakeGetter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/FakeGetter.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using System; +using System.Reflection; + +namespace BLToolkit.TypeBuilder.Builders +{ + class FakeGetter : FakeMethodInfo + { + public FakeGetter(PropertyInfo propertyInfo) + : base(propertyInfo, propertyInfo.GetSetMethod(true)) + { + } + + public override ParameterInfo[] GetParameters() + { + return _property.GetIndexParameters(); + } + + public override string Name + { + get { return "get_" + _property.Name; } + } + + public override Type ReturnType + { + get { return _property.PropertyType; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/FakeMethodInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/FakeMethodInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,111 @@ +using System; +using System.Globalization; +using System.Reflection; + +namespace BLToolkit.TypeBuilder.Builders +{ + abstract class FakeMethodInfo : MethodInfo + { + protected FakeMethodInfo(PropertyInfo propertyInfo, MethodInfo pair) + { + _property = propertyInfo; + _pair = pair; + } + + protected MethodInfo _pair; + protected PropertyInfo _property; + + public override MethodAttributes Attributes + { + get { return _pair.Attributes; } + } + + public override CallingConventions CallingConvention + { + get { return _pair.CallingConvention; } + } + + public override Type DeclaringType + { + get { return _property.DeclaringType; } + } + + public override MethodInfo GetBaseDefinition() + { + return _pair.GetBaseDefinition(); + } + + public override object[] GetCustomAttributes(bool inherit) + { + return _property.GetCustomAttributes(inherit); + } + + public override object[] GetCustomAttributes(Type attributeType, bool inherit) + { + return _property.GetCustomAttributes(attributeType, inherit); + } + + public override MethodImplAttributes GetMethodImplementationFlags() + { + return _pair.GetMethodImplementationFlags(); + } + + public override object Invoke( + object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + { + return null; + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + return false; + } + + public override MemberTypes MemberType + { + get { return _property.MemberType; } + } + + public override RuntimeMethodHandle MethodHandle + { + get { return new RuntimeMethodHandle(); } + } + + public override Type ReflectedType + { + get { return _property.ReflectedType; } + } + + class CustomAttributeProvider : ICustomAttributeProvider + { + static readonly object[] _object = new object[0]; + + public object[] GetCustomAttributes(bool inherit) + { + return _object; + } + + public object[] GetCustomAttributes(Type attributeType, bool inherit) + { + return _object; + } + + public bool IsDefined(Type attributeType, bool inherit) + { + return false; + } + } + + static readonly CustomAttributeProvider _customAttributeProvider = new CustomAttributeProvider(); + + public override ICustomAttributeProvider ReturnTypeCustomAttributes + { + get { return _customAttributeProvider; } + } + + public override ParameterInfo ReturnParameter + { + get { return new FakeParameterInfo("ret", ReturnType, this, null); } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/FakeParameterInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/FakeParameterInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,92 @@ +using System; +using System.Collections; +using System.Reflection; + +namespace BLToolkit.TypeBuilder.Builders +{ + class FakeParameterInfo : ParameterInfo + { + public FakeParameterInfo(string name, Type type, MemberInfo memberInfo, object[] attributes) + { + _name = name; + _type = type; + _memberInfo = memberInfo; + _attributes = attributes ?? new object[0]; + } + + public FakeParameterInfo(MethodInfo method) : this( + "ret", + method.ReturnType, + method, + method.ReturnTypeCustomAttributes.GetCustomAttributes(true)) + { + } + + public override ParameterAttributes Attributes + { + get { return ParameterAttributes.Retval; } + } + + public override object DefaultValue + { + get { return DBNull.Value; } + } + + private readonly object[] _attributes; + + public override object[] GetCustomAttributes(bool inherit) + { + return _attributes; + } + + public override object[] GetCustomAttributes(Type attributeType, bool inherit) + { + if (attributeType == null) throw new ArgumentNullException("attributeType"); + + if (_attributes.Length == 0) + return (object[]) Array.CreateInstance(attributeType, 0); + + ArrayList list = new ArrayList(); + + foreach (object o in _attributes) + if (o.GetType() == attributeType || attributeType.IsInstanceOfType(o)) + list.Add(o); + + return (object[]) list.ToArray(attributeType); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + if (attributeType == null) throw new ArgumentNullException("attributeType"); + + foreach (object o in _attributes) + if (o.GetType() == attributeType || attributeType.IsInstanceOfType(o)) + return true; + + return false; + } + + private readonly MemberInfo _memberInfo; + public override MemberInfo Member + { + get { return _memberInfo; } + } + + private readonly string _name; + public override string Name + { + get { return _name; } + } + + private readonly Type _type; + public override Type ParameterType + { + get { return _type; } + } + + public override int Position + { + get { return 0; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/FakeSetter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/FakeSetter.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,34 @@ +using System; +using System.Reflection; + +namespace BLToolkit.TypeBuilder.Builders +{ + class FakeSetter : FakeMethodInfo + { + public FakeSetter(PropertyInfo propertyInfo) + : base(propertyInfo, propertyInfo.GetGetMethod(true)) + { + } + + public override ParameterInfo[] GetParameters() + { + var index = _property.GetIndexParameters(); + var pi = new ParameterInfo[index.Length + 1]; + + index.CopyTo(pi, 0); + pi[index.Length] = new FakeParameterInfo("value", _property.PropertyType, _property, null); + + return pi; + } + + public override string Name + { + get { return "set_" + _property.Name; } + } + + public override Type ReturnType + { + get { return typeof(void); } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/GeneratedAttributeBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/GeneratedAttributeBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; +using BLToolkit.Reflection; + +namespace BLToolkit.TypeBuilder.Builders +{ + internal class GeneratedAttributeBuilder : AbstractTypeBuilderBase + { + private CustomAttributeBuilder _attributeBuilder; + + public GeneratedAttributeBuilder(Type attributeType, object[] arguments, string[] names, object[] values) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + + ConstructorInfo constructor = null; + + if (arguments == null || arguments.Length == 0) + { + constructor = attributeType.GetConstructor(Type.EmptyTypes); + arguments = Type.EmptyTypes; + } + else + { + // Some arguments may be null. We can not infer a type from the null reference. + // So we must iterate all of them and got a suitable one. + // + foreach (ConstructorInfo ci in attributeType.GetConstructors()) + { + if (CheckParameters(ci.GetParameters(), arguments)) + { + constructor = ci; + break; + } + } + } + + if (constructor == null) + throw new TypeBuilderException(string.Format("No suitable constructors found for the type '{0}'.", attributeType.FullName)); + + if (names == null || names.Length == 0) + { + _attributeBuilder = new CustomAttributeBuilder(constructor, arguments); + } + else if (values == null || names.Length != values.Length) + { + throw new TypeBuilderException(string.Format("Named argument names count should match named argument values count.")); + } + else + { + List namedProperties = new List(); + List propertyValues = new List(); + List namedFields = new List(); + List fieldValues = new List(); + + for (int i = 0; i < names.Length; i++) + { + string name = names[i]; + MemberInfo[] mi = attributeType.GetMember(name); + + if (mi.Length == 0) + throw new TypeBuilderException(string.Format("The type '{0}' does not have a public member '{1}'.", attributeType.FullName, name)); + + if (mi[0].MemberType == MemberTypes.Property) + { + namedProperties.Add((PropertyInfo)mi[0]); + propertyValues.Add(values[i]); + } + else if (mi[0].MemberType == MemberTypes.Field) + { + namedFields.Add((FieldInfo)mi[0]); + fieldValues.Add(values[i]); + } + else + throw new TypeBuilderException(string.Format("The member '{1}' of the type '{0}' is not a filed nor a property.", name, attributeType.FullName)); + } + + _attributeBuilder = new CustomAttributeBuilder(constructor, arguments, + namedProperties.ToArray(), propertyValues.ToArray(), namedFields.ToArray(), fieldValues.ToArray()); + } + } + + private static bool CheckParameters(ParameterInfo[] argumentTypes, object[] arguments) + { + if (argumentTypes.Length != arguments.Length) + return false; + + for (int i = 0; i < arguments.Length; i++) + { + if (arguments[i] == null && argumentTypes[i].ParameterType.IsClass) + continue; + + if (argumentTypes[i].ParameterType.IsAssignableFrom(arguments[i].GetType())) + continue; + + // Bad match + // + return false; + } + + return true; + } + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + return context.IsAfterStep && context.BuildElement == BuildElement.Type == TargetElement is TypeHelper; + } + + public override void Build(BuildContext context) + { + if (context.BuildElement == BuildElement.Type) + { + context.TypeBuilder.TypeBuilder.SetCustomAttribute(_attributeBuilder); + } + else if (TargetElement is MethodInfo) + { + context.MethodBuilder.MethodBuilder.SetCustomAttribute(_attributeBuilder); + } + else if (TargetElement is PropertyInfo && context.IsAbstractProperty) + { + if (_attributeBuilder != null) + { + var field = context.Fields[(PropertyInfo)TargetElement]; + + field.SetCustomAttribute(_attributeBuilder); + + // Suppress multiple instances when the property has both getter and setter. + // + _attributeBuilder = null; + } + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/IAbstractTypeBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/IAbstractTypeBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,17 @@ +using System; + +namespace BLToolkit.TypeBuilder.Builders +{ + public interface IAbstractTypeBuilder + { + int ID { get; set; } + object TargetElement { get; set; } + + Type[] GetInterfaces(); + bool IsCompatible (BuildContext context, IAbstractTypeBuilder typeBuilder); + + bool IsApplied (BuildContext context, AbstractTypeBuilderList builders); + int GetPriority (BuildContext context); + void Build (BuildContext context); + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/ITypeBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/ITypeBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,14 @@ +using System; + +using BLToolkit.Reflection.Emit; + +namespace BLToolkit.TypeBuilder.Builders +{ + public interface ITypeBuilder + { + string AssemblyNameSuffix { get; } + Type Build (AssemblyBuilderHelper assemblyBuilder); + string GetTypeName (); + Type GetBuildingType(); + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/ImplementInterfaceBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/ImplementInterfaceBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,212 @@ +using System; +using System.Reflection.Emit; + +namespace BLToolkit.TypeBuilder.Builders +{ + using Reflection; + + class ImplementInterfaceBuilder : AbstractTypeBuilderBase + { + public ImplementInterfaceBuilder(Type type) + { + _type = type; + } + + private readonly Type _type; + + public override Type[] GetInterfaces() + { + return new[] { _type }; + } + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + if (context == null) throw new ArgumentNullException("context"); + + return context.BuildElement == BuildElement.InterfaceMethod; + } + + protected override void BuildInterfaceMethod() + { + var returnIfNonZero = false; + var returnIfZero = false; + + if (Context.ReturnValue != null) + { + var attrs = Context.MethodBuilder.OverriddenMethod.ReturnTypeCustomAttributes.GetCustomAttributes(true); + + foreach (var o in attrs) + { + if (o is ReturnIfNonZeroAttribute) returnIfNonZero = true; + else if (o is ReturnIfZeroAttribute) returnIfZero = true; + } + } + + var interfaceType = Context.CurrentInterface; + var emit = Context.MethodBuilder.Emitter; + + foreach (var de in Context.Fields) + { + var property = de.Key; + var field = de.Value; + + if (field.FieldType.IsPrimitive || field.FieldType == typeof(string)) + continue; + + var types = field.FieldType.GetInterfaces(); + + foreach (var type in types) + { + if (type != interfaceType.Type) + continue; + + var im = field.FieldType.GetInterfaceMap(type); + + for (var j = 0; j < im.InterfaceMethods.Length; j++) + { + if (im.InterfaceMethods[j] == Context.MethodBuilder.OverriddenMethod) + { + var targetMethod = im.TargetMethods[j]; + + var label = new Label(); + var checkNull = false; + + if (CallLazyInstanceInsurer(field) == false && field.FieldType.IsClass) + { + // Check if field is null. + // + checkNull = true; + + label = emit.DefineLabel(); + + emit + .ldarg_0 + .ldfld (field) + .brfalse_s (label) + ; + } + + // this. + // + emit + .ldarg_0 + .end(); + + // Load the field and prepare it for interface method call if the method is private. + // + if (field.FieldType.IsValueType) + { + if (targetMethod.IsPublic) + emit.ldflda (field); + else + emit + .ldfld (field) + .box (field.FieldType); + } + else + { + if (targetMethod.IsPublic) + emit.ldfld (field); + else + emit + .ldfld (field) + .castclass (interfaceType); + } + + // Check parameter attributes. + // + var pi = Context.MethodBuilder.OverriddenMethod.GetParameters(); + + for (var k = 0; k < pi.Length; k++) + { + var attrs = pi[k].GetCustomAttributes(true); + var stop = false; + + foreach (var a in attrs) + { + // Parent - set this. + // + if (a is ParentAttribute) + { + emit + .ldarg_0 + .end() + ; + + if (!TypeHelper.IsSameOrParent(pi[k].ParameterType, Context.Type)) + emit + .castclass (pi[k].ParameterType) + ; + + stop = true; + + break; + } + + // PropertyInfo. + // + if (a is PropertyInfoAttribute) + { + var ifb = GetPropertyInfoField(property); + + emit.ldsfld(ifb); + stop = true; + + break; + } + } + + if (stop) + continue; + + // Pass argument. + // + emit.ldarg ((byte)(k + 1)); + } + + // Call the method. + // + if (field.FieldType.IsValueType) + { + if (targetMethod.IsPublic) emit.call (targetMethod); + else emit.callvirt (im.InterfaceMethods[j]); + } + else + { + if (targetMethod.IsPublic) emit.callvirt (targetMethod); + else emit.callvirt (im.InterfaceMethods[j]); + } + + // Return if appropriated result. + // + if (Context.ReturnValue != null) + { + emit.stloc(Context.ReturnValue); + + if (returnIfNonZero) + { + emit + .ldloc (Context.ReturnValue) + .brtrue (Context.ReturnLabel); + } + else if (returnIfZero) + { + emit + .ldloc (Context.ReturnValue) + .brfalse (Context.ReturnLabel); + } + } + + if (checkNull) + emit.MarkLabel(label); + + break; + } + } + + break; + } + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/InstanceTypeBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/InstanceTypeBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,313 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +using BLToolkit.Properties; +using BLToolkit.Reflection; +using BLToolkit.Reflection.Emit; + +namespace BLToolkit.TypeBuilder.Builders +{ + class InstanceTypeBuilder : DefaultTypeBuilder + { + public InstanceTypeBuilder(Type instanceType, bool isObjectHolder) + { + _instanceType = instanceType; + _isObjectHolder = isObjectHolder; + } + + public InstanceTypeBuilder(Type propertyType, Type instanceType, bool isObjectHolder) + { + _propertyType = propertyType; + _instanceType = instanceType; + _isObjectHolder = isObjectHolder; + } + + private readonly bool _isObjectHolder; + + private readonly Type _propertyType; + public Type PropertyType + { + get { return _propertyType; } + } + + private readonly Type _instanceType; + public Type InstanceType + { + get { return _instanceType; } + } + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + if (context == null) throw new ArgumentNullException("context"); + + return + base.IsApplied(context, builders) && + context.CurrentProperty != null && + context.CurrentProperty.GetIndexParameters().Length == 0 && + (PropertyType == null || + TypeHelper.IsSameOrParent(PropertyType, context.CurrentProperty.PropertyType)); + } + + protected override Type GetFieldType() + { + return InstanceType; + } + + protected override Type GetObjectType() + { + return IsObjectHolder? Context.CurrentProperty.PropertyType: base.GetObjectType(); + } + + protected override bool IsObjectHolder + { + get { return _isObjectHolder && Context.CurrentProperty.PropertyType.IsClass; } + } + + protected override void BuildAbstractGetter() + { + var field = GetField(); + var emit = Context.MethodBuilder.Emitter; + var propertyType = Context.CurrentProperty.PropertyType; + var getter = GetGetter(); + + if (InstanceType.IsValueType) emit.ldarg_0.ldflda(field); + else emit.ldarg_0.ldfld (field); + + Type memberType; + + if (getter is PropertyInfo) + { + var pi = ((PropertyInfo)getter); + + if (InstanceType.IsValueType) emit.call (pi.GetGetMethod()); + else emit.callvirt(pi.GetGetMethod()); + + memberType = pi.PropertyType; + } + else if (getter is FieldInfo) + { + var fi = (FieldInfo)getter; + + emit.ldfld(fi); + + memberType = fi.FieldType; + } + else + { + var mi = (MethodInfo)getter; + var pi = mi.GetParameters(); + + for (var k = 0; k < pi.Length; k++) + { + var p = pi[k]; + + if (p.IsDefined(typeof(ParentAttribute), true)) + { + // Parent - set this. + // + emit.ldarg_0.end(); + + if (!TypeHelper.IsSameOrParent(p.ParameterType, Context.Type)) + emit.castclass(p.ParameterType); + } + else if (p.IsDefined(typeof (PropertyInfoAttribute), true)) + { + // PropertyInfo. + // + emit.ldsfld(GetPropertyInfoField()).end(); + } + else + throw new TypeBuilderException(string.Format( + Resources.TypeBuilder_UnknownParameterType, + mi.Name, mi.DeclaringType.FullName, p.Name)); + + } + + if (InstanceType.IsValueType) emit.call (mi); + else emit.callvirt(mi); + + memberType = mi.ReturnType; + } + + if (propertyType.IsValueType) + { + if (memberType.IsValueType == false) + emit.CastFromObject(propertyType); + } + else + { + if (memberType != propertyType) + emit.castclass(propertyType); + } + + emit.stloc(Context.ReturnValue); + } + + protected override void BuildAbstractSetter() + { + var field = GetField(); + var emit = Context.MethodBuilder.Emitter; + var propertyType = Context.CurrentProperty.PropertyType; + var setter = GetSetter(); + + if (InstanceType.IsValueType) emit.ldarg_0.ldflda(field); + else emit.ldarg_0.ldfld (field); + + if (setter is PropertyInfo) + { + var pi = ((PropertyInfo)setter); + + emit.ldarg_1.end(); + + if (propertyType.IsValueType && !pi.PropertyType.IsValueType) + emit.box(propertyType); + + if (InstanceType.IsValueType) emit.call (pi.GetSetMethod()); + else emit.callvirt(pi.GetSetMethod()); + } + else if (setter is FieldInfo) + { + var fi = (FieldInfo)setter; + + emit.ldarg_1.end(); + + if (propertyType.IsValueType && !fi.FieldType.IsValueType) + emit.box(propertyType); + + emit.stfld(fi); + } + else + { + var mi = (MethodInfo)setter; + var pi = mi.GetParameters(); + var gotValueParam = false; + + for (var k = 0; k < pi.Length; k++) + { + var p = pi[k]; + + if (p.IsDefined(typeof (ParentAttribute), true)) + { + // Parent - set this. + // + emit.ldarg_0.end(); + + if (!TypeHelper.IsSameOrParent(p.ParameterType, Context.Type)) + emit.castclass(p.ParameterType); + } + else if (p.IsDefined(typeof (PropertyInfoAttribute), true)) + { + // PropertyInfo. + // + emit.ldsfld(GetPropertyInfoField()).end(); + } + else if (!gotValueParam) + { + // This must be a value. + // + emit.ldarg_1.end(); + + if (propertyType.IsValueType && !p.ParameterType.IsValueType) + emit.box(propertyType); + + gotValueParam = true; + } + else + throw new TypeBuilderException(string.Format( + Resources.TypeBuilder_UnknownParameterType, + mi.Name, mi.DeclaringType.FullName, p.Name)); + } + + if (InstanceType.IsValueType) emit.call(mi); + else emit.callvirt(mi); + } + } + + private MemberInfo GetGetter() + { + const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance; + + var propertyType = Context.CurrentProperty.PropertyType; + var fields = InstanceType.GetFields(bindingFlags); + + foreach (var field in fields) + { + var attrs = field.GetCustomAttributes(typeof(GetValueAttribute), true); + + if (attrs.Length > 0 && TypeHelper.IsSameOrParent(field.FieldType, propertyType)) + return field; + } + + var props = InstanceType.GetProperties(bindingFlags); + + foreach (var prop in props) + { + var attrs = prop.GetCustomAttributes(typeof(GetValueAttribute), true); + + if (attrs.Length > 0 && TypeHelper.IsSameOrParent(prop.PropertyType, propertyType)) + return prop; + } + + foreach (var field in fields) + if (field.Name == "Value" && TypeHelper.IsSameOrParent(field.FieldType, propertyType)) + return field; + + foreach (var prop in props) + if (prop.Name == "Value" && TypeHelper.IsSameOrParent(prop.PropertyType, propertyType)) + return prop; + + var method = TypeHelper.GetMethod(InstanceType, false, "GetValue", bindingFlags); + + if (method != null && TypeHelper.IsSameOrParent(propertyType, method.ReturnType)) + return method; + + throw new TypeBuilderException(string.Format( + Resources.TypeBuilder_CannotGetGetter, InstanceType.FullName, + propertyType.FullName, Context.CurrentProperty.Name, Context.Type.FullName)); + } + + private MemberInfo GetSetter() + { + const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance; + + var propertyType = Context.CurrentProperty.PropertyType; + var fields = InstanceType.GetFields(bindingFlags); + + foreach (var field in fields) + { + var attrs = field.GetCustomAttributes(typeof(SetValueAttribute), true); + + if (attrs.Length > 0 && TypeHelper.IsSameOrParent(field.FieldType, propertyType)) + return field; + } + + var props = InstanceType.GetProperties(bindingFlags); + + foreach (var prop in props) + { + var attrs = prop.GetCustomAttributes(typeof(SetValueAttribute), true); + + if (attrs.Length > 0 && TypeHelper.IsSameOrParent(prop.PropertyType, propertyType)) + return prop; + } + + foreach (var field in fields) + if (field.Name == "Value" && TypeHelper.IsSameOrParent(field.FieldType, propertyType)) + return field; + + foreach (var prop in props) + if (prop.Name == "Value" && TypeHelper.IsSameOrParent(prop.PropertyType, propertyType)) + return prop; + + var method = TypeHelper.GetMethod(InstanceType, false, "SetValue", bindingFlags); + + if (method != null && method.ReturnType == typeof(void)) + return method; + + throw new TypeBuilderException(string.Format( + Resources.TypeBuilder_CannotGetSetter, InstanceType.FullName, + propertyType.FullName, Context.CurrentProperty.Name, Context.Type.FullName)); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/PropertyChangedBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/PropertyChangedBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,250 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; +using BLToolkit.Reflection; +using BLToolkit.Reflection.Emit; + +namespace BLToolkit.TypeBuilder.Builders +{ + public class PropertyChangedBuilder : AbstractTypeBuilderBase + { + public PropertyChangedBuilder() + : this(Common.Configuration.NotifyOnEqualSet, true, true) + { + } + + public PropertyChangedBuilder(bool notifyOnEqualSet, bool useReferenceEquals, bool skipSetterOnNoChange) + { + _notifyOnEqualSet = notifyOnEqualSet; + _useReferenceEquals = useReferenceEquals; + _skipSetterOnNoChange = skipSetterOnNoChange; + } + + private readonly bool _notifyOnEqualSet; + private readonly bool _useReferenceEquals; + private readonly bool _skipSetterOnNoChange; + + public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders) + { + if (context == null) throw new ArgumentNullException("context"); + + return context.IsSetter && (context.IsBeforeStep || context.IsAfterStep); + } + + protected override void BeforeBuildAbstractSetter() + { + if (!_notifyOnEqualSet && Context.CurrentProperty.CanRead) + GenerateIsSameValueComparison(); + } + + protected override void BeforeBuildVirtualSetter() + { + if (!_notifyOnEqualSet && Context.CurrentProperty.CanRead) + GenerateIsSameValueComparison(); + } + + protected override void AfterBuildAbstractSetter() + { + BuildSetter(); + } + + protected override void AfterBuildVirtualSetter() + { + BuildSetter(); + } + + public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder) + { + if (typeBuilder is PropertyChangedBuilder) + return false; + + return base.IsCompatible(context, typeBuilder); + } + + public override int GetPriority(BuildContext context) + { + return TypeBuilderConsts.Priority.PropChange; + } + + private LocalBuilder _isSameValueBuilder; + private Label _afterNotificationLabel; + + private void GenerateIsSameValueComparison() + { + EmitHelper emit = Context.MethodBuilder.Emitter; + + if (_skipSetterOnNoChange) + _afterNotificationLabel = emit.DefineLabel(); + else + _isSameValueBuilder = emit.DeclareLocal(typeof(bool)); + + MethodInfo op_InequalityMethod = + Context.CurrentProperty.PropertyType.GetMethod("op_Inequality", + new Type[] + { + Context.CurrentProperty.PropertyType, + Context.CurrentProperty.PropertyType + }); + + if (op_InequalityMethod == null) + { + if (Context.CurrentProperty.PropertyType.IsValueType) + { + if (TypeHelper.IsNullableType(Context.CurrentProperty.PropertyType)) + { + // Handled nullable types + + var currentValue = emit.DeclareLocal(Context.CurrentProperty.PropertyType); + var newValue = emit.DeclareLocal(Context.CurrentProperty.PropertyType); + var notEqualLabel = emit.DefineLabel(); + var comparedLabel = emit.DefineLabel(); + var hasValueGetMethod = Context.CurrentProperty.PropertyType.GetProperty("HasValue").GetGetMethod(); + + emit + .ldarg_0 + .callvirt(Context.CurrentProperty.GetGetMethod(true)) + .stloc(currentValue) + .ldarg_1 + .stloc(newValue) + .ldloca(currentValue) + .call(Context.CurrentProperty.PropertyType, "GetValueOrDefault") + .ldloca(newValue) + .call(Context.CurrentProperty.PropertyType, "GetValueOrDefault"); + + var nullableUnderlyingType = TypeHelper.GetUnderlyingType(Context.CurrentProperty.PropertyType); + + op_InequalityMethod = nullableUnderlyingType.GetMethod("op_Inequality", + new Type[] + { + nullableUnderlyingType, + nullableUnderlyingType + }); + + if (op_InequalityMethod != null) + { + emit + .call(op_InequalityMethod) + .brtrue_s(notEqualLabel); + } + else + emit.bne_un_s(notEqualLabel); + + emit + .ldloca(currentValue) + .call(hasValueGetMethod) + .ldloca(newValue) + .call(hasValueGetMethod) + .ceq + .ldc_bool(true) + .ceq + .br(comparedLabel) + .MarkLabel(notEqualLabel) + .ldc_bool(false) + .MarkLabel(comparedLabel) + .end(); + } + else if (!Context.CurrentProperty.PropertyType.IsPrimitive) + { + // Handle structs without op_Inequality. + var currentValue = emit.DeclareLocal(Context.CurrentProperty.PropertyType); + + emit + .ldarg_0 + .callvirt(Context.CurrentProperty.GetGetMethod(true)) + .stloc(currentValue) + .ldloca(currentValue) + .ldarg_1 + .box(Context.CurrentProperty.PropertyType) + .constrained(Context.CurrentProperty.PropertyType) + .callvirt(typeof(object), "Equals", new [] {typeof(object)}) + .end(); + } + else + { + // Primitive value type comparison + emit + .ldarg_0 + .callvirt(Context.CurrentProperty.GetGetMethod(true)) + .ldarg_1 + .ceq + .end(); + } + } + else if (!_useReferenceEquals) + { + // Do not use ReferenceEquals comparison for objects + emit + .ldarg_0 + .callvirt(Context.CurrentProperty.GetGetMethod(true)) + .ldarg_1 + .ceq + .end(); + } + else + { + // ReferenceEquals comparison for objects + emit + .ldarg_0 + .callvirt(Context.CurrentProperty.GetGetMethod(true)) + .ldarg_1 + .call(typeof(object), "ReferenceEquals", typeof(object), typeof(object)) + .end(); + } + } + else + { + // Items compared have op_Inequality operator (!=) + emit + .ldarg_0 + .callvirt(Context.CurrentProperty.GetGetMethod(true)) + .ldarg_1 + .call(op_InequalityMethod) + .ldc_i4_0 + .ceq + .end(); + } + + if (_skipSetterOnNoChange) + emit.brtrue(_afterNotificationLabel); + else + emit.stloc(_isSameValueBuilder); + } + + private void BuildSetter() + { + InterfaceMapping im = Context.Type.GetInterfaceMap(typeof(IPropertyChanged)); + MethodInfo mi = im.TargetMethods[0]; + FieldBuilder ifb = GetPropertyInfoField(); + EmitHelper emit = Context.MethodBuilder.Emitter; + + if (!_notifyOnEqualSet && Context.CurrentProperty.CanRead && !_skipSetterOnNoChange) + { + _afterNotificationLabel = emit.DefineLabel(); + emit + .ldloc (_isSameValueBuilder) + .brtrue(_afterNotificationLabel); + } + + if (mi.IsPublic) + { + emit + .ldarg_0 + .ldsfld (ifb) + .callvirt (mi) + ; + } + else + { + emit + .ldarg_0 + .castclass (typeof(IPropertyChanged)) + .ldsfld (ifb) + .callvirt (im.InterfaceMethods[0]) + ; + } + + if (!_notifyOnEqualSet && Context.CurrentProperty.CanRead) + emit.MarkLabel(_afterNotificationLabel); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/TypeAccessorBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/TypeAccessorBuilder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,890 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.CompilerServices; + +namespace BLToolkit.TypeBuilder.Builders +{ + using Mapping; + using Reflection; + using Reflection.Emit; + + internal class TypeAccessorBuilder : ITypeBuilder + { + public TypeAccessorBuilder(Type type, Type originalType) + { + if (type == null) throw new ArgumentNullException("type"); + if (originalType == null) throw new ArgumentNullException("originalType"); + + _type = type; + _originalType = originalType; + } + + readonly TypeHelper _type; + readonly TypeHelper _originalType; + readonly TypeHelper _accessorType = new TypeHelper(typeof(TypeAccessor)); + readonly TypeHelper _memberAccessor = new TypeHelper(typeof(MemberAccessor)); + readonly List _nestedTypes = new List(); + TypeBuilderHelper _typeBuilder; + bool _friendlyAssembly; + + public string AssemblyNameSuffix + { + get { return "TypeAccessor"; } + } + + public string GetTypeName() + { + // It's a bad idea to use '.TypeAccessor' here since we got + // a class and a namespace with the same full name. + // The sgen utility fill fail in such case. + // + return _type.FullName.Replace('+', '.') + "$TypeAccessor"; + } + + public Type GetBuildingType() + { + return _type; + } + + public Type Build(AssemblyBuilderHelper assemblyBuilder) + { + if (assemblyBuilder == null) throw new ArgumentNullException("assemblyBuilder"); + + // Check InternalsVisibleToAttributes of the source type's assembly. + // Even if the sourceType is public, it may have internal fields and props. + // + _friendlyAssembly = false; + + // Usually, there is no such attribute in the source assembly. + // Therefore we do not cache the result. + // + var attributes = _originalType.Type.Assembly.GetCustomAttributes(typeof(InternalsVisibleToAttribute), true); + + foreach (InternalsVisibleToAttribute visibleToAttribute in attributes) + { + var an = new AssemblyName(visibleToAttribute.AssemblyName); + + if (AssemblyName.ReferenceMatchesDefinition(assemblyBuilder.AssemblyName, an)) + { + _friendlyAssembly = true; + break; + } + } + + if (!_originalType.Type.IsVisible && !_friendlyAssembly || + ( + from p in _originalType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + from a in p.GetCustomAttributes(typeof(MapFieldAttribute), true).Cast() + where a.Storage != null + select a + ).Any()) + return typeof (ExprTypeAccessor<,>).MakeGenericType(_type, _originalType); + + var typeName = GetTypeName(); + + _typeBuilder = assemblyBuilder.DefineType(typeName, _accessorType); + + _typeBuilder.DefaultConstructor.Emitter + .ldarg_0 + .call (TypeHelper.GetDefaultConstructor(_accessorType)) + ; + + BuildCreateInstanceMethods(); + BuildTypeProperties(); + BuildMembers(); + BuildObjectFactory(); + + _typeBuilder.DefaultConstructor.Emitter + .ret() + ; + + var result = _typeBuilder.Create(); + + foreach (TypeBuilderHelper tb in _nestedTypes) + tb.Create(); + + return result; + } + + void BuildCreateInstanceMethods() + { + var isValueType = _type.IsValueType; + var baseDefCtor = isValueType? null: _type.GetPublicDefaultConstructor(); + var baseInitCtor = _type.GetPublicConstructor(typeof(InitContext)); + + if (baseDefCtor == null && baseInitCtor == null && !isValueType) + return; + + // CreateInstance. + // + var method = _typeBuilder.DefineMethod(_accessorType.GetMethod(false, "CreateInstance", Type.EmptyTypes)); + + if (baseDefCtor != null) + { + method.Emitter + .newobj (baseDefCtor) + .ret() + ; + } + else if (isValueType) + { + var locObj = method.Emitter.DeclareLocal(_type); + + method.Emitter + .ldloca (locObj) + .initobj (_type) + .ldloc (locObj) + .box (_type) + .ret() + ; + } + else + { + method.Emitter + .ldnull + .newobj (baseInitCtor) + .ret() + ; + } + + // CreateInstance(IniContext). + // + method = _typeBuilder.DefineMethod( + _accessorType.GetMethod(false, "CreateInstance", typeof(InitContext))); + + if (baseInitCtor != null) + { + method.Emitter + .ldarg_1 + .newobj (baseInitCtor) + .ret() + ; + } + else if (isValueType) + { + var locObj = method.Emitter.DeclareLocal(_type); + + method.Emitter + .ldloca (locObj) + .initobj (_type) + .ldloc (locObj) + .box (_type) + .ret() + ; + } + else + { + method.Emitter + .newobj (baseDefCtor) + .ret() + ; + } + } + + private void BuildTypeProperties() + { + // Type. + // + var method = _typeBuilder.DefineMethod(_accessorType.GetProperty("Type").GetGetMethod()); + + method.Emitter + .LoadType(_type) + .ret() + ; + + // OriginalType. + // + method = + _typeBuilder.DefineMethod(_accessorType.GetProperty("OriginalType").GetGetMethod()); + + method.Emitter + .LoadType(_originalType) + .ret() + ; + } + + private void BuildMembers() + { + var members = new Dictionary(); + + foreach (var fi in _originalType.GetFields(BindingFlags.Instance | BindingFlags.Public)) + AddMemberToDictionary(members, fi); + + if (_friendlyAssembly) + { + foreach (var fi in _originalType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)) + if (fi.IsAssembly || fi.IsFamilyOrAssembly) + AddMemberToDictionary(members, fi); + } + + foreach (var pi in _originalType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) + if (pi.GetIndexParameters().Length == 0) + AddMemberToDictionary(members, pi); + + var interfaceMethods = _originalType.Type.IsClass && !_originalType.Type.IsArray ? _originalType.Type.GetInterfaces().SelectMany(ti => _originalType.GetInterfaceMap(ti).TargetMethods).ToList() : new List(); + foreach (var pi in _originalType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic)) + { + if (pi.GetIndexParameters().Length == 0) + { + var getter = pi.GetGetMethod(true); + var setter = pi.GetSetMethod(true); + + if (getter != null && (getter.IsAbstract || interfaceMethods.Contains(getter)) + || setter != null && (setter.IsAbstract || interfaceMethods.Contains(setter))) + AddMemberToDictionary(members, pi); + } + } + + foreach (var mi in members.Values) + BuildMember(mi); + } + + private static void AddMemberToDictionary(IDictionary members, MemberInfo mi) + { + MemberInfo existing; + + var name = mi.Name; + + if (!members.TryGetValue(name, out existing)) + { + members.Add(name, mi); + } + else if (mi.DeclaringType.IsSubclassOf(existing.DeclaringType)) + { + // mi is a member of the most descendant type. + // + members[name] = mi; + } + } + + private void BuildMember(MemberInfo mi) + { + var isValueType = _originalType.IsValueType; + var name = "Accessor$" + mi.Name.Replace('.', '_').Replace('<', '_').Replace('>', '_'); + var nestedType = _typeBuilder.DefineNestedType(name, TypeAttributes.NestedPrivate, typeof(MemberAccessor)); + var ctorBuilder = BuildNestedTypeConstructor(nestedType); + + BuildGetter (mi, nestedType); + if (!isValueType) + BuildSetter(mi, nestedType); + BuildInitMember(mi, ctorBuilder); + + var type = mi is FieldInfo ? ((FieldInfo)mi).FieldType : ((PropertyInfo)mi).PropertyType; + + BuildIsNull (mi, nestedType, type); + + if (type.IsEnum) + type = Enum.GetUnderlyingType(type); + + var typedPropertyName = type.Name; + + if (type.IsGenericType) + { + var underlyingType = Nullable.GetUnderlyingType(type); + + if (underlyingType != null) + { + BuildTypedGetterForNullable (mi, nestedType, underlyingType); + if (!isValueType) + BuildTypedSetterForNullable(mi, nestedType, underlyingType); + + if (underlyingType.IsEnum) + { + // Note that PEVerify will complain on using Nullable as Nullable. + // It works in the current CLR implementation, bu may not work in future releases. + // + underlyingType = Enum.GetUnderlyingType(underlyingType); + type = typeof(Nullable<>).MakeGenericType(underlyingType); + } + + typedPropertyName = "Nullable" + underlyingType.Name; + } + else + { + typedPropertyName = null; + } + } + + if (typedPropertyName != null) + { + BuildTypedGetter (mi, nestedType, typedPropertyName); + if (!isValueType) + BuildTypedSetter(mi, nestedType, type, typedPropertyName); + } + + if (!isValueType) + BuildCloneValueMethod(mi, nestedType, type); + + // FW 1.1 wants nested types to be created before parent. + // + _nestedTypes.Add(nestedType); + } + + private void BuildInitMember(MemberInfo mi, ConstructorBuilderHelper ctorBuilder) + { + _typeBuilder.DefaultConstructor.Emitter + .ldarg_0 + .ldarg_0 + .ldarg_0 + .ldc_i4 (mi is FieldInfo? 1: 2) + .ldstr (mi.Name) + .call (_accessorType.GetMethod("GetMember", typeof(int), typeof(string))) + .newobj (ctorBuilder) + .call (_accessorType.GetMethod("AddMember", typeof(MemberAccessor))) + ; + } + + /// + /// Figure out is base type method is accessible by extension type method. + /// + /// A instance. + /// True if the method access is Public or Family and it's assembly is friendly. + private bool IsMethodAccessible(MethodInfo method) + { + if (method == null) throw new ArgumentNullException("method"); + + return method.IsPublic || (_friendlyAssembly && (method.IsAssembly || method.IsFamilyOrAssembly)); + } + + private void BuildGetter(MemberInfo mi, TypeBuilderHelper nestedType) + { + var methodType = mi.DeclaringType; + var getMethod = null as MethodInfo; + + if (mi is PropertyInfo) + { + getMethod = ((PropertyInfo)mi).GetGetMethod(); + + if (getMethod == null) + { + if (_type != _originalType) + { + getMethod = _type.GetMethod("get_" + mi.Name); + methodType = _type; + } + + if (getMethod == null || !IsMethodAccessible(getMethod)) + return; + } + } + + var method = nestedType.DefineMethod(_memberAccessor.GetMethod("GetValue", typeof(object))); + var emit = method.Emitter; + + emit + .ldarg_1 + .castType (methodType) + .end(); + + if (mi is FieldInfo) + { + var fi = (FieldInfo)mi; + + emit + .ldfld (fi) + .boxIfValueType (fi.FieldType) + ; + } + else + { + if (methodType.IsValueType) + { + var loc = emit.DeclareLocal(methodType); + + emit + .stloc ((byte)loc.LocalIndex) + .ldloca_s ((byte)loc.LocalIndex); + } + + var pi = (PropertyInfo)mi; + + emit + .callvirt (getMethod) + .boxIfValueType (pi.PropertyType) + ; + } + + emit + .ret() + ; + + nestedType.DefineMethod(_memberAccessor.GetProperty("HasGetter").GetGetMethod()).Emitter + .ldc_i4_1 + .ret() + ; + } + + private void BuildSetter(MemberInfo mi, TypeBuilderHelper nestedType) + { + var methodType = mi.DeclaringType; + var setMethod = null as MethodInfo; + + if (mi is PropertyInfo) + { + setMethod = ((PropertyInfo)mi).GetSetMethod(); + + if (setMethod == null) + { + if (_type != _originalType) + { + setMethod = _type.GetMethod("set_" + mi.Name); + methodType = _type; + } + + if (setMethod == null || !IsMethodAccessible(setMethod)) + return; + } + } + //else if (((FieldInfo)mi).IsLiteral) + // return; + + var method = nestedType.DefineMethod(_memberAccessor.GetMethod("SetValue", typeof(object), typeof(object))); + var emit = method.Emitter; + + emit + .ldarg_1 + .castType (methodType) + .ldarg_2 + .end(); + + if (mi is FieldInfo) + { + var fi = (FieldInfo)mi; + + emit + .CastFromObject (fi.FieldType) + .stfld (fi) + ; + } + else + { + var pi = (PropertyInfo)mi; + + emit + .CastFromObject (pi.PropertyType) + .callvirt (setMethod) + ; + } + + emit + .ret() + ; + + nestedType.DefineMethod(_memberAccessor.GetProperty("HasSetter").GetGetMethod()).Emitter + .ldc_i4_1 + .ret() + ; + } + + private void BuildIsNull( + MemberInfo mi, + TypeBuilderHelper nestedType, + Type memberType) + { + var methodType = mi.DeclaringType; + var getMethod = null as MethodInfo; + var isNullable = TypeHelper.IsNullable(memberType); + var isValueType = (!isNullable && memberType.IsValueType); + + if (!isValueType && mi is PropertyInfo) + { + getMethod = ((PropertyInfo)mi).GetGetMethod(); + + if (getMethod == null) + { + if (_type != _originalType) + { + getMethod = _type.GetMethod("get_" + mi.Name); + methodType = _type; + } + + if (getMethod == null) + return; + } + } + + var methodInfo = _memberAccessor.GetMethod("IsNull"); + + if (methodInfo == null) + return; + + var method = nestedType.DefineMethod(methodInfo); + var emit = method.Emitter; + + if (isValueType) + { + emit + .ldc_i4_0 + .end() + ; + } + else + { + LocalBuilder locObj = null; + + if (isNullable) + locObj = method.Emitter.DeclareLocal(memberType); + + emit + .ldarg_1 + .castType (methodType) + .end(); + + if (mi is FieldInfo) emit.ldfld ((FieldInfo)mi); + else emit.callvirt(getMethod); + + if (isNullable) + { + emit + .stloc(locObj) + .ldloca(locObj) + .call(memberType, "get_HasValue") + .ldc_i4_0 + .ceq + .end(); + } + else + { + emit + .ldnull + .ceq + .end(); + } + } + + emit + .ret() + ; + } + + private void BuildTypedGetter( + MemberInfo mi, + TypeBuilderHelper nestedType, + string typedPropertyName) + { + var methodType = mi.DeclaringType; + var getMethod = null as MethodInfo; + + if (mi is PropertyInfo) + { + getMethod = ((PropertyInfo)mi).GetGetMethod(); + + if (getMethod == null) + { + if (_type != _originalType) + { + getMethod = _type.GetMethod("get_" + mi.Name); + methodType = _type; + } + + if (getMethod == null || !IsMethodAccessible(getMethod)) + return; + } + } + + var methodInfo = _memberAccessor.GetMethod("Get" + typedPropertyName, typeof(object)); + + if (methodInfo == null) + return; + + var method = nestedType.DefineMethod(methodInfo); + var emit = method.Emitter; + + emit + .ldarg_1 + .castType (methodType) + .end(); + + if (mi is FieldInfo) emit.ldfld ((FieldInfo)mi); + else emit.callvirt(getMethod); + + emit + .ret() + ; + } + + private void BuildTypedSetter( + MemberInfo mi, + TypeBuilderHelper nestedType, + Type memberType, + string typedPropertyName) + { + var methodType = mi.DeclaringType; + var setMethod = null as MethodInfo; + + if (mi is PropertyInfo) + { + setMethod = ((PropertyInfo)mi).GetSetMethod(); + + if (setMethod == null) + { + if (_type != _originalType) + { + setMethod = _type.GetMethod("set_" + mi.Name); + methodType = _type; + } + + if (setMethod == null || !IsMethodAccessible(setMethod)) + return; + } + } + + var methodInfo = _memberAccessor.GetMethod("Set" + typedPropertyName, typeof(object), memberType); + + if (methodInfo == null) + return; + + var method = nestedType.DefineMethod(methodInfo); + var emit = method.Emitter; + + emit + .ldarg_1 + .castType (methodType) + .ldarg_2 + .end(); + + if (mi is FieldInfo) emit.stfld ((FieldInfo)mi); + else emit.callvirt(setMethod); + + emit + .ret() + ; + } + + private void BuildCloneValueMethod( + MemberInfo mi, + TypeBuilderHelper nestedType, + Type memberType + ) + { + var methodType = mi.DeclaringType; + var getMethod = null as MethodInfo; + var setMethod = null as MethodInfo; + + if (mi is PropertyInfo) + { + getMethod = ((PropertyInfo)mi).GetGetMethod(); + + if (getMethod == null) + { + if (_type != _originalType) + { + getMethod = _type.GetMethod("get_" + mi.Name); + methodType = _type; + } + + if (getMethod == null || !IsMethodAccessible(getMethod)) + return; + } + + setMethod = ((PropertyInfo)mi).GetSetMethod(); + + if (setMethod == null) + { + if (_type != _originalType) + { + setMethod = _type.GetMethod("set_" + mi.Name); + methodType = _type; + } + + if (setMethod == null || !IsMethodAccessible(setMethod)) + return; + } + } + + var method = nestedType.DefineMethod(_memberAccessor.GetMethod("CloneValue", typeof(object), typeof(object))); + var emit = method.Emitter; + + emit + .ldarg_2 + .castType (methodType) + .ldarg_1 + .castType (methodType) + .end(); + + if (mi is FieldInfo) + emit.ldfld ((FieldInfo)mi); + else + emit.callvirt(getMethod); + + if (typeof(string) != memberType && TypeHelper.IsSameOrParent(typeof(ICloneable), memberType)) + { + if (memberType.IsValueType) + emit + .box (memberType) + .callvirt (typeof(ICloneable), "Clone") + .unbox_any (memberType) + ; + else + { + var valueIsNull = emit.DefineLabel(); + + emit + .dup + .brfalse_s (valueIsNull) + .callvirt (typeof(ICloneable), "Clone") + .castclass (memberType) + .MarkLabel (valueIsNull) + ; + } + } + + if (mi is FieldInfo) + emit.stfld ((FieldInfo)mi); + else + emit.callvirt(setMethod); + + emit + .ret() + ; + } + + private void BuildTypedGetterForNullable( + MemberInfo mi, + TypeBuilderHelper nestedType, + Type memberType) + { + var methodType = mi.DeclaringType; + var getMethod = null as MethodInfo; + + if (mi is PropertyInfo) + { + getMethod = ((PropertyInfo)mi).GetGetMethod(); + + if (getMethod == null) + { + if (_type != _originalType) + { + getMethod = _type.GetMethod("get_" + mi.Name); + methodType = _type; + } + + if (getMethod == null || !IsMethodAccessible(getMethod)) + return; + } + } + + var setterType = (memberType.IsEnum ? Enum.GetUnderlyingType(memberType) : memberType); + var methodInfo = _memberAccessor.GetMethod("Get" + setterType.Name, typeof(object)); + + if (methodInfo == null) + return; + + var method = nestedType.DefineMethod(methodInfo); + var nullableType = typeof(Nullable<>).MakeGenericType(memberType); + var emit = method.Emitter; + + emit + .ldarg_1 + .castType (methodType) + .end(); + + if (mi is FieldInfo) + { + emit.ldflda ((FieldInfo)mi); + } + else + { + var locNullable = emit.DeclareLocal(nullableType); + + emit + .callvirt (getMethod) + .stloc (locNullable) + .ldloca (locNullable) + ; + } + + emit + .call(nullableType, "get_Value") + .ret() + ; + } + + private void BuildTypedSetterForNullable( + MemberInfo mi, + TypeBuilderHelper nestedType, + Type memberType) + { + var methodType = mi.DeclaringType; + var setMethod = null as MethodInfo; + + if (mi is PropertyInfo) + { + setMethod = ((PropertyInfo)mi).GetSetMethod(); + + if (setMethod == null) + { + if (_type != _originalType) + { + setMethod = _type.GetMethod("set_" + mi.Name); + methodType = _type; + } + + if (setMethod == null || !IsMethodAccessible(setMethod)) + return; + } + } + + var setterType = (memberType.IsEnum ? Enum.GetUnderlyingType(memberType) : memberType); + var methodInfo = _memberAccessor.GetMethod("Set" + setterType.Name, typeof(object), setterType); + + if (methodInfo == null) + return; + + var method = nestedType.DefineMethod(methodInfo); + var emit = method.Emitter; + + emit + .ldarg_1 + .castType (methodType) + .ldarg_2 + .newobj (typeof(Nullable<>).MakeGenericType(memberType), memberType) + .end(); + + if (mi is FieldInfo) emit.stfld ((FieldInfo)mi); + else emit.callvirt(setMethod); + + emit + .ret() + ; + } + + private static ConstructorBuilderHelper BuildNestedTypeConstructor(TypeBuilderHelper nestedType) + { + Type[] parameters = { typeof(TypeAccessor), typeof(MemberInfo) }; + + var ctorBuilder = nestedType.DefinePublicConstructor(parameters); + + ctorBuilder.Emitter + .ldarg_0 + .ldarg_1 + .ldarg_2 + .call (TypeHelper.GetConstructor(typeof(MemberAccessor), parameters)) + .ret() + ; + + return ctorBuilder; + } + + private void BuildObjectFactory() + { + var attr = TypeHelper.GetFirstAttribute(_type, typeof(ObjectFactoryAttribute)); + + if (attr != null) + { + _typeBuilder.DefaultConstructor.Emitter + .ldarg_0 + .LoadType (_type) + .LoadType (typeof(ObjectFactoryAttribute)) + .call (typeof(TypeHelper), "GetFirstAttribute", typeof(Type), typeof(Type)) + .castclass (typeof(ObjectFactoryAttribute)) + .call (typeof(ObjectFactoryAttribute).GetProperty("ObjectFactory").GetGetMethod()) + .call (typeof(TypeAccessor). GetProperty("ObjectFactory").GetSetMethod()) + ; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/TypeBuilderAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/TypeBuilderAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.TypeBuilder.Builders +{ + public abstract class AbstractTypeBuilderAttribute : Attribute + { + public abstract IAbstractTypeBuilder TypeBuilder { get; } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/Builders/TypeBuilderConsts.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/Builders/TypeBuilderConsts.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ +namespace BLToolkit.TypeBuilder.Builders +{ + public static class TypeBuilderConsts + { + public static class Priority + { + public const int Low = int.MinValue / 2; + public const int Normal = 0; + public const int High = int.MaxValue / 2; + + public const int NotNullAspect = High; + public const int OverloadAspect = High; + public const int AsyncAspect = Normal; + public const int ClearCacheAspect = Normal; + public const int LoggingAspect = Normal; + public const int CacheAspect = Low; + public const int DataAccessor = Low; + public const int PropChange = int.MinValue + 1000000; + } + + public const string AssemblyNameSuffix = "TypeBuilder"; + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/DefaultInstanceTypeAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/DefaultInstanceTypeAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.Property)] + public sealed class DefaultInstanceTypeAttribute : Builders.AbstractTypeBuilderAttribute + { + public override Builders.IAbstractTypeBuilder TypeBuilder + { + get { return new Builders.DefaultTypeBuilder(); } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/GenerateAttributeAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/GenerateAttributeAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,109 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] + public class GenerateAttributeAttribute: Builders.AbstractTypeBuilderAttribute + { + public GenerateAttributeAttribute(Type attributeType) + { + _attributeType = attributeType; + } + + public GenerateAttributeAttribute(Type attributeType, params object[] arguments) + { + _attributeType = attributeType; + _arguments = arguments; + } + + private readonly Type _attributeType; + public Type AttributeType + { + get { return _attributeType; } + } + + private readonly object[] _arguments; + public object[] Arguments + { + get { return _arguments; } + } + + private string[] _namedArgumentNames; + public string[] NamedArgumentNames + { + get { return _namedArgumentNames; } + set { _namedArgumentNames = value; } + } + + private object[] _namedArgumentValues; + public object[] NamedArgumentValues + { + get { return _namedArgumentValues; } + set { _namedArgumentValues = value; } + } + + public object this[string name] + { + get + { + if (_namedArgumentNames == null) + return null; + + int idx = Array.IndexOf(_namedArgumentNames, name); + + return idx < 0? null: _namedArgumentValues[idx]; + } + set + { + if (_namedArgumentNames == null) + { + _namedArgumentNames = new string[]{ name }; + _namedArgumentValues = new object[]{ value }; + return; + } + + int idx = Array.IndexOf(_namedArgumentNames, name); + if (idx < 0) + { + idx = _namedArgumentNames.Length; + + Array.Resize(ref _namedArgumentNames, idx + 1); + Array.Resize(ref _namedArgumentValues, idx + 1); + + _namedArgumentNames [idx] = name; + _namedArgumentValues[idx] = value; + } + else + { + _namedArgumentValues[idx] = value; + } + } + } + + public T GetValue(string name) + { + object value = this[name]; + return value == null? default(T): (T)value; + } + + public T GetValue(string name, T defaultValue) + { + return _namedArgumentNames == null || Array.IndexOf(_namedArgumentNames, name) < 0? + defaultValue : GetValue(name); + } + + public void SetValue(string name, T value) + { + this[name] = value; + } + + public override Builders.IAbstractTypeBuilder TypeBuilder + { + get + { + return new Builders.GeneratedAttributeBuilder( + _attributeType, _arguments, _namedArgumentNames, _namedArgumentValues); + } + } + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/GetValueAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/GetValueAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + /// + /// Indicates that a field, property or method can be treated as a value getter. + /// + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method)] + public sealed class GetValueAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/GlobalInstanceTypeAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/GlobalInstanceTypeAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,78 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace BLToolkit.TypeBuilder +{ + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true)] + public class GlobalInstanceTypeAttribute : InstanceTypeAttribute + { + public GlobalInstanceTypeAttribute(Type propertyType, Type instanceType) + : base(instanceType) + { + _propertyType = propertyType; + } + + public GlobalInstanceTypeAttribute(Type propertyType, Type instanceType, object parameter1) + : base(instanceType, parameter1) + { + _propertyType = propertyType; + } + + public GlobalInstanceTypeAttribute(Type propertyType, Type instanceType, + object parameter1, + object parameter2) + : base(instanceType, parameter1, parameter2) + { + _propertyType = propertyType; + } + + public GlobalInstanceTypeAttribute(Type propertyType, Type instanceType, + object parameter1, + object parameter2, + object parameter3) + : base(instanceType, parameter1, parameter2, parameter3) + { + _propertyType = propertyType; + } + + public GlobalInstanceTypeAttribute(Type propertyType, Type instanceType, + object parameter1, + object parameter2, + object parameter3, + object parameter4) + : base(instanceType, parameter1, parameter2, parameter3, parameter4) + { + _propertyType = propertyType; + } + + public GlobalInstanceTypeAttribute(Type propertyType, Type instanceType, + object parameter1, + object parameter2, + object parameter3, + object parameter4, + object parameter5) + : base(instanceType, parameter1, parameter2, parameter3, parameter4, parameter5) + { + _propertyType = propertyType; + } + + private readonly Type _propertyType; + public Type PropertyType + { + get { return _propertyType; } + } + + private Builders.IAbstractTypeBuilder _typeBuilder; + public override Builders.IAbstractTypeBuilder TypeBuilder + { + get + { + if (_typeBuilder == null) + _typeBuilder = new Builders.InstanceTypeBuilder(_propertyType, InstanceType, IsObjectHolder); + + return _typeBuilder; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/IPropertyChanged.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/IPropertyChanged.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +using System.Reflection; + +namespace BLToolkit.TypeBuilder +{ + [PropertyChanged] + public interface IPropertyChanged + { + void OnPropertyChanged(PropertyInfo propertyInfo); + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/ISetParent.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/ISetParent.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System.Reflection; + +namespace BLToolkit.TypeBuilder +{ + public interface ISetParent + { + void SetParent([Parent]object parent, [PropertyInfo]PropertyInfo propertyInfo); + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/ImplementInterfaceAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/ImplementInterfaceAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.TypeBuilder +{ + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true)] + public class ImplementInterfaceAttribute : AbstractTypeBuilderAttribute + { + public ImplementInterfaceAttribute(Type type) + { + _type = type; + } + + private readonly Type _type; + public Type Type + { + get { return _type; } + } + + public override IAbstractTypeBuilder TypeBuilder + { + get { return new ImplementInterfaceBuilder(_type); } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/InstanceTypeAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/InstanceTypeAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,180 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +using BLToolkit.Reflection; + +namespace BLToolkit.TypeBuilder +{ + /// + /// Specifies a value holder type. + /// + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")] + [AttributeUsage(AttributeTargets.Property)] + public class InstanceTypeAttribute : Builders.AbstractTypeBuilderAttribute + { + /// + /// Initializes a new instance of the InstanceTypeAttribute class. + /// + ///The of an instance. + public InstanceTypeAttribute(Type instanceType) + { + _instanceType = instanceType; + } + + /// + /// Initializes a new instance of the InstanceTypeAttribute class. + /// + ///The of an instance. + ///An additional parameter. + /// + public InstanceTypeAttribute(Type instanceType, object parameter1) + { + _instanceType = instanceType; + SetParameters(parameter1); + } + + /// + /// Initializes a new instance of the InstanceTypeAttribute class. + /// + ///The of an instance. + ///An additional parameter. + ///An additional parameter. + /// + public InstanceTypeAttribute(Type instanceType, + object parameter1, + object parameter2) + { + _instanceType = instanceType; + SetParameters(parameter1, parameter2); + } + + /// + /// Initializes a new instance of the InstanceTypeAttribute class. + /// + ///The of an instance. + ///An additional parameter. + ///An additional parameter. + ///An additional parameter. + /// + public InstanceTypeAttribute(Type instanceType, + object parameter1, + object parameter2, + object parameter3) + { + _instanceType = instanceType; + SetParameters(parameter1, parameter2, parameter3); + } + + /// + /// Initializes a new instance of the InstanceTypeAttribute class. + /// + ///The of an instance. + ///An additional parameter. + ///An additional parameter. + ///An additional parameter. + ///An additional parameter. + /// + public InstanceTypeAttribute(Type instanceType, + object parameter1, + object parameter2, + object parameter3, + object parameter4) + { + _instanceType = instanceType; + SetParameters(parameter1, parameter2, parameter3, parameter4); + } + + /// + /// Initializes a new instance of the InstanceTypeAttribute class. + /// + ///The of an instance. + ///An additional parameter. + ///An additional parameter. + ///An additional parameter. + ///An additional parameter. + ///An additional parameter. + /// + public InstanceTypeAttribute(Type instanceType, + object parameter1, + object parameter2, + object parameter3, + object parameter4, + object parameter5) + { + _instanceType = instanceType; + SetParameters(parameter1, parameter2, parameter3, parameter4, parameter5); + } + + /// + /// Initializes a new instance of the InstanceTypeAttribute class. + /// + ///The of an instance. + ///An additional parameter. + ///More additional parameters. + /// + public InstanceTypeAttribute(Type instanceType, object parameter1, params object[] parameters) + { + _instanceType = instanceType; + + // Note: we can not use something like + // public InstanceTypeAttribute(Type instanceType, params object[] parameters) + // because [InstanceType(typeof(Foo), new object[] {1,2,3})] will be treated as + // [InstanceType(typeof(Foo), 1, 2, 3)] so it will be not possible to specify + // an instance type with array as the type of the one and only parameter. + // An extra parameter of type object made it successul. + + int len = parameters.Length; + Array.Resize(ref parameters, len + 1); + Array.ConstrainedCopy(parameters, 0, parameters, 1, len); + parameters[0] = parameter1; + + SetParameters(parameters); + } + + protected void SetParameters(params object[] parameters) + { + _parameters = parameters; + } + + private object[] _parameters; + /// + /// Any additional parameters passed to a value holder constructor + /// with parameter. + /// + public object[] Parameters + { + get { return _parameters; } + } + + private readonly Type _instanceType; + protected Type InstanceType + { + get { return _instanceType; } + } + + private bool _isObjectHolder; + /// + /// False (default value) for holders for scalar types, + /// true for holders for complex objects. + /// + public bool IsObjectHolder + { + get { return _isObjectHolder; } + set { _isObjectHolder = value; } + } + + private Builders.IAbstractTypeBuilder _typeBuilder; + /// + /// An required for this attribute + /// to build an abstract type inheritor. + /// + public override Builders.IAbstractTypeBuilder TypeBuilder + { + get + { + return _typeBuilder ?? (_typeBuilder = + new Builders.InstanceTypeBuilder(_instanceType, _isObjectHolder)); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/LazyInstanceAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/LazyInstanceAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.Property)] + public sealed class LazyInstanceAttribute : Attribute + { + public LazyInstanceAttribute() + { + _isLazy = true; + } + + public LazyInstanceAttribute(bool isLazy) + { + _isLazy = isLazy; + } + + private bool _isLazy; + public bool IsLazy + { + get { return _isLazy; } + set { _isLazy = value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/LazyInstancesAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/LazyInstancesAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,44 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace BLToolkit.TypeBuilder +{ + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] + public class LazyInstancesAttribute : Attribute + { + public LazyInstancesAttribute() + { + } + + public LazyInstancesAttribute(Type type) + { + _type = type; + } + + public LazyInstancesAttribute(bool isLazy) + { + _isLazy = isLazy; + } + + public LazyInstancesAttribute(Type type, bool isLazy) + { + _type = type; + _isLazy = isLazy; + } + + private bool _isLazy = true; + public bool IsLazy + { + get { return _isLazy; } + set { _isLazy = value; } + } + + private Type _type = typeof(object); + public Type Type + { + get { return _type; } + set { _type = value ?? typeof(object); } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/NoInstanceAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/NoInstanceAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.Property)] + public sealed class NoInstanceAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/ParameterAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/ParameterAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,65 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace BLToolkit.TypeBuilder +{ + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")] + [AttributeUsage(AttributeTargets.Property)] + public class ParameterAttribute : Attribute + { + protected ParameterAttribute() + { + SetParameters(); + } + + public ParameterAttribute(object parameter1) + { + SetParameters(parameter1); + } + + public ParameterAttribute( + object parameter1, + object parameter2) + { + SetParameters(parameter1, parameter2); + } + + public ParameterAttribute( + object parameter1, + object parameter2, + object parameter3) + { + SetParameters(parameter1, parameter2, parameter3); + } + + public ParameterAttribute( + object parameter1, + object parameter2, + object parameter3, + object parameter4) + { + SetParameters(parameter1, parameter2, parameter3, parameter4); + } + + public ParameterAttribute( + object parameter1, + object parameter2, + object parameter3, + object parameter4, + object parameter5) + { + SetParameters(parameter1, parameter2, parameter3, parameter4, parameter5); + } + + protected void SetParameters(params object[] parameters) + { + _parameters = parameters; + } + + private object[] _parameters; + public object[] Parameters + { + get { return _parameters; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/ParentAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/ParentAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.Parameter)] + public sealed class ParentAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/PropertyChangedAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/PropertyChangedAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,91 @@ +using System; +using BLToolkit.Common; +using BLToolkit.TypeBuilder.Builders; + +namespace BLToolkit.TypeBuilder +{ + /// + /// This attribute allows to control generation of PropertyChanged notification at class level + /// + [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class)] + public sealed class PropertyChangedAttribute : AbstractTypeBuilderAttribute + { + /// + /// Specifies default generation options should be used for PropertyChanged notification + /// + public PropertyChangedAttribute() + :this(Common.Configuration.NotifyOnEqualSet) + { + } + + /// + /// This constructor allows control of PropertyChanged code generation + /// + /// See + public PropertyChangedAttribute(bool notifyOnEqualSet) + :this(notifyOnEqualSet, true) + { + } + + /// + /// This constructor allows control of PropertyChanged code generation + /// + /// See + /// See + public PropertyChangedAttribute(bool notifyOnEqualSet, bool useReferenceEquals) + :this(notifyOnEqualSet, useReferenceEquals, true) + { + } + + /// + /// This constructor allows control of PropertyChanged code generation + /// + /// See + /// See + /// See + public PropertyChangedAttribute(bool notifyOnEqualSet, bool useReferenceEquals, bool skipSetterOnNoChange) + { + _notifyOnEqualSet = notifyOnEqualSet; + _useReferenceEquals = useReferenceEquals; + _skipSetterOnNoChange = skipSetterOnNoChange; + } + + private bool _notifyOnEqualSet; + /// + /// Controls whether OnPropertyChanged notifications are sent when current value is same as new one. + /// + /// Default value controlled via and by default is set to false + /// + public bool NotifyOnEqualSet + { + get { return _notifyOnEqualSet; } + set { _notifyOnEqualSet = value; } + } + + private bool _useReferenceEquals; + /// + /// Specifies if Object.ReferenceEquals should be used for equality comparison of current and new value + /// for reference types. If value type implements op_Inequality, UseReferenceEquals is ignored. + /// + public bool UseReferenceEquals + { + get { return _useReferenceEquals; } + set { _useReferenceEquals = value; } + } + + private bool _skipSetterOnNoChange; + /// + /// Specifies whether call to setter is made when current value is same as new one + /// + public bool SkipSetterOnNoChange + { + get { return _skipSetterOnNoChange; } + set { _skipSetterOnNoChange = value; } + } + + public override IAbstractTypeBuilder TypeBuilder + { + get { return new PropertyChangedBuilder(_notifyOnEqualSet, _useReferenceEquals, _skipSetterOnNoChange); } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/PropertyInfoAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/PropertyInfoAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.Parameter)] + public sealed class PropertyInfoAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/RefCursorAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/RefCursorAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,18 @@ +using System; +using System.Reflection; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] + public class RefCursorAttribute : Attribute + { + } + + public static class RefCursorAttributeHelpers + { + public static bool IsRefCursor(this ParameterInfo pi) + { + return pi.GetCustomAttributes(typeof(RefCursorAttribute), false).Length > 0; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/ReturnIfFalseAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/ReturnIfFalseAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.ReturnValue)] + public sealed class ReturnIfFalseAttribute : ReturnIfZeroAttribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/ReturnIfNonZeroAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/ReturnIfNonZeroAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace BLToolkit.TypeBuilder +{ + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")] + [AttributeUsage(AttributeTargets.ReturnValue)] + public class ReturnIfNonZeroAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/ReturnIfNotNullAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/ReturnIfNotNullAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.ReturnValue)] + public sealed class ReturnIfNotNullAttribute : ReturnIfNonZeroAttribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/ReturnIfNullAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/ReturnIfNullAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.ReturnValue)] + public sealed class ReturnIfNullAttribute : ReturnIfZeroAttribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/ReturnIfTrueAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/ReturnIfTrueAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + [AttributeUsage(AttributeTargets.ReturnValue)] + public sealed class ReturnIfTrueAttribute : ReturnIfNonZeroAttribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/ReturnIfZeroAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/ReturnIfZeroAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace BLToolkit.TypeBuilder +{ + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")] + [AttributeUsage(AttributeTargets.ReturnValue)] + public class ReturnIfZeroAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/SetValueAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/SetValueAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +using System; + +namespace BLToolkit.TypeBuilder +{ + /// + /// Indicates that a field, property or method can be treated as a value setter. + /// + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method)] + public sealed class SetValueAttribute : Attribute + { + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/TypeBuilderException.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/TypeBuilderException.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,85 @@ +using System; +using System.Runtime.Serialization; + +namespace BLToolkit.TypeBuilder +{ + /// + /// Defines the base class for the namespace exceptions. + /// + /// + /// This class is the base class for exceptions that may occur during + /// execution of the namespace members. + /// + [Serializable] + public class TypeBuilderException : Exception + { + /// + /// Initializes a new instance of the class. + /// + /// + /// This constructor initializes the + /// property of the new instance such as "A Build Type exception has occurred." + /// + public TypeBuilderException() + : base("A Build Type exception has occurred.") + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message. + /// + /// The message to display to the client when the + /// exception is thrown. + /// + public TypeBuilderException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message and InnerException property. + /// + /// The message to display to the client when the + /// exception is thrown. + /// The InnerException, if any, that threw + /// the current exception. + /// + /// + public TypeBuilderException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified InnerException property. + /// + /// The InnerException, if any, that threw + /// the current exception. + /// + public TypeBuilderException(Exception innerException) + : base(innerException.Message, innerException) + { + } + +#if !SILVERLIGHT + + /// + /// Initializes a new instance of the class + /// with serialized data. + /// + /// The object that holds the serialized object data. + /// The contextual information about the source or + /// destination. + /// This constructor is called during deserialization to + /// reconstitute the exception object transmitted over a stream. + protected TypeBuilderException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + +#endif + } +} diff -r 000000000000 -r f990fcb411a9 Source/TypeBuilder/TypeFactory.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/TypeBuilder/TypeFactory.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,484 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq.Expressions; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.Permissions; + +using JetBrains.Annotations; + +using BLToolkit.Reflection; +using BLToolkit.Reflection.Emit; +using BLToolkit.TypeBuilder.Builders; +using BLToolkit.Properties; +#if !SILVERLIGHT +using BLToolkit.Configuration; +#endif + +namespace BLToolkit.TypeBuilder +{ + public static class TypeFactory + { + static TypeFactory() + { + SealTypes = true; + +#if !SILVERLIGHT + + var section = BLToolkitSection.Instance; + + if (section != null) + { + var elm = section.TypeFactory; + + if (elm != null) + { + SaveTypes = elm.SaveTypes; + SealTypes = elm.SealTypes; + LoadTypes = elm.LoadTypes; + + SetGlobalAssembly(elm.AssemblyPath, elm.Version, elm.KeyFile); + } + } + +#endif + +#if !SILVERLIGHT + + var perm = new SecurityPermission(SecurityPermissionFlag.ControlAppDomain); + +#if FW4 + try + { + //var permissionSet = new PermissionSet(PermissionState.None); + //permissionSet.AddPermission(perm); + + //if (permissionSet.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet)) + SubscribeAssemblyResolver(); + } + catch + { + } +#else + if (SecurityManager.IsGranted(perm)) + SubscribeAssemblyResolver(); +#endif + +#endif + } + + static void SubscribeAssemblyResolver() + { +#if FW4 + // This hack allows skipping FW 4.0 security check for partial trusted assemblies. + // + + var dm = new DynamicMethod("SubscribeAssemblyResolverEx", typeof(void), null); + var emit = new EmitHelper(dm.GetILGenerator()); + + emit + .call (typeof(AppDomain).GetProperty("CurrentDomain").GetGetMethod()) + .ldnull + .ldftn (typeof(TypeFactory).GetMethod("AssemblyResolver")) + .newobj (typeof(ResolveEventHandler).GetConstructor(new[] { typeof(object), typeof(IntPtr) })) + .callvirt (typeof(AppDomain).GetEvent("AssemblyResolve").GetAddMethod()) + .ret() + ; + + var setter = (Action)dm.CreateDelegate(typeof(Action)); + + setter(); +#else + AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver; +#endif + } + + #region Create Assembly + + private static string _globalAssemblyPath; + private static string _globalAssemblyKeyFile; + private static Version _globalAssemblyVersion; + private static AssemblyBuilderHelper _globalAssembly; + + private static AssemblyBuilderHelper GlobalAssemblyBuilder + { + get + { + if (_globalAssembly == null && _globalAssemblyPath != null) + _globalAssembly = new AssemblyBuilderHelper(_globalAssemblyPath, _globalAssemblyVersion, _globalAssemblyKeyFile); + + return _globalAssembly; + } + } + + public static bool SaveTypes { get; set; } + public static bool SealTypes { get; set; } + + [SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")] + public static void SetGlobalAssembly(string path) + { + SetGlobalAssembly(path, null, null); + } + + [SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")] + public static void SetGlobalAssembly(string path, Version version, string keyFile) + { + if (_globalAssembly != null) + SaveGlobalAssembly(); + + if (!string.IsNullOrEmpty(path)) + _globalAssemblyPath = path; + + _globalAssemblyVersion = version; + _globalAssemblyKeyFile = keyFile; + } + + public static void SaveGlobalAssembly() + { + if (_globalAssembly != null) + { + _globalAssembly.Save(); + + WriteDebug("The global assembly saved in '{0}'.", _globalAssembly.Path); + + _globalAssembly = null; + _globalAssemblyPath = null; + _globalAssemblyVersion = null; + _globalAssemblyKeyFile = null; + } + } + + private static AssemblyBuilderHelper GetAssemblyBuilder(Type type, string suffix) + { + var ab = GlobalAssemblyBuilder; + + if (ab == null) + { +#if SILVERLIGHT + var assemblyDir = "."; +#else + var assemblyDir = AppDomain.CurrentDomain.BaseDirectory; + + // Dynamic modules are locationless, so ignore them. + // _ModuleBuilder is the base type for both + // ModuleBuilder and InternalModuleBuilder classes. + // + if (!(type.Module is _ModuleBuilder) && type.Module.FullyQualifiedName != null && type.Module.FullyQualifiedName.IndexOf('<') < 0) + assemblyDir = Path.GetDirectoryName(type.Module.FullyQualifiedName); +#endif + + var fullName = type.FullName; + + if (type.IsGenericType) + fullName = AbstractClassBuilder.GetTypeFullName(type); + + fullName = fullName.Replace('<', '_').Replace('>', '_'); + + ab = new AssemblyBuilderHelper(Path.Combine(assemblyDir, fullName + "." + suffix + ".dll")); + } + + return ab; + } + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + private static void SaveAssembly(AssemblyBuilderHelper assemblyBuilder, Type type) + { + if (!SaveTypes || _globalAssembly != null) + return; + try + { + assemblyBuilder.Save(); + + WriteDebug("The '{0}' type saved in '{1}'.", + type.FullName, + assemblyBuilder.Path); + } + catch (Exception ex) + { + WriteDebug("Can't save the '{0}' assembly for the '{1}' type: {2}.", + assemblyBuilder.Path, + type.FullName, + ex.Message); + } + } + + #endregion + + #region GetType + + static readonly Dictionary> _builtTypes = new Dictionary>(10); + static readonly Dictionary _assemblies = new Dictionary(10); + + public static bool LoadTypes { get; set; } + + public static Type GetType(object hashKey, Type sourceType, ITypeBuilder typeBuilder) + { + if (hashKey == null) throw new ArgumentNullException("hashKey"); + if (sourceType == null) throw new ArgumentNullException("sourceType"); + if (typeBuilder == null) throw new ArgumentNullException("typeBuilder"); + + try + { + lock (_builtTypes) + { + Type type; + IDictionary builderTable; + + if (_builtTypes.TryGetValue(typeBuilder.GetType(), out builderTable)) + { + if (builderTable.TryGetValue(hashKey, out type)) + return type; + } + else + _builtTypes.Add(typeBuilder.GetType(), builderTable = new Dictionary()); + + if (LoadTypes) + { + var originalAssembly = sourceType.Assembly; + + Assembly extensionAssembly; + + if (!_assemblies.TryGetValue(originalAssembly, out extensionAssembly)) + { + extensionAssembly = LoadExtensionAssembly(originalAssembly); + _assemblies.Add(originalAssembly, extensionAssembly); + } + + if (extensionAssembly != null) + { + type = extensionAssembly.GetType(typeBuilder.GetTypeName()); + + if (type != null) + { + builderTable.Add(hashKey, type); + return type; + } + } + } + + var assemblyBuilder = GetAssemblyBuilder(sourceType, typeBuilder.AssemblyNameSuffix); + + type = typeBuilder.Build(assemblyBuilder); + + if (type != null) + { + builderTable.Add(hashKey, type); + SaveAssembly(assemblyBuilder, type); + } + + return type; + } + } + catch (TypeBuilderException) + { + throw; + } + catch (Exception ex) + { + // Convert an Exception to TypeBuilderException. + // + throw new TypeBuilderException(string.Format(Resources.TypeFactory_BuildFailed, sourceType.FullName), ex); + } + } + + public static Type GetType(Type sourceType) + { + return + TypeHelper.IsScalar(sourceType) || sourceType.IsSealed || + (!sourceType.IsAbstract && sourceType.IsDefined(typeof(BLToolkitGeneratedAttribute), true)) ? + sourceType: + GetType(sourceType, sourceType, new AbstractClassBuilder(sourceType)); + } + + static class InstanceCreator + { + public static readonly Func CreateInstance = Expression.Lambda>(Expression.New(TypeFactory.GetType(typeof(T)))).Compile(); + } + + public static T CreateInstance() where T: class + { + return InstanceCreator.CreateInstance(); + } + + #endregion + + #region Private Helpers + + static Assembly LoadExtensionAssembly(Assembly originalAssembly) + { +#if !SILVERLIGHT + + if (originalAssembly is _AssemblyBuilder) + { + // This is a generated assembly. Even if it has a valid Location, + // there is definitelly no extension assembly at this path. + // + return null; + } + + try + { + var originalAssemblyLocation = new Uri(originalAssembly.EscapedCodeBase).LocalPath; + var extensionAssemblyLocation = Path.ChangeExtension( + originalAssemblyLocation, "BLToolkitExtension.dll"); + + if (File.GetLastWriteTime(originalAssemblyLocation) <= File.GetLastWriteTime(extensionAssemblyLocation)) + return Assembly.LoadFrom(extensionAssemblyLocation); + + Debug.WriteLineIf(File.Exists(extensionAssemblyLocation), + string.Format("Extension assembly '{0}' is out of date. Please rebuild.", + extensionAssemblyLocation), typeof(TypeAccessor).FullName); + + // Some good man may load this assembly already. Like IIS does it. + // + var extensionAssemblyName = originalAssembly.GetName(true); + extensionAssemblyName.Name += ".BLToolkitExtension"; + + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + // Note that assembly version and strong name are compared too. + // + if (AssemblyName.ReferenceMatchesDefinition(assembly.GetName(false), extensionAssemblyName)) + return assembly; + } + } + catch (Exception ex) + { + // Extension exist, but can't be loaded for some reason. + // Switch back to code generation + // + Debug.WriteLine(ex, typeof(TypeAccessor).FullName); + } + +#endif + + return null; + } + + [Conditional("DEBUG")] + private static void WriteDebug(string format, params object[] parameters) + { + Debug.WriteLine(string.Format(format, parameters)); + } + + #endregion + + #region Resolve Types + + /// + /// Initializes AssemblyResolve hooks for the current . + /// + public static void Init() + { + // + // The code actually does nothing except an implicit call to the type constructor. + // + } + + public static Assembly AssemblyResolver(object sender, ResolveEventArgs args) + { + var name = args.Name; + var nameParts = name.Split(','); + + if (nameParts.Length > 0 && nameParts[0].ToLower().EndsWith(".dll")) + { + nameParts[0] = nameParts[0].Substring(0, nameParts[0].Length - 4); + name = string.Join(",", nameParts); + } + + lock (_builtTypes) + foreach (var type in _builtTypes.Keys) + if (type.FullName == name) + return type.Assembly; + +#if !SILVERLIGHT + + var idx = name.IndexOf("." + TypeBuilderConsts.AssemblyNameSuffix); + + if (idx > 0) + { + var typeName = name.Substring(0, idx); + var type = Type.GetType(typeName); + + if (type == null) + { + var ass = ((AppDomain)sender).GetAssemblies(); + + // CLR can't find an assembly built on previous AssemblyResolve event. + // + for (var i = ass.Length - 1; i >= 0; i--) + { + if (string.Compare(ass[i].FullName, name) == 0) + return ass[i]; + } + + for (var i = ass.Length - 1; i >= 0; i--) + { + var a = ass[i]; + + if (!( +#if FW4 + a.IsDynamic || +#endif + a is _AssemblyBuilder) && + (a.CodeBase.IndexOf("Microsoft.NET/Framework") > 0 || a.FullName.StartsWith("System."))) continue; + + type = a.GetType(typeName); + + if (type != null) break; + + foreach (var t in a.GetTypes()) + { + if (!t.IsAbstract) + continue; + + if (t.FullName == typeName) + { + type = t; + } + else + { + if (t.FullName.IndexOf('+') > 0) + { + var s = typeName; + + while (type == null && (idx = s.LastIndexOf(".")) > 0) + { + s = s.Remove(idx, 1).Insert(idx, "+"); + + if (t.FullName == s) + type = t; + } + } + } + + if (type != null) break; + } + + if (type != null) break; + } + } + + if (type != null) + { + var newType = GetType(type); + + if (newType.Assembly.FullName == name) + return newType.Assembly; + } + } + +#endif + + return null; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/FriendlyNameAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/FriendlyNameAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +using System; + +namespace BLToolkit.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class)] + public class FriendlyNameAttribute : Attribute + { + public FriendlyNameAttribute(string name) + { + _name = name; + } + + private readonly string _name; + public string Name + { + get { return _name; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/IValidatable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/IValidatable.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +namespace BLToolkit.Validation +{ + public interface IValidatable + { + void Validate(); + + bool IsValid (string fieldName); + string[] GetErrorMessages(string fieldName); + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/MaxDateValueAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/MaxDateValueAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,41 @@ +using System; + +namespace BLToolkit.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public class MaxDateValueAttribute : MaxValueAttribute + { + public MaxDateValueAttribute(int year, int month, int day) + : base(new DateTime(year, month, day)) + { + } + + public MaxDateValueAttribute(int year, int month, int day, string errorMessage) + : this(year, month, day) + { + ErrorMessage = errorMessage; + } + + public MaxDateValueAttribute(int year, int month, int day, bool isExclusive) + : base(new DateTime(year, month, day), isExclusive) + { + } + + public MaxDateValueAttribute(int year, int month, int day, bool isExclusive, string errorMessage) + : this(year, month, day, isExclusive) + { + ErrorMessage = errorMessage; + } + + public override bool IsValid(ValidationContext context) + { + if (context.IsNull(context)) + return true; + + DateTime contextValue = Convert.ToDateTime(context.Value); + DateTime testValue = (DateTime)GetValue(context); + + return testValue > contextValue || !IsExclusive && testValue == contextValue; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/MaxLengthAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/MaxLengthAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,41 @@ +using System; + +namespace BLToolkit.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public class MaxLengthAttribute : ValidatorBaseAttribute + { + public MaxLengthAttribute(int maxLength) + { + _value = maxLength; + } + + public MaxLengthAttribute(int maxLength, string errorMessage) + : this(maxLength) + { + ErrorMessage = errorMessage; + } + + private readonly int _value; + public int Value + { + get { return _value; } + } + + public override bool IsValid(ValidationContext context) + { + return context.IsNull(context) || context.Value.ToString().Length <= _value; + } + + public override string ErrorMessage + { + get { return base.ErrorMessage ?? "'{0}' maximum length is {1}."; } + set { base.ErrorMessage = value; } + } + + public override string GetErrorMessage(ValidationContext context) + { + return string.Format(ErrorMessage, GetPropertyFriendlyName(context), Value); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/MaxValueAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/MaxValueAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,140 @@ +using System; + +namespace BLToolkit.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public class MaxValueAttribute : ValidatorBaseAttribute + { + public MaxValueAttribute(object maxValue) + : this(maxValue, false) + { + } + + public MaxValueAttribute(object maxValue, string errorMessage) + : this(maxValue, false, errorMessage) + { + } + + public MaxValueAttribute(object maxValue, bool isExclusive) + { + _value = maxValue; + _isExclusive = isExclusive; + } + + public MaxValueAttribute(object maxValue, bool isExclusive, string errorMessage) + : this(maxValue, isExclusive) + { + ErrorMessage = errorMessage; + } + + private readonly object _value; + public virtual object GetValue(ValidationContext context) + { + return _value; + } + + private bool _isExclusive; + public bool IsExclusive + { + get { return _isExclusive; } + set { _isExclusive = value; } + } + + public override bool IsValid(ValidationContext context) + { + if (context.IsNull(context)) + return true; + + object contextValue = context.Value; + object testValue = GetValue(context); + + if (contextValue is Int32) + { + Int32 tv = Convert.ToInt32(testValue); + return tv > (Int32)contextValue || !IsExclusive && tv == (Int32)contextValue; + } + + if (contextValue is decimal) + { + decimal tv = Convert.ToDecimal(testValue); + return tv > (decimal)contextValue || !IsExclusive && tv == (decimal)contextValue; + } + + if (contextValue is double) + { + double tv = Convert.ToDouble(testValue); + return tv > (double)contextValue || !IsExclusive && tv == (double)contextValue; + } + + if (contextValue is float) + { + float tv = Convert.ToSingle(testValue); + return tv > (float)contextValue || !IsExclusive && tv == (float)contextValue; + } + + if (contextValue is byte) + { + byte tv = Convert.ToByte(testValue); + return tv > (byte)contextValue || !IsExclusive && tv == (byte)contextValue; + } + + if (contextValue is char) + { + char tv = Convert.ToChar(testValue); + return tv > (char)contextValue || !IsExclusive && tv == (char)contextValue; + } + + if (contextValue is Int16) + { + Int16 tv = Convert.ToInt16(testValue); + return tv > (Int16)contextValue || !IsExclusive && tv == (Int16)contextValue; + } + + if (contextValue is sbyte) + { + sbyte tv = Convert.ToSByte(testValue); + return tv > (sbyte)contextValue || !IsExclusive && tv == (sbyte)contextValue; + } + + if (contextValue is UInt16) + { + UInt16 tv = Convert.ToUInt16(testValue); + return tv > (UInt16)contextValue || !IsExclusive && tv == (UInt16)contextValue; + } + + if (contextValue is UInt32) + { + UInt32 tv = Convert.ToUInt32(testValue); + return tv > (UInt32)contextValue || !IsExclusive && tv == (UInt32)contextValue; + } + + if (contextValue is Int64) + { + Int64 tv = Convert.ToInt64(testValue); + return tv > (Int64)contextValue || !IsExclusive && tv == (Int64)contextValue; + } + + if (contextValue is UInt64) + { + UInt64 tv = Convert.ToUInt64(testValue); + return tv > (UInt64)contextValue || !IsExclusive && tv == (UInt64)contextValue; + } + + return true; + } + + public override string ErrorMessage + { + get { return base.ErrorMessage ?? "Maximum value for '{0}' is {1}{2}."; } + set { base.ErrorMessage = value; } + } + + public override string GetErrorMessage(ValidationContext context) + { + return string.Format(ErrorMessage, + GetPropertyFriendlyName(context), + GetValue(context), + IsExclusive? " exclusive": string.Empty); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/MinDateValueAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/MinDateValueAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,41 @@ +using System; + +namespace BLToolkit.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public class MinDateValueAttribute : MinValueAttribute + { + public MinDateValueAttribute(int year, int month, int day) + : base(new DateTime(year, month, day)) + { + } + + public MinDateValueAttribute(int year, int month, int day, string errorMessage) + : this(year, month, day) + { + ErrorMessage = errorMessage; + } + + public MinDateValueAttribute(int year, int month, int day, bool isExclusive) + : base(new DateTime(year, month, day), isExclusive) + { + } + + public MinDateValueAttribute(int year, int month, int day, bool isExclusive, string errorMessage) + : this(year, month, day, isExclusive) + { + ErrorMessage = errorMessage; + } + + public override bool IsValid(ValidationContext context) + { + if (context.IsNull(context)) + return true; + + DateTime contextValue = Convert.ToDateTime(context.Value); + DateTime testValue = (DateTime)GetValue(context); + + return testValue < contextValue || !IsExclusive && testValue == contextValue; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/MinLengthAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/MinLengthAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,41 @@ +using System; + +namespace BLToolkit.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public class MinLengthAttribute : ValidatorBaseAttribute + { + public MinLengthAttribute(int minLength) + { + _value = minLength; + } + + public MinLengthAttribute(int minLength, string errorMessage) + : this(minLength) + { + ErrorMessage = errorMessage; + } + + private readonly int _value; + public int Value + { + get { return _value; } + } + + public override bool IsValid(ValidationContext context) + { + return context.IsNull(context) || context.Value.ToString().Length >= _value; + } + + public override string ErrorMessage + { + get { return base.ErrorMessage ?? "'{0}' minimum length is {1}."; } + set { base.ErrorMessage = value; } + } + + public override string GetErrorMessage(ValidationContext context) + { + return string.Format(ErrorMessage, GetPropertyFriendlyName(context), Value); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/MinValueAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/MinValueAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,140 @@ +using System; + +namespace BLToolkit.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public class MinValueAttribute : ValidatorBaseAttribute + { + public MinValueAttribute(object minValue) + : this(minValue, false) + { + } + + public MinValueAttribute(object minValue, string errorMessage) + : this(minValue, false, errorMessage) + { + } + + public MinValueAttribute(object minValue, bool isExclusive) + { + _value = minValue; + _isExclusive = isExclusive; + } + + public MinValueAttribute(object minValue, bool isExclusive, string errorMessage) + : this(minValue, isExclusive) + { + ErrorMessage = errorMessage; + } + + private readonly object _value; + public virtual object GetValue(ValidationContext context) + { + return _value; + } + + private bool _isExclusive; + public bool IsExclusive + { + get { return _isExclusive; } + set { _isExclusive = value; } + } + + public override bool IsValid(ValidationContext context) + { + if (context.IsNull(context)) + return true; + + object contextValue = context.Value; + object testValue = GetValue(context); + + if (contextValue is Int32) + { + Int32 tv = Convert.ToInt32(testValue); + return tv < (Int32)contextValue || !IsExclusive && tv == (Int32)contextValue; + } + + if (contextValue is decimal) + { + decimal tv = Convert.ToDecimal(testValue); + return tv < (decimal)contextValue || !IsExclusive && tv == (decimal)contextValue; + } + + if (contextValue is double) + { + double tv = Convert.ToDouble(testValue); + return tv < (double)contextValue || !IsExclusive && tv == (double)contextValue; + } + + if (contextValue is float) + { + float tv = Convert.ToSingle(testValue); + return tv < (float)contextValue || !IsExclusive && tv == (float)contextValue; + } + + if (contextValue is byte) + { + byte tv = Convert.ToByte(testValue); + return tv < (byte)contextValue || !IsExclusive && tv == (byte)contextValue; + } + + if (contextValue is char) + { + char tv = Convert.ToChar(testValue); + return tv < (char)contextValue || !IsExclusive && tv == (char)contextValue; + } + + if (contextValue is Int16) + { + Int16 tv = Convert.ToInt16(testValue); + return tv < (Int16)contextValue || !IsExclusive && tv == (Int16)contextValue; + } + + if (contextValue is sbyte) + { + sbyte tv = Convert.ToSByte(testValue); + return tv < (sbyte)contextValue || !IsExclusive && tv == (sbyte)contextValue; + } + + if (contextValue is UInt16) + { + UInt16 tv = Convert.ToUInt16(testValue); + return tv < (UInt16)contextValue || !IsExclusive && tv == (UInt16)contextValue; + } + + if (contextValue is UInt32) + { + UInt32 tv = Convert.ToUInt32(testValue); + return tv < (UInt32)contextValue || !IsExclusive && tv == (UInt32)contextValue; + } + + if (contextValue is Int64) + { + Int64 tv = Convert.ToInt64(testValue); + return tv < (Int64)contextValue || !IsExclusive && tv == (Int64)contextValue; + } + + if (contextValue is UInt64) + { + UInt64 tv = Convert.ToUInt64(testValue); + return tv < (UInt64)contextValue || !IsExclusive && tv == (UInt64)contextValue; + } + + return true; + } + + public override string ErrorMessage + { + get { return base.ErrorMessage ?? "Minimum value for '{0}' is {1}{2}."; } + set { base.ErrorMessage = value; } + } + + public override string GetErrorMessage(ValidationContext context) + { + return string.Format(ErrorMessage, + GetPropertyFriendlyName(context), + GetValue(context), + IsExclusive? " exclusive": string.Empty); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/RegExAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/RegExAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,76 @@ +using System; +using System.Text.RegularExpressions; + +namespace BLToolkit.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public class RegExAttribute : ValidatorBaseAttribute + { + public RegExAttribute(string pattern) + : this(pattern, RegexOptions.IgnorePatternWhitespace +#if !SILVERLIGHT + | RegexOptions.Compiled +#endif + ) + { + } + + public RegExAttribute(string pattern, RegexOptions options) + { + _pattern = pattern; + _options = options; + } + + public RegExAttribute(string pattern, string errorMessage) + : this(pattern) + { + ErrorMessage = errorMessage; + } + + public RegExAttribute(string pattern, RegexOptions options, string errorMessage) + :this(pattern, options) + { + ErrorMessage = errorMessage; + } + + [Obsolete("Use RegExAttribute.Pattern instead.")] + public string Value { get { return Pattern; } } + + private readonly string _pattern; + public string Pattern { get { return _pattern; } } + + private readonly RegexOptions _options; + public RegexOptions Options { get { return _options; } } + +#if !SILVERLIGHT + [NonSerialized] +#endif + private Regex _validator; + public Regex Validator + { + get + { + if (_validator == null) + _validator = new Regex(_pattern, _options); + + return _validator; + } + } + + public override bool IsValid(ValidationContext context) + { + if (context.IsNull(context)) + return true; + + Match match = Validator.Match(context.Value.ToString()); + + return match.Success && match.Value == context.Value.ToString(); + } + + public override string ErrorMessage + { + get { return base.ErrorMessage ?? "'{0}' format is not valid."; } + set { base.ErrorMessage = value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/RequiredAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/RequiredAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +using System; + +namespace BLToolkit.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public class RequiredAttribute : ValidatorBaseAttribute + { + public RequiredAttribute() + { + } + + public RequiredAttribute(string errorMessage) + : base(errorMessage) + { + } + + public override bool IsValid(ValidationContext context) + { + return context.IsNull(context) == false; + } + + public override string ErrorMessage + { + get { return base.ErrorMessage ?? "'{0}' is required."; } + set { base.ErrorMessage = value; } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/ValidatableObjectBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/ValidatableObjectBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +namespace BLToolkit.Validation +{ + public class ValidatableObjectBase + { + public virtual void Validate() + { + Validator.Validate(this); + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/ValidationContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/ValidationContext.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,119 @@ +using System; +using System.ComponentModel; +using System.Reflection; +using BLToolkit.Mapping; +using BLToolkit.Reflection; + +namespace BLToolkit.Validation +{ + public class ValidationContext + { + public delegate bool IsNullHandler(ValidationContext context); + + private object _object; + public object Object + { + get { return _object; } + set { _object = value; } + } + + private TypeAccessor _typeAccessor; + public TypeAccessor TypeAccessor + { + get + { + if (_typeAccessor == null) + _typeAccessor = TypeAccessor.GetAccessor(_object.GetType()); + + return _typeAccessor; + } + } + + private PropertyDescriptor _propertyDescriptor; + public PropertyDescriptor PropertyDescriptor + { + get { return _propertyDescriptor; } + set { _propertyDescriptor = value; } + } + + private IsNullHandler _isNull; + public IsNullHandler IsNull + { + get { return _isNull; } + set { _isNull = value; } + } + + public bool IsValueNull + { + get { return _isNull(this); } + } + + private object _value; + public object Value + { + get { return _value; } + set + { + _value = value; + _nullValue = null; + } + } + + private MemberAccessor _memberAccessor; + public MemberAccessor MemberAccessor + { + get { return _memberAccessor; } + set + { + _memberAccessor = value; + _memberInfo = value != null? value.MemberInfo: null; + } + } + + private MemberInfo _memberInfo; + public MemberInfo MemberInfo + { + get { return _memberInfo; } + } + + private object _nullValue; + public object NullValue + { + get + { + if (_nullValue == null) + { + if (_value == null) + throw new InvalidOperationException("NullValue is undefined when Value == null"); + + ObjectMapper om = Map.GetObjectMapper(Object.GetType()); + MemberMapper mm = om[MemberName, true]; + + _nullValue = + mm != null && mm.MapMemberInfo.Nullable && mm.MapMemberInfo.NullValue != null? + mm.MapMemberInfo.NullValue: + TypeAccessor.GetNullValue(Value.GetType()); + + if (_nullValue == null) + _nullValue = DBNull.Value; + } + + return _nullValue; + + } + } + + public string MemberName + { + get + { + return + _memberInfo != null? _memberInfo.Name: +#if !SILVERLIGHT + _propertyDescriptor != null? _propertyDescriptor.Name: +#endif + null; + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/ValidationException.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/ValidationException.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,86 @@ +using System; +using System.Runtime.Serialization; + +namespace BLToolkit.Validation +{ + /// + /// Defines the base class for the namespace exceptions. + /// + /// + /// This class is the base class for exceptions that may occur during + /// execution of the namespace members. + /// + [Serializable] + public class ValidationException : Exception + { + /// + /// Initializes a new instance of the class. + /// + /// + /// This constructor initializes the + /// property of the new instance such as "A Validation exception has occurred." + /// + public ValidationException() + : base("A Validation exception has occurred.") + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message. + /// + /// The message to display to the client when the + /// exception is thrown. + /// + public ValidationException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified error message and InnerException property. + /// + /// The message to display to the client when the + /// exception is thrown. + /// The InnerException, if any, that threw + /// the current exception. + /// + /// + public ValidationException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified InnerException property. + /// + /// The InnerException, if any, that threw + /// the current exception. + /// + /// + public ValidationException(Exception innerException) + : base(innerException.Message, innerException) + { + } + +#if !SILVERLIGHT + + /// + /// Initializes a new instance of the class + /// with serialized data. + /// + /// The object that holds the serialized object data. + /// The contextual information about the source or + /// destination. + /// This constructor is called during deserialization to + /// reconstitute the exception object transmitted over a stream. + protected ValidationException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + +#endif + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/Validator.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/Validator.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,212 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; + +using BLToolkit.Reflection; + +namespace BLToolkit.Validation +{ + public class Validator + { + #region Validate + + public static void Validate(ValidationContext context) + { + foreach (MemberAccessor ma in context.TypeAccessor) + { + var attrs = ma.GetAttributes(); + + if (attrs == null) + continue; + + context.MemberAccessor = ma; + context.Value = ma.GetValue(context.Object); + + for (var i = 0; i < attrs.Length; i++) + { + var attr = attrs[i]; + if (attr.IsValid(context) == false) + throw new ValidationException(attr.GetErrorMessage(context)); + } + } + } + + public static void Validate(object obj, ValidationContext.IsNullHandler isNull) + { + Validate(InitContext(null, obj, null, isNull)); + } + + public static void Validate(object obj) + { + Validate(obj, null); + } + + #endregion + + #region Protected Members + + private static bool IsNullInternal(ValidationContext context) + { + if (context.Value == null) + return true; + + if (context.NullValue is DBNull) + return false; + + return context.NullValue.Equals(context.Value); + } + + public static ValidationContext InitContext( + ValidationContext context, + object obj, + PropertyDescriptor pd, + ValidationContext.IsNullHandler isNull) + { + if (context == null) + context = new ValidationContext(); + + context.Object = obj; + context.IsNull = isNull ?? new ValidationContext.IsNullHandler(IsNullInternal); + context.PropertyDescriptor = pd; + + return context; + } + + #endregion + + #region IsValid + + public static bool IsValid(ValidationContext context, string fieldName) + { + ValidatorBaseAttribute[] attrs = null; + object value = null; + +#if !SILVERLIGHT + + if (context.PropertyDescriptor != null) + { + value = context.PropertyDescriptor.GetValue(context.Object); + + List list = null; + + foreach (var o in context.PropertyDescriptor.Attributes) + { + if (o is ValidatorBaseAttribute) + { + if (list == null) + list = new List(); + + list.Add((ValidatorBaseAttribute)o); + } + } + + if (list != null) + attrs = list.ToArray(); + } + else + +#endif + + { + context.MemberAccessor = context.TypeAccessor[fieldName]; + + if (context.MemberAccessor != null) + { + value = context.MemberAccessor.GetValue(context.Object); + attrs = context.MemberAccessor.GetAttributes(); + } + } + + if (attrs != null) + { + context.Value = value; + + for (var i = 0; i < attrs.Length; i++) + { + if (!attrs[i].IsValid(context)) + return false; + } + } + + return true; + } + + public static bool IsValid(object obj, string fieldName, ValidationContext.IsNullHandler isNull) + { + return IsValid(InitContext(null, obj, null, isNull), fieldName); + } + +#if !SILVERLIGHT + + public static bool IsValid(object obj, PropertyDescriptor pd, ValidationContext.IsNullHandler isNull) + { + return IsValid(InitContext(null, obj, pd, isNull), pd.Name); + } + + public static bool IsValid(object obj, PropertyDescriptor pd) + { + return IsValid(obj, pd, null); + } + +#endif + + public static bool IsValid(object obj, string fieldName) + { + return IsValid(obj, fieldName, null); + } + + #endregion + + #region GetErrorMessages + + public static string[] GetErrorMessages(ValidationContext context, string fieldName) + { + context.MemberAccessor = context.TypeAccessor[fieldName]; + + if (context.MemberAccessor != null) + { + var messages = new List(); + var attrs = context.MemberAccessor.GetAttributes(); + + if (attrs != null) + { + context.Value = context.MemberAccessor.GetValue(context.Object); + + for (var i = 0; i < attrs.Length; i++) + messages.Add(attrs[i].GetErrorMessage(context)); + + return messages.ToArray(); + } + } + + return new string[0]; + } + + public static string[] GetErrorMessages( + object obj, string fieldName, ValidationContext.IsNullHandler isNull) + { + return GetErrorMessages(InitContext(null, obj, null, isNull), fieldName); + } + +#if !SILVERLIGHT + + public static string[] GetErrorMessages(object obj, PropertyDescriptor pd, ValidationContext.IsNullHandler isNull) + { + return GetErrorMessages(InitContext(null, obj, pd, isNull), pd.Name); + } + + public static string[] GetErrorMessages(object obj, PropertyDescriptor pd) + { + return GetErrorMessages(obj, pd, null); + } + +#endif + + public static string[] GetErrorMessages(object obj, string fieldName) + { + return GetErrorMessages(obj, fieldName, null); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Validation/ValidatorBaseAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Validation/ValidatorBaseAttribute.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,69 @@ +using System; +using System.Reflection; +using System.ComponentModel; + +namespace BLToolkit.Validation +{ + public abstract class ValidatorBaseAttribute : Attribute + { + protected ValidatorBaseAttribute() + { + } + + protected ValidatorBaseAttribute(string errorMessage) + { + _errorMessage = errorMessage; + } + + private string _errorMessage; + public virtual string ErrorMessage + { + get { return _errorMessage; } + set { _errorMessage = value; } + } + + public abstract bool IsValid(ValidationContext context); + + public virtual string GetErrorMessage(ValidationContext context) + { + return string.Format(ErrorMessage, GetPropertyFriendlyName(context)); + } + + protected virtual string GetPropertyFriendlyName(ValidationContext context) + { + MemberInfo mi = context.MemberInfo; + string className = mi.DeclaringType.Name; + string fieldName = mi.Name; + + // Get class name. + // + object[] attrs = mi.DeclaringType.GetCustomAttributes(typeof(FriendlyNameAttribute), true); + + if (attrs.Length > 0) + className = ((FriendlyNameAttribute)attrs[0]).Name; + else + { + attrs = mi.DeclaringType.GetCustomAttributes(typeof(DisplayNameAttribute), true); + + if (attrs.Length > 0) + className = ((DisplayNameAttribute)attrs[0]).DisplayName; + } + + // Get field name. + // + attrs = mi.GetCustomAttributes(typeof(FriendlyNameAttribute), true); + + if (attrs.Length > 0) + fieldName = ((FriendlyNameAttribute)attrs[0]).Name; + else + { + attrs = mi.GetCustomAttributes(typeof(DisplayNameAttribute), true); + + if (attrs.Length > 0) + fieldName = ((DisplayNameAttribute)attrs[0]).DisplayName; + } + + return string.IsNullOrEmpty(className)? fieldName: className + "." + fieldName; + } + } +} diff -r 000000000000 -r f990fcb411a9 Source/Web/UI/Design/WebObjectBinderDesigner.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Web/UI/Design/WebObjectBinderDesigner.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,160 @@ +using System; +using System.Web.UI.Design; +using System.Security.Permissions; +using System.ComponentModel; + +namespace BLToolkit.Web.UI.Design +{ + [SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] + class WebObjectBinderDesigner : DataSourceDesigner + { + private DesignerDataSourceView _view; + private WebObjectBinder _component; + + public override string[] GetViewNames() + { + return new string[] { "DefaultView" }; + } + + public override DesignerDataSourceView GetView(string viewName) + { + if (string.IsNullOrEmpty(viewName)) + viewName = "DefaultView"; + + if (viewName != "DefaultView") + return null; + + if (_view == null) + _view = new ObjectDesignerDataSourceView(this, viewName); + + return _view; + } + + public override void Initialize(IComponent component) + { + _component = (WebObjectBinder)component; + + base.Initialize(component); + } + + public override bool CanConfigure + { + get { return true; } + } + + public override void Configure() + { + } + + #region ObjectDesignerDataSourceView + + class ObjectDesignerDataSourceView : DesignerDataSourceView + { + public ObjectDesignerDataSourceView(WebObjectBinderDesigner owner, string viewName) + : base(owner, viewName) + { + _owner = owner; + } + + private readonly WebObjectBinderDesigner _owner; + + public override IDataSourceViewSchema Schema + { + get { return new ObjectViewSchema(_owner); } + } + + public override bool CanDelete { get { return _owner._component._objectBinder.AllowRemove; } } + public override bool CanInsert { get { return _owner._component._objectBinder.AllowNew; } } + public override bool CanUpdate { get { return _owner._component._objectBinder.AllowEdit; } } + public override bool CanPage { get { return true; } } + public override bool CanSort { get { return true; } } + public override bool CanRetrieveTotalRowCount { get { return true; } } + + class ObjectViewSchema : IDataSourceViewSchema + { + public ObjectViewSchema(WebObjectBinderDesigner owner) + { + _owner = owner; + } + + private readonly WebObjectBinderDesigner _owner; + + public IDataSourceViewSchema[] GetChildren() + { + return null; + } + + public IDataSourceFieldSchema[] GetFields() + { + PropertyDescriptorCollection fields = + ((ITypedList)_owner._component._objectBinder).GetItemProperties(null); + + IDataSourceFieldSchema[] schema = new IDataSourceFieldSchema[fields.Count]; + + for (int i = 0; i < schema.Length; i++) + schema[i] = new ObjectFieldSchema(fields[i]); + + return schema; + } + + public string Name + { + get + { + Type type = _owner._component._objectBinder.ItemType; + + return type != null? type.Name: string.Empty; + } + } + + class ObjectFieldSchema : IDataSourceFieldSchema + { + public ObjectFieldSchema(PropertyDescriptor propertyDescriptor) + { + _propertyDescriptor = propertyDescriptor; + + DataObjectFieldAttribute attr = + (DataObjectFieldAttribute)_propertyDescriptor.Attributes[typeof(DataObjectFieldAttribute)]; + + if (attr != null) + { + _length = attr.Length; + _primaryKey = attr.PrimaryKey; + _isIdentity = attr.IsIdentity; + _isNullable = attr.IsNullable; + } + } + + private readonly PropertyDescriptor _propertyDescriptor; + private readonly int _length = -1; + private readonly bool _isIdentity; + private readonly bool _isNullable; + private readonly bool _primaryKey; + + public Type DataType { get { return _propertyDescriptor.PropertyType; } } + public bool Identity { get { return _isIdentity; } } + public bool IsReadOnly { get { return _propertyDescriptor.IsReadOnly; } } + public bool IsUnique { get { return false; } } + public int Length { get { return _length; } } + public string Name { get { return _propertyDescriptor.Name; } } + public int Precision { get { return -1; } } + public bool PrimaryKey { get { return _primaryKey; } } + public int Scale { get { return -1; } } + + public bool Nullable + { + get + { + Type type = _propertyDescriptor.PropertyType; + Type underlyingType = System.Nullable.GetUnderlyingType(type); + + return underlyingType != null? true: _isNullable; + } + } + } + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Web/UI/WebObjectBinder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Web/UI/WebObjectBinder.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,251 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Web.Compilation; +using System.Web.UI; + +using BLToolkit.ComponentModel; +using BLToolkit.ComponentModel.Design; +using BLToolkit.EditableObjects; + +namespace BLToolkit.Web.UI +{ + [DefaultProperty("TypeName")] + [ToolboxBitmap(typeof(WebObjectBinder))] +#if !FW4 + [Designer(typeof(BLToolkit.Web.UI.Design.WebObjectBinderDesigner))] +#endif + [PersistChildren(false)] + [ParseChildren(true)] + [Description("BLToolkit Web Object Binder")] + [DisplayName("Object Binder")] + public class WebObjectBinder : DataSourceControl, IListSource + { + #region Constructors + + public WebObjectBinder() + { + _objectBinder.ListChanged += _objectBinder_ListChanged; + } + + #endregion + + #region Public Members + + [RefreshProperties(RefreshProperties.Repaint)] + [DefaultValue(null)] + [Category("Data")] + [Editor(typeof(TypeNameEditor), typeof(UITypeEditor))] + public string TypeName + { + get + { + Type type = _objectBinder.ItemType; + return type == null ? "(none)" : type.FullName; + } + set + { + _objectBinder.ItemType = string.IsNullOrEmpty(value) || value == "(none)"? + null: BuildManager.GetType(value, false, true); + } + } + + [RefreshProperties(RefreshProperties.Repaint)] + [DefaultValue(null)] + [Category("Data")] + [Editor(typeof(ObjectViewTypeNameEditor), typeof(UITypeEditor))] + public string ObjectViewTypeName + { + get + { + Type type = _objectBinder.ObjectViewType; + return type == null ? "(none)" : type.FullName; + } + set + { + _objectBinder.ObjectViewType = string.IsNullOrEmpty(value) || value == "(none)"? + null: BuildManager.GetType(value, false, true); + } + } + + [Browsable(false)] + [RefreshProperties(RefreshProperties.Repaint)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object Object + { + get { return _objectBinder.Object; } + set { _objectBinder.Object = value; } + } + + [Browsable(false)] + [RefreshProperties(RefreshProperties.Repaint)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IList List + { + get { return _objectBinder.List; } + set { _objectBinder.List = value; } + } + + #endregion + + #region Protected members + + internal ObjectBinder _objectBinder = new ObjectBinder(); + + private void _objectBinder_ListChanged(object sender, ListChangedEventArgs e) + { + switch (e.ListChangedType) + { + case ListChangedType.PropertyDescriptorAdded: + case ListChangedType.PropertyDescriptorChanged: + case ListChangedType.PropertyDescriptorDeleted: + RaiseDataSourceChangedEvent(e); + break; + } + } + + public override void Dispose() + { + _objectBinder.Dispose(); + + base.Dispose(); + } + + #endregion + + #region IListSource Members + + bool IListSource.ContainsListCollection + { + get { return false; } + } + + IList IListSource.GetList() + { + return _objectBinder.List; + } + + #endregion + + #region IDataSource Members + + private ObjectDataSourceView _view; + + protected override DataSourceView GetView(string viewName) + { + if (_view == null) + _view = new ObjectDataSourceView(this, "DefaultView"); + + return _view; + } + + protected override ICollection GetViewNames() + { + return new string[] { "DefaultView" }; + } + + #endregion + + #region ObjectDataSourceView + + class ObjectDataSourceView : DataSourceView + { + public ObjectDataSourceView(WebObjectBinder owner, string viewName) + : base(owner, viewName) + { + _owner = owner; + } + + readonly WebObjectBinder _owner; + + protected override IEnumerable ExecuteSelect(DataSourceSelectArguments arguments) + { + return new ObjectEnumerator(_owner._objectBinder, arguments); + } + + public override bool CanDelete { get { return _owner._objectBinder.AllowRemove; } } + public override bool CanInsert { get { return _owner._objectBinder.AllowNew; } } + public override bool CanUpdate { get { return _owner._objectBinder.AllowEdit; } } + public override bool CanPage { get { return true; } } + public override bool CanSort { get { return true; } } + public override bool CanRetrieveTotalRowCount { get { return true; } } + } + + #endregion + + #region ObjectEnumerator + + class ObjectEnumerator : ICollection + { + public ObjectEnumerator(ObjectBinder objectBinder, DataSourceSelectArguments arguments) + { + _objectBinder = objectBinder; + _arguments = arguments; + } + + private readonly ObjectBinder _objectBinder; + private readonly DataSourceSelectArguments _arguments; + + #region ICollection Members + + public void CopyTo(Array array, int index) + { + _objectBinder.List.CopyTo(array, index); + } + + public int Count + { + get { return _objectBinder.List.Count; } + } + + public bool IsSynchronized + { + get { return _objectBinder.List.IsSynchronized; } + } + + public object SyncRoot + { + get { return _objectBinder.List.SyncRoot; } + } + + #endregion + + #region IEnumerable Members + + public IEnumerator GetEnumerator() + { + _arguments.AddSupportedCapabilities(DataSourceCapabilities.Page); + _arguments.AddSupportedCapabilities(DataSourceCapabilities.Sort); + _arguments.AddSupportedCapabilities(DataSourceCapabilities.RetrieveTotalRowCount); + + EditableArrayList list = (EditableArrayList)_objectBinder.List; + + _arguments.TotalRowCount = list.Count; + + if (!string.IsNullOrEmpty(_arguments.SortExpression)) + { + list = new EditableArrayList(list.ItemType, list.Count); + list.AddRange(_objectBinder.List); + list.SortEx(_arguments.SortExpression); + } + + int start = _arguments.StartRowIndex >= 0? _arguments.StartRowIndex: 0; + int count = _arguments.MaximumRows > 0? + Math.Min(_arguments.MaximumRows, list.Count): list.Count; + + for (int i = 0; i < count; i++) + { + object o = list[i + start]; + + yield return o is ICustomTypeDescriptor? o: new ObjectHolder(o, _objectBinder); + } + } + + #endregion + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Source/Web/UI/WebObjectBinder.ico Binary file Source/Web/UI/WebObjectBinder.ico has changed diff -r 000000000000 -r f990fcb411a9 Tools/BLTgen/BLTgen.2005.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/BLTgen/BLTgen.2005.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,57 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {65FC918C-FF12-4C75-96F5-180B552989E5} + Exe + Properties + BLTgen + BLTgen + + + true + full + false + bin\Debug\ + TRACE;DEBUG + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + {F4DF7358-8EE6-49FD-AB13-EA5145058D79} + BLToolkit.2 + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/BLTgen/BLTgen.2008.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/BLTgen/BLTgen.2008.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,98 @@ + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {65FC918C-FF12-4C75-96F5-180B552989E5} + Exe + Properties + BLTgen + BLTgen + + + 2.0 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + v3.5 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + + + + + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.3 + + + + + + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/BLTgen/BLTgen.2010.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/BLTgen/BLTgen.2010.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,147 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {65FC918C-FF12-4C75-96F5-180B552989E5} + Exe + Properties + BLTgen + BLTgen.4 + + + 3.5 + + + false + v4.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\DebugMono\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\BLTgen.4.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + bin\ReleaseMono\ + TRACE + true + pdbonly + AnyCPU + bin\Release\BLTgen.4.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + + + 3.5 + + + + + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + {0C325F5D-E50E-4340-8724-D29896CCC583} + BLToolkit.4 + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/BLTgen/Program.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/BLTgen/Program.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,242 @@ +using System; +using System.ComponentModel; +using System.IO; +using System.Reflection; +using System.Text.RegularExpressions; + +using BLToolkit.Mapping; +using BLToolkit.Reflection; +using BLToolkit.TypeBuilder; + +namespace BLTgen +{ + public class Arguments + { + [MapField(""), Description("source assembly location")] + public string SourceAssembly; + + [MapField("B"), Description("Base type names to include (default: none). Example: /B:*EntityBase;SomeNamespace.*Base")] + public string BaseTypes; + + [MapField("O"), Description("Output directory name (default: target assembly location). Example: /O:C:\\Temp")] + public string OutputDirectory; + + [MapField("I"), Description("Type names to include (default: all). Example: /I:*Accessor;SomeNamespace.*;OtherNamespace.*")] + public string Include; + + [MapField("X"), Description("Type names to exclude (default: none). Example: /X:SomeNamespace.SomeType")] + public string Exclude; + + [MapField("K"), Description("The key pair that is used to create a strong name signature for the output assembly (default: none). Example: /K:C:\\SomePath\\key.snk")] + public string KeyPairFile; + + [MapField("V"), Description("The version of the output assembly (same as source assembly by default). Example: /V:1.2.3.4")] + public string Version; + + [MapField("D"), Description("Detailed output (default: false). Example: /D")] + public string Debug; + } + + class Program + { + public static void Main(string[] args) + { + var parsedArgs = new Arguments(); + + Map.MapSourceToDestination(new StringListMapper(args), args, + Map.GetObjectMapper(typeof(Arguments)), parsedArgs); + + WriteBanner(); + + if (string.IsNullOrEmpty(parsedArgs.SourceAssembly)) + Usage(); + else + GenerateExtensionAssembly(parsedArgs); + } + + private static void GenerateExtensionAssembly(Arguments parsedArgs) + { + var verbose = parsedArgs.Debug != null; + var sourceAsm = Assembly.LoadFrom(parsedArgs.SourceAssembly); + var extensionAssemblyPath = GetOutputAssemblyLocation(sourceAsm.Location, parsedArgs.OutputDirectory); + var extensionAssemblyVersion = parsedArgs.Version != null? new Version(parsedArgs.Version): sourceAsm.GetName().Version; + var extensionAssemblyFolder = Path.GetDirectoryName(extensionAssemblyPath); + + if (verbose) + Console.WriteLine("{0} =>{1}{2}", sourceAsm.Location, Environment.NewLine, extensionAssemblyPath); + + if (!string.IsNullOrEmpty(extensionAssemblyFolder) && !Directory.Exists(extensionAssemblyFolder)) + Directory.CreateDirectory(extensionAssemblyFolder); + + var typesToProcess = sourceAsm.GetExportedTypes(); + + typesToProcess = FilterBaseTypes(typesToProcess, parsedArgs.BaseTypes); + typesToProcess = FilterTypes(typesToProcess, parsedArgs.Include, true); + typesToProcess = FilterTypes(typesToProcess, parsedArgs.Exclude, false); + + if (typesToProcess.Length > 0) + { + AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs args) + { + foreach (var asm in ((AppDomain)sender).GetAssemblies()) + { + if (string.Compare(asm.FullName, args.Name) == 0) + return asm; + } + + return null; + }; + + TypeFactory.SaveTypes = true; + TypeFactory.SetGlobalAssembly(extensionAssemblyPath, extensionAssemblyVersion, parsedArgs.KeyPairFile); + + foreach (var t in typesToProcess) + { + if (verbose) + Console.Write(GetFullTypeName(t)); + + // We cannot create accessors for generic definitions + // + if (t.IsGenericTypeDefinition) + { + if (verbose) + Console.WriteLine(" - skipping. Generic Definition"); + + continue; + } + + if (verbose) + Console.WriteLine(); + + try + { + TypeAccessor.GetAccessor(t); + } + catch (Exception e) + { + if (verbose) + Console.WriteLine(e); + } + } + + TypeFactory.SaveGlobalAssembly(); + } + else if (verbose) + Console.WriteLine("No types to process."); + } + + private static Type[] FilterBaseTypes(Type[] types, string pattern) + { + if (string.IsNullOrEmpty(pattern)) + return types; + + var re = new Regex("^" + Regex.Escape(pattern).Replace("\\*", ".*").Replace(";", "$|") + "$"); + + return Array.FindAll(types, delegate(Type t) + { + for (var bt = t.BaseType; bt != null; bt = bt.BaseType) + { + if (re.Match(GetFullTypeName(bt)).Success) + return true; + } + return false; + }); + } + + private static Type[] FilterTypes(Type[] types, string pattern, bool include) + { + if (string.IsNullOrEmpty(pattern)) + return types; + + var re = new Regex("^" + Regex.Escape(pattern).Replace("\\*", ".*").Replace(";", "$|") + "$"); + + return Array.FindAll(types, t => re.Match(GetFullTypeName(t)).Success == include); + } + + // System.Type.FullName may be null under some conditions. See + // http://blogs.msdn.com/haibo_luo/archive/2006/02/17/534480.aspx + // + private static string GetFullTypeName(Type t) + { + var fullName = t.FullName; + + if (fullName != null) + return fullName; + + if (t.DeclaringType != null) + return GetFullTypeName(t.DeclaringType) + "+" + t.Name; + + fullName = t.Namespace; + if (fullName != null) + fullName += "."; + + fullName += t.Name; + + return fullName; + } + + private static string GetOutputAssemblyLocation(string sourceAssembly, string outputDirectory) + { + if (string.IsNullOrEmpty(outputDirectory)) + outputDirectory = Path.GetDirectoryName(sourceAssembly); + + var fileName = Path.ChangeExtension(Path.GetFileName(sourceAssembly), "BLToolkitExtension.dll"); + return Path.Combine(Path.GetFullPath(outputDirectory), fileName); + } + + #region Usage + + private static void WriteBanner() + { + var asm = Assembly.GetExecutingAssembly(); + var descriptionAttribute = (AssemblyDescriptionAttribute) + Attribute.GetCustomAttribute(asm, typeof (AssemblyDescriptionAttribute)); + var copyrightAttribute = (AssemblyCopyrightAttribute) + Attribute.GetCustomAttribute(asm, typeof(AssemblyCopyrightAttribute)); + + Console.WriteLine("{0}, Version {1}", descriptionAttribute.Description, asm.GetName().Version); + Console.WriteLine(copyrightAttribute.Copyright); + Console.WriteLine(); + } + + private static string ExecutableName + { + get { return Path.GetFileName(new Uri(Assembly.GetEntryAssembly().EscapedCodeBase).LocalPath); } + } + + private static string GetDescription(MemberMapper mm) + { + var desc = mm.MemberAccessor.GetAttribute(); + + return (null != desc) ? desc.Description : string.Empty; + } + + private static void Usage() + { + var om = Map.GetObjectMapper(typeof(Arguments)); + + Console.Write("Usage: {0}", ExecutableName); + + foreach (MemberMapper mm in om) + { + if (0 == mm.Name.Length) + Console.Write(" <{0}>", GetDescription(mm)); + else + Console.Write(" /{0}:", mm.Name); + } + + Console.WriteLine(); + Console.WriteLine("Options:"); + + foreach (MemberMapper mm in om) + { + if (0 != mm.Name.Length) + Console.WriteLine("\t{0}: {1}", mm.Name, GetDescription(mm)); + } + + Console.WriteLine(); + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Tools/BLTgen/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/BLTgen/Properties/AssemblyInfo.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BLTgen")] +[assembly: AssemblyDescription("Business Logic Toolkit Extension Assembly Generator")] +[assembly: AssemblyProduct("Business Logic Toolkit")] +[assembly: AssemblyCopyright("\xA9 2002-2012 www.bltoolkit.net")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("92fdb31a-0bc4-4e4d-a44b-67cbad205bd5")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion ("4.1")] +[assembly: AssemblyFileVersion("4.1")] diff -r 000000000000 -r f990fcb411a9 Tools/BLTgen/StringListMapper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/BLTgen/StringListMapper.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,75 @@ +using System; + +using BLToolkit.Mapping; + +namespace BLTgen +{ + public class StringListMapper : MapDataSourceBase + { + string[] _list; + + public StringListMapper(string[] list) + { + _list = list; + } + + #region IMapDataSource + + public override int Count + { + get { return _list.Length; } + } + + public override Type GetFieldType(int index) + { + return (index > 0 && index < _list.Length)? typeof(string): null; + } + + public override string GetName(int index) + { + return GetNameOrValue(_list[index], true); + } + + public override int GetOrdinal(string name) + { + throw new InvalidOperationException("IMapDataSource.GetOrdinal(string)"); + } + + public override object GetValue(object o, int index) + { + return GetNameOrValue(_list[index], false); + } + + public override object GetValue(object o, string name) + { + throw new InvalidOperationException("IMapDataSource.GetValue(object, string)"); + } + + #endregion + + #region Implementation + + private static string GetNameOrValue(string str, bool name) + { + if (str.StartsWith("\"") && str.EndsWith("\"")) + str = str.Substring(1, str.Length - 2); + + // Option + // + if (str.StartsWith("-") || str.StartsWith("/")) + { + int colon = str.IndexOfAny(new char[] { ':', '=' }, 1); + if (colon > 0) + return name ? str.Substring(1, colon - 1) : str.Substring(colon + 1); + + return name ? str.Substring(1) : string.Empty; + } + + // Default parameter + // + return name ? string.Empty : str; + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Tools/BLTgen/app.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/BLTgen/app.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3 @@ + + + diff -r 000000000000 -r f990fcb411a9 Tools/CodeGenerator/CodeGenerator.2.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/CodeGenerator/CodeGenerator.2.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,68 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {E7735874-6552-4B35-A9C1-1279A9E9C8B9} + Library + Properties + CodeGenerator + CodeGenerator.2 + OnOutputUpdated + + + + + true + full + false + bin\Debug\ + TRACE;DEBUG + prompt + 4 + default + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + TransformCodeGenerator + Convert.cs + BLToolkit.Common + + + + TransformCodeGenerator + ValueMapping.cs + BLToolkit.Mapping + + + + + + True + True + Convert.xml + + + + + True + True + ValueMapping.xml + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/CodeGenerator/CodeGenerator.2008.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/CodeGenerator/CodeGenerator.2008.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,73 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {E7735874-6552-4B35-A9C1-1279A9E9C8B9} + Library + Properties + CodeGenerator + CodeGenerator.2 + OnOutputUpdated + + + + + + + 2.0 + + + true + full + false + bin\Debug\ + TRACE;DEBUG + prompt + 4 + default + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + TransformCodeGenerator + Convert.cs + BLToolkit.Common + + + + TransformCodeGenerator + ValueMapping.cs + BLToolkit.Mapping + + + + + + True + True + Convert.xml + + + + + True + True + ValueMapping.xml + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/CodeGenerator/Convert.Declare.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/CodeGenerator/Convert.Declare.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,60 @@ +using System; + +[assembly: CLSCompliant(true)] + +namespace BLToolkit.Common +{ + public class TypeHelper + { + public static bool IsSameOrParent(Type type,Type type1) + { + return true; + } + } + + public interface IConvertible + { + T From(P p); + } + + public static partial class Convert + { + public static IConvertible Instance = GetConverter(); + + private static IConvertible GetConverter() + { + if (TypeHelper.IsSameOrParent(typeof(T), typeof(P))) + { + return (IConvertible)(object)(new ConvertAssignable()); + } + + return new ConvertExplicit(); + } + } + + internal class ConvertAssignable: IConvertible where P: T + { + T IConvertible.From(P p) { return p; } + } + + internal class ConvertDefault: IConvertible + { + T IConvertible.From(P p) { return (T)System.Convert.ChangeType(p, typeof(T)); } + } + + internal partial class ConvertPartial: ConvertDefault + { + } + + internal partial class ConvertExplicit: ConvertPartial + { + } +} + +namespace BLToolkit.Properties +{ + public class Resources + { + public const string Convert_InvalidCast = "{0} {1}"; + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/CodeGenerator/Convert.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/CodeGenerator/Convert.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1832 @@ + + + +<<<<<<<<<<<<<<< This crap should not be used anymore. + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + return p.ToString(); + + + + + + + + + return p.ToString(); + + + + + return p.IsNull? null: p.ToSqlString().Value; + return p.IsNull? null: p.Value; + return p.ToString(); + + + return p == null? null: p.FullName; + return p == null? null: p.InnerXml; + return p == null? null: System.Text.Encoding.UTF8.GetString(p); + return p == null? null: System.Text.Encoding.UTF8.GetString(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToString(null); + if (p is IFormattable) return ((IFormattable)p).ToString(null, null); + + return p.ToString(); + +
+ + + return p == null? (SByte)0: SByte.Parse(p); +
+ + return (SByte)(p? 1: 0); + + return checked((SByte)p); +
+ + return p.HasValue? p.Value: (SByte)0; +
+ + + return (p.HasValue && p.Value)? (SByte)1: (SByte)0; + return p.HasValue? checked((SByte)p.Value): (SByte)0; +
+ + + return p.IsNull? (SByte)0: ToSByte(p.Value); + + + return p == null || p.Length == 0? (SByte)0: checked((SByte)p[0]); + return p == null || p.Length == 0? (SByte)0: checked((SByte)p.ToArray()[0]); + + + if (p is IConvertible) return ((IConvertible)p).ToSByte(null); + +
+ + + return p == null? (Int16)0: Int16.Parse(p); +
+ + return (Int16)(p? 1: 0); + + return checked((Int16)p); +
+ + return p.HasValue? p.Value: (Int16)0; +
+ + + return (p.HasValue && p.Value)? (Int16)1: (Int16)0; + return p.HasValue? checked((Int16)p.Value): (Int16)0; +
+ + return p.IsNull? (Int16)0: p.Value; + + return p.IsNull? (Int16)0: ToInt16(p.Value); + + + return p == null || p.Length == 0? (Int16)0: BitConverter.ToInt16(p, 0); + return p == null || p.Length == 0? (Int16)0: BitConverter.ToInt16(p.ToArray(), 0); + + + if (p is IConvertible) return ((IConvertible)p).ToInt16(null); + +
+ + + return p == null? 0: Int32.Parse(p); +
+ + return p? 1: 0; + + return checked((Int32)p); +
+ + return p.HasValue? p.Value: 0; +
+ + + return (p.HasValue && p.Value)? 1: 0; + return p.HasValue? checked((Int32)p.Value): 0; +
+ + return p.IsNull? 0: p.Value; + + return p.IsNull? 0: ToInt32(p.Value); + + + return p == null || p.Length == 0? 0: BitConverter.ToInt32(p, 0); + return p == null || p.Length == 0? 0: BitConverter.ToInt32(p.ToArray(), 0); + + + if (p is IConvertible) return ((IConvertible)p).ToInt32(null); + +
+ + + return p == null? 0: Int64.Parse(p); +
+ + + return p? 1: 0; + return (p - DateTime.MinValue).Ticks; + return (p - DateTime.MinValue).Ticks; + return p.Ticks; + return checked((Int64)p); +
+ + return p.HasValue? p.Value: 0; +
+ + + return (p.HasValue && p.Value)? 1: 0; + return p.HasValue? (p.Value - DateTime.MinValue).Ticks: 0; + return p.HasValue? (p.Value - DateTime.MinValue).Ticks: 0; + return p.HasValue? p.Value.Ticks: 0; + return p.HasValue? checked((Int64)p.Value): 0; +
+ + return p.IsNull? 0: p.Value; + + + return p.IsNull? 0: ToInt64(p.Value); + + + return p == null || p.Length == 0? 0: BitConverter.ToInt64(p, 0); + return p == null || p.Length == 0? 0: BitConverter.ToInt64(p.ToArray(), 0); + + + if (p is IConvertible) return ((IConvertible)p).ToInt64(null); + +
+
+ + + return p == null? (Byte)0: Byte.Parse(p); +
+ + return (Byte)(p? 1: 0); + + return checked((Byte)p); +
+ + return p.HasValue? p.Value: (Byte)0; +
+ + + return (p.HasValue && p.Value)? (Byte)1: (Byte)0; + return p.HasValue? checked((Byte)p.Value): (Byte)0; +
+ + return p.IsNull? (Byte)0: p.Value; + + return p.IsNull? (Byte)0: ToByte(p.Value); + + + return p == null || p.Length == 0? (Byte)0: p[0]; + return p == null || p.Length == 0? (Byte)0: p.ToArray()[0]; + + + if (p is IConvertible) return ((IConvertible)p).ToByte(null); + +
+ + + return p == null? (UInt16)0: UInt16.Parse(p); +
+ + return (UInt16)(p? 1: 0); + + return checked((UInt16)p); +
+ + return p.HasValue? p.Value: (UInt16)0; +
+ + + return (p.HasValue && p.Value)? (UInt16)1: (UInt16)0; + return p.HasValue? checked((UInt16)p.Value): (UInt16)0; +
+ + + return p.IsNull? (UInt16)0: ToUInt16(p.Value); + + + return p == null || p.Length == 0? (UInt16)0: BitConverter.ToUInt16(p, 0); + return p == null || p.Length == 0? (UInt16)0: BitConverter.ToUInt16(p.ToArray(), 0); + + + if (p is IConvertible) return ((IConvertible)p).ToUInt16(null); + +
+ + + return p == null? 0: UInt32.Parse(p); +
+ + return (UInt32)(p? 1: 0); + + return checked((UInt32)p); +
+ + return p.HasValue? p.Value: 0; +
+ + + return (p.HasValue && p.Value)? (UInt32)1: 0; + return p.HasValue? checked((UInt32)p.Value): 0; +
+ + + return p.IsNull? 0: ToUInt32(p.Value); + + + return p == null || p.Length == 0? 0: BitConverter.ToUInt32(p, 0); + return p == null || p.Length == 0? 0: BitConverter.ToUInt32(p.ToArray(), 0); + + + if (p is IConvertible) return ((IConvertible)p).ToUInt32(null); + +
+ + + return p == null? 0: UInt64.Parse(p); +
+ + return (UInt64)(p? 1: 0); + + return checked((UInt64)p); +
+ + return p.HasValue? p.Value: 0; +
+ + + return (p.HasValue && p.Value)? (UInt64)1: 0; + return p.HasValue? checked((UInt64)p.Value): 0; +
+ + + return p.IsNull? 0: ToUInt64(p.Value); + + + return p == null || p.Length == 0? 0: BitConverter.ToUInt64(p, 0); + return p == null || p.Length == 0? 0: BitConverter.ToUInt64(p.ToArray(), 0); + + + if (p is IConvertible) return ((IConvertible)p).ToUInt64(null); + +
+
+ + + return p == null? (Char)0: Char.Parse(p); +
+ + return (Char)(p? 1: 0); + return checked((Char)p); +
+ + return p.HasValue? p.Value: (Char)0; +
+ + return (p.HasValue && p.Value)? (Char)1: (Char)0; + return p.HasValue? checked((Char)p.Value): (Char)0; +
+ + + return p.IsNull? (Char)0: ToChar(p.Value); + + + return p == null || p.Length == 0? (Char)0: BitConverter.ToChar(p, 0); + return p == null || p.Length == 0? (Char)0: BitConverter.ToChar(p.ToArray(), 0); + + + if (p is IConvertible) return ((IConvertible)p).ToChar(null); + +
+ + + return p == null? 0.0f: Single.Parse(p); +
+ + return p? 1.0f: 0.0f; + + return checked((Single)p); +
+ + return p.HasValue? p.Value: 0.0f; +
+ + + return (p.HasValue && p.Value)? 1.0f: 0.0f; + return p.HasValue? checked((Single)p.Value): 0.0f; +
+ + return p.IsNull? 0.0f: p.Value; + + return p.IsNull? 0.0f: ToSingle(p.Value); + + + return p == null || p.Length == 0? 0.0f: BitConverter.ToSingle(p, 0); + return p == null || p.Length == 0? 0.0f: BitConverter.ToSingle(p.ToArray(), 0); + + + if (p is IConvertible) return ((IConvertible)p).ToSingle(null); + +
+ + + return p == null? 0.0: Double.Parse(p); +
+ + return p? 1.0: 0.0; + + return (p - DateTime.MinValue).TotalDays; + return (p - DateTime.MinValue).TotalDays; + return p.TotalDays; + return checked((Double)p); +
+ + return p.HasValue? p.Value: 0.0; +
+ + + return (p.HasValue && p.Value)? 1.0: 0.0; + return p.HasValue? (p.Value - DateTime.MinValue).TotalDays: 0.0; + return p.HasValue? (p.Value - DateTime.MinValue).TotalDays: 0.0; + return p.HasValue? p.Value.TotalDays: 0.0; + return p.HasValue? checked((Double)p.Value): 0.0; +
+ + return p.IsNull? 0.0: p.Value; + + + return p.IsNull? 0.0: ToDouble(p.Value); + + + return p == null || p.Length == 0? 0.0: BitConverter.ToDouble(p, 0); + return p == null || p.Length == 0? 0.0: BitConverter.ToDouble(p.ToArray(), 0); + + + if (p is IConvertible) return ((IConvertible)p).ToDouble(null); + +
+
+ + + return p == null? false : p.Length == 1 ? ToBoolean(p[0]) : Boolean.Parse(p); +
+ +
+ + switch (p) + { + case (Char)0: return false; // Allow int <=> Char <=> Boolean + case '0': return false; + case 'n': return false; + case 'N': return false; + case 'f': return false; + case 'F': return false; + + case (Char)1: return true; // Allow int <=> Char <=> Boolean + case '1': return true; + case 'y': return true; + case 'Y': return true; + case 't': return true; + case 'T': return true; + } + + throw CreateInvalidCastException(typeof(Char), typeof(Boolean)); + return p != 0; +
+ + return p.HasValue? p.Value: false; +
+ +
+ return p.HasValue? ToBoolean(p.Value): false; + return p.HasValue? p.Value != 0: false; +
+ + return p.IsNull? false: p.Value; + + return p.IsNull? false: ToBoolean(p.Value); + + + return p == null || p.Length == 0? false: BitConverter.ToBoolean(p, 0); + return p == null || p.Length == 0? false: BitConverter.ToBoolean(p.ToArray(), 0); + + + if (p is IConvertible) return ((IConvertible)p).ToBoolean(null); + +
+ + + return p == null? 0.0m: Decimal.Parse(p); +
+ + return p? 1.0m: 0.0m; + + return checked((Decimal)p); +
+ + return p.HasValue? p.Value: 0.0m; +
+ + + return (p.HasValue && p.Value)? 1.0m: 0.0m; + return p.HasValue? checked((Decimal)p.Value): 0.0m; +
+ + return p.IsNull? 0.0m: p.Value; + return p.IsNull? 0.0m: p.Value; + + return p.IsNull? 0.0m: ToDecimal(p.Value); + + + + if (p == null || p.Length == 0) return 0.0m; + + int[] bits = new int[p.Length / sizeof(int)]; + + Buffer.BlockCopy(p, 0, bits, 0, p.Length); + return new Decimal(bits); + + if (p == null || p.Length == 0) return 0.0m; + + int[] bits = new int[p.Length / sizeof(int)]; + + Buffer.BlockCopy(p.ToArray(), 0, bits, 0, p.Length); + return new Decimal(bits); + + + + if (p is IConvertible) return ((IConvertible)p).ToDecimal(null); + +
+ + + return p == null? DateTime.MinValue: DateTime.Parse(p, null, DateTimeStyles.NoCurrentDateDefault); + return DateTime.MinValue + p; + return DateTime.MinValue + TimeSpan.FromTicks(p); + return DateTime.MinValue + TimeSpan.FromDays(p); + return p.LocalDateTime; + + + return p.HasValue? p.Value: DateTime.MinValue; + return p.HasValue? p.Value.LocalDateTime: DateTime.MinValue; + return p.HasValue? DateTime.MinValue + p.Value: DateTime.MinValue; + return p.HasValue? DateTime.MinValue + TimeSpan.FromTicks(p.Value): DateTime.MinValue; + return p.HasValue? DateTime.MinValue + TimeSpan.FromDays(p.Value): DateTime.MinValue; + + + return p.IsNull? DateTime.MinValue: p.Value; + return p.IsNull? DateTime.MinValue: ToDateTime(p.Value); + return p.IsNull? DateTime.MinValue: DateTime.MinValue + TimeSpan.FromTicks(p.Value); + return p.IsNull? DateTime.MinValue: DateTime.MinValue + TimeSpan.FromDays(p.Value); + + + return p == null || p.Length == 0? DateTime.MinValue: DateTime.FromBinary(ToInt64(p)); + return p == null || p.Length == 0? DateTime.MinValue: DateTime.FromBinary(ToInt64(p.ToArray())); + + + if (p is IConvertible) return ((IConvertible)p).ToDateTime(null); + + + + + return p == null? DateTimeOffset.MinValue: DateTimeOffset.Parse(p); + return DateTimeOffset.MinValue + p; + return DateTimeOffset.MinValue + TimeSpan.FromTicks(p); + return DateTimeOffset.MinValue + TimeSpan.FromDays(p); + return p; + + + return p.HasValue? p.Value: DateTimeOffset.MinValue; + return p.HasValue? p.Value: DateTimeOffset.MinValue; + return p.HasValue? DateTimeOffset.MinValue + p.Value: DateTimeOffset.MinValue; + return p.HasValue? DateTimeOffset.MinValue + TimeSpan.FromTicks(p.Value): DateTimeOffset.MinValue; + return p.HasValue? DateTimeOffset.MinValue + TimeSpan.FromDays(p.Value): DateTimeOffset.MinValue; + + + return p.IsNull? DateTimeOffset.MinValue: p.Value; + return p.IsNull? DateTimeOffset.MinValue: ToDateTimeOffset(p.Value); + return p.IsNull? DateTimeOffset.MinValue: DateTimeOffset.MinValue + TimeSpan.FromTicks(p.Value); + return p.IsNull? DateTimeOffset.MinValue: DateTimeOffset.MinValue + TimeSpan.FromDays(p.Value); + + + return p == null || p.Length == 0? DateTimeOffset.MinValue: new DateTimeOffset(ToDateTime(p)); + return p == null || p.Length == 0? DateTimeOffset.MinValue: new DateTimeOffset(ToDateTime(p.ToArray())); + + + if (p is IConvertible) return ToDateTimeOffset(((IConvertible)p).ToDateTime(null)); + + + + + return p == null? TimeSpan.MinValue: TimeSpan.Parse(p); + return p - DateTime.MinValue; + return p - DateTimeOffset.MinValue; + return TimeSpan.FromTicks(p); + return TimeSpan.FromDays(p); + + + return p.HasValue? p.Value: TimeSpan.MinValue; + return p.HasValue? p.Value - DateTime.MinValue: TimeSpan.MinValue; + return p.HasValue? p.Value - DateTimeOffset.MinValue: TimeSpan.MinValue; + return p.HasValue? TimeSpan.FromTicks(p.Value): TimeSpan.MinValue; + return p.HasValue? TimeSpan.FromDays(p.Value): TimeSpan.MinValue; + + + return p.IsNull? TimeSpan.MinValue: TimeSpan.Parse(p.Value); + return p.IsNull? TimeSpan.MinValue: p.Value - DateTime.MinValue; + return p.IsNull? TimeSpan.MinValue: TimeSpan.FromTicks(p.Value); + return p.IsNull? TimeSpan.MinValue: TimeSpan.FromDays(p.Value); + + + return p == null || p.Length == 0? TimeSpan.MinValue: TimeSpan.FromTicks(ToInt64(p)); + return p == null || p.Length == 0? TimeSpan.MinValue: TimeSpan.FromTicks(ToInt64(p.ToArray())); + + + + + + return p == null? Guid.Empty: new Guid(p); + + + return p.HasValue? p.Value: Guid.Empty; + + + return p.IsNull? Guid.Empty: p.Value; + return p.IsNull? Guid.Empty: new Guid(p.Value); + return p.IsNull? Guid.Empty: p.ToSqlGuid().Value; + + + return p == null? Guid.Empty: new Guid(p); + return p == null? Guid.Empty: new Guid(p.ToArray()); + return p == null? Guid.Empty: p.GUID; + + + +
+ + + + return p; + return p == null? null: (SByte?)SByte.Parse(p); +
+ + + return (SByte?)(p? 1: 0); + return checked((SByte?)p); +
+ + + + return p.HasValue? (SByte?)(p.Value? 1: 0): null; + return p.HasValue? checked((SByte?)p.Value): null; + + + + return p.IsNull? null: ToNullableSByte(p.Value); + + + return p == null || p.Length == 0? null: (SByte?)ToSByte(p); + return p == null || p.Length == 0? null: (SByte?)ToSByte(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToSByte(null); + +
+ + + return p; + return p == null? null: (Int16?)Int16.Parse(p); +
+ + + return (Int16?)(p? 1: 0); + return checked((Int16?)p); +
+ + + + return p.HasValue? (Int16?)(p.Value? 1: 0): null; + return p.HasValue? checked((Int16?)p.Value): null; + + + return p.IsNull? null: (Int16?)p.Value; + + return p.IsNull? null: ToNullableInt16(p.Value); + + + return p == null || p.Length == 0? null: (Int16?)ToInt16(p); + return p == null || p.Length == 0? null: (Int16?)ToInt16(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToInt16(null); + +
+ + + return p; + return p == null? null: (Int32?)Int32.Parse(p); +
+ + + return p? 1: 0; + return checked((Int32?)p); +
+ + + + return p.HasValue? (Int32?)(p.Value? 1: 0): null; + return p.HasValue? checked((Int32?)p.Value): null; + + + return p.IsNull? null: (Int32?)p.Value; + + return p.IsNull? null: ToNullableInt32(p.Value); + + + return p == null || p.Length == 0? null: (Int32?)ToInt32(p); + return p == null || p.Length == 0? null: (Int32?)ToInt32(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToInt32(null); + +
+ + + return p; + return p == null? null: (Int64?)Int64.Parse(p); +
+ + + return p? 1: 0; + return (p - DateTime.MinValue).Ticks; + return (p - DateTimeOffset.MinValue).Ticks; + return p.Ticks; + return checked((Int64?)p); +
+ + + + return p.HasValue? (Int64?)(p.Value? 1: 0): null; + return p.HasValue? (Int64?)(p.Value - DateTime.MinValue).Ticks: null; + return p.HasValue? (Int64?)(p.Value - DateTimeOffset.MinValue).Ticks: null; + return p.HasValue? (Int64?)p.Value.Ticks: null; + return p.HasValue? checked((Int64?)p.Value): null; + + + return p.IsNull? null: (Int64?)p.Value; + + + return p.IsNull? null: ToNullableInt64(p.Value); + + + return p == null || p.Length == 0? null: (Int64?)ToInt64(p); + return p == null || p.Length == 0? null: (Int64?)ToInt64(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToInt64(null); + +
+
+ + + return p; + return p == null? null: (Byte?)Byte.Parse(p); +
+ + + return (Byte?)(p? 1: 0); + return checked((Byte?)p); +
+ + + + return p.HasValue? (Byte?)(p.Value? 1: 0): null; + return p.HasValue? checked((Byte?)p.Value): null; + + + return p.IsNull? null: (Byte?)p.Value; + + return p.IsNull? null: ToNullableByte(p.Value); + + + return p == null || p.Length == 0? null: (Byte?)ToByte(p); + return p == null || p.Length == 0? null: (Byte?)ToByte(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToByte(null); + +
+ + + return p; + return p == null? null: (UInt16?)UInt16.Parse(p); +
+ + + return (UInt16?)(p? 1: 0); + return checked((UInt16?)p); +
+ + + + return p.HasValue? (UInt16?)(p.Value? 1: 0): null; + return p.HasValue? checked((UInt16?)p.Value): null; + + + + return p.IsNull? null: ToNullableUInt16(p.Value); + + + return p == null || p.Length == 0? null: (UInt16?)ToUInt16(p); + return p == null || p.Length == 0? null: (UInt16?)ToUInt16(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToUInt16(null); + +
+ + + return p; + return p == null? null: (UInt32?)UInt32.Parse(p); +
+ + + return (UInt32?)(p? 1: 0); + return checked((UInt32?)p); +
+ + + + return p.HasValue? (UInt32?)(p.Value? 1: 0): null; + return p.HasValue? checked((UInt32?)p.Value): null; + + + + return p.IsNull? null: ToNullableUInt32(p.Value); + + + return p == null || p.Length == 0? null: (UInt32?)ToUInt32(p); + return p == null || p.Length == 0? null: (UInt32?)ToUInt32(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToUInt32(null); + +
+ + + return p; + return p == null? null: (UInt64?)UInt64.Parse(p); +
+ + + return (UInt64?)(p? 1: 0); + return checked((UInt64?)p); +
+ + + + return p.HasValue? (UInt64?)(p.Value? 1: 0): null; + return p.HasValue? checked((UInt64?)p.Value): null; + + + + return p.IsNull? null: ToNullableUInt64(p.Value); + + + return p == null || p.Length == 0? null: (UInt64?)ToUInt64(p); + return p == null || p.Length == 0? null: (UInt64?)ToUInt64(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToUInt64(null); + +
+
+ + + return p; + return p == null? null: (Char?)Char.Parse(p); +
+ + return (Char?)(p? 1: 0); + return checked((Char?)p); +
+ + + return p.HasValue? (Char?)(p.Value? 1: 0): null; + return p.HasValue? checked((Char?)p.Value): null; + + + + return p.IsNull? null: ToNullableChar(p.Value); + + + return p == null || p.Length == 0? null: (Char?)ToChar(p); + return p == null || p.Length == 0? null: (Char?)ToChar(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToChar(null); + +
+ + + return p; + return p == null? null: (Single?)Single.Parse(p); +
+ + + return p? 1.0f: 0.0f; + return checked((Single?)p); +
+ + + + return p.HasValue? (Single?)(p.Value? 1.0f: 0.0f): null; + return p.HasValue? checked((Single?)p.Value): null; + + + return p.IsNull? null: (Single?)p.Value; + + return p.IsNull? null: ToNullableSingle(p.Value); + + + return p == null || p.Length == 0? null: (Single?)ToSingle(p); + return p == null || p.Length == 0? null: (Single?)ToSingle(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToSingle(null); + +
+ + + return p; + return p == null? null: (Double?)Double.Parse(p); +
+ + + return p? 1.0: 0.0; + return (p - DateTime.MinValue).TotalDays; + return (p - DateTimeOffset.MinValue).TotalDays; + return p.TotalDays; + return checked((Double?)p); +
+ + + + return p.HasValue? (Double?)(p.Value? 1.0: 0.0): null; + return p.HasValue? (Double?)(p.Value - DateTime.MinValue).TotalDays: null; + return p.HasValue? (Double?)(p.Value - DateTimeOffset.MinValue).TotalDays: null; + return p.HasValue? (Double?)p.Value.TotalDays: null; + return p.HasValue? checked((Double?)p.Value): null; + + + return p.IsNull? null: (Double?)p.Value; + + return p.IsNull? null: (Double?)(p.Value - DateTime.MinValue).TotalDays; + return p.IsNull? null: ToNullableDouble(p.Value); + + + return p == null || p.Length == 0? null: (Double?)ToDouble(p); + return p == null || p.Length == 0? null: (Double?)ToDouble(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToDouble(null); + +
+
+ + + return p; + return p == null? null: (Boolean?)Boolean.Parse(p); +
+ + + return ToBoolean(p); +
+ + + + return p.HasValue? (Boolean?)ToBoolean(p.Value): null; + + + return p.IsNull? null: (Boolean?) p.Value; + + return p.IsNull? null: (Boolean?)ToBoolean(p.Value); + + + return p == null || p.Length == 0? null: (Boolean?)ToBoolean(p); + return p == null || p.Length == 0? null: (Boolean?)ToBoolean(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToBoolean(null); + +
+ + + return p; + return p == null? null: (Decimal?)Decimal.Parse(p); +
+ + + return p? 1.0m: 0.0m; + return checked((Decimal?)p); +
+ + + + return p.HasValue? (Decimal?)(p.Value? 1.0m: 0.0m): null; + return p.HasValue? checked((Decimal?)p.Value): null; + + + return p.IsNull? null: (Decimal?)p.Value; + return p.IsNull? null: (Decimal?)p.Value; + + return p.IsNull? null: ToNullableDecimal(p.Value); + + + return p == null || p.Length == 0? null: (Decimal?)ToDecimal(p); + return p == null || p.Length == 0? null: (Decimal?)ToDecimal(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToDecimal(null); + +
+ + + return p; + return p.LocalDateTime; + return p == null? null: (DateTime?)DateTime.Parse(p); +
+ return DateTime.MinValue + p; + return DateTime.MinValue + TimeSpan.FromTicks(p); + return DateTime.MinValue + TimeSpan.FromDays(p); +
+ + return p.HasValue? DateTime.MinValue + p.Value: (DateTime?)null; + return p.HasValue? DateTime.MinValue + TimeSpan.FromTicks(p.Value): (DateTime?)null; + return p.HasValue? DateTime.MinValue + TimeSpan.FromDays(p.Value): (DateTime?)null; + return p.HasValue? p.Value.LocalDateTime: (DateTime?)null; + + + return p.IsNull? (DateTime?)null: p.Value; + return p.IsNull? (DateTime?)null: ToDateTime(p.Value); + return p.IsNull? (DateTime?)null: DateTime.MinValue + TimeSpan.FromTicks(p.Value); + return p.IsNull? (DateTime?)null: DateTime.MinValue + TimeSpan.FromDays(p.Value); + + + return p == null || p.Length == 0? null: (DateTime?)ToDateTime(p); + return p == null || p.Length == 0? null: (DateTime?)ToDateTime(p.ToArray()); + + + if (p is IConvertible) return ((IConvertible)p).ToDateTime(null); + +
+ + + return p; + return p; + return p == null? null: (DateTimeOffset?)DateTimeOffset.Parse(p); +
+ return DateTimeOffset.MinValue + p; + return DateTimeOffset.MinValue + TimeSpan.FromTicks(p); + return DateTimeOffset.MinValue + TimeSpan.FromDays(p); +
+ + return p.HasValue? DateTimeOffset.MinValue + p.Value: (DateTimeOffset?)null; + return p.HasValue? DateTimeOffset.MinValue + TimeSpan.FromTicks(p.Value): (DateTimeOffset?)null; + return p.HasValue? DateTimeOffset.MinValue + TimeSpan.FromDays(p.Value): (DateTimeOffset?)null; + return p.HasValue? p: null; + + + return p.IsNull? (DateTimeOffset?)null: p.Value; + return p.IsNull? (DateTimeOffset?)null: ToDateTimeOffset(p.Value); + return p.IsNull? (DateTimeOffset?)null: DateTimeOffset.MinValue + TimeSpan.FromTicks(p.Value); + return p.IsNull? (DateTimeOffset?)null: DateTimeOffset.MinValue + TimeSpan.FromDays(p.Value); + + + return p == null || p.Length == 0? null: (DateTimeOffset?)ToDateTimeOffset(p); + return p == null || p.Length == 0? null: (DateTimeOffset?)ToDateTimeOffset(p.ToArray()); + + + if (p is IConvertible) return ToDateTimeOffset(((IConvertible)p).ToDateTime(null)); + +
+ + + return p; + return p == null? null: (TimeSpan?)TimeSpan.Parse(p); + return p - DateTime.MinValue; + return p - DateTimeOffset.MinValue; + return TimeSpan.FromTicks(p); + return TimeSpan.FromDays(p); + + + + return p.HasValue? p.Value - DateTime.MinValue: (TimeSpan?)null; + return p.HasValue? p.Value - DateTimeOffset.MinValue: (TimeSpan?)null; + return p.HasValue? TimeSpan.FromTicks(p.Value): (TimeSpan?)null; + return p.HasValue? TimeSpan.FromDays(p.Value): (TimeSpan?)null; + + + + return p.IsNull? (TimeSpan?)null: TimeSpan.Parse(p.Value); + return p.IsNull? (TimeSpan?)null: p.Value - DateTime.MinValue; + return p.IsNull? (TimeSpan?)null: TimeSpan.FromTicks(p.Value); + return p.IsNull? (TimeSpan?)null: TimeSpan.FromDays(p.Value); + + + return p == null || p.Length == 0? null: (TimeSpan?)ToTimeSpan(p); + return p == null || p.Length == 0? null: (TimeSpan?)ToTimeSpan(p.ToArray()); + + + + + + return p; + return p == null? null: (Guid?)new Guid(p); + + + return p.IsNull? null: (Guid?)p.Value; + return p.IsNull? null: (Guid?)new Guid(p.Value); + return p.IsNull? null: (Guid?)p.ToSqlGuid().Value; + + + return p == null? null: (Guid?)p.GUID; + return p == null? null: (Guid?)new Guid(p); + return p == null? null: (Guid?)new Guid(p.ToArray()); + + + +
+ + + + return p ?? SqlString.Null; +
+ + + + + + + return new String(p); + return p.ToString(); +
+ + + + + + + + + return p.HasValue? p.ToString(): SqlString.Null; + + + + + + return p.IsNull? SqlString.Null: p.Value; + + + return p.ToSqlString(); + + + return p == null? SqlString.Null: p.FullName; + return p == null? SqlString.Null: p.InnerXml; + return p == null || p.Length == 0? SqlString.Null: new SqlString(ToString(p)); + return p == null || p.Length == 0? SqlString.Null: new SqlString(ToString(p.ToArray())); + + + return ToString(p); +
+
+ + + return p; + return p == null? SqlByte.Null: SqlByte.Parse(p); +
+ + + return (Byte)(p? 1: 0); + return checked((Byte)p); +
+ + + return p.HasValue? p.Value: SqlByte.Null; + + + return p.HasValue? ToByte(p.Value): SqlByte.Null; + + + + + return p.IsNull? SqlByte.Null: ToByte(p.Value); + return p.ToSqlByte(); + + + return p == null || p.Length == 0? SqlByte.Null: new SqlByte(ToByte(p)); + return p == null || p.Length == 0? SqlByte.Null: new SqlByte(ToByte(p.ToArray())); + + + return ToByte(p); +
+ + + return p; + return p == null? SqlInt16.Null: SqlInt16.Parse(p); +
+ + + return (Int16)(p? 1: 0); + return checked((Int16)p); +
+ + + return p.HasValue? p.Value: SqlInt16.Null; + + + return p.HasValue? ToInt16(p.Value): SqlInt16.Null; + + + + + return p.IsNull? SqlInt16.Null: ToInt16(p.Value); + return p.ToSqlInt16(); + + + return p == null || p.Length == 0? SqlInt16.Null: new SqlInt16(ToInt16(p)); + return p == null || p.Length == 0? SqlInt16.Null: new SqlInt16(ToInt16(p.ToArray())); + + + return ToInt16(p); +
+ + + return p; + return p == null? SqlInt32.Null: SqlInt32.Parse(p); +
+ + + return p? 1: 0; + return checked((Int32)p); +
+ + + return p.HasValue? p.Value: SqlInt32.Null; + + + return p.HasValue? ToInt32(p.Value): SqlInt32.Null; + + + + + return p.IsNull? SqlInt32.Null: ToInt32(p.Value); + return p.ToSqlInt32(); + + + return p == null || p.Length == 0? SqlInt32.Null: new SqlInt32(ToInt32(p)); + return p == null || p.Length == 0? SqlInt32.Null: new SqlInt32(ToInt32(p.ToArray())); + + + return ToInt32(p); +
+ + + return p; + return p == null? SqlInt64.Null: SqlInt64.Parse(p); +
+ + + return p? 1: 0; + return (p - DateTime.MinValue).Ticks; + return (p - DateTimeOffset.MinValue).Ticks; + return p.Ticks; + return checked((Int64)p); +
+ + + return p.HasValue? p.Value: SqlInt64.Null; + + + + + + return p.HasValue? ToInt64(p.Value): SqlInt64.Null; + + + + + return p.IsNull? SqlInt64.Null: ToInt64(p.Value); + return p.ToSqlInt64(); + + + return p == null || p.Length == 0? SqlInt64.Null: new SqlInt64(ToInt64(p)); + return p == null || p.Length == 0? SqlInt64.Null: new SqlInt64(ToInt64(p.ToArray())); + + + return ToInt64(p); +
+
+ + + return p; + return p == null? SqlSingle.Null: SqlSingle.Parse(p); +
+ + + return p? 1.0f: 0.0f; + return checked((Single)p); +
+ + + return p.HasValue? p.Value: SqlSingle.Null; + + return p.HasValue? ToSingle(p.Value): SqlSingle.Null; + + + + + return p.ToSqlSingle(); + + + return p == null || p.Length == 0? SqlSingle.Null: new SqlSingle(ToSingle(p)); + return p == null || p.Length == 0? SqlSingle.Null: new SqlSingle(ToSingle(p.ToArray())); + + + return ToSingle(p); +
+ + + return p; + return p == null? SqlDouble.Null: SqlDouble.Parse(p); +
+ + + return p? 1.0: 0.0; + return (p - DateTime.MinValue).TotalDays; + return (p - DateTimeOffset.MinValue).TotalDays; + return p.TotalDays; + return checked((Double)p); +
+ + + return p.HasValue? p.Value: SqlDouble.Null; + + + + + return p.HasValue? ToDouble(p.Value): SqlDouble.Null; + + + + + return p.IsNull? SqlDouble.Null: ToDouble(p.Value); + return p.ToSqlDouble(); + + + return p == null || p.Length == 0? SqlDouble.Null: new SqlDouble(ToDouble(p)); + return p == null || p.Length == 0? SqlDouble.Null: new SqlDouble(ToDouble(p.ToArray())); + + + return ToDouble(p); +
+ + + return p; + return p == null? SqlDecimal.Null: SqlDecimal.Parse(p); +
+ + + return p? 1.0m: 0.0m; + return checked((Decimal)p); +
+ + + return p.HasValue? p.Value: SqlDecimal.Null; + + return p.HasValue? ToDecimal(p.Value): SqlDecimal.Null; + + + + + return p.ToSqlDecimal(); + + + return p == null || p.Length == 0? SqlDecimal.Null: new SqlDecimal(ToDecimal(p)); + return p == null || p.Length == 0? SqlDecimal.Null: new SqlDecimal(ToDecimal(p.ToArray())); + + + return ToDecimal(p); +
+ + + return p; + return p == null? SqlMoney.Null: SqlMoney.Parse(p); +
+ + + return p? 1.0m: 0.0m; + return checked((Decimal)p); +
+ + + return p.HasValue? p.Value: SqlMoney.Null; + + return p.HasValue? ToDecimal(p.Value): SqlMoney.Null; + + + + + return p.ToSqlMoney(); + + + return p == null || p.Length == 0? SqlMoney.Null: new SqlMoney(ToDecimal(p)); + return p == null || p.Length == 0? SqlMoney.Null: new SqlMoney(ToDecimal(p.ToArray())); + + + return ToDecimal(p); +
+
+ + + return p; + return p == null? SqlBoolean.Null: SqlBoolean.Parse(p); +
+ + + return p != 0; +
+ + + return p.HasValue? p.Value: SqlBoolean.Null; + + + return p.HasValue? ToBoolean(p.Value): SqlBoolean.Null; + + + + + return p.ToSqlBoolean(); + + + return p == null || p.Length == 0? SqlBoolean.Null: new SqlBoolean(ToBoolean(p)); + return p == null || p.Length == 0? SqlBoolean.Null: new SqlBoolean(ToBoolean(p.ToArray())); + + + return ToBoolean(p); +
+ + + return p == null? SqlDateTime.Null: SqlDateTime.Parse(p); + return p; + return p.LocalDateTime; + + + + return ToDateTime(p); + + + + return p.HasValue? p.Value: SqlDateTime.Null; + return p.HasValue? p.Value.LocalDateTime: SqlDateTime.Null; + + + + return p.HasValue? ToDateTime(p.Value): SqlDateTime.Null; + + + + return p.ToSqlDateTime(); + + + return p.IsNull? SqlDateTime.Null: ToDateTime(p); + + + return p == null || p.Length == 0? SqlDateTime.Null: new SqlDateTime(ToDateTime(p)); + return p == null || p.Length == 0? SqlDateTime.Null: new SqlDateTime(ToDateTime(p.ToArray())); + + + return ToDateTime(p); + + + + return p; + return p == null? SqlGuid.Null: SqlGuid.Parse(p); + + + return p.HasValue? p.Value: SqlGuid.Null; + + + + return p.ToSqlBinary().ToSqlGuid(); + + return p.ToSqlGuid(); + + + return p == null? SqlGuid.Null: p.GUID; + return p == null? SqlGuid.Null: new SqlGuid(p); + return p == null? SqlGuid.Null: new SqlGuid(p.ToArray()); + + + return ToGuid(p); + + + + return p; + return p.ToArray(); + return p == Guid.Empty? SqlBinary.Null: new SqlGuid(p).ToSqlBinary(); + + + return p.HasValue? new SqlGuid(p.Value).ToSqlBinary(): SqlBinary.Null; + + + + + return p.ToSqlBinary(); + + + return ToByteArray(p); + + + + return p == null? SqlBytes.Null: new SqlBytes(p); + return p == null? SqlBytes.Null: new SqlBytes(p.ToArray()); + return p == null? SqlBytes.Null: new SqlBytes(p); + return p == Guid.Empty? SqlBytes.Null: new SqlBytes(p.ToByteArray()); + + + return p.HasValue? new SqlBytes(p.Value.ToByteArray()): SqlBytes.Null; + + + return p.IsNull? SqlBytes.Null: new SqlBytes(p); + return p.IsNull? SqlBytes.Null: new SqlBytes(p.ToByteArray()); + + + return new SqlBytes(ToByteArray(p)); + + + + return p == null? SqlChars.Null: new SqlChars(p.ToCharArray()); + return p == null? SqlChars.Null: new SqlChars(p); + return p == null? SqlChars.Null: new SqlChars(ToCharArray(p)); + return p == null? SqlChars.Null: new SqlChars(ToCharArray(p.ToArray())); +
+ + + + + + + return new SqlChars(ToString(p).ToCharArray()); +
+ + + + return p.HasValue? new SqlChars(new Char[]{p.Value}) : SqlChars.Null; + + + + + return p.HasValue? new SqlChars(p.ToString().ToCharArray()): SqlChars.Null; + + + + return (SqlChars)p; + + + + return p.IsNull? SqlChars.Null: new SqlChars(p.ToString().ToCharArray()); + return (SqlChars)p.ToSqlString(); + + return p == null? SqlChars.Null: new SqlChars(p.FullName.ToCharArray()); + + return new SqlChars(ToString(p).ToCharArray()); +
+ + + return p == null? SqlXml.Null: new SqlXml(new XmlTextReader(new StringReader(p))); +
+ + + return p == null? SqlXml.Null: new SqlXml(new XmlTextReader(new StringReader(p.InnerXml))); +
+ return p == null? SqlXml.Null: new SqlXml(new XmlTextReader(new StringReader(new string(p)))); + return p == null? SqlXml.Null: new SqlXml(new MemoryStream(p)); + return p == null? SqlXml.Null: new SqlXml(new MemoryStream(p.ToArray())); + return p == null? SqlXml.Null: new SqlXml(p); +
+ + return p.IsNull? SqlXml.Null: new SqlXml(new XmlTextReader(new StringReader(p.Value))); + return p.IsNull? SqlXml.Null: new SqlXml(new XmlTextReader(new StringReader(p.ToSqlString().Value))); + return p.IsNull? SqlXml.Null: new SqlXml(new MemoryStream(p.Value)); + return p.IsNull? SqlXml.Null: new SqlXml(p.Stream); + + +
+
+ + + + return p == null? null: Type.GetType(p); + return p == null? null: Type.GetType(new string(p)); + return p == null? null: Type.GetTypeFromCLSID(ToGuid(p)); + return p == null? null: Type.GetTypeFromCLSID(ToGuid(p.ToArray())); + return p == Guid.Empty? null: Type.GetTypeFromCLSID(p); + + + return p.HasValue? Type.GetTypeFromCLSID(p.Value): null; + + + return p.IsNull ? null: Type.GetType(p.Value); + return p.IsNull ? null: Type.GetType(new string(p.Value)); + return p.IsNull ? null: Type.GetTypeFromCLSID(p.Value); + + + + + + return p == Guid.Empty? Stream.Null: new MemoryStream(p.ToByteArray()); + return p == null? Stream.Null: new MemoryStream(p); + return p == null? Stream.Null: new MemoryStream(p.ToArray()); + + + return p.HasValue? new MemoryStream(p.Value.ToByteArray()): Stream.Null; + + + return p.IsNull? Stream.Null: p.Stream; + return p.IsNull? Stream.Null: new MemoryStream(p.Value); + return p.IsNull? Stream.Null: new MemoryStream(p.Value.ToByteArray()); + + + + + + + return p == null? null: System.Text.Encoding.UTF8.GetBytes(p); + return new byte[]{p}; + return new byte[]{checked((Byte)p)}; + + int[] bits = Decimal.GetBits(p); + Byte[] bytes = new Byte[Buffer.ByteLength(bits)]; + + Buffer.BlockCopy(bits, 0, bytes, 0, bytes.Length); + return bytes; + + + return ToByteArray(p.ToBinary()); + return ToByteArray(p.LocalDateTime.ToBinary()); + return ToByteArray(p.Ticks); + + if (p == null) return null; + if (p is MemoryStream) return ((MemoryStream)p).ToArray(); + + long position = p.Seek(0, SeekOrigin.Begin); + Byte[] bytes = new Byte[p.Length]; + p.Read(bytes, 0, bytes.Length); + p.Position = position; + + return bytes; + + Byte[] bytes = new Byte[Buffer.ByteLength(p)]; + + Buffer.BlockCopy(p, 0, bytes, 0, bytes.Length); + return bytes; + return p == Guid.Empty? null: p.ToByteArray(); + return p == null? null: p.ToArray(); + return BitConverter.GetBytes(p); + + + + + + + + + return p.HasValue? ToByteArray(p.Value): null; + + + return p.IsNull? null: p.Value; + return p.IsNull? null: p.Value; + return p.IsNull? null: p.ToByteArray(); + + return p.IsNull? null: ToByteArray(p.Value); + + + + + + + return p == null? null: new Binary(System.Text.Encoding.UTF8.GetBytes(p)); + return new Binary(new byte[]{p}); + return new Binary(new byte[]{checked((Byte)p)}); + + int[] bits = Decimal.GetBits(p); + Byte[] bytes = new Byte[Buffer.ByteLength(bits)]; + + Buffer.BlockCopy(bits, 0, bytes, 0, bytes.Length); + return new Binary(bytes); + + + + return new Binary(ToByteArray(p.ToBinary())); + return new Binary(ToByteArray(p.LocalDateTime.ToBinary())); + return new Binary(ToByteArray(p.Ticks)); + + if (p == null) return null; + if (p is MemoryStream) return ((MemoryStream)p).ToArray(); + + long position = p.Seek(0, SeekOrigin.Begin); + Byte[] bytes = new Byte[p.Length]; + p.Read(bytes, 0, bytes.Length); + p.Position = position; + + return new Binary(bytes); + + + Byte[] bytes = new Byte[Buffer.ByteLength(p)]; + + Buffer.BlockCopy(p, 0, bytes, 0, bytes.Length); + return new Binary(bytes); + + return p == Guid.Empty? null: new Binary(p.ToByteArray()); + return p == null? null: new Binary(p); + return new Binary(BitConverter.GetBytes(p)); + + + + + + + + + return p.HasValue? new Binary(ToByteArray(p.Value)): null; + + + return p.IsNull? null: new Binary(p.Value); + return p.IsNull? null: new Binary(p.Value); + return p.IsNull? null: new Binary(p.ToByteArray()); + + return p.IsNull? null: new Binary(ToByteArray(p.Value)); + + + + + + + return p == null? null: p.ToCharArray(); + + + return p.IsNull? null: p.Value.ToCharArray(); + return p.IsNull? null: p.Value; + + + if (p == null) return null; + + Char[] chars = new Char[p.Length / sizeof(Char)]; + + Buffer.BlockCopy(p, 0, chars, 0, p.Length); + return chars; + + + if (p == null) return null; + + Char[] chars = new Char[p.Length / sizeof(Char)]; + + Buffer.BlockCopy(p.ToArray(), 0, chars, 0, p.Length); + return chars; + + + return ToString(p).ToCharArray(); + + + + return p == null? null: new XmlTextReader(new StringReader(p)); + + + return p.IsNull? null: p.CreateReader(); + return p.IsNull? null: new XmlTextReader(new StringReader(p.Value)); + return p.IsNull? null: new XmlTextReader(new StringReader(p.ToSqlString().Value)); + return p.IsNull? null: new XmlTextReader(new MemoryStream(p.Value)); + return p.IsNull? null: new XmlTextReader(p.Value); + + + + + return p == null? null: new XmlTextReader(new StringReader(p.InnerXml)); +
+ return p == null? null: new XmlTextReader(new StringReader(new string(p))); + return p == null? null: new XmlTextReader(new MemoryStream(p)); + return p == null? null: new XmlTextReader(new MemoryStream(p.ToArray())); + return p == null? null: new XmlTextReader(p); +
+ +
+ + + + if (string.IsNullOrEmpty(p)) return null; + + XmlDocument doc = new XmlDocument(); + doc.LoadXml(p); + return doc; + + + + + return p.IsNull? null: ToXmlDocument(p.ToSqlString().Value); + return p.IsNull? null: ToXmlDocument(new MemoryStream(p.Value)); + return p.IsNull? null: ToXmlDocument(p.Value); + + + + + +
+ return p == null || p.Length == 0? null: ToXmlDocument(new string(p)); + return p == null || p.Length == 0? null: ToXmlDocument(new MemoryStream(p)); + return p == null || p.Length == 0? null: ToXmlDocument(new MemoryStream(p.ToArray())); + + if (p == null) return null; + + XmlDocument doc = new XmlDocument(); + doc.Load(p); + return doc; + +
+ +
+
+
diff -r 000000000000 -r f990fcb411a9 Tools/CodeGenerator/Convert.xslt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/CodeGenerator/Convert.xslt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,812 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #region Generated File + + /* + + * GENERATED FILE -- DO NOT EDIT + + * + + * Generator: + + + * Version: + + + * + + * + + * Generated code from " + + " + + * + + * Created: + + + * By: + + + * + + */ + + #endregion + + + + + + + namespace + + + { + + + } + + + + + + #if + + + + using + + ; + + + #endif + + + + + + + + /// <summary>Converts a base data type to another base data type.</summary> + + + public class Convert + + + { + + + + + + + + private static Exception CreateInvalidCastException(Type originalType, Type conversionType) + + + { + + + return new InvalidCastException(string.Format( + + + Resources.Convert_InvalidCast, originalType.FullName, conversionType.FullName)); + + + } + + + + } + + + + + + + #region + + + + + + + #endregion + + + + + + + + + + + ? + + + + + + + + + #if + + + + + + #region + + + + + + + + + + + + + + + + + + + + + + /// <summary>Converts the value of a specified object to an equivalent <c> + + </c> value.</summary> + + + + + [CLSCompliant(false)] + + + + + public static + + + + + Nullable + + + + + + + + + + (object p) + + + + + + + + + + + + + + + + #endregion + + + + + + #endif + + + + + + + + + + + + + + + + + // + + + + // + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ? + + + + + + + ? + + + + + + #if + + + + + + /// <summary>Converts the value from <c> + + </c> to an equivalent <c> + + </c> value.</summary> + + + + + [CLSCompliant(false)] + + + + + public static + + + + + + Nullable + + + ( + + p) + + + + + + + + + + + + + + + + + + + #endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ? + + + + + + + + + + + #if + + + + + if (p is + + ) + + + + return + + + Nullable + + + (( + + )p); + + + + #endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // + + + + // + + + + + + + + + + + + + + + + + + + + + if (p == null || p is DBNull) return + + ; + + + + + if (p is + + ) return ( + + )p; + + + + + + + + + + + + + + + + + + + + + + throw CreateInvalidCastException(p.GetType(), typeof( + + + ? + + )); + + + + + + + + + // + + + + // + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + + + + } + + + + { + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Tools/CodeGenerator/TransformCodeGenerator.dll Binary file Tools/CodeGenerator/TransformCodeGenerator.dll has changed diff -r 000000000000 -r f990fcb411a9 Tools/CodeGenerator/ValueMapping.Declare.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/CodeGenerator/ValueMapping.Declare.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,255 @@ +using System; +using System.Data.SqlTypes; + +using KeyValue = System.Collections.Generic.KeyValuePair; +using Table = System.Collections.Generic.Dictionary, BLToolkit.Mapping.IValueMapper>; + +namespace BLToolkit.Mapping +{ + [CLSCompliant(false)] + public interface IMapDataSource + { + int Count { get; } + + Type GetFieldType (int index); + string GetName (int index); + int GetOrdinal (string name); + object GetValue (object o, int index); + object GetValue (object o, string name); + + bool IsNull (object o, int index); + + bool SupportsTypedValues(int index); + + // Simple type getters. + // + [CLSCompliant(false)] + SByte GetSByte (object o, int index); + Int16 GetInt16 (object o, int index); + Int32 GetInt32 (object o, int index); + Int64 GetInt64 (object o, int index); + + Byte GetByte (object o, int index); + [CLSCompliant(false)] + UInt16 GetUInt16 (object o, int index); + [CLSCompliant(false)] + UInt32 GetUInt32 (object o, int index); + [CLSCompliant(false)] + UInt64 GetUInt64 (object o, int index); + + Boolean GetBoolean (object o, int index); + Char GetChar (object o, int index); + Single GetSingle (object o, int index); + Double GetDouble (object o, int index); + Decimal GetDecimal (object o, int index); + DateTime GetDateTime (object o, int index); + Guid GetGuid (object o, int index); + +#if FW2 + // Simple type getters. + // + [CLSCompliant(false)] + SByte? GetNullableSByte (object o, int index); + Int16? GetNullableInt16 (object o, int index); + Int32? GetNullableInt32 (object o, int index); + Int64? GetNullableInt64 (object o, int index); + + Byte? GetNullableByte (object o, int index); + [CLSCompliant(false)] + UInt16? GetNullableUInt16 (object o, int index); + [CLSCompliant(false)] + UInt32? GetNullableUInt32 (object o, int index); + [CLSCompliant(false)] + UInt64? GetNullableUInt64 (object o, int index); + + Boolean? GetNullableBoolean (object o, int index); + Char? GetNullableChar (object o, int index); + Single? GetNullableSingle (object o, int index); + Double? GetNullableDouble (object o, int index); + Decimal? GetNullableDecimal (object o, int index); + DateTime? GetNullableDateTime(object o, int index); + Guid? GetNullableGuid (object o, int index); +#endif + + // SQL type getters. + // + SqlByte GetSqlByte (object o, int index); + SqlInt16 GetSqlInt16 (object o, int index); + SqlInt32 GetSqlInt32 (object o, int index); + SqlInt64 GetSqlInt64 (object o, int index); + SqlSingle GetSqlSingle (object o, int index); + SqlBoolean GetSqlBoolean (object o, int index); + SqlDouble GetSqlDouble (object o, int index); + SqlDateTime GetSqlDateTime (object o, int index); + SqlDecimal GetSqlDecimal (object o, int index); + SqlMoney GetSqlMoney (object o, int index); + SqlGuid GetSqlGuid (object o, int index); + SqlString GetSqlString (object o, int index); + } + + [CLSCompliant(false)] + public interface IMapDataDestination + { + Type GetFieldType (int index); + int GetOrdinal (string name); + void SetValue (object o, int index, object value); + void SetValue (object o, string name, object value); + + void SetNull (object o, int index); + + bool SupportsTypedValues(int index); + + // Simple type setters. + // + [CLSCompliant(false)] + void SetSByte (object o, int index, SByte value); + void SetInt16 (object o, int index, Int16 value); + void SetInt32 (object o, int index, Int32 value); + void SetInt64 (object o, int index, Int64 value); + + void SetByte (object o, int index, Byte value); + [CLSCompliant(false)] + void SetUInt16 (object o, int index, UInt16 value); + [CLSCompliant(false)] + void SetUInt32 (object o, int index, UInt32 value); + [CLSCompliant(false)] + void SetUInt64 (object o, int index, UInt64 value); + + void SetBoolean (object o, int index, Boolean value); + void SetChar (object o, int index, Char value); + void SetSingle (object o, int index, Single value); + void SetDouble (object o, int index, Double value); + void SetDecimal (object o, int index, Decimal value); + void SetGuid (object o, int index, Guid value); + void SetDateTime (object o, int index, DateTime value); + +#if FW2 + // Simple type setters. + // + [CLSCompliant(false)] + void SetNullableSByte (object o, int index, SByte? value); + void SetNullableInt16 (object o, int index, Int16? value); + void SetNullableInt32 (object o, int index, Int32? value); + void SetNullableInt64 (object o, int index, Int64? value); + + void SetNullableByte (object o, int index, Byte? value); + [CLSCompliant(false)] + void SetNullableUInt16 (object o, int index, UInt16? value); + [CLSCompliant(false)] + void SetNullableUInt32 (object o, int index, UInt32? value); + [CLSCompliant(false)] + void SetNullableUInt64 (object o, int index, UInt64? value); + + void SetNullableBoolean (object o, int index, Boolean? value); + void SetNullableChar (object o, int index, Char? value); + void SetNullableSingle (object o, int index, Single? value); + void SetNullableDouble (object o, int index, Double? value); + void SetNullableDecimal (object o, int index, Decimal? value); + void SetNullableGuid (object o, int index, Guid? value); + void SetNullableDateTime (object o, int index, DateTime? value); +#endif + + // SQL type setters. + // + void SetSqlByte (object o, int index, SqlByte value); + void SetSqlInt16 (object o, int index, SqlInt16 value); + void SetSqlInt32 (object o, int index, SqlInt32 value); + void SetSqlInt64 (object o, int index, SqlInt64 value); + void SetSqlSingle (object o, int index, SqlSingle value); + void SetSqlBoolean (object o, int index, SqlBoolean value); + void SetSqlDouble (object o, int index, SqlDouble value); + void SetSqlDateTime(object o, int index, SqlDateTime value); + void SetSqlDecimal (object o, int index, SqlDecimal value); + void SetSqlMoney (object o, int index, SqlMoney value); + void SetSqlGuid (object o, int index, SqlGuid value); + void SetSqlString (object o, int index, SqlString value); + } + + [CLSCompliant(false)] + public interface IValueMapper + { + void Map( + IMapDataSource source, object sourceObject, int sourceIndex, + IMapDataDestination dest, object destObject, int destIndex); + } + + public static partial class ValueMapping + { + #region Init + + private static Table _mappers = new Table(); + + private static void AddSameType(Type type, IValueMapper mapper) + { + _mappers.Add(new KeyValue(type, type), mapper); + } + + #endregion + + #region Default Mapper + + class DefaultValueMapper : IValueMapper + { + public void Map( + IMapDataSource source, object sourceObject, int sourceIndex, + IMapDataDestination dest, object destObject, int destIndex) + { + dest.SetValue(destObject, destIndex, source.GetValue(sourceObject, sourceIndex)); + + //object o = source.GetValue(sourceObject, sourceIndex); + + //if (o == null) dest.SetNull (destObject, destIndex); + //else dest.SetValue(destObject, destIndex, o); + } + } + + private static IValueMapper _defaultMapper = new DefaultValueMapper(); + [CLSCompliant(false)] + public static IValueMapper DefaultMapper + { + get { return _defaultMapper; } + set { _defaultMapper = value; } + } + + #endregion + + #region GetMapper + + private static object _sync = new object(); + + [CLSCompliant(false)] + public static IValueMapper GetMapper(Type t1, Type t2) + { + lock (_sync) + { + if (t1 == null) t1 = typeof(object); + if (t2 == null) t2 = typeof(object); + + if (t1.IsEnum) t1 = Enum.GetUnderlyingType(t1); + if (t2.IsEnum) t2 = Enum.GetUnderlyingType(t2); + + KeyValue key = new KeyValue(t1, t2); + + IValueMapper t; + +#if FW2 + if (_mappers.TryGetValue(key, out t)) + return t; + +#else + t = (IValueMapper)_mappers[key]; + + if (t != null) + return t; + + t = _defaultMapper; +#endif + _mappers.Add(key, t); + + return t; + } + } + + #endregion + } +} diff -r 000000000000 -r f990fcb411a9 Tools/CodeGenerator/ValueMapping.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/CodeGenerator/ValueMapping.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+ + + +
+ + + + +
+ + + + +
+ + + +
+ +
diff -r 000000000000 -r f990fcb411a9 Tools/CodeGenerator/ValueMapping.xslt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/CodeGenerator/ValueMapping.xslt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,492 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #region Generated File + + /* + + * GENERATED FILE -- DO NOT EDIT + + * + + * Generator: + + + * Version: + + + * + + * + + * Generated code from " + + " + + * + + * Created: + + + * By: + + + * + + */ + + #endregion + + + + + + + namespace + + + { + + + } + + + + + using + + ; + + + + + + + public static partial class ValueMapping + + + { + + + + + + + } + + + + + + + + + + #if FW2 + + + + + + #region + + + + + + + + + + + + + + #endregion + + + + + #endif + + + + + + + + + + + + + + #if FW2 + + + + + + + + + + + + + #endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #if FW2 + + + + + + private static IValueMapper Get + + Mapper(Type t) + + + { + + + + + + + + + + + + return null; + + + + } + + + + #endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ? + + + + + Nullable + + + + + + + + + ? + + + + + Nullable + + + + + + + + + internal sealed class + + To + + : IValueMapper + + + { + + + public void Map( + + + IMapDataSource source, object sourceObject, int sourceIndex, + + + IMapDataDestination dest, object destObject, int destIndex) + + + { + + + if (source.IsNull(sourceObject, sourceIndex)) + + + dest.SetNull(destObject, destIndex); + + + else + + + dest.Set + + (destObject, destIndex, + + + + + Convert.To + + ( + + + + + source.Get + + (sourceObject, sourceIndex)) + + + ) + + + ; + + + + } + + + } + + + + + if (t == typeof( + + )) + + + + return new + + To + + (); + + + + + + + + + + + // + + + + // + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Tools/CodeGenerator/install.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/CodeGenerator/install.bat Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +@if "%DevEnvDir%"=="" goto error_no_DevEnvDir + +copy TransformCodeGenerator.dll "%DevEnvDir%\PrivateAssemblies\" +regasm "%DevEnvDir%\PrivateAssemblies\TransformCodeGenerator.dll" + +@goto end + +:error_no_DevEnvDir +@echo ERROR: DevEnvDir variable is not set. +@goto end + +:end diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/ChmGen.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/ChmGen.csproj Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,73 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {23AD6408-9310-4D0F-B461-C590EAF82868} + Exe + Properties + DocGen + ChmGen + v3.5 + 512 + + + true + full + false + bin\Debug\ + TRACE;DEBUG;CHM + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE;CHM + prompt + 4 + + + + False + ..\Rsdn\Rsdn.Framework.Common.dll + + + False + ..\Rsdn\Rsdn.Framework.Formatting.dll + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/ChmTemplate.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/ChmTemplate.html Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,29 @@ + + + {3} + + + +Business Logic Toolkit for .NET
+www.bltoolkit.net + + + + + + + + + + + + +
 {0} 
+ +© 2010 www.bltoolkit.net
+support@bltoolkit.net +
+
+ + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/AsyncAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/AsyncAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,45 @@ +[BLToolkitGenerated] +internal delegate int TestObject$Test$Delegate(int, string); + +[BLToolkitGenerated] +public sealed class AsyncTestObject : HowTo.Aspects.AsyncAspectTest.AsyncTestObject +{ + public override IAsyncResult BeginTest(int intVal, string strVal) + { + AsyncAspectBuilder.InternalAsyncResult r = new AsyncAspectBuilder.InternalAsyncResult(); + + r.Delegate = new TestObject$Test$Delegate(base.Test); + r.InnerResult = r.Delegate.BeginInvoke(intVal, strVal, null, null); + + return r; + } + + public override IAsyncResult BeginTest(int intVal, string strVal, AsyncCallback callback) + { + AsyncAspectBuilder.InternalAsyncResult r = new AsyncAspectBuilder.InternalAsyncResult(); + + r.Delegate = new TestObject$Test$Delegate(base.Test); + r.AsyncCallback = callback; + r.InnerResult = r.Delegate.BeginInvoke(intVal, strVal, new AsyncCallback(r.CallBack), null); + + return r; + } + + public override IAsyncResult BeginTest(int intVal, string strVal, AsyncCallback callback, object state) + { + AsyncAspectBuilder.InternalAsyncResult r = new AsyncAspectBuilder.InternalAsyncResult(); + + r.Delegate = new TestObject$Test$Delegate(base.Test); + r.AsyncCallback = callback; + r.InnerResult = r.Delegate.BeginInvoke(intVal, strVal, new AsyncCallback(r.CallBack), state); + + return r; + } + + public override int EndTest(IAsyncResult asyncResult) + { + AsyncAspectBuilder.InternalAsyncResult r = (AsyncAspectBuilder.InternalAsyncResult)asyncResult; + + return ((TestObject$Test$Delegate)r.Delegate).EndInvoke(r.InnerResult); + } +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/AsyncAspect.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/AsyncAspect.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +<% title # Async aspect %> +

+This aspect simplifies asynchronous operations. +Note the AsyncAspect is not compatible with other type builders that generate a method body. +If you apply them along with the AsyncAspect to an abstract method, they will be igored. +

+ +AsyncAspect.cs +<% ..\..\..\HowTo\Aspects\AsyncAspect.cs %> + +BLToolkit type builder will generate the following for the class above: +<% Doc\Aspects\AsyncAspect.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/CacheAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/CacheAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,62 @@ +[BLToolkitGenerated] +public sealed class TestClass : HowTo.Aspects.TestClass +{ + private static CallMethodInfo _methodInfo; + private static IInterceptor _interceptor; + + public override int CachedMethod(int p1, int p2) + { + int returnValue = 0; + + if (_methodInfo == null) + { + _methodInfo = new CallMethodInfo((MethodInfo)MethodBase.GetCurrentMethod()); + } + + InterceptCallInfo info = new InterceptCallInfo(); + + info.Object = this; + info.CallMethodInfo = _methodInfo; + info.ParameterValues[0] = p1; + info.ParameterValues[1] = p2; + info.ReturnValue = returnValue; + info.InterceptResult = InterceptResult.Continue; + info.InterceptType = InterceptType.BeforeCall; + + if (_interceptor == null) + { + _interceptor = new CacheAspect(); + _interceptor.Init(_methodInfo, "MaxCacheTime=500;IsWeak=False"); + } + + // 'BeforeCall' step checks if the method is cached. + // If it is and the cache is not expired, the Intercept method populates + // return value and output parameters with the cached values and + // sets info.InterceptResult to InterceptResult.Return. + // See the [link][file]Aspects/CacheAspect.cs[/file]CacheAspect.BeforeCall[/link] method for details. + // + _interceptor.Intercept(info); + + returnValue = (int)info.ReturnValue; + + if (info.InterceptResult != InterceptResult.Return) + { + // If the method call is not cached, target method is called. + // + returnValue = base.CachedMethod(p1, p2); + + info.ReturnValue = returnValue; + info.InterceptResult = InterceptResult.Continue; + info.InterceptType = InterceptType.AfterCall; + + // 'AfterCall' step stores parameters and return values in the cache. + // See the [link][file]Aspects/CacheAspect.cs[/file]CacheAspect.AfterCall[/link] method for details. + // + _interceptor.Intercept(info); + + returnValue = (int)info.ReturnValue; + } + + return returnValue; + } +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/CacheAspect.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/CacheAspect.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +<% title # Cache aspect %> +<% group # Cache aspect %> +

This aspect helps to cache method calls. +The aspect uses input method parameters to create a cache key and +caches return value and all output (both ref and out) parameters. +By default only value types and string type of the method parameters are used +to create a cache key. Any other types are ignored. +This behavior can be changed by assigning the CacheAspect.IsCacheableParameterType property +to a delegate providing custom logic. +

+ +CacheAspect.cs +<% ..\..\..\HowTo\Aspects\CacheAspect.cs %> + +If we decompile the actual emitted TestClass class, we may see something like the following: +<% Doc\Aspects\CacheAspect.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/ClearCacheAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/ClearCacheAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,84 @@ +[BLToolkitGenerated] +public sealed class TestClass : ClearCacheAspect.TestClass +{ + private static MethodInfo _methodInfo1; + private static MethodInfo _methodInfo2; + private static Type _type3; + private static Type _type4; + + public override int CachedMethod(int p1, int p2) + { + // Method implementation. + } + + public override void ClearCache() + { + try + { + // Here should be main method implementation. + // It is empty as this method does nothing. + } + finally + { + if (_methodInfo1 == null) + { + _methodInfo1 = + ClearCacheAspect.GetMethodInfo(this, null, "CachedMethod", null); + } + + CacheAspect.ClearCache(_methodInfo1); + } + } + + public override void ClearCache2() + { + try + { + } + finally + { + if (_methodInfo2 == null) + { + _methodInfo2 = ClearCacheAspect.GetMethodInfo( + this, + null, + "CachedMethod", + new Type[] { typeof(int), typeof(int) }); + } + + CacheAspect.ClearCache(_methodInfo2); + } + } + + public override void ClearAll() + { + try + { + } + finally + { + if (_type3 == null) + { + _type3 = ClearCacheAspect.GetType(this, typeof(TestClass)); + } + + CacheAspect.ClearCache(_type3); + } + } + + public override void ClearAll2() + { + try + { + } + finally + { + if (_type4 == null) + { + _type4 = ClearCacheAspect.GetType(this, null); + } + + CacheAspect.ClearCache(_type4); + } + } +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/ClearCacheAspect.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/ClearCacheAspect.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +<% title # ClearCache aspect %> +<% group # Cache aspect %> +

+The ClearCache attribute clears cached data for the provided method. +

+ +ClearCacheAspect.cs +<% ..\..\..\HowTo\Aspects\ClearCacheAspect.cs %> + +BLToolkit type builder will generate the following for the class above: +<% Doc\Aspects\ClearCacheAspect.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/CounterAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/CounterAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,68 @@ +[BLToolkitGenerated] +public sealed class TestClass : CounterAspectTest.TestClass +{ + private static CallMethodInfo _methodInfo; + private static IInterceptor _interceptor; + + public override void TestMethod() + { + if (_methodInfo == null) + { + _methodInfo = new CallMethodInfo((MethodInfo)MethodBase.GetCurrentMethod()); + } + + InterceptCallInfo info = new InterceptCallInfo(); + + try + { + info.Object = this; + info.CallMethodInfo = _methodInfo; + info.InterceptResult = InterceptResult.Continue; + info.InterceptType = InterceptType.BeforeCall; + + if (_interceptor == null) + { + _interceptor = new CounterAspect(); + _interceptor.Init(_methodInfo, null); + } + + // 'BeforeCall' creates or gets a counter for the method and + // registers the current call. + // See the [link][file]Aspects/CounterAspect.cs[/file]CounterAspect.BeforeCall[/link] method for details. + // + _interceptor.Intercept(info); + + if (info.InterceptResult != InterceptResult.Return) + { + // Target method call. + // + base.TestMethod(); + } + } + catch (Exception exception) + { + info.Exception = exception; + info.InterceptResult = InterceptResult.Continue; + info.InterceptType = InterceptType.OnCatch; + + // 'OnCatch' is required to count calls with exceptions. + // + _interceptor.Intercept(info); + + if (info.InterceptResult != InterceptResult.Return) + { + throw; + } + } + finally + { + info.InterceptResult = InterceptResult.Continue; + info.InterceptType = InterceptType.OnFinally; + + // 'OnFinally' step adds statistic to the method counter. + // See the [link][file]Aspects/CounterAspect.cs[/file]CounterAspect.OnFinally[/link] method for details. + // + _interceptor.Intercept(info); + } + } +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/CounterAspect.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/CounterAspect.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +<% title # Counter aspect %> +

This aspect helps to collect statistical information for the members it is applied to.

+ +CounterAspect.cs +<% ..\..\..\HowTo\Aspects\CounterAspect.cs %> + +BLToolkit type builder will generate the following for the class above: +<% Doc\Aspects\CounterAspect.cs %> + +

The following picture shows the information collected for data accessors +of the BLToolkit.Demo.Asp.Net project.

+ \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/Counters.png Binary file Tools/DocGen/Content/Doc/Aspects/Counters.png has changed diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/LoggingAspect.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/LoggingAspect.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,18 @@ +<% title # Logging aspect %> +

This aspect allows logging some diagnostic information with minimum efforts. +All you need to do is to decorate your class with the Log attribute. +If you have a class hierarchy you can decorate only your base class. +Diagnostic information will be logged for all virtual and abstract members +of your abstract class.

+ +LoggingAspect.cs +<% ..\..\..\HowTo\Aspects\LoggingAspect.cs %> + +

Here is the logging output.

+ +<% txt # +4/20/2008 11:19:44 PM: HowTo.Aspects.LoggingAspectTest.BLToolkitExtension.TestClass.Test1(1) - 105 ms. + +4/20/2008 11:19:46 PM: HowTo.Aspects.LoggingAspectTest.BLToolkitExtension.TestClass.Test3("3") - 1507 ms + with exception 'System.ApplicationException' - "Test exception.". +%> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/MixinAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/MixinAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +[BLToolkitGenerated] +public sealed class TestClass : MixinAspectTest.TestClass, MixinAspectTest.ITestInterface1, MixinAspectTest.ITestInterface2 +{ + int MixinAspectTest.ITestInterface1.TestMethod(int value) + { + if (base._testInterface1 == null) + throw new InvalidOperationException("'ITestInterface1._testInterface1' is not initialized."); + + return base._testInterface1.TestMethod(value); + } + + int MixinAspectTest.ITestInterface2.TestMethod1(int value) + { + // The [link][file]Aspects/MixinOverrideAttribute.cs[/file]MixinOverride[/link] attribute enforces direct method call. + // + return base.TestMethod1(value); + } + + int MixinAspectTest.ITestInterface2.TestMethod2(int value) + { + if (base.TestInterface2 == null) + throw new InvalidOperationException("'ITestInterface2.TestInterface2' is null."); + + return base.TestInterface2.TestMethod2(value); + } +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/MixinAspect.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/MixinAspect.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +<% title # Mixin aspect %> +

A mixin is a... well, Wiki describes it much better.

+ +MixinAspect.cs +<% ..\..\..\HowTo\Aspects\MixinAspect.cs %> + +BLToolkit type builder will generate the following for the class above: +<% Doc\Aspects\MixinAspect.cs %> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/NoCacheAttribute.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/NoCacheAttribute.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +<% title # NoCache attribute %> +<% group # Cache aspect %> +

Cache aspect can be applied to entire class. +In this case all virtual and abstract member calls will be cached. +However you can use the NoCache attribute to exclude particular members from caching.

+ +NoCache.cs +<% ..\..\..\HowTo\Aspects\NoCache.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/NotNull.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/NotNull.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ +[BLToolkitGenerated] +public sealed class TestObject : NotNullTest.TestObject +{ + public override void Foo1(string str1, string str2, string str3) + { + if (str2 == null) throw new ArgumentNullException("str2"); + + base.Foo1(str1, str2, str3); + } + + public override void Foo2(string str1, string str2, string str3) + { + if (str2 == null) throw new ArgumentNullException("str2", "Null"); + + base.Foo2(str1, str2, str3); + } + + public override void Foo3(string str1, string str2, string str3) + { + if (str2 == null) throw new ArgumentNullException("str2", "Null: str2"); + + base.Foo3(str1, str2, str3); + } +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/NotNullAttribute.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/NotNullAttribute.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +<% title # NotNull attribute %> +

This attribute allows checking a virtual or abstract method parameter if it is null at runtime. +BLToolkit type builder will override methods with NotNull parameters and +emit code for checking null value at the beginning of the method.

+ +NotNull.cs +<% ..\..\..\HowTo\Aspects\NotNull.cs %> + +BLToolkit type builder will generate the following for the class above: +<% Doc\Aspects\NotNull.cs %> \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/OverloadAspect.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/OverloadAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,21 @@ +[BLToolkitGenerated] +public sealed class OverloadTestObject : OverloadTestObject +{ + [BLToolkitGenerated] + public override int Test(int intVal) + { + return this.Test(intVal, string.Empty); + } + + [BLToolkitGenerated] + public override int Test(string strVal) + { + return this.Test(0x0, strVal); + } + + [BLToolkitGenerated] + public override int Test(int intVal, string strVal, bool boolVal) + { + return this.Test(intVal, strVal); + } +} \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/OverloadAspect.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/OverloadAspect.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +<% title # Async aspect %> +

+This aspect simplifies method overloading. +Note the OverloadAspect is not compatible with other type builders that generate a method body. +If you apply them along with the OverloadAspect to an abstract method, they will be igored. +

+ +OverloadAspect.cs +<% ..\..\..\HowTo\Aspects\OverloadAspect.cs %> + +BLToolkit type builder will generate the following for the class above: +<% Doc\Aspects\OverloadAspect.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Aspects/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Aspects/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +

All BLToolkit aspects are implemented as attributes and have to be applied to +abstract or virtual members of an abstract class. +You need to use TypeAccessor<T>.CreateInstance() method to create an instance of the class. +BLToolkit class builder creates an actual class and applies aspects to abstract and virtual members +by overriding the members and emitting (see System.Reflection.Emit namespace) +additional code around them. +

+ + + +Cache aspect + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/ComponentModel/ObjectBinder.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/ComponentModel/ObjectBinder.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +

+The ObjectBinder component has been designed to simplify binding controls on a form to objects for FW 1.x. +Since Microsoft has released FW 2.0 we can use the BindingSource component to bind controls to objects. +However the ObjectBinder still can be useful as it supports a few features which are not available for the BindingSource. +Those features are: +

+ +
    +
  • Support for field binding along with property binding.

  • +
  • Support for inner class field and property binding such as Order.Address.Line1.

  • +
  • Support for the ObjectView feature which is available by assigning an object view type to the +ObjectBinder.ObjectViewType property. An object view is an object that implements the IObjectView interface. +This interface includes only one property - object Object { get; set; }. +An object view can implement additional properties based on the assosiated object. +The ObjectBinder will combine all of these properties with main object properties and create a single PropertyDescriptor collection. +This feature can be used to separate UI presentation logic from business model objects and to keep them clean. +ObjectView should be a stateless, lightweight object as its single instance can be assigned to many assosiated objects.

  • +
  • The ObjectBinder is optimized for high performance applications such real-time multithreaded message processing and +distribution banking systems. So it does not use reflection to access objects. +The standard way (which is used by the BindingSource) is to call the TypeDescriptor.GetProperties method +to get a PropertyDescriptor collection. This method creates property descriptors that access object properties by reflection. +The ObjectBinder has its own mechanism to avoid unnessasy reflection and boxing/unboxing operations.

  • +
+ +

The dev version of BLToolkit contains a demo project (Demo\WinForms) showing the use of the ObjectBinder.

diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/ComponentModel/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/ComponentModel/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +<% noindex # ObjectBinder component %> +

+ + + + + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/App.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/App.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ + + + + + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/App1.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/App1.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ + + + + + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/App2.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/App2.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/Close.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/Close.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ +<% group # Methods %> +<% order # 50 %> +Close.cs +<% ..\..\..\HowTo\Data\Close.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/CreateSql.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/CreateSql.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3 @@ +<% order # 1111 %> +Create.sql +<% ..\..\..\Data\Create Scripts\MsSql.sql %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/DataProvider/App.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/DataProvider/App.config Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ + + + + + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/DataProvider/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/DataProvider/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,54 @@ +<% order # 20 %> +

+The BLToolkit.DbManager component is a data provider independent wrapper for ADO.NET. +It means that the DbManager does not use any specific data source classes such as SqlConnection, +SqlCommand, etc. It uses common classes and interfaces instead. +All data source specific logic is encapsulated in special classes called DataProviders. +

+

+The following table lists providers available with BLToolkit: +

+ + + + + + + + + + + + + + + + + + +
Class Provider NameNamespace Vendor
AccessDataProvider Access System.Data.OleDb Microsoft
OdbcDataProvider Odbc System.Data.Odbc Microsoft
OleDbDataProvider OleDb System.Data.OleDb Microsoft
OracleDataProvider Oracle System.Data.OracleClient Microsoft
SqlDataProvider Sql System.Data.SqlClient Microsoft
DB2DataProvider DB2 IBM.Data.DB2 IBM
FdpDataProvider Fdp FirebirdSql.Data.FirebirdClientFirebird
InformixDataProvider Informix IBM.Data.Informix IBM
MySqlDataProvider MySql MySql.Data.MySqlClient Sun Microsystems
OdpDataProvider ODP Oracle.DataAccess.Client Oracle
SqlCeDataProvider SqlCe System.Data.SqlServerCe Microsoft
SQLiteDataProvider SQLite System.Data.SQLite SQLite.org
SybaseAdoDataProviderSybaseAdoSystem.Data.OleDb Support for DataDirect Sybase ADO Provider
SybaseDataProvider Sybase Sybase.Data.AseClient Sybase
+ +

+The first five providers are preregistered in the library and are ready to use. +The remaining providers need additional configuration as they require references to 3rd party components. +

+ +

+You can add a listed above or your own data provider into your project and register it as shown below: +

+ +AddDataProvider.cs +<% ..\..\..\HowTo\Data\DataProvider\AddDataProvider.cs %> + +

+Also a data provider can be registered by configuration file: +

+ +App.config +<% Doc\Data\DataProvider\App.config %> + +Also you can use BLToolkit config section. + +<% ..\..\..\UnitTests\Linq\App.config %> + +Here UnitTests.Linq assembly name should be replaces by your own. diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/DbManagerVsAdo.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/DbManagerVsAdo.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,17 @@ +<% title # Compare DbManager with ADO.NET %> +<% order # 1 %> +

+This example contains two demos to demonstrate the difference between ADO.NET and BLToolkit. +The AdoDemo represents a typical data access method which takes one parameter and +returns a list of objects. All routine mapping work is done manually inside the method. +

+AdoDemo.cs +<% ..\..\..\HowTo\Data\AdoDemo.cs %> +

+The DbManagerDemo does the same work performed by BLToolkit.DbManager. +

+DbManagerDemo.cs +<% ..\..\..\HowTo\Data\DbManagerDemo.cs %> +App.config +<% Doc\Data\App1.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/ExecuteDataSet.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/ExecuteDataSet.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ +<% group # Execute Methods %> +<% order # 100 %> +ExecuteDataSet.cs +<% ..\..\..\HowTo\Data\ExecuteDataSet.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/ExecuteDataTable.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/ExecuteDataTable.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ +<% group # Execute Methods %> +ExecuteDataTable.cs +<% ..\..\..\HowTo\Data\ExecuteDataTable.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/ExecuteDictionary.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/ExecuteDictionary.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +<% group # Execute Methods %> +ExecuteDictionary.cs +<% ..\..\..\HowTo\Data\ExecuteDictionary.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/ExecuteForEach.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/ExecuteForEach.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +<% group # Execute Methods %> +

+The ExecuteForEach method executes an SQL statement for every item in the provided collection +and returns the number of rows affected. +

+ +ExecuteForEach.cs +<% ..\..\..\HowTo\Data\ExecuteForEach.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/ExecuteList.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/ExecuteList.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ +<% group # Execute Methods %> +ExecuteList.cs +<% ..\..\..\HowTo\Data\ExecuteList.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/ExecuteNonQuery.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/ExecuteNonQuery.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +<% group # Execute Methods %> +

+The ExecuteNonQuery executes an SQL statement and returns the number of rows affected. +

+ +ExecuteNonQuery.cs +<% ..\..\..\HowTo\Data\ExecuteNonQuery.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/ExecuteObject.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/ExecuteObject.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ +<% group # Execute Methods %> +ExecuteObject.cs +<% ..\..\..\HowTo\Data\ExecuteObject.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/ExecuteReader.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/ExecuteReader.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ +<% group # Execute Methods %> +ExecuteReader.cs +<% ..\..\..\HowTo\Data\ExecuteReader.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/ExecuteResultSet.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/ExecuteResultSet.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ +<% group # Execute Methods %> +ComplexMapping.cs +<% ..\..\..\HowTo\Data\ComplexMapping.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/ExecuteScalar.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/ExecuteScalar.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ +<% group # Execute Methods %> +ExecuteScalar.cs +<% ..\..\..\HowTo\Data\ExecuteScalar.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/ExecuteScalarDictionary.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/ExecuteScalarDictionary.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +<% group # Execute Methods %> +

+The ExecuteScalarDictionary method executes the query, and returns the dictionary. +The keys are loaded from a column specified by the keyField parameter and +values are loaded from a column specified by the valueField. Other columns are ignored. +

+ +ExecuteScalarDictionary.cs +<% ..\..\..\HowTo\Data\ExecuteScalarDictionary.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/ExecuteScalarList.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/ExecuteScalarList.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +<% group # Execute Methods %> +

+The ExecuteScalarList method executes the query and returns a list of values of the +specified column of the every row in the resultset returned by the query. +Other columns are ignored. +

+ +ExecuteScalarList.cs +<% ..\..\..\HowTo\Data\ExecuteScalarList.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/Linq.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/Linq.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,35 @@ +

Data providers supported.

+ + + + + + + + + + + + + + +
Data Provider Provider Name Namespace Vendor
AccessDataProvider Access System.Data.OleDb Microsoft
DB2DataProvider DB2 IBM.Data.DB2 IBM
InformixDataProvider Informix IBM.Data.Informix IBM
FdpDataProvider Fdp FirebirdSql.Data.FirebirdClient Firebird
MySqlDataProvider MySql MySql.Data.MySqlClient Sun Microsystems
OdpDataProvider ODP Oracle.DataAccess.Client Oracle
PostgreSQLProvider PostgreSQL Npgsql PostgreSQL.org
SqlCeDataProvider SqlCe System.Data.SqlServerCe Microsoft
SQLiteDataProvider SQLite System.Data.SQLite SQLite.org
SqlDataProvider Sql System.Data.SqlClient Microsoft
SybaseDataProvider Sybase Sybase.Data.AseClient Sybase
+ +

Operators.

+<% table # Doc\Data\LinqOperators.txt %> + +

Core string functions.
+<% table # Doc\Data\LinqStringCoreFunctions.txt %> + +

Extended Linq string functions.

+To support methods listed below provider must implement all used functions.

+<% table # Doc\Data\LinqStringFunctions.txt %> + +

Core datetime functions.
+<% table # Doc\Data\LinqDateTimeCoreFunctions.txt %> + +

Extended Linq datetime functions.

+<% table # Doc\Data\LinqDateTimeFunctions.txt %> + +

SQL transformations.

+<% table # Doc\Data\LinqSqlTransformations.txt %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/LinqDateTimeCoreFunctions.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/LinqDateTimeCoreFunctions.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ +* +| Current Timestamp | Sql.CurrentTimestamp | CURRENT_TIMESTAMP +| Current Timestamp | Sql.GetDate() | CURRENT_TIMESTAMP + +* DB2 +| Current Timestamp | Sql.CurrentTimestamp | CURRENT_TIMESTAMP +| Current Timestamp | Sql.GetDate() | CURRENT_TIMESTAMP + +* Informix +| Current Timestamp | Sql.CurrentTimestamp | CURRENT +| Current Timestamp | Sql.GetDate() | CURRENT + +* Oracle +| Current Timestamp | Sql.CurrentTimestamp | CURRENT_TIMESTAMP +| Current Timestamp | Sql.GetDate() | CURRENT_TIMESTAMP + +* Firebird +| Current Timestamp | Sql.CurrentTimestamp | CURRENT_TIMESTAMP +| Current Timestamp | Sql.GetDate() | CURRENT_TIMESTAMP + +* PostgreSQL +| Current Timestamp | Sql.CurrentTimestamp | CURRENT_TIMESTAMP +| Current Timestamp | Sql.GetDate() | CURRENT_TIMESTAMP + +* MySql +| Current Timestamp | Sql.CurrentTimestamp | CURRENT_TIMESTAMP +| Current Timestamp | Sql.GetDate() | CURRENT_TIMESTAMP + +* MS SQL +| Current Timestamp | Sql.CurrentTimestamp | CURRENT_TIMESTAMP +| Current Timestamp | Sql.GetDate() | CURRENT_TIMESTAMP + +* SqlCe +| Current Timestamp | Sql.CurrentTimestamp | GetDate() +| Current Timestamp | Sql.GetDate() | GetDate() + +* Sybase +| Current Timestamp | Sql.CurrentTimestamp | GetDate() +| Current Timestamp | Sql.GetDate() | GetDate() + +* SQLite +| Current Timestamp | Sql.CurrentTimestamp | CURRENT_TIMESTAMP +| Current Timestamp | Sql.GetDate() | CURRENT_TIMESTAMP + +* Access +| Current Timestamp | Sql.CurrentTimestamp | Now +| Current Timestamp | Sql.GetDate() | Now diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/LinqDateTimeFunctions.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/LinqDateTimeFunctions.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2 @@ +* All data providers +| Current Timestamp | DateTime.Now | Sql.CurrentTimestamp diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/LinqOperators.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/LinqOperators.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,117 @@ +* DB2 +| Modulo | a % b | Mod(a, b) +| Bitwise AND | a & b | BitAnd(a, b) +| Bitwise OR | a || b | BitOr(a, b) +| Bitwise XOR | a ^ b | BitXor(a, b) +| Coalesce | a ?? b | Coalesce(a, b) +| Coalesce | a ?? b ?? c | Coalesce(a, b, c) +| Conditional | a ? b : c | CASE WHEN a THEN b ELSE c END +| Conditional | a ? b : c ? d : e | CASE WHEN a THEN b WHEN c THEN d ELSE e END +| Concatenation | a + b + c | a || b || c + +* Informix +| Modulo | a % b | Mod(a, b) +| Bitwise AND | a & b | BitAnd(a, b) +| Bitwise OR | a || b | BitOr(a, b) +| Bitwise XOR | a ^ b | BitXor(a, b) +| Coalesce | a ?? b | Nvl(a, b) +| Coalesce | a ?? b ?? c | Nvl(a, b, c) +| Conditional | a ? b : c | CASE WHEN a THEN b ELSE c END +| Conditional | a ? b : c ? d : e | CASE WHEN a THEN b WHEN c THEN d ELSE e END +| Concatenation | a + b + c | a || b || c + +* Oracle +| Modulo | a % b | Mod(a, b) +| Bitwise AND | a & b | BitAnd(a, b) +| Bitwise OR | a || b | (a + b) - BitAnd(a, b) +| Bitwise XOR | a ^ b | (a + b) - BitAnd(a, b) * 2 +| Coalesce | a ?? b | Nvl(a, b) +| Coalesce | a ?? b ?? c | Nvl(a, b, c) +| Conditional | a ? b : c | CASE WHEN a THEN b ELSE c END +| Conditional | a ? b : c ? d : e | CASE WHEN a THEN b WHEN c THEN d ELSE e END +| Concatenation | a + b + c | a || b || c + +* Firebird +| Modulo | a % b | Mod(a, b) +| Bitwise AND | a & b | Bin_And(a, b) +| Bitwise OR | a || b | Bin_Or(a, b) +| Bitwise XOR | a ^ b | Bin_Xor(a, b) +| Coalesce | a ?? b | Coalesce(a, b) +| Coalesce | a ?? b ?? c | Coalesce(a, b, c) +| Conditional | a ? b : c | CASE WHEN a THEN b ELSE c END +| Conditional | a ? b : c ? d : e | CASE WHEN a THEN b WHEN c THEN d ELSE e END +| Concatenation | a + b + c | a || b || c + +* PostgreSQL +| Modulo | a % b | a % b +| Bitwise AND | a & b | a & b +| Bitwise OR | a || b | a || b +| Bitwise XOR | a ^ b | a # b +| Coalesce | a ?? b | Coalesce(a, b) +| Coalesce | a ?? b ?? c | Coalesce(a, b, c) +| Conditional | a ? b : c | CASE WHEN a THEN b ELSE c END +| Conditional | a ? b : c ? d : e | CASE WHEN a THEN b WHEN c THEN d ELSE e END +| Concatenation | a + b + c | a || b || c + +* MySql +| Modulo | a % b | a % b +| Bitwise AND | a & b | a & b +| Bitwise OR | a || b | a || b +| Bitwise XOR | a ^ b | a ^ b +| Coalesce | a ?? b | Coalesce(a, b) +| Coalesce | a ?? b ?? c | Coalesce(a, b, c) +| Conditional | a ? b : c | CASE WHEN a THEN b ELSE c END +| Conditional | a ? b : c ? d : e | CASE WHEN a THEN b WHEN c THEN d ELSE e END +| Concatenation | a + b + c | Concat(a, b, c) + +* MS SQL +| Modulo | a % b | a % b +| Bitwise AND | a & b | a & b +| Bitwise OR | a || b | a || b +| Bitwise XOR | a ^ b | a ^ b +| Coalesce | a ?? b | Coalesce(a, b) +| Coalesce | a ?? b ?? c | Coalesce(a, b, c) +| Conditional | a ? b : c | CASE WHEN a THEN b ELSE c END +| Conditional | a ? b : c ? d : e | CASE WHEN a THEN b WHEN c THEN d ELSE e END +| Concatenation | a + b + c | a + b + c + +* SqlCe +| Modulo | a % b | a % b +| Bitwise AND | a & b | a & b +| Bitwise OR | a || b | a || b +| Bitwise XOR | a ^ b | a ^ b +| Coalesce | a ?? b | Coalesce(a, b) +| Coalesce | a ?? b ?? c | Coalesce(a, b, c) +| Conditional | a ? b : c | CASE WHEN a THEN b ELSE c END +| Conditional | a ? b : c ? d : e | CASE WHEN a THEN b WHEN c THEN d ELSE e END +| Concatenation | a + b + c | a + b + c + +* Sybase +| Modulo | a % b | a % b +| Bitwise AND | a & b | a & b +| Bitwise OR | a || b | a || b +| Bitwise XOR | a ^ b | a ^ b +| Coalesce | a ?? b | Coalesce(a, b) +| Coalesce | a ?? b ?? c | Coalesce(a, b, c) +| Conditional | a ? b : c | CASE WHEN a THEN b ELSE c END +| Conditional | a ? b : c ? d : e | CASE WHEN a THEN b WHEN c THEN d ELSE e END +| Concatenation | a + b + c | a + b + c + +* SQLite +| Modulo | a % b | a % b +| Bitwise AND | a & b | a & b +| Bitwise OR | a || b | a || b +| Bitwise XOR | a ^ b | (a + b) - (a & b) * 2 +| Coalesce | a ?? b | Coalesce(a, b) +| Coalesce | a ?? b ?? c | Coalesce(a, b, c) +| Conditional | a ? b : c | CASE WHEN a THEN b ELSE c END +| Conditional | a ? b : c ? d : e | CASE WHEN a THEN b WHEN c THEN d ELSE e END +| Concatenation | a + b + c | a || b || c + +* Access +| Modulo | a % b | a MOD b +| Coalesce | a ?? b | Iif(a IS NULL, b, a) +| Coalesce | a ?? b ?? c | Iif(a IS NULL, Iif(b IS NULL, c, b), a) +| Conditional | a ? b : c | Iif(a, b, c) +| Conditional | a ? b : c ? d : e | Iif(a, b, Iif(c, d, e)) +| Concatenation | a + b + c | a + b + c diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/LinqSqlTransformations.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/LinqSqlTransformations.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,42 @@ +* DB2 +| SELECT x | db.Select(() => x) | #sql SELECT x \nFROM SYSIBM.SYSDUMMY1 \nFETCH FIRST 1 ROW ONLY +| TAKE x | query.Take(x) | #sql ... FETCH FIRST x ROWS ONLY + +* Informix +| SELECT x | db.Select(() => x) | #sql SELECT FIRST 1 x\nFROM SYSTABLES +| TAKE x | query.Take(x) | #sql SELECT FIRST x + +* Oracle +| SELECT x | db.Select(() => x) | #sql SELECT x \nFROM SYS.DUAL +| TAKE x | query.Take(x) | #sql ... WHERE rownum <= x + +* Firebird +| SELECT x | db.Select(() => x) | #sql SELECT x \nFROM rdb$database +| TAKE x | query.Take(x) | #sql SELECT FIRST x + +* PostgreSQL +| SELECT x | db.Select(() => x) | #sql SELECT x +| TAKE x | query.Take(x) | #sql ... LIMIT x + +* MySql +| SELECT x | db.Select(() => x) | #sql SELECT x +| TAKE x | query.Take(x) | #sql ... LIMIT x + +* MS SQL +| SELECT x | db.Select(() => x) | #sql SELECT x +| TAKE x | query.Take(x) | #sql SELECT TOP x + +* SqlCe +| SELECT x | db.Select(() => x) | #sql SELECT x + +* Sybase +| SELECT x | db.Select(() => x) | #sql SELECT x +| TAKE x | query.Take(x) | #sql SELECT TOP x + +* SQLite +| SELECT x | db.Select(() => x) | #sql SELECT x +| TAKE x | query.Take(x) | #sql ... LIMIT x + +* Access +| SELECT x | db.Select(() => x) | #sql SELECT x +| TAKE x | query.Take(x) | #sql SELECT TOP x diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/LinqStringCoreFunctions.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/LinqStringCoreFunctions.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,166 @@ +* +| LIKE | s.Contains("abc") | s LIKE '%abc%' +| LIKE | s.Contains("a%b") | s LIKE '%a~%b%' ESCAPE '~' +| LIKE | s.Contains(str) | s LIKE @str ESCAPE '~' +| LIKE | !s.Contains(a) | s NOT LIKE a +| LIKE | s.StartsWith("abc") | s LIKE 'abc%' +| LIKE | s.EndsWith("abc") | s LIKE '%abc' +| LIKE | SqlMethods.Like(s, "%abc%") | s LIKE '%abc%' +| LIKE | SqlMethods.Like(s, "a~%b", '~') | s LIKE "a~%b" ESCAPE '~' +| LIKE | Sql.Like(s, "%abc%") | s LIKE '%abc%' +| LIKE | Sql.Like(s, "a~%b", '~') | s LIKE "a~%b" ESCAPE '~' +| Length | Sql.Length(s) | Length(s) +| Trim | Sql.Trim(s) | Trim(s) +| Trim | Sql.TrimLeft(s) | LTrim(s) +| Trim | Sql.TrimRight(s) | RTrim(s) +| Case | Sql.Lower(s) | Lower(s) +| Case | Sql.Upper(s) | Upper(s) + +* DB2 +| CharIndex | Sql.CharIndex(a, s) | Locate(a, s) +| CharIndex | Sql.CharIndex(a, s, b) | Locate(a, s, b) +| Substring | Sql.Substring(s, a, b) | Substr(s, a, b) +| Substring | Sql.Left(s, a) | Left(s, a) +| Substring | Sql.Right(s, a) | Right(s, a) +| Stuff | Sql.Stuff(s, a, b, c) | Substring(s, 1, a-1) + c + Substring(s, a+b, Length(s)-a-b+1)) +| Space | Sql.Space(a) | VarChar(
 Repeat(' ', a), 1000) +| Pad | Sql.PadRight(s, a, b) | s || VarChar(Repeat(
 b, a-Length(s)), 1000) +| Pad | Sql.PadLeft(s, a, b) | VarChar(Repeat(b,
 a-Length(s)), 1000) || s +| Replace | Sql.Replace(s, a, b) | Replace(s, a, b) + +* Informix +| LIKE | !s.Contains(a) | NOT s LIKE a +| Substring | Sql.Substring(s, a, b) | Substr(s, a, b) +| Substring | Sql.Left(s, a) | Substr(s, 1, a) +| Substring | Sql.Right(s, a) | Substr(s,
  Length(s)-a+1, a) +| Stuff | Sql.Stuff(s, a, b, c) | Substring(s, 1, a-1) + c + Substring(s, a+b, Length(s)-a-b+1)) +| Space | Sql.Space(a) | RPad(' ', a, ' ') +| Pad | Sql.PadRight(s, a, b) | RPad(s, a, b) +| Pad | Sql.PadLeft(s, a, b) | LPad(s, a, b) +| Replace | Sql.Replace(s, a, b) | Replace(s, a, b) + +* Oracle +| CharIndex | Sql.CharIndex(a, s) | InStr(s, a) +| CharIndex | Sql.CharIndex(a, s, b) | InStr(s, a, b) +| Substring | Sql.Substring(s, a, b) | Substr(s, a, b) +| Substring | Sql.Left(s, a) | Substr(s, 1, a) +| Substring | Sql.Right(s, a) | Substr(s,
  Length(s)-a+1, a) +| Reverse | Sql.Reverse(s) | Reverse(s) +| Stuff | Sql.Stuff(s, a, b, c) | Substring(s, 1, a-1) + c + Substring(s, a+b, Length(s)-a-b+1)) +| Space | Sql.Space(a) | RPad(' ', a, ' ') +| Pad | Sql.PadRight(s, a, b) | RPad(s, a, b) +| Pad | Sql.PadLeft(s, a, b) | LPad(s, a, b) +| Replace | Sql.Replace(s, a, b) | Replace(s, a, b) + +* Firebird +| Length | Sql.Length(s) | Char_Length(s) +| Substring | Sql.Substring(s, a, b) | Substring(
 s from a for b) +| Substring | Sql.Left(s, a) | Left(s, a) +| Substring | Sql.Right(s, a) | Right(s, a) +| Reverse | Sql.Reverse(s) | Reverse(s) +| Stuff | Sql.Stuff(s, a, b, c) | Substring(s, 1, a-1) + c + Substring(s, a+b, Length(s)-a-b+1)) +| Space | Sql.Space(a) | RPad(' ', a, ' ') +| Pad | Sql.PadRight(s, a, b) | RPad(s, a, b) +| Pad | Sql.PadLeft(s, a, b) | LPad(s, a, b) +| Replace | Sql.Replace(s, a, b) | Replace(s, a, b) + +* PostgreSQL +| CharIndex | Sql.CharIndex(a, s) | Position(a in s) +| CharIndex | Sql.CharIndex(a, s, b) | Position(a in Substring(s, b,
  Length(s)-b)) + b-1 +| Substring | Sql.Substring(s, a, b) | Substring(s, a, b) +| Substring | Sql.Left(s, a) | Substring(s, 1, a) +| Substring | Sql.Right(s, a) | Substring(s, Length(s)-a+1, a) +| Reverse | Sql.Reverse(s) | Reverse(s) -- implemented as UDF +| Stuff | Sql.Stuff(s, a, b, c) | Substring(s, 1, a-1) + c + Substring(s, a+b, Length(s)-a-b+1)) +| Space | Sql.Space(a) | Repeat(' ', a) +| Pad | Sql.PadRight(s, a, b) | RPad(s, a, b) +| Pad | Sql.PadLeft(s, a, b) | LPad(s, a, b) +| Replace | Sql.Replace(s, a, b) | Replace(s, a, b) + +* MySql +| CharIndex | Sql.CharIndex(a, s) | Locate(a, s) +| CharIndex | Sql.CharIndex(a, s, b) | Locate(a, s, b) +| Substring | Sql.Substring(s, a, b) | Substring(s, a, b) +| Substring | Sql.Left(s, a) | Left(s, a) +| Substring | Sql.Right(s, a) | Right(s, a) +| Reverse | Sql.Reverse(s) | Reverse(s) +| Stuff | Sql.Stuff(s, a, b, c) | Substring(s, 1, a-1) + c + Substring(s, a+b, Length(s)-a-b+1)) +| Space | Sql.Space(a) | Space(a) +| Pad | Sql.PadRight(s, a, b) | RPad(s, a, b) +| Pad | Sql.PadLeft(s, a, b) | LPad(s, a, b) +| Replace | Sql.Replace(s, a, b) | Replace(s, a, b) + +* MS SQL +| Length | Sql.Length(s) | Len(s) +| CharIndex | Sql.CharIndex(a, s) | CharIndex(a, s) +| CharIndex | Sql.CharIndex(a, s, b) | CharIndex(a, s, b) +| Substring | Sql.Substring(s, a, b) | Substring(s, a, b) +| Substring | Sql.Left(s, a) | Left(s, a) +| Substring | Sql.Right(s, a) | Right(s, a) +| Reverse | Sql.Reverse(s) | Reverse(s) +| Stuff | Sql.Stuff(s, a, b, c) | Stuff(s, a, b, c) +| Space | Sql.Space(a) | Space(a) +| Pad | Sql.PadRight(s, a, b) | s + Replicate(b, a - Len(s)) +| Pad | Sql.PadLeft(s, a, b) | Replicate(b, a - Len(s)) + s +| Replace | Sql.Replace(s, a, b) | Replace(s, a, b) +| Trim | Sql.Trim(s) | LTrim(RTrim(s)) + +* SqlCe +| Length | Sql.Length(s) | Len(s) +| CharIndex | Sql.CharIndex(a, s) | CharIndex(a, s) +| CharIndex | Sql.CharIndex(a, s, b) | CharIndex(a, s, b) +| Substring | Sql.Substring(s, a, b) | Substring(s, a, b) +| Substring | Sql.Left(s, a) | Substring(s, 1, a) +| Substring | Sql.Right(s, a) | Substring(s,
  Len(s)-a+1, a) +| Stuff | Sql.Stuff(s, a, b, c) | Stuff(s, a, b, c) +| Space | Sql.Space(a) | Space(a) +| Pad | Sql.PadRight(s, a, b) | s + Replicate(b, a - Len(s)) +| Pad | Sql.PadLeft(s, a, b) | Replicate(b, a - Len(s)) + s +| Replace | Sql.Replace(s, a, b) | Replace(s, a, b) +| Trim | Sql.Trim(s) | LTrim(RTrim(s)) + +* Sybase +| Length | Sql.Length(s) | Len(s) +| CharIndex | Sql.CharIndex(a, s) | CharIndex(a, s) +| CharIndex | Sql.CharIndex(a, s, b) | CharIndex(a,Substring(
  s, b, Len(s)-b)) + b - 1 +| Substring | Sql.Substring(s, a, b) | Substring(s, a, b) +| Substring | Sql.Left(s, a) | Left(s, a) +| Substring | Sql.Right(s, a) | Right(s, a) +| Reverse | Sql.Reverse(s) | Reverse(s) +| Stuff | Sql.Stuff(s, a, b, c) | Stuff(s, a, b, c) +| Space | Sql.Space(a) | Space(a) +| Pad | Sql.PadRight(s, a, b) | s + Replicate(b, a - Len(s)) +| Pad | Sql.PadLeft(s, a, b) | Replicate(b, a - Len(s)) + s +| Replace | Sql.Replace(s, a, b) | Str_Replace(s, a, b) +| Trim | Sql.Trim(s) | LTrim(RTrim(s)) + +* SQLite +| CharIndex | Sql.CharIndex(a, s) | CharIndex(a, s) +| CharIndex | Sql.CharIndex(a, s, b) | CharIndex(a, s, b) +| Substring | Sql.Substring(s, a, b) | Substr(s, a, b) +| Substring | Sql.Left(s, a) | LeftStr(s, a) +| Substring | Sql.Right(s, a) | RigthStr(s, a) +| Reverse | Sql.Reverse(s) | Reverse(s) +| Stuff | Sql.Stuff(s, a, b, c) | Substring(s, 1, a-1) + c +
Substring(s, a+b, Length(s)-a-b+1)) +| Space | Sql.Space(a) | PadR(' ', a) +| Pad | Sql.PadRight(s, a, b) | s + Replicate(b, a - Len(s)) +| Pad | Sql.PadLeft(s, a, b) | Replicate(b, a - Len(s)) + s +| Replace | Sql.Replace(s, a, b) | Replace(s, a, b) + +* Access +| LIKE | s.Contains("a%b") | s LIKE "%a[%]b%" +| LIKE | s.Contains(str) | s LIKE @str +| LIKE | SqlMethods.Like(s, "a~%b", '~') | s LIKE "a[%]b" +| LIKE | Sql.Like(s, "a~%b", '~') | s LIKE "a[%]b" +| Length | Sql.Length(s) | Len(s) +| CharIndex | Sql.CharIndex(a, s) | InStr(1, s, a, 1) +| CharIndex | Sql.CharIndex(a, s, b) | InStr(b, s, a, 1) +| Substring | Sql.Substring(s, a, b) | Mid(s, a, b) +| Substring | Sql.Left(s, a) | Left(s, a) +| Substring | Sql.Right(s, a) | Right(s, a) +| Stuff | Sql.Stuff(s, a, b, c) | Substring(s, 1, a-1) + c +
Substring(s, a+b, Length(s)-a-b+1)) +| Space | Sql.Space(a) | Space(a) +| Pad | Sql.PadRight(s, a, b) | s + String(a-Len(s), b)) +| Pad | Sql.PadLeft(s, a, b) | String(a-Len(s), b)) + s +| Case | Sql.Lower(s) | LCase(s) +| Case | Sql.Upper(s) | UCase(s) diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/LinqStringFunctions.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/LinqStringFunctions.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ +* All data providers +| Length | s.Length | Sql.Length(s) +| Substring | s.Substring (a) | Sql.Substring(s, a + 1, Sql.Length(s) - a) +| Substring | s.Substring (a, b) | Sql.Substring(s, a + 1, b) +| IndexOf | s.IndexOf (a) | Sql.Length(a) == 0 ? 0 : (Sql.CharIndex(a, s) ?? 0) - 1 +| IndexOf | s.IndexOf (a, b) | Sql.Length(a) == 0 && Sql.Length(s) > b ? b : (Sql.CharIndex(a, s, b + 1) ?? 0) - 1 +| IndexOf | s.IndexOf (a, b, c) | Sql.Length(a) == 0 && Sql.Length(s) > b ? b : (Sql.CharIndex(a, Sql.Left(s, c), b) ?? 0) - 1 +| LastIndexOf | s.LastIndexOf(a) | Sql.Length(a) == 0 ? Sql.Length(s) - 1 :
(Sql.CharIndex(a, s) ?? 0) == 0 ? -1 :
  Sql.Length(s) - (Sql.CharIndex(Sql.Reverse(a), Sql.Reverse(s)) ?? 0) - Sql.Length(a) + 1 +| LastIndexOf | s.LastIndexOf(a, b) | Sql.Length(a) == 0 ? b :
(Sql.CharIndex(a, s, b + 1) ?? 0) == 0 ? -1 :
  Sql.Length(s) - (Sql.CharIndex(Sql.Reverse(a), Sql.Reverse(Sql.Substring(s, b + 1, Sql.Length(s) - b))) ?? 0) - Sql.Length(a) + 1 +| LastIndexOf | s.LastIndexOf(a, b, c) | Sql.Length(a) == 0 ? b :
(Sql.CharIndex(a, Sql.Left(s, b + c), b + 1) ?? 0) == 0 ? -1 :
  b + c - (Sql.CharIndex(Sql.Reverse(a), Sql.Reverse(Sql.Substring(s, b + 1, c))) ?? 0) - Sql.Length(a) + 1 +| Insert | s.Insert (a, b) | Sql.Length(s) == a ? s + b : Sql.Stuff(s, a + 1, 0, b) +| Remove | s.Remove (a) | Sql.Left(s, a) +| Remove | s.Remove (a, b) | Sql.Stuff(s, a + 1, b, "") +| Pad | s.PadLeft (a) | Sql.PadLeft(s, a, ' ') +| Pad | s.PadLeft (a, b) | Sql.PadLeft(s, a, b) +| Pad | s.PadRight (a) | Sql.PadRight(s, a, ' ') +| Pad | s.PadRight (a, b) | Sql.PadRight(s, a, b) +| Replace | s.Replace (a, b) | Sql.Replace(s, a, b) +| Trim | s.Trim () | Sql.Trim(s) +| Trim | s.TrimEnd () | Sql.TrimRight(s) +| Trim | s.TrimStart () | Sql.TrimLeft(s) +| Case | s.ToLower () | Sql.Lower(s) +| Case | s.ToUpper () | Sql.Upper(s) +| Compare | s.CompareTo (a) | s > a ? 1 : s == 0 ? 0 : -1 diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/OpenConfig1.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/OpenConfig1.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,46 @@ +<% title # Configure using app.config %> +<% group # Configuration %> +<% order # 10 %> +

+Since Microsoft has released FW 2.0 and the <connectionStrings> section of +configuration file is available, it should be used. This configuration method is preferable. +The following method demonstrates this ability. +

+OpenConfig1FW2.cs +<% ..\..\..\HowTo\Data\OpenConfig1FW2.cs %> +App.config +<% Doc\Data\App1.config %> + +

+In addition BLToolkit supports an alternative way which uses the <appSettings> section. +At the bottom of this page you can find a demo App.config file with a few examples. +

+

+BLToolkit recognizes configuration strings in the <appSettings> section +by looking for a ConnectionString key prefix. Actual key value can be the following: + + + + + + + + + + +
key valueProviderConfiguration
key="ConnectionString"default providerdefault configuration
key="ConnectionString.Foo.Bar"'Foo' provider'Bar' configuration
key="ConnectionString.Foo."'Foo' providerdefault configuration
key="ConnectionString.Foo"default provider'Foo' configuration
or'Foo' providerdefault configuration
key="ConnectionString..Foo"default provider'Foo' configuration
key="ConnectionString..Foo.Bar"default provider'Foo.Bar' configuration
+ +Default provider is SqlDataProvider. +See also Data Providers. +

+ +OpenConfig1.cs +<% ..\..\..\HowTo\Data\OpenConfig1.cs %> +App.config +<% ..\..\..\UnitTests\All\App.config %> + +

The default configuration can be set by a configuration file:

+App.config +<% Doc\Data\App2.config %> + +
Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/OpenConfig2.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/OpenConfig2.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +<% title # Configure programmatically %> +<% group # Configuration %> +<% order # 11 %> +

+Connection string can be also assigned programmatically. +The DbManager.AddConnectionString method can be used for this. +You should do it once when your application starts. +

+OpenConfig2.cs +<% ..\..\..\HowTo\Data\OpenConfig2.cs %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/OpenConfig3.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/OpenConfig3.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,6 @@ +<% title # Configure by passing objects %> +<% group # Configuration %> +<% order # 12 %> +OpenConfig3.cs +<% ..\..\..\HowTo\Data\OpenConfig3.cs %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/Parameter.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/Parameter.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +<% group # Methods %> +<% order # 3 %> +

+The DbManager.Parameter method allows assigning parameters to an SQL query, +setting parameter values before query, and getting return/out values after. +

+Parameter.cs +<% ..\..\..\HowTo\Data\Parameter.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/Prepare.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/Prepare.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +<% group # Methods %> +<% order # 4 %> +

+The Prepare method can be useful if you need to execute the same command multiple times. +

+ +Prepare.cs +<% ..\..\..\HowTo\Data\Prepare.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/SetCommand.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/SetCommand.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ +<% group # Methods %> +<% order # 1 %> +

+Typical scenario of using DbManager includes the following steps: +

    +
  • Create a DbManager class instance. +
  • Set an SQL command or a stored procedure name. +
  • Call an ExecuteXXX method. +
+The SetCommand method is used to set an SQL statement and to provide command parameters, if any. +

+ +SetCommand.cs +<% ..\..\..\HowTo\Data\SetCommand.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/SetSpCommand.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/SetSpCommand.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,22 @@ +<% group # Methods %> +<% order # 2 %> +

+Typical scenario of using DbManager includes the following steps: +

    +
  • Create a DbManager class instance. +
  • Set an SQL command or a stored procedure name. +
  • Call an ExecuteXXX method. +
+The SetSpCommand method is used to set a stored procedure name and to provide command parameters, if any. +

+ +SetSpCommand.cs +<% ..\..\..\HowTo\Data\SetSpCommand.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/Transaction.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/Transaction.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ +<% group # Methods %> +<% order # 5 %> +Transaction.cs +<% ..\..\..\HowTo\Data\Transaction.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Data/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Data/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,34 @@ +<% noindex # %> +

The DbManager class is a high-level, data provider independent wrapper for ADO.NET. +It has been designed to simplify working with database and encapsulates most of ADO.NET objects +such as Connection, Transaction, Command, and Parameter in one single object. +

+ + + +How to configure +using app.config. +programmatically. +by passing DataProvider, Connection or Transaction object. + + +Using SQL statements +Using stored procedures + + + + + + + + + + + + +Complex mapping + + + + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/AbstractAccessor.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/AbstractAccessor.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,37 @@ +<% group # Abstract accessors %> +<% order # 20 %> + +

The following example demonstrates how to create and use an abstract data accessor class. +All abstract methods of the class are generated at run-time depending on each method declaration. +Every part of the method declaration is important. +Method's return value specifies one of the Execute methods in the following way: + + + + + + + + + + +
Return TypeExecute Method
IDataReader interfaceExecuteReader
Subclass of DataSetExecuteDataSet
Subclass of DataTableExecuteDataTable
Class implementing the IList interfaceExecuteList or ExecuteScalarList
Class implementing the IDictionary interfaceExecuteDictionary or ExecuteScalarDictionary
voidExecuteNonQuery
string, byte[] or value typeExecuteScalar
In any other caseExecuteObject
+Method name explicitly defines action name which is converted to stored procedure name.
+Type, sequential order, and name of the method parameters is mapped to the command parameters. +Exceptions from this rule are: +
+

    +
  • a parameter of DbManager type. In this case generator uses provided DbManager to call the command.
  • +
  • parameters decorated with attribute FormatAttribute.
  • +
+

+AbstractAccessor.cs +<% ..\..\..\HowTo\DataAccess\AbstractAccessor.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ActionName.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ActionName.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +<% group # Abstract accessor attributes %> +<% order # 50 %> + +

+ActionName is a logical name of an operation. By default a method name is an action name, +but ActionNameAttribute allows overriding this behavior. +Actual stored procedure name will be built depending on naming convention which is defined in the +GetDefaultSpName method. +

+ +ActionName.cs +<% ..\..\..\HowTo\DataAccess\ActionName.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ActionSprocName.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ActionSprocName.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +<% group # Abstract accessor attributes %> + +

+The ActionSprocName attribute is applied to a business object (NOT to data accessor class) and +associates ActionName with stored procedure name. +

+ +ActionSprocName.cs +<% ..\..\..\HowTo\DataAccess\ActionSprocName.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ActualType.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ActualType.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +<% group # Abstract accessor attributes %> + +

+The ActualType attribute associates an actual type with the type returned by an abstract method. +Note the ObjectType attribute has higher priority. +

+ +ActualType.cs +<% ..\..\..\HowTo\DataAccess\ActualType.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/CommandBehavior.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/CommandBehavior.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +<% group # Abstract accessor attributes %> + +

+The CommandBehavior attribute provides a description of the results of the query and its effect on the database. +

+ +CommandBehavior.cs +<% ..\..\..\HowTo\DataAccess\CommandBehavior.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/CustomSqlQuery1.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/CustomSqlQuery1.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,18 @@ +<% title # SqlQuery customization 1 %> +<% group # Abstract accessor attributes %> + +

+This example demonstrates how to create a custom attribute +which allows specifying more than one SQL query for different data providers. +

+ +CustomSqlQuery1.cs +<% ..\..\..\HowTo\DataAccess\CustomSqlQuery1.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/CustomSqlQuery2.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/CustomSqlQuery2.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,24 @@ +<% title # SqlQuery customization 2 %> +<% group # Abstract accessor attributes %> + +

+This example demonstrates how to specify SQL query for different data providers by using XML. +

+ +CustomSqlQuery2.cs +<% ..\..\..\HowTo\DataAccess\CustomSqlQuery2.cs %> + +Sql.xml <% ..\..\..\HowTo\DataAccess\Sql\Sql.xml %> +Access.xml <% ..\..\..\HowTo\DataAccess\Sql\Access.xml %> +Oracle.xml <% ..\..\..\HowTo\DataAccess\Sql\Oracle.xml %> +Fdp.xml <% ..\..\..\HowTo\DataAccess\Sql\Fdp.xml %> +SQLite.xml <% ..\..\..\HowTo\DataAccess\Sql\SQLite.xml %> + + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/DataSetTable.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/DataSetTable.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +<% group # Abstract accessor attributes %> + +

+The DataSetTable attribute specifies table to be populated +by the method in destination or returning dataset. +

+ +DataSetTable.cs +<% ..\..\..\HowTo\DataAccess\DataSetTable.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/Delete.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/Delete.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +<% group # Basic CRUDL operations and stored procedures %> +<% order # 204 %> + +Delete.cs +<% ..\..\..\HowTo\DataAccess\Delete.cs %> +Both DataAccessor.DeleteByKey and DataAccessor.Delete methods generate and execute the following SQL statement: +<% sql # exec Person_Delete @PersonID=2 %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/DeleteSql.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/DeleteSql.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +<% group # Basic CRUDL operations and SQL text generation %> +<% order # 154 %> + +DeleteSql.cs +<% ..\..\..\HowTo\DataAccess\DeleteSql.cs %> +Both DataAccessor.DeleteByKeySql and DataAccessor.DeleteSql methods generate and execute the following SQL statement: +<% sql # +DELETE FROM + [Person] +WHERE + [PersonID] = @PersonID +%> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/Destination.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/Destination.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +<% group # Abstract accessor attributes %> + +

+Return value of an abstract method defines a result that this method returns. +The Destination attribute allows specifying one of the method parameters as the result. +

+ +Destination.cs +<% ..\..\..\HowTo\DataAccess\Destination.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/Direction.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/Direction.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +<% group # Abstract accessor attributes %> + +

+The Direction attributes allow controlling mapping from/to a business object. +The following table contains brief description of the direction attributes: + + + + + + + +
AttributeDescription
Output Provided members are output parameters of the query.
InputOutputProvided members are input/output parameters of the query.
Ignore Provided members are excluded from mapping.
ReturnValueProvided member is mapped to return value.
+

+ +Direction.cs +<% ..\..\..\HowTo\DataAccess\Direction.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/DiscoverParameters.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/DiscoverParameters.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +<% group # Abstract accessor attributes %> + +

+By default, BLToolkit expects method parameter names to match stored procedure +parameter names. The sequential order of parameters is not important in this +case. The DiscoverParameters attribute enforces BLToolkit to retrieve parameter +information from the sproc and to assign method parameters in the order they go. +Parameter names are ignored. +

+ +DiscoverParameters.cs +<% ..\..\..\HowTo\DataAccess\DiscoverParameters.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ExecuteDictionary.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ExecuteDictionary.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +<% group # Abstract accessors %> +<% index # ExecuteDictionary method %> + +ExecuteDictionary.cs +<% ..\..\..\HowTo\DataAccess\ExecuteDictionary.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ExecuteList.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ExecuteList.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +<% group # Abstract accessors %> +<% index # ExecuteList method %> + +ExecuteList.cs +<% ..\..\..\HowTo\DataAccess\ExecuteList.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ExecuteObject.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ExecuteObject.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +<% group # Abstract accessors %> +<% index # ExecuteObject method %> + +ExecuteObject.cs +<% ..\..\..\HowTo\DataAccess\ExecuteObject.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ExecuteScalar.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ExecuteScalar.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +<% group # Abstract accessors %> +<% index # ExecuteScalar method %> + +ExecuteScalar.cs +<% ..\..\..\HowTo\DataAccess\ExecuteScalar.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/Format.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/Format.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +<% group # Abstract accessor attributes %> + +

+The Format indicates that the specified parameter is used to construct the stored procedure name or SQL statement: +

+ +Format.cs +<% ..\..\..\HowTo\DataAccess\Format.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/IndexAttribute.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/IndexAttribute.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +<% group # Abstract accessor attributes %> +<% title # Index %> + +ExecuteDictionary.cs +<% ..\..\..\HowTo\DataAccess\ExecuteDictionary.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/Insert.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/Insert.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +<% group # Basic CRUDL operations and stored procedures %> +<% order # 202 %> + +Insert.cs +<% ..\..\..\HowTo\DataAccess\Insert.cs %> +DataAccessor.Insert method generates and executes the following SQL statement: +<% sql # exec Person_Insert @FirstName='Crazy', @LastName='Frog', @MiddleName=NULL, @Gender='U' %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/InsertSql.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/InsertSql.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,27 @@ +<% group # Basic CRUDL operations and SQL text generation %> +<% order # 152 %> + +InsertSql.cs +<% ..\..\..\HowTo\DataAccess\InsertSql.cs %> +DataAccessor.InsertSql method generates and executes the following SQL statement: +<% sql # +INSERT INTO [Person] ( + [MiddleName], + [Gender], + [LastName], + [FirstName] +) VALUES ( + @MiddleName, + @Gender, + @LastName, + @FirstName +) +%> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/Introduction.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/Introduction.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,629 @@ +<% title # Introduction to abstract data accessors %> +<% order # 1 %> +

Introduction

+ +

+Before we start talking about the data accessors, let us create a few examples of +typical data accessor methods. +

+

+The following table contains three stored procedures and +three data access methods implementing the stored procedure calls. +

+ + + + + + + + + + + + + + + + + + +
Stored procedureData access method
+The first stored procedure takes filter and page parameters and returns recordset from the Person table. +
<% sql # +CREATE Procedure GetPersonListByName( + @firstName varchar(50), + @lastName varchar(50), + @pageNumber int, + @pageSize int) +AS + -- stored procedure implementation + -- +%><% cs # +public List GetPersonListByName( + string firstName, + string lastName, + int pageNumber, + int pageSize) +{ + // method implementation. +} +%>
+Second example will return single Person record by id. +
<% sql # +CREATE Procedure GetPersonByID(@id int) +AS + -- stored procedure implementation + -- +%> +<% cs # +public Person GetPersonByID(int id) +{ + // method implementation. +} +%>
+The last example will delete a record from the database by id. +
<% sql # +CREATE Procedure DeletePersonByID(@id int) +AS + -- stored procedure implementation + -- +%><% cs # +public void DeletePersonByID(int id) +{ + // method implementation. +} +%>
+ +

Now lets see what we can say if we compare the stored procedure and C# method signatures. +

    +
  1. Stored procedure and method names match up.
  2. +
  3. Sequential order, method parameter types and names correspond to stored procedure parameters.
  4. +
  5. Methods' return values can give us an idea what Execute method we +should utilize and what object type has to be used to map data from recordset if needed.
  6. +
+

+ +

+As demonstrated above method definition contains all the information we need +to implement the method body. Actually, by defining the method signatures, we +completed the most intelligent part of data accessor development. The rest of +work is definitely a monkey's job. Honestly, I got bored of being just a coding +machine writing the same data access code over and over again, especially +understanding that this process can be automated. +

+

+This introduction shows how to avoid the implementation step of data access +development and how to reduce this routine process to the method declaration. +

+ +

Abstract classes

+ +

+Unfortunately, mainstream .NET languages still do not have a compile-time +transformation system like some functional or hybrid languages do. +All we have today is pre-compile- and run-time code generation. +

+

+This introduction concentrates on run-time code generation and its support by +Business Logic Toolkit for .NET. +

+

+Let us step back and bring the methods from the previous examples together in one class. +Ideally, this data accessor class could look like the following: +

+<% cs # +using System; +using System.Collections.Generic; + +public class PersonAccessor +{ + public List GetPersonListByName( + string firstName, string lastName, int pageNumber, int pageSize); + + public Person GetPersonByID (int id); + public void DeletePersonByID(int id); +} +%> + +

+The bad news about this sample is that we cannot use such syntax as the +compiler expects the method's body implementation. +

+

+The good news is we can use abstract classes and methods that give us quite +similar, compilable source code. +

+<% cs # +using System; +using System.Collections.Generic; + +public /*[a]*/abstract/*[/a]*/ class PersonAccessor +{ + public /*[a]*/abstract/*[/a]*/ List GetPersonListByName( + string firstName, string lastName, int pageNumber, int pageSize); + + public /*[a]*/abstract/*[/a]*/ Person GetPersonByID (int id); + public /*[a]*/abstract/*[/a]*/ void DeletePersonByID(int id); +} +%> + +

This code is 100% valid and our next step is to make it workable.

+ +

Abstract DataAccessor

+ +

+Business Logic Toolkit provides the DataAccessor class, which is +used as a base class to develop data accessor classes. If we add +DataAccessor to our previous example, it will look like the following: +

+<% cs # +using System; +using System.Collections.Generic; + +public abstract class PersonAccessor : /*[a]*/DataAccessor/*[/a]*/ +{ + public abstract List GetPersonListByName( + string firstName, string lastName, int pageNumber, int pageSize); + + public abstract Person GetPersonByID (int id); + public abstract void DeletePersonByID(int id); +} +%> + +

That's it! Now this class is complete and fully functional. The code below shows how to use it:

+ +<% cs # +using System; +using System.Collections.Generic; + +using BLToolkit.Reflection; + +namespace DataAccess +{ + class Program + { + static void Main(string[] args) + { + PersonAccessor pa = /*[a]*/TypeAccessor/*[/a]*/./*[a]*/CreateInstance/*[/a]*/(); + + List list = pa.GetPersonListByName("Crazy", "Frog", 0, 20); + + foreach (Person p in list) + Console.Write("{0} {1}", p.FirstName, p.LastName); + } + } +} +%> + +

+The only magic here is the TypeAccessor.CreateInstance method. First of all this +method creates a new class inherited from the PersonAccessor class and +then generates abstract method bodies depending on each method declaration. +If we wrote those methods manually, we could get something like the following: +

+<% cs # +using System; +using System.Collections.Generic; + +using BLToolkit.Data; + +namespace Example.BLToolkitExtension +{ + public sealed class PersonAccessor : Example.PersonAccessor + { + public override List GetPersonListByName( + string firstName, + string lastName, + int pageNumber, + int pageSize) + { + using (DbManager db = GetDbManager()) + { + return db + .SetSpCommand("GetPersonListByName", + db.Parameter("@firstName", firstName), + db.Parameter("@lastName", lastName), + db.Parameter("@pageNumber", pageNumber), + db.Parameter("@pageSize", pageSize)) + .ExecuteList(); + } + } + + public override Person GetPersonByID(int id) + { + using (DbManager db = GetDbManager()) + { + return db + .SetSpCommand("GetPersonByID", db.Parameter("@id", id)) + .ExecuteObject(); + } + } + + public override void DeletePersonByID(int id) + { + using (DbManager db = GetDbManager()) + { + db + .SetSpCommand("DeletePersonByID", db.Parameter("@id", id)) + .ExecuteNonQuery(); + } + } + } +} +%> + +

+(The DbManager class is another BLToolkit class used for 'low-level' database access). +

+ +

+Every part of the method declaration is important. +Method's return value specifies one of the Execute methods in the following way: + + + + + + + + + + +
Return TypeExecute Method
IDataReader interfaceExecuteReader
Subclass of DataSetExecuteDataSet
Subclass of DataTableExecuteDataTable
Class implementing the IList interfaceExecuteList or ExecuteScalarList
Class implementing the IDictionary interfaceExecuteDictionary or ExecuteScalarDictionary
voidExecuteNonQuery
string, byte[] or value typeExecuteScalar
In any other caseExecuteObject
+The method name explicitly defines the action name, which is converted to the stored procedure name. +Type, sequential order, and name of the method parameters are mapped to the command parameters. +Exceptions from this rule are: +
+

+

+ +

Generating process control

+ +

+The PersonAccessor class above is a very simple example and, of +course, it seems too ideal to be real. In real life, we need more flexibility +and more control over the generated code. BLToolkit contains a bunch of +attributes to control DataAccessor generation in addition to DataAccessor virtual members. +

+ +
Method CreateDbManager
+ +<% cs # +protected virtual DbManager CreateDbManager() +{ + return new DbManager(); +} +%> + +

+By default, this method creates a new instance of DbManager that uses default database configuration. +You can change this behavior by overriding this method. For example: +

+<% cs # +public abstract class OracleDataAccessor : DataAccessor +{ + protected override DbManager CreateDbManager() + { + return new DbManager("Oracle", "Production"); + } +} +%> + +

+This code will use the Oracle data provider and Production configuration. +

+ +
Method GetDefaultSpName
+ +<% cs # +protected virtual string GetDefaultSpName(string typeName, string actionName) +{ + return typeName == null? + actionName: + string.Format("{0}_{1}", typeName, actionName); +} +%> + +

+As I mentioned, the method name explicitly defines the so-called action name. +The final stored procedure name is created by the GetDefaultSpName +method. The default implementation uses the following naming convention: +

+ +
    +
  • +If type name is provided, the method constructs the stored proc name by +concatenating the type and action names. Thus, if the type name is "Person" and +the action name is "GetAll", the resulting sproc name will be "Person_GetAll". +
  • +
  • +If the type name is NOT provided, the stored procedure name will equal the +action name.
  • +
+ +

+You can easily change this behavior. For example, for the naming convention "p_Person_GetAll", +the method implementation can be the following: +

+<% cs # +public abstract class MyBaseDataAccessor : DataAccessor + where A : DataAccessor +{ + protected override string GetDefaultSpName(string typeName, string actionName) + { + return string.Format("p_{0}_{1}", typeName, actionName); + } +} +%> + +
Method GetTableName
+ +<% cs # +protected virtual string GetTableName(Type type) +{ + // ... + return type.Name; +} +%> + +

+By default, the table name is the associated object type name (Person in our examples). +There are two ways to associate an object type with an accessor. By providing generic parameter: +

+ <% cs # +public abstract class PersonAccessor : DataAccessor +{ +} +%> + +

+And by the ObjectType attribute: +

+<% cs # +[ObjectType(typeof(Person))] +public abstract class PersonAccessor : DataAccessor +{ +} +%> + +

+If you want to have different table and type names in your application, you may override the GetTableName method: +

+<% cs # +public abstract class OracleDataAccessor : DataAccessor + where A : DataAccessor +{ + protected override string GetTableName(Type type) + { + return base.GetTableName(type).ToUpper(); + } +} +%> + +
TableNameAttribute
+ +

+Also, you can change the table name for a particular object type by decorating this object +with the TableNameAttribute attribute: +

+<% cs # +[TableName("PERSON")] +public class Person +{ + public int ID; + public string FirstName; + public string LastName; +} +%> + +
ActionNameAttribute
+ +

+This attribute allows changing the action name. +

+<% cs # +public abstract class PersonAccessor : DataAccessor +{ + [ActionName("GetByID")] + protected abstract IDataReader GetByIDInternal(DbManager db, int id); + + public Person GetByID(int id) + { + using (DbManager db = GetDbManager()) + using (IDataReader rd = GetByIDInternal(db, id)) + { + Person p = new Person(); + + // do something complicated. + + return p; + } + } +} +%> + +
ActionSprocNameAttribute
+ +

+This attribute associates the action name with a stored procedure name: +

+<% cs# +[ActionSprocName("Insert", sp_Person_Insert")] +public abstract class PersonAccessor : DataAccessor +{ + public abstract void Insert(Person p); +} +%> + +

+This attribute can be useful when you need to reassign a stored procedure name for a method defined in your base class. +

+ +
SprocNameAttribute
+ +

+The regular way to assign deferent from default sproc name for a method is the SprocName attribute. +

+<% cs # +public abstract class PersonAccessor : DataAccessor +{ + [SprocName("sp_Person_Insert")] + public abstract void Insert(Person p); +} +%> + +
DestinationAttribute
+ +

+By default, the DataAccessor generator uses method's return value to determine which Execute method +should be used to perform the current operation. +The DestinationAttribute indicates that target object is a parameter decorated with this attribute: +

+<% cs # +public abstract class PersonAccessor : DataAccessor +{ + public abstract void GetAll([Destination] List list); +} +%> + +
DirectionAttributes
+ +

+DataAccessor generator can map provided business object to stored +procedure parameters. Direction attributes allow controlling this process more precisely. +

+<% cs # +public abstract class PersonAccessor : DataAccessor +{ + public abstract void Insert( + [Direction.Output("ID"), Direction.Ignore("LastName")] Person person); +} +%> + +

+In addition, BLToolkit provides two more direction attributes: +Direction.InputOutputAttribute and Direction.ReturnValueAttribute. +

+ +
DiscoverParametersAttribute
+

+By default, BLToolkit expects method parameter names to match stored procedure +parameter names. The sequential order of parameters is not important in this +case. This attribute enforces BLToolkit to retrieve parameter information from +the sproc and to assign method parameters in the order they go. Parameter names +are ignored. +

+ +
FormatAttribute
+ +

+This attribute indicates that the specified parameter is used to construct the stored procedure name or SQL statement: +

+<% cs # +public abstract class PersonAccessor : DataAccessor +{ + [SqlQuery("SELECT {0} FROM {1} WHERE {2}")] + public abstract List GetStrings( + [Format(0)] string fieldName, + [Format(1)] string tableName, + [Format(2)] string whereClause); +} +%> + +
IndexAttribute
+ +

+If you want your method to return a dictionary, you will have to specify fields to build the dictionary key. +The Index attribute allows you to do that: +

+<% cs # +public abstract class PersonAccessor : DataAccessor +{ + [SqlQuery("SELECT * FROM Person")] + [Index("ID")] + public abstract Dictionary SelectAll1(); + + [SqlQuery("SELECT * FROM Person")] + [Index("@PersonID", "LastName")] + public abstract Dictionary SelectAll2(); +} +%> +

Note: if your key has more than one field, the type of this key should be CompoundValue.

+

If the field name starts from '@' symbol, BLToolkit reads the field value from data source, +otherwise from an object property/field.

+ +
ParamNameAttribute
+ +

+By default, the method parameter name should match the stored procedure parameter name. +This attribute specifies the sproc parameter name explicitly. +

+<% cs # +public abstract class PersonAccessor : DataAccessor +{ + public abstract Person SelectByName( + [ParamName("FirstName")] string name1, + [ParamName("@LastName")] string name2); +} +%> + +
ScalarFieldNameAttribute
+ +

+If your method returns a dictionary of scalar values, you will have to specify the name or index of the field +used to populate the scalar list. The ScalarFieldName attribute allows you to do that: +

+<% cs # +public abstract class PersonAccessor : DataAccessor +{ + [SqlQuery("SELECT * FROM Person")] + [Index("@PersonID")] + [ScalarFieldName("FirstName")] + public abstract Dictionary SelectAll1(); + + [SqlQuery("SELECT * FROM Person")] + [Index("PersonID", "LastName")] + [ScalarFieldName("FirstName")] + public abstract Dictionary SelectAll2(); +} +%> + +
ScalarSourceAttribute
+ +

+If a method returns a scalar value, this attribute can be used to specify how database returns this value. +The ScalarSource attribute take a parameter of the ScalarSourceType type: +

+ + + + + + + +
ScalarSourceTypeDescription
DataReaderCalls the DbManager.ExecuteReader method, and then calls IDataReader.GetValue method to read the value.
OutputParameterCalls the DbManager.ExecuteNonQuery method, and then reads value from the IDbDataParameter.Value property.
ReturnValueCalls the DbManager.ExecuteNonQuery method, and then reads return value from command parameter collection.
AffectedRowsCalls the DbManager.ExecuteNonQuery method, and then returns its return value.
+ +
SqlQueryAttribute
+ +

+This attribute allows specifying SQL statement. +

+<% cs # public abstract class PersonAccessor : DataAccessor +{ + [SqlQuery("SELECT * FROM Person WHERE PersonID = @id")] + public abstract Person GetByID(int @id); +} +%> + +

Conclusion

+ +

+I hope this brief tutorial demonstrates one of the simplest, quickest and +most low-maintenance ways to develop your data access layer. In addition, you +will get one more benefit, which is incredible object mapping performance. But +that is a topic we will discuss later. +

diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/NonUpdatable.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/NonUpdatable.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +<% group # SQL text generation control attributes %> + +

+The NonUpdatable attribute indicates the field that should not be updated by UPDATE or INSERT SQL statements. +

+ +NonUpdatable.cs +<% ..\..\..\HowTo\DataAccess\NonUpdatable.cs %> +DataAccessor.Insert method generates and executes the following SQL statement: +<% sql # +INSERT INTO [Person] ( + [MiddleName], + [Gender], + [LastName], + [FirstName] +) VALUES ( + @MiddleName, + @Gender, + @LastName, + @FirstName +) +%> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ObjectType.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ObjectType.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,12 @@ +<% group # Abstract accessor attributes %> + +

+The ObjectType attribute associates an actual type with the type returned by an abstract method. +Note the ActualType attribute has lower priority. +

+ +ActualType.cs +<% ..\..\..\HowTo\DataAccess\ActualType.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/OpenConfig.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/OpenConfig.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +<% title # Open and Configure %> +<% group # Abstract accessors %> + +OpenConfig.cs +<% ..\..\..\HowTo\DataAccess\OpenConfig.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/OpenConfigQuery.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/OpenConfigQuery.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +<% group # SqlQuery & SprocQuery %> +<% title # Open and Configure %> +<% order # 100 %> +

+The SqlQuery and SprocQuery classes can be used to perform simple CRUDL operations +such as SelectByKey, SelectAll, Insert, Update, and Delete. +

+ +OpenConfigQuery.cs +<% ..\..\..\HowTo\DataAccess\OpenConfigQuery.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ParamDbType.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ParamDbType.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +<% group # Abstract accessor attributes %> + +

+The ParamDbType can be used to specify parameter DbType. +

+ +Param.cs +<% ..\..\..\HowTo\DataAccess\Param.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ParamName.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ParamName.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,17 @@ +<% group # Abstract accessor attributes %> + +

+By default, the method parameter name should match the stored procedure parameter name. +The ParamName specifies the sproc parameter name explicitly. +

+ +ParamName.cs +<% ..\..\..\HowTo\DataAccess\ParamName.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ParamNullValue.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ParamNullValue.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +<% group # Abstract accessor attributes %> + +

+The ParamNullValue specifies the parameter value replaced with NULL. +

+ +ParamNullValue.cs +<% ..\..\..\HowTo\DataAccess\ParamNullValue.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ParamSize.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ParamSize.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +<% group # Abstract accessor attributes %> + +

+The ParamSize can be used to specify db parameter size. +

+ +Param.cs +<% ..\..\..\HowTo\DataAccess\Param.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/PrimaryKey.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/PrimaryKey.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,37 @@ +<% group # SQL text generation control attributes %> +

+The PrimaryKey attribute indicates the field that is a part of a primary key. +

+ +PrimaryKey.cs +<% ..\..\..\HowTo\DataAccess\PrimaryKey.cs %> +DataAccessor.SelectByKeySql method generates and executes the following SQL statement: +<% sql # +SELECT + [MiddleName], + [PersonID], + [LastName], + [FirstName] +FROM + [Person] +WHERE + [PersonID] = @PersonID +%> +MultiplePrimaryKey.cs +<% ..\..\..\HowTo\DataAccess\MultiplePrimaryKey.cs %> +In this case DataAccessor.SelectByKeySql method generates and executes the following SQL statement: +<% sql # +SELECT + [MiddleName], + [PersonID], + [LastName], + [FirstName] +FROM + [Person] +WHERE + [FirstName] = @FirstName AND + [LastName] = @LastName +%> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ScalarFieldName.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ScalarFieldName.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,17 @@ +<% group # Abstract accessor attributes %> + +

+If your method returns a dictionary of scalar values, you will have to specify the name or index of the field +used to populate the scalar list. The ScalarFieldName attribute allows you to do that. +

+ +ScalarFieldName.cs +<% ..\..\..\HowTo\DataAccess\ScalarFieldName.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/ScalarSource.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/ScalarSource.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,20 @@ +<% group # Abstract accessor attributes %> + +

+If a method returns a scalar value, this attribute can be used to specify how database returns this value. +The ScalarSource attribute take a parameter of the ScalarSourceType type: + + + + + + + +
ScalarSourceTypeDescription
DataReaderCalls the DbManager.ExecuteReader method, and then calls IDataReader.GetValue method to read the value.
OutputParameterCalls the DbManager.ExecuteNonQuery method, and then reads value from the IDbDataParameter.Value property.
ReturnValueCalls the DbManager.ExecuteNonQuery method, and then reads return value from command parameter collection.
AffectedRowsCalls the DbManager.ExecuteNonQuery method, and then returns its return value.
+

+ +ScalarSource.cs +<% ..\..\..\HowTo\DataAccess\ScalarSource.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/SelectAll.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/SelectAll.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +<% group # Basic CRUDL operations and stored procedures %> +<% order # 201 %> + +SelectAll.cs +<% ..\..\..\HowTo\DataAccess\SelectAll.cs %> +DataAccessor.SelectAll method generates and executes the following SQL statement: +<% sql # exec Person_SelectAll %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/SelectAllSql.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/SelectAllSql.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,23 @@ +<% group # Basic CRUDL operations and SQL text generation %> +<% order # 151 %> + +SelectAllSql.cs +<% ..\..\..\HowTo\DataAccess\SelectAllSql.cs %> +DataAccessor.SelectAllSql method generates and executes the following SQL statement: +<% sql # +SELECT + [MiddleName], + [PersonID], + [LastName], + [FirstName] +FROM + [Person] +%> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/SelectByKey.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/SelectByKey.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +<% group # Basic CRUDL operations and stored procedures %> +<% order # 200 %> + +SelectByKey.cs +<% ..\..\..\HowTo\DataAccess\SelectByKey.cs %> +DataAccessor.SelectByKet method generates and executes the following SQL statement: +<% sql # exec Person_SelectByKey @id=1 %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/SelectByKeySql.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/SelectByKeySql.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +<% group # Basic CRUDL operations and SQL text generation %> +<% order # 150 %> + +SelectByKeySql.cs +<% ..\..\..\HowTo\DataAccess\SelectByKeySql.cs %> +DataAccessor.SelectByKetSql method generates and executes the following SQL statement: +<% sql # +SELECT + [MiddleName], + [PersonID], + [LastName], + [FirstName] +FROM + [Person] +WHERE + [PersonID] = @PersonID +%> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/SprocName.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/SprocName.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +<% group # Abstract accessor attributes %> + +

+The SprocName attribute allows assigning a stored procedure name explicitly. +

+ +SprocName.cs +<% ..\..\..\HowTo\DataAccess\SprocName.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/SqlQuery.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/SqlQuery.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,16 @@ +<% group # Abstract accessor attributes %> + +

+The SqlQuery attribute allows specifying SQL statement. +

+ +SqlQuery.cs +<% ..\..\..\HowTo\DataAccess\SqlQuery.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/TableName.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/TableName.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +<% group # SQL text generation control attributes %> +

+The TableName attribute specifies a name of the table represented by the decorated object. +

+ +TableName.cs +<% ..\..\..\HowTo\DataAccess\TableName.cs %> +DataAccessor.SelectByKeySql and DataAccessor.SelectByKey methods generate and execute the following SQL statement: +<% sql # +-- SelectByKeySql +SELECT + [MiddleName], + [PersonID], + [LastName], + [FirstName] +FROM + [Person] +WHERE + [PersonID] = @PersonID + +-- SelectByKey +exec Person_SelectByKey @id=1 +%> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/Transaction.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/Transaction.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,13 @@ +<% title # Transactions %> +<% group # Abstract accessors %> + +Transaction.cs +<% ..\..\..\HowTo\DataAccess\Transaction.cs %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/Update.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/Update.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,15 @@ +<% group # Basic CRUDL operations and stored procedures %> +<% order # 203 %> + +Update.cs +<% ..\..\..\HowTo\DataAccess\Update.cs %> +DataAccessor.Update method generates and executes the following SQL statement: +<% sql # exec Person_Update @PersonID=2, @FirstName='Crazy', @LastName='Frog', @MiddleName='', @Gender='O' %> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/UpdateSql.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/UpdateSql.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +<% group # Basic CRUDL operations and SQL text generation %> +<% order # 153 %> + +UpdateSql.cs +<% ..\..\..\HowTo\DataAccess\UpdateSql.cs %> +DataAccessor.UpdateSql method generates and executes the following SQL statement: +<% sql # +UPDATE + [Person] +SET + [MiddleName] = @MiddleName, + [Gender] = @Gender, + [LastName] = @LastName, + [FirstName] = @FirstName +WHERE + [PersonID] = @PersonID +%> + +Person.cs +<% ..\..\..\HowTo\DataAccess\Person.cs %> +Gender.cs +<% ..\..\..\HowTo\DataAccess\Gender.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/XmlExtension.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/XmlExtension.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +<% group # SQL text generation control attributes %> +

+BLToolkit supports different ways to provide metadata information for business objects. +One of the ways is using attributes. Another one is XmlExtension. +XmlExtension is a simple xml file where you can specify a type and its attributes. +

+ +XmlExtension.cs +<% ..\..\..\HowTo\DataAccess\XmlExtension.cs %> +XmlExtension.xml +<% ..\..\..\HowTo\DataAccess\XmlExtension.xml %> +DataAccessor.SelectByKetSql method generates and executes the following SQL statement: +<% sql # +SELECT + [MiddleName], + [PersonID], + [LastName], + [FirstName] +FROM + [Person] +WHERE + [PersonID] = @PersonID +%> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/DataAccess/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/DataAccess/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,47 @@ + + + + +Abstract accessors. +How to open and configure data accessors. + + +Abstract accessor example. +DataAccessor + List. +DataAccessor + Dictionary. +DataAccessor + business objects. +DataAccessor + scalar values. + +Abstract accessor attributes. + + + + + + + + +SqlQuery & SprocQuery +How to open and configure SqlQuery & SprocQuery. + +Basic CRUDL operations and SQL text generation. +Reads a record by Primary Key. +Reads all records from specified table. +Inserts a new record. +Updates a record. +Deletes a record either by Primary Key or by provided object. + +Basic CRUDL operations and stored procedures. +Reads a record by Primary Key. +Reads all records from specified table. +Inserts a new record. +Updates a record. +Deletes a record either by Primary Key or by provided object. + +SQL text generation control attributes. + + + + + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/EditableObjects/AcceptRejectChanges.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/EditableObjects/AcceptRejectChanges.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +<% title # Accept and Reject changes %> +<% order # 2 %> +

+After verifying the accuracy of changes made to the object, you can accept the changes +using the AcceptChanges method of the object, which will set the Current field values +to be the Original values. The RejectChanges method rejects all changes made to the object +since AcceptChanges was last called. +

+ +AcceptRejectChanges.cs +<% ..\..\..\HowTo\EditableObjects\AcceptRejectChanges.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/EditableObjects/EditableObject.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/EditableObjects/EditableObject.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,119 @@ +[BLToolkitGenerated] +public sealed class TestObject : EditableObjectTest.TestObject, IEditable, IMemberwiseEditable, IPrintDebugState +{ + // Note that the internal representation of the properties is EditableValue. + // The EditableValue class provides a mechanism to keep and control the field value state. + // + private /*[a]*/EditableValue/*[/a]*/ _firstName; + private /*[a]*/EditableValue/*[/a]*/ _lastName; + + // PropertyInfo is used for internal purposes. + // + private static PropertyInfo _firstName_propertyInfo = + TypeHelper.GetPropertyInfo(typeof(EditableObjectTest.TestObject), "FirstName", typeof(string), Type.EmptyTypes); + private static PropertyInfo _lastName_propertyInfo = + TypeHelper.GetPropertyInfo(typeof(EditableObjectTest.TestObject), "LastName", typeof(string), Type.EmptyTypes); + + // Constructors. + // + public TestObject() + { + this._firstName = new EditableValue(""); + this._lastName = new EditableValue(""); + } + + public TestObject(InitContext ctx) + { + this._firstName = new EditableValue(""); + this._lastName = new EditableValue(""); + } + + // Abstract property implementation. + // + public override string FirstName + { + get + { + return _firstName./*[a]*/Value/*[/a]*/; + } + + set + { + _firstName./*[a]*/Value/*[/a]*/ = value; + + // The PropertyChanged event support. + // + ((IPropertyChanged)this)./*[a]*/OnPropertyChanged/*[/a]*/(_firstName_propertyInfo); + } + } + + public override string LastName + { + get + { + return _lastName./*[a]*/Value/*[/a]*/; + } + + set + { + _lastName./*[a]*/Value/*[/a]*/ = value; + ((IPropertyChanged)this)./*[a]*/OnPropertyChanged/*[/a]*/(_lastName_propertyInfo); + } + } + + // The IEditable interface implementation. + // + bool IEditable.IsDirty + { + get { return _firstName.IsDirty || _lastName.IsDirty; } + } + + void IEditable.AcceptChanges() + { + this._firstName.AcceptChanges(); + this._lastName. AcceptChanges(); + } + + void IEditable.RejectChanges() + { + this._firstName.RejectChanges(); + this._lastName. RejectChanges(); + } + + // The IMemberwiseEditable interface implementation. + // + bool IMemberwiseEditable.AcceptMemberChanges(PropertyInfo propertyInfo, string memberName) + { + return + _firstName.AcceptMemberChanges(_firstName_propertyInfo, memberName) || + _lastName. AcceptMemberChanges(_lastName_propertyInfo, memberName); + } + + void IMemberwiseEditable.GetDirtyMembers(PropertyInfo propertyInfo, ArrayList list) + { + _firstName.GetDirtyMembers(_firstName_propertyInfo, list); + _lastName. GetDirtyMembers(_lastName_propertyInfo, list); + } + + bool IMemberwiseEditable.IsDirtyMember(PropertyInfo propertyInfo, string memberName, ref bool isDirty) + { + return + _firstName.IsDirtyMember(_firstName_propertyInfo, memberName, ref isDirty) || + _lastName. IsDirtyMember(_lastName_propertyInfo, memberName, ref isDirty); + } + + bool IMemberwiseEditable.RejectMemberChanges(PropertyInfo propertyInfo, string memberName) + { + return + _firstName.RejectMemberChanges(_firstName_propertyInfo, memberName) || + _lastName. RejectMemberChanges(_lastName_propertyInfo, memberName); + } + + // The IPrintDebugState interface implementation. + // + void IPrintDebugState.PrintDebugState(PropertyInfo propertyInfo, ref string str) + { + _firstName.PrintDebugState(_firstName_propertyInfo, ref str); + _lastName. PrintDebugState(_lastName_propertyInfo, ref str); + } +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/EditableObjects/EditableObject.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/EditableObjects/EditableObject.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,26 @@ +<% title # EditableObject class %> +<% order # 1 %> +

+EditableObject is an object that provides functionality to commit and rollback changes to itself. +After verifying the accuracy of changes made to the object, you can accept the changes +using the AcceptChanges method of the object, which will set the Current field values +to be the Original values. The RejectChanges method rejects all changes made to the object +since AcceptChanges was last called. The IsDirty property gets a value that indicates +whether the object has changed. +

+

+If we wrote an editable object manually, we could get the following code just for two editable properties: +

+<% Doc\EditableObjects\ManualEditableObject.cs %> + +

+BLToolkit allows implementing the same functionality by inheriting your object +from the BLToolkit EditableObject base class and replacing editable members with abstract properties. +

+EditableObjectTest.cs +<% ..\..\..\HowTo\EditableObjects\EditableObjectTest.cs %> + +

+BLToolkit type builder will generate the following for the class above: +

+<% Doc\EditableObjects\EditableObject.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/EditableObjects/IsDirty.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/EditableObjects/IsDirty.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ +<% title # IsDirty flag %> +<% order # 3 %> +

+The IsDirty property gets a value that indicates whether the object has changed. +

+ +IsDirty.cs +<% ..\..\..\HowTo\EditableObjects\IsDirty.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/EditableObjects/ManualEditableObject.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/EditableObjects/ManualEditableObject.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,108 @@ +public class TestObject : INotifyPropertyChanged +{ + // The FirstName editable property. + // + private string _originalFirstName; + private string _currentFirstName; + + public override string FirstName + { + get { return _currentFirstName; } + set + { + _currentFirstName = value; + OnPropertyChanged("FirstName"); + } + } + + bool IsFirstNameDirty + { + get { return _currentFirstName != _originalFirstName; } + } + + void AcceptFirstNameChange() + { + if (IsFirstNameDirty) + { + _originalFirstName = _currentFirstName; + OnPropertyChanged("FirstName"); + } + } + + void RejectFirstNameChange() + { + if (IsFirstNameDirty) + { + _currentFirstName = _originalFirstName; + OnPropertyChanged("FirstName"); + } + } + + // The LastName editable property. + // + private string _originalLastName; + private string _currentLastName; + + public override string LastName + { + get { return _currentLastName; } + set + { + _currentLastName = value; + OnPropertyChanged("LastName"); + } + } + + bool IsLastNameDirty + { + get { return _currentLastName != _originalLastName; } + } + + void AcceptLastNameChange() + { + if (IsLastNameDirty) + { + _originalLastName = _currentLastName; + OnPropertyChanged("LastName"); + } + } + + void RejectLastNameChange() + { + if (IsLastNameDirty) + { + _currentLastName = _originalLastName; + OnPropertyChanged("LastName"); + } + } + + // Common members. + // + public bool IsDirty + { + get + { + return IsFirstNameChange || IsLastNameChange; + } + } + + public void AcceptChanges() + { + AcceptFirstNameChange(); + AcceptLastNameChange(); + } + + public void RejectChanges() + { + RejectFirstNameChange(); + RejectLastNameChange(); + } + + public virtual event PropertyChangedEventHandler PropertyChanged; + + protected virtual void OnPropertyChanged(string propertyName) + { + if (PropertyChanged != null) + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/EditableObjects/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/EditableObjects/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,32 @@ +

+The EditableObjects namespace contains classes that can help you to make your object model editable. +That means your objects will support the following list of standard and BLToolkit interfaces: + + + + + + + + + + + + + + + + + + + +
for business objects
namespaceinterface
System.ComponentModelIEditableObject
System.ComponentModelINotifyPropertyChanged
System.ComponentModelICustomTypeDescriptor
SystemICloneable
BLToolkit.ComponentModelINotifyObjectEdit
BLToolkit.EditableObjectsIEditable
BLToolkit.ValidationIValidatable
for collections
namespaceinterface
System.ComponentModelITypedList
System.ComponentModelIBindingList
System.ComponentModelIBindingListView
System.ComponentModelICancelAddNew
BLToolkit.ComponentModelISortable
BLToolkit.EditableObjectsIEditable
+

+ + + + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Mapping/EnumToValue.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Mapping/EnumToValue.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2 @@ +EnumToValue.cs +<% ..\..\..\HowTo\Mapping\EnumToValue.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Mapping/MapFieldAttribute.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Mapping/MapFieldAttribute.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,9 @@ +Note that the mapper tries to convert the source values to their destination types.
+
+ObjectToObject.cs +<% ..\..\..\HowTo\Mapping\ObjectToObject.cs %> +To map data to inner objects the MapField attribute can be used in the following way: +
+
+MapFieldAttribute.cs +<% ..\..\..\HowTo\Mapping\MapFieldAttribute.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Mapping/MapToJson.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Mapping/MapToJson.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2 @@ +MapToJson.cs +<% ..\..\..\HowTo\Mapping\MapToJson.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Mapping/MapValueAttribute.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Mapping/MapValueAttribute.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ +MapValueAttribute1.cs +<% ..\..\..\HowTo\Mapping\MapValueAttribute1.cs %> +MapValueAttribute2.cs +<% ..\..\..\HowTo\Mapping\MapValueAttribute2.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Mapping/ObjectToObject.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Mapping/ObjectToObject.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,4 @@ +Note that the mapper tries to convert the source values to their destination types.
+
+ObjectToObject.cs +<% ..\..\..\HowTo\Mapping\ObjectToObject.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Mapping/ValueToEnum.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Mapping/ValueToEnum.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2 @@ +ValueToEnum.cs +<% ..\..\..\HowTo\Mapping\ValueToEnum.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Mapping/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Mapping/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,17 @@ + + +How to map DB source to object. +How to map object to object. + +Enumerator mapping. +How to map enumerator to value. +How to map value to enumerator. + +Mapping attributes. + + + +Custom mapping. + + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Reflection/Emit/HelloWorld.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Reflection/Emit/HelloWorld.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,27 @@ +

The System.Reflection.Emit namespace provides classes to create dynamic assemblies at runtime. +It allows compilers and tools to emit MSIL, execute it and store it to a disk. +Although Emit is a powerful tool, it is also extremely hard to use.

+

Let us take a look at the following example, which demonstrates the "normal" way of emit programming:

+ +HelloWorld.cs +<% ..\..\..\Examples\CS\Reflection.Emit\HelloWorldnormal.cs %> + +

Note that the Emit method takes one parameter as an OpCode and optionally another one, +which does not depend on the current operation context. So, this way is not entirely type safe.

+ +

Fortunately, there is an alternative way. BLToolkit provides a helper class, +EmitHelper, +which can make your life a little bit easy. +It contains typed wrapper methods for almost all emit commands and allows writing source code +that looks similar to MSIL.

+

The following examples show how to use the EmitHelper class with C#, VB.NET, and C++/CLI.

+ +HelloWorld.cs +<% ..\..\..\Examples\CS\Reflection.Emit\HelloWorld.cs %> +Cool!!! Isn't it?

+ +HelloWorld.vb +<% ..\..\..\Examples\VB\Reflection.Emit\HelloWorld.vb %> + +HelloWorld.cpp +<% ..\..\..\Examples\Cpp\HelloWorld.cpp %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Reflection/Emit/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Reflection/Emit/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,5 @@ + + +EmitHelper in action. + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Reflection/ObjectFactory.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Reflection/ObjectFactory.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,19 @@ +

+The following example shows how to create objects of different types coming from the same data source. +

+

+Typically, to create an object, BLToolkit calls the TypeAccessor.CreateInstanceEx method. +First of all, this method verifies if there is an object factory (ObjectFactory property) +associated with the creating objects type. +If the property value is not null, it is used to create an object. +

+

+The ObjectFactory property can be assigned explicitly at any time or +by decorating the target class with the ObjectFactory attribute. +

+ +ObjectFactory.cs +<% ..\..\..\HowTo\Reflection\ObjectFactory.cs %> +App.config +<% Doc\Data\App.config %> +Create.sql script diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Reflection/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Reflection/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,7 @@ + + + + + + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/TypeBuilder/InitialValues.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/TypeBuilder/InitialValues.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2 @@ +InitialValues.cs +<% ..\..\..\HowTo\TypeBuilder\InitialValues.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/TypeBuilder/InternalTypes.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/TypeBuilder/InternalTypes.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2 @@ +InternalTypes.cs +<% ..\..\..\HowTo\TypeBuilder\InternalTypes.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/TypeBuilder/XmlSerialization.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/TypeBuilder/XmlSerialization.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,2 @@ +XmlSerialization.cs +<% ..\..\..\HowTo\TypeBuilder\XmlSerialization.cs %> diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/TypeBuilder/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/TypeBuilder/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,8 @@ + + +Abstract types. +How to specify initial value for an abstract property. +How to use internal abstract types. +How to serialize an abstract type to xml. + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/Validation/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/Validation/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,1 @@ + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Doc/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Doc/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,14 @@ +<% title # Documentation %> + + + + + + + + + + + + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Download.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Download.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,28 @@ +

+Download one of the following zip-files. Unzip it. Add either BLToolkit.2.csproj (FW 2.0: VS 2005, VS 2008) or +BLToolkit.3.csproj (FW 3.5: VS 2008) project into your solution. Add project references where you need it. +Compile. Enjoy. +

+ + + +Version 3.1 +Source code +Full dev version + +Current SVN working copy +SVN checkout source code +SVN checkout full dev version + +Current SVN snapshot +Source code +Full dev version +Binaries + + + +
+ChangeLog.txt +
+<% ..\..\..\Source\Doc\ChangeLog.txt %>
+
diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/Home.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/Home.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,29 @@ +

+Business Logic Toolkit is a set of components to simplify .NET application development. +BLToolkit is provided as source code that you can use "as is" +or customize for your applications. +It is written in C# and compatible with .NET Framework 2.0, 3.0, and 3.5. +

+ + + +Version 3.1 +Source code +Full dev version + +Current SVN working copy +SVN checkout source code +SVN checkout full dev version + +Current SVN snapshot +Source code +Full dev version +Binaries + + + +
+ChangeLog.txt +
+<% ..\..\..\Source\Doc\ChangeLog.txt %>
+
diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/License.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/License.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,25 @@ +

BLToolkit is licensed under MIT License:

+ +
+ +

Copyright © 2010 www.bltoolkit.net

+ +

Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions:

+ +

The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software.

+ +

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE.

+
+
diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/WebTemplate.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/WebTemplate.html Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,57 @@ + + + {3}Business Logic Toolkit for .NET + + + +Business Logic Toolkit for .NET
+www.bltoolkit.net + + + + +
+ +|  Home   +|  Download   +|  Documentation   +|  Discussions   +|  License   +| + +
{2} +
+ + + + + + +
  +{0} + 
+ + + + +
+ +© 2010 www.bltoolkit.net
+support@bltoolkit.net +
+
+ +
+ + + + + + \ No newline at end of file diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/bltoolkit.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/bltoolkit.css Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,190 @@ +body +{ + background : White; + font-family : Verdana; + font-size : .80em; +} + +a:link { text-decoration: none; color : #338899; } +a:visited { text-decoration: none; color : #55AABB; } +a:hover { text-decoration: underline; color : #338899; } + +a.m:link { text-decoration: underline; color : Black; } +a.m:visited { text-decoration: underline; color : Black; } +a.m:hover { text-decoration: underline; color : Black; } + +.title +{ + font-size : 1.75em; + color : #116677; + font-family : Arial; +} + +.homeurl +{ + color : #338899; +} + +.hr +{ + height : 1px; + background-color : #338899; +} + +.sp +{ + height : 7px; +} + +th +{ + font-size : .80em; + vertical-align : top; + background-color : #EEEEEE; + text-align : center; +} + +td +{ + font-size : .80em; + vertical-align : top; +} + +td.p +{ + font-size : .80em; + vertical-align : top; + padding-top : 7px; +} + +td.pj +{ + font-size : .80em; + vertical-align : top; + padding-top : 7px; + text-align : justify; +} + +.j +{ + text-align : justify; +} + +.kw +{ + color : blue; +} + +.com +{ + color : green; +} + +.str +{ + color : DarkCyan; +} + +.a +{ + color : DarkRed; + font-weight : bold; + text-decoration : underline; +} + +table.code +{ + border-color : #116677; + border-style : solid; + border-width : 1px; + margin-top : .6em; + margin-bottom : .6em; + background-color : #F7F7F7; +} + +pre.code +{ + font : 120% Consolas, Monospace, Courier New, Courier; + margin : 0; + padding : 5px; +} + +.j pre.code, .pj pre.code +{ + font : 80% Consolas, Monospace, Courier New, Courier; + margin : 0; + padding : 3px; +} + +.j table.code, .pj table.code +{ + margin-top : .4em; + margin-bottom : .0em; +} + +a.rss +{ + color : White; + background-color : DarkOrange; + font-weight : bold; + font-size : .80em; + font-family : Arial; +} + +table.data +{ + margin: 10px 7px 10px 7px; +} + +.data td, .data th +{ + padding: 2px 5px 2px 5px; +} + +.bordered td, .bordered th +{ + border-color: #AAAAAA; + border-style: solid; + border-width: 1px; +} + +.nowrappable td, .nowrappable th +{ + white-space: nowrap; +} + +a.rss:link { text-decoration: none; color : White; } +a.rss:visited { text-decoration: none; color : White; } +a.rss:hover { text-decoration: nonr; color : White; } + +h4, h5 +{ + font-family : Verdana; + color : #338899; +} + +.data table.code +{ + border-style : none; + margin : 0; + padding : 0; + background : #FFFFFF; +} + +.data pre.code +{ + padding : 0; + padding : 0; +} + +.code td, .code th +{ + border-style: none; +} + +td.nosup +{ + font-weight: bold; + color : Red; + text-align : center; +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/index.htm Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,113 @@ +
+Business Logic Toolkit is a set of components to simplify .NET application development. +BLToolkit is provided as source code that you can use "as is" or customize for your applications. +It is written in C# and compatible with .NET Framework 2.0, 3.0, and 3.5.

+
+ + + + + + + + + + +
+<% rss # rss.xml %> +
+  RSS   +
     + + +CacheAspect, CounterAspect, LoggingAspect, MixinAttribute. All of these are available now in C# (well, with one little limitation). +<% cs # +[/*[a]*/Counter/*[/a]*/, /*[a]*/Log/*[/a]*/] +public /*[a]*/abstract/*[/a]*/ class MyClass +{ + [/*[a]*/Cache/*[/a]*/] + public /*[a]*/virtual/*[/a]*/ int MyMethod(int p1, int p2) + { +%> + +Object Binder. Add Business Objects' native purity and flexibility to your ASP.NET and WinForms applications. + +High-level, data provider independent wrapper for ADO.NET. +<% cs # +using (DbManager db = new DbManager()) +{ + return db + .SetCommand("SELECT * FROM Person") + .ExecuteList(); +%> + + +Data Access Layer. Got bored of writing the same data access code over and over again? Now you are saved from being just a coding machine! +<% cs # +public /*[a]*/abstract/*[/a]*/ class PersonAccessor : /*[a]*/DataAccessor/*[/a]*/ +{ + [/*[a]*/SqlText/*[/a]*/(@"SELECT * FROM Person WHERE FirstName = @firstName")] + public /*[a]*/abstract/*[/a]*/ List GetPersonListByFirstName(string @firstName); + + [/*[a]*/SprocName/*[/a]*/("sp_GetPersonListByLastName")] + public /*[a]*/abstract/*[/a]*/ List GetPersonListByLastName(string @lastName); +%> + + +Set of base classes to build custom object hierarchies. The EditableObject and EditableList classes support such methods as AcceptChanges, RejectChanges, flag IsDirty, and event PropertyChanged. +<% cs # +public /*[a]*/abstract/*[/a]*/ class TestObject : /*[a]*/EditableObject/*[/a]*/ +{ + public /*[a]*/abstract/*[/a]*/ string FirstName { get; set; } + public /*[a]*/abstract/*[/a]*/ string LastName { get; set; } +} + +... + +TestObject obj = TestObject./*[a]*/CreateInstance/*[/a]*/(); +obj.FirstName = "Tester"; +obj.AcceptChanges(); +%> + +High performance object mapper will help you build your own ORM. +The TypeAccessor class allows to avoid slowness of Reflection and gain incredible performance of applications working with types dynamically. + +The EmitHelper class - emit with a human face. +<% cs # +emit + // string.Format("Hello, {0}!", toWhom) + // + ./*[a]*/ldstr/*[/a]*/ ("Hello, {0}!") + ./*[a]*/ldarg_1/*[/a]*/ + ./*[a]*/call/*[/a]*/ (typeof(string), "Format", typeof(string), typeof(object)) + + // Console.WriteLine("Hello, World!"); + // + ./*[a]*/call/*[/a]*/ (typeof(Console), "WriteLine", typeof(string)) + ./*[a]*/ret/*[/a]*/() + ; +%> + +Extensible run-time class generator. +Simple way to do a complex thing. + +
+
+
+ +
+ + +
+ +Google + + + + +
Search WWW Search bltoolkit.net +
+
+ +
+ diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/robots.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/robots.txt Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,3 @@ +User-Agent: * +Disallow: /Source/ +Allow: / diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Content/rss.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Content/rss.xml Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,115 @@ + + + + Business Logic Toolkit for .NET + http://www.bltoolkit.net + + 2009-01-11 + + Version 3.1 released + http://www.bltoolkit.net/Download.htm + See <a href="http://www.bltoolkit.net/Download.htm">change log</a> + 2009-01-11 + + + Version 3.0 released + http://www.bltoolkit.net/Download.htm + See <a href="http://www.bltoolkit.net/Download.htm">change log</a> + 2008-05-21 + + + New examples + http://www.bltoolkit.net/Doc/ + See the following <a href="http://www.bltoolkit.net/Doc/">link</a> + 2008-05-10 + + + Version 2.0.7 released + http://www.bltoolkit.net/Download.htm + See <a href="http://www.bltoolkit.net/Download.htm">change log</a> + 2008-02-12 + + + New web demo project + http://www.bltoolkit.net/Download.htm + MS PetShop 4.0 powered by BLToolkit. See the dev version of the project. + 2007-07-21 + + + Version 2.0.6 released + http://www.bltoolkit.net/Download.htm + See <a href="http://www.bltoolkit.net/Download.htm">change log</a> + 2007-07-21 + + + How to map into internal object + http://www.bltoolkit.net/Doc/Mapping/MapFieldAttribute.htm + + <a href="http://www.bltoolkit.net/Doc/Mapping/MapFieldAttribute.htm">Map.MapFieldAttribute</a> + + Examples + 2007-06-05 + + + Version 2.0.5 released + http://www.bltoolkit.net/Download.htm + See <a href="http://www.bltoolkit.net/Download.htm">change log</a> + 2007-05-17 + + + Version 2.0.4 released + http://www.bltoolkit.net/Download.htm + See <a href="http://www.bltoolkit.net/Download.htm">change log</a> + 2007-02-12 + + + Version 2.0.3 released + http://www.bltoolkit.net/Download.htm + See <a href="http://www.bltoolkit.net/Download.htm">change log</a> + 2006-10-22 + + + Version 2.0.1 released + http://www.bltoolkit.net/Download.htm + + 2006-08-27 + + + How to map one object to another + http://www.bltoolkit.net/Doc/Mapping/ObjectToObject.htm + + <a href="http://www.bltoolkit.net/Doc/Mapping/ObjectToObject.htm">Map.ObjectToObject</a> + + Examples + 2006-05-21 + + + How to emit with BLToolkit + http://www.bltoolkit.net/Doc/Reflection/Emit/HelloWorld.htm + + <a href="http://www.bltoolkit.net/Doc/Reflection/Emit/HelloWorld.htm">Hello, World!</a> + + Examples + 2006-05-10 + + + DataAccessor examples + http://www.bltoolkit.net/Doc/DataAccess/index.htm + + <a href="http://www.bltoolkit.net/Doc/DataAccess/ExecuteList.htm">ExecuteList</a><br> + <a href="http://www.bltoolkit.net/Doc/DataAccess/ExecuteDictionary.htm">ExecuteDictionary</a><br> + <a href="http://www.bltoolkit.net/Doc/DataAccess/ExecuteObject.htm">ExecuteObject</a><br> + <a href="http://www.bltoolkit.net/Doc/DataAccess/ExecuteScalar.htm">ExecuteScalar</a> + + Examples + 2006-04-30 + + + IDictionary support for abstract accessors + http://www.bltoolkit.net/Doc/DataAccess/ExecuteDictionary.htm + Now abstract accessor can return an object that implemens IDictionary interface. + Features + 2006-04-26 + + + diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/DocGen.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/DocGen.sln Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebGen", "WebGen.csproj", "{06353283-C802-4706-BB18-5BBC49B03D59}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChmGen", "ChmGen.csproj", "{23AD6408-9310-4D0F-B461-C590EAF82868}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "_Content", "_Content.csproj", "{DE11BCB2-94A1-4691-9192-5FC8E0323E2E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {06353283-C802-4706-BB18-5BBC49B03D59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {06353283-C802-4706-BB18-5BBC49B03D59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {06353283-C802-4706-BB18-5BBC49B03D59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {06353283-C802-4706-BB18-5BBC49B03D59}.Release|Any CPU.Build.0 = Release|Any CPU + {23AD6408-9310-4D0F-B461-C590EAF82868}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {23AD6408-9310-4D0F-B461-C590EAF82868}.Debug|Any CPU.Build.0 = Debug|Any CPU + {23AD6408-9310-4D0F-B461-C590EAF82868}.Release|Any CPU.ActiveCfg = Release|Any CPU + {23AD6408-9310-4D0F-B461-C590EAF82868}.Release|Any CPU.Build.0 = Release|Any CPU + {DE11BCB2-94A1-4691-9192-5FC8E0323E2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE11BCB2-94A1-4691-9192-5FC8E0323E2E}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/FileAction.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/FileAction.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,11 @@ +using System; + +namespace DocGen +{ + enum FileAction + { + Skip, + Copy, + Process + } +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/FileItem.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/FileItem.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; + +namespace DocGen +{ + class FileItem + { + public bool IsFile; + public string Name; + public List Items; + public FileItem Parent; + public string Group; + public List Indexes = new List(); + public List NoIndexes = new List(); + public bool NoIndex; + + private string _title; + public string Title + { + get { return _title ?? System.IO.Path.GetFileNameWithoutExtension(Name); } + set { _title = value; } + } + + private int _sortOrder; + public int SortOrder + { + get + { + if (_sortOrder == 0 && Items != null) + return Items[0].SortOrder; + + return _sortOrder; + } + + set { _sortOrder = value; } + } + + public string Path + { + get + { + return Name.Replace(Program.destPath, "").Replace("\\", "/"); + } + } + + public IEnumerable GetFiles() + { + if (Items != null) + { + foreach (var item in Items) + { + if (item.IsFile) + yield return item; + + if (item.Items != null) + foreach (var i in item.GetFiles()) + yield return i; + } + } + } + + public void Add(FileItem item) + { + item.Parent = this; + + if (Items == null) + Items = new List(); + + Items.Add(item); + } + + public void Prepare() + { + if (Items != null) + { + var groups = new List(); + + for (var i = 0; i < Items.Count; i++) + { + var item = Items[i]; + + if (item.Group != null && item.Group != Name) + { + var group = groups.Find(file => file.Name == item.Group); + + if (group == null) + groups.Add(group = new FileItem { Name = item.Group, SortOrder = item.SortOrder }); + + group.Add(item); + Items.RemoveAt(i); + + i--; + } + } + + Items.AddRange(groups); + + foreach (var item in Items) + item.Prepare(); + + Items.Sort((x, y) => + { + var xname = x.Title.ToLower(); + var yname = y.Title.ToLower(); + + if (xname == yname) return 0; + if (x.Name.ToLower().EndsWith("index.htm")) return -1; + if (y.Name.ToLower().EndsWith("index.htm")) return 1; + + if (x.SortOrder != 0 && y.SortOrder != 0) + return x.SortOrder - y.SortOrder; + + if (x.SortOrder != 0) return -1; + if (y.SortOrder != 0) return 1; + + return string.Compare(xname, yname); + }); + } + } + } +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Generator.Chm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Generator.Chm.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +using System; + +namespace DocGen +{ + partial class Generator + { + const bool _addDashToTitle = false; + const bool _modifySourceLinks = true; + } +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Generator.Web.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Generator.Web.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,10 @@ +using System; + +namespace DocGen +{ + partial class Generator + { + const bool _addDashToTitle = true; + const bool _modifySourceLinks = false; + } +} diff -r 000000000000 -r f990fcb411a9 Tools/DocGen/Generator.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/DocGen/Generator.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,663 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using System.Xml; + +using Rsdn.Framework.Formatting; + +namespace DocGen +{ + delegate FileAction FileActionHandler(string ext); + + partial class Generator + { + string _sourcePath; + string _destFolder; + FileActionHandler _fileAction; + + public void Generate( + FileItem createdFiles, + string templateFileName, + string[] path, + string destFolder, + string sourcePath, + bool cleanUp, + bool createIndex, + FileActionHandler fileAction) + { + _sourcePath = Path.GetFullPath(sourcePath); + _destFolder = Path.GetFullPath(destFolder); + _fileAction = fileAction; + + if (cleanUp) + CleanUp(); + + CreateDestFolder(); + + var template = File.ReadAllText(templateFileName); + + GenerateContent(createdFiles, template, path, createIndex); + } + + private void CreateDestFolder() + { + if (Directory.Exists(_destFolder) == false) + Directory.CreateDirectory(_destFolder); + } + + private void CleanUp() + { + if (Directory.Exists(_destFolder) == false) + return; + + Action clean = null; clean = delegate(string path) + { + foreach (var file in Directory.GetFiles(path)) + if (Path.GetExtension(file).ToLower() != ".zip") + try { File.Delete(file); } catch {} + + foreach (var dir in Directory.GetDirectories(path)) + { + clean(dir); + try { Directory.Delete(dir); } catch {} + } + }; + + clean(_destFolder); + } + + static readonly Regex ct_item1 = new Regex(@".*?)\s*label=['""](?