diff --git a/CS.sln b/CS.sln new file mode 100644 index 0000000..5e77c66 --- /dev/null +++ b/CS.sln @@ -0,0 +1,253 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CodeBehind", "CodeBehind", "{21D36955-95DF-189F-F462-3EA64FE19AA5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ViewModel", "ViewModel", "{6F543814-7740-FC98-73A5-CC0A913546B8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EFCore", "EFCore", "{183ED980-C32E-C675-E55D-281EBAB34CB4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EntityFramework", "EntityFramework", "{E304686B-213A-3A36-A534-4EE68562656A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "XPO", "XPO", "{BA298011-020E-89D7-9A29-3E4378A90301}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EFCore", "EFCore", "{8E928C27-5585-9913-8FA6-24A164DF3179}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EntityFramework", "EntityFramework", "{9130DE36-C8E7-253F-F380-218962E462D9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "XPO", "XPO", "{2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfiniteAsyncSource", "CS\CodeBehind\EFCore\InfiniteAsyncSource\InfiniteAsyncSource.csproj", "{B7E6D722-D306-C409-A1F5-6AEAFB21A281}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantFeedbackMode", "CS\CodeBehind\EFCore\InstantFeedbackMode\InstantFeedbackMode.csproj", "{2138333B-751D-1786-5AB5-04A2980BC1D6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalData", "CS\CodeBehind\EFCore\LocalData\LocalData.csproj", "{47801E06-424B-AAF6-B81A-3A255896EBF7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagedAsyncSource", "CS\CodeBehind\EFCore\PagedAsyncSource\PagedAsyncSource.csproj", "{ADFA4798-6BAA-6967-F813-89F0229D1B96}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerMode", "CS\CodeBehind\EFCore\ServerMode\ServerMode.csproj", "{87473A0C-89A5-1C21-97E7-6F40ACD3C060}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfiniteAsyncSource", "CS\CodeBehind\EntityFramework\InfiniteAsyncSource\InfiniteAsyncSource.csproj", "{15015E00-900F-7BBE-4987-3CFC3042F716}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantFeedbackMode", "CS\CodeBehind\EntityFramework\InstantFeedbackMode\InstantFeedbackMode.csproj", "{BA2F5788-A3EB-7034-A5F0-B3DB3950B3DD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalData", "CS\CodeBehind\EntityFramework\LocalData\LocalData.csproj", "{F486CC2C-3626-63E6-E2FE-02205E6ACC1C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagedAsyncSource", "CS\CodeBehind\EntityFramework\PagedAsyncSource\PagedAsyncSource.csproj", "{F88441FF-7433-8D05-B0D4-D04A1B5FD597}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerMode", "CS\CodeBehind\EntityFramework\ServerMode\ServerMode.csproj", "{8606B7BB-3F4D-C687-BBFA-13D6D10B366D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfiniteAsyncSource", "CS\CodeBehind\XPO\InfiniteAsyncSource\InfiniteAsyncSource.csproj", "{E6B48ECF-D1AE-2578-8ED2-6C2F30D1EE45}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantFeedbackMode", "CS\CodeBehind\XPO\InstantFeedbackMode\InstantFeedbackMode.csproj", "{3669B2E4-A2B9-6F16-C3CA-605028AA0AAB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalData", "CS\CodeBehind\XPO\LocalData\LocalData.csproj", "{3A7AE472-766F-98FF-6FFE-E1BF5438D9D5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagedAsyncSource", "CS\CodeBehind\XPO\PagedAsyncSource\PagedAsyncSource.csproj", "{72F1F8F8-6DA9-2B57-1ADC-B179DFAC534D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerMode", "CS\CodeBehind\XPO\ServerMode\ServerMode.csproj", "{B0473BD1-804F-68B7-AC1B-D24EFC3E3C0F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfiniteAsyncSource", "CS\ViewModel\EFCore\InfiniteAsyncSource\InfiniteAsyncSource.csproj", "{75B40700-47BF-EE34-106B-49B693C14CD3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantFeedbackMode", "CS\ViewModel\EFCore\InstantFeedbackMode\InstantFeedbackMode.csproj", "{CAD2530B-A4C1-61AD-CBA7-DB8548EBCCDB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalData", "CS\ViewModel\EFCore\LocalData\LocalData.csproj", "{9C83E2AC-8A16-8CF6-05A1-4D24A6D37010}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagedAsyncSource", "CS\ViewModel\EFCore\PagedAsyncSource\PagedAsyncSource.csproj", "{6F66E7B7-3AF3-5381-0DE6-27A3F07078E8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerMode", "CS\ViewModel\EFCore\ServerMode\ServerMode.csproj", "{30677180-75CA-B378-283E-592104E900AE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfiniteAsyncSource", "CS\ViewModel\EntityFramework\InfiniteAsyncSource\InfiniteAsyncSource.csproj", "{15B732AA-52FF-31FF-1FA8-B2BB46A99604}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantFeedbackMode", "CS\ViewModel\EntityFramework\InstantFeedbackMode\InstantFeedbackMode.csproj", "{426D6BB0-E022-7346-0A39-5708229FA581}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalData", "CS\ViewModel\EntityFramework\LocalData\LocalData.csproj", "{A053A495-BD20-6118-236F-AC8E61E5C05A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagedAsyncSource", "CS\ViewModel\EntityFramework\PagedAsyncSource\PagedAsyncSource.csproj", "{DBA236C5-087D-899B-EAE5-6FFC0C4BAFB1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerMode", "CS\ViewModel\EntityFramework\ServerMode\ServerMode.csproj", "{F514D2C9-5E68-3383-866B-4EFAB5C6E8D9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfiniteAsyncSource", "CS\ViewModel\XPO\InfiniteAsyncSource\InfiniteAsyncSource.csproj", "{D45CE161-9F15-E3EA-D8E3-D32E1005A3A6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantFeedbackMode", "CS\ViewModel\XPO\InstantFeedbackMode\InstantFeedbackMode.csproj", "{458CC994-873E-B932-DFAC-BA1D47463452}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalData", "CS\ViewModel\XPO\LocalData\LocalData.csproj", "{B9622751-FE28-84F8-EB26-5F3F95EF6497}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagedAsyncSource", "CS\ViewModel\XPO\PagedAsyncSource\PagedAsyncSource.csproj", "{F9C7D214-7314-7427-227C-4D0D062CD3E9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerMode", "CS\ViewModel\XPO\ServerMode\ServerMode.csproj", "{2B8C4A5D-723E-AC15-5905-BDBCE5C10D75}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B7E6D722-D306-C409-A1F5-6AEAFB21A281}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B7E6D722-D306-C409-A1F5-6AEAFB21A281}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B7E6D722-D306-C409-A1F5-6AEAFB21A281}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B7E6D722-D306-C409-A1F5-6AEAFB21A281}.Release|Any CPU.Build.0 = Release|Any CPU + {2138333B-751D-1786-5AB5-04A2980BC1D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2138333B-751D-1786-5AB5-04A2980BC1D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2138333B-751D-1786-5AB5-04A2980BC1D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2138333B-751D-1786-5AB5-04A2980BC1D6}.Release|Any CPU.Build.0 = Release|Any CPU + {47801E06-424B-AAF6-B81A-3A255896EBF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47801E06-424B-AAF6-B81A-3A255896EBF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47801E06-424B-AAF6-B81A-3A255896EBF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47801E06-424B-AAF6-B81A-3A255896EBF7}.Release|Any CPU.Build.0 = Release|Any CPU + {ADFA4798-6BAA-6967-F813-89F0229D1B96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ADFA4798-6BAA-6967-F813-89F0229D1B96}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ADFA4798-6BAA-6967-F813-89F0229D1B96}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ADFA4798-6BAA-6967-F813-89F0229D1B96}.Release|Any CPU.Build.0 = Release|Any CPU + {87473A0C-89A5-1C21-97E7-6F40ACD3C060}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87473A0C-89A5-1C21-97E7-6F40ACD3C060}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87473A0C-89A5-1C21-97E7-6F40ACD3C060}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87473A0C-89A5-1C21-97E7-6F40ACD3C060}.Release|Any CPU.Build.0 = Release|Any CPU + {15015E00-900F-7BBE-4987-3CFC3042F716}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15015E00-900F-7BBE-4987-3CFC3042F716}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15015E00-900F-7BBE-4987-3CFC3042F716}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15015E00-900F-7BBE-4987-3CFC3042F716}.Release|Any CPU.Build.0 = Release|Any CPU + {BA2F5788-A3EB-7034-A5F0-B3DB3950B3DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA2F5788-A3EB-7034-A5F0-B3DB3950B3DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA2F5788-A3EB-7034-A5F0-B3DB3950B3DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA2F5788-A3EB-7034-A5F0-B3DB3950B3DD}.Release|Any CPU.Build.0 = Release|Any CPU + {F486CC2C-3626-63E6-E2FE-02205E6ACC1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F486CC2C-3626-63E6-E2FE-02205E6ACC1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F486CC2C-3626-63E6-E2FE-02205E6ACC1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F486CC2C-3626-63E6-E2FE-02205E6ACC1C}.Release|Any CPU.Build.0 = Release|Any CPU + {F88441FF-7433-8D05-B0D4-D04A1B5FD597}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F88441FF-7433-8D05-B0D4-D04A1B5FD597}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F88441FF-7433-8D05-B0D4-D04A1B5FD597}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F88441FF-7433-8D05-B0D4-D04A1B5FD597}.Release|Any CPU.Build.0 = Release|Any CPU + {8606B7BB-3F4D-C687-BBFA-13D6D10B366D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8606B7BB-3F4D-C687-BBFA-13D6D10B366D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8606B7BB-3F4D-C687-BBFA-13D6D10B366D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8606B7BB-3F4D-C687-BBFA-13D6D10B366D}.Release|Any CPU.Build.0 = Release|Any CPU + {E6B48ECF-D1AE-2578-8ED2-6C2F30D1EE45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6B48ECF-D1AE-2578-8ED2-6C2F30D1EE45}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6B48ECF-D1AE-2578-8ED2-6C2F30D1EE45}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E6B48ECF-D1AE-2578-8ED2-6C2F30D1EE45}.Release|Any CPU.Build.0 = Release|Any CPU + {3669B2E4-A2B9-6F16-C3CA-605028AA0AAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3669B2E4-A2B9-6F16-C3CA-605028AA0AAB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3669B2E4-A2B9-6F16-C3CA-605028AA0AAB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3669B2E4-A2B9-6F16-C3CA-605028AA0AAB}.Release|Any CPU.Build.0 = Release|Any CPU + {3A7AE472-766F-98FF-6FFE-E1BF5438D9D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A7AE472-766F-98FF-6FFE-E1BF5438D9D5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A7AE472-766F-98FF-6FFE-E1BF5438D9D5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A7AE472-766F-98FF-6FFE-E1BF5438D9D5}.Release|Any CPU.Build.0 = Release|Any CPU + {72F1F8F8-6DA9-2B57-1ADC-B179DFAC534D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72F1F8F8-6DA9-2B57-1ADC-B179DFAC534D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72F1F8F8-6DA9-2B57-1ADC-B179DFAC534D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72F1F8F8-6DA9-2B57-1ADC-B179DFAC534D}.Release|Any CPU.Build.0 = Release|Any CPU + {B0473BD1-804F-68B7-AC1B-D24EFC3E3C0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0473BD1-804F-68B7-AC1B-D24EFC3E3C0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0473BD1-804F-68B7-AC1B-D24EFC3E3C0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0473BD1-804F-68B7-AC1B-D24EFC3E3C0F}.Release|Any CPU.Build.0 = Release|Any CPU + {75B40700-47BF-EE34-106B-49B693C14CD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {75B40700-47BF-EE34-106B-49B693C14CD3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {75B40700-47BF-EE34-106B-49B693C14CD3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {75B40700-47BF-EE34-106B-49B693C14CD3}.Release|Any CPU.Build.0 = Release|Any CPU + {CAD2530B-A4C1-61AD-CBA7-DB8548EBCCDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CAD2530B-A4C1-61AD-CBA7-DB8548EBCCDB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CAD2530B-A4C1-61AD-CBA7-DB8548EBCCDB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CAD2530B-A4C1-61AD-CBA7-DB8548EBCCDB}.Release|Any CPU.Build.0 = Release|Any CPU + {9C83E2AC-8A16-8CF6-05A1-4D24A6D37010}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C83E2AC-8A16-8CF6-05A1-4D24A6D37010}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C83E2AC-8A16-8CF6-05A1-4D24A6D37010}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C83E2AC-8A16-8CF6-05A1-4D24A6D37010}.Release|Any CPU.Build.0 = Release|Any CPU + {6F66E7B7-3AF3-5381-0DE6-27A3F07078E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6F66E7B7-3AF3-5381-0DE6-27A3F07078E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6F66E7B7-3AF3-5381-0DE6-27A3F07078E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6F66E7B7-3AF3-5381-0DE6-27A3F07078E8}.Release|Any CPU.Build.0 = Release|Any CPU + {30677180-75CA-B378-283E-592104E900AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {30677180-75CA-B378-283E-592104E900AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {30677180-75CA-B378-283E-592104E900AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {30677180-75CA-B378-283E-592104E900AE}.Release|Any CPU.Build.0 = Release|Any CPU + {15B732AA-52FF-31FF-1FA8-B2BB46A99604}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15B732AA-52FF-31FF-1FA8-B2BB46A99604}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15B732AA-52FF-31FF-1FA8-B2BB46A99604}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15B732AA-52FF-31FF-1FA8-B2BB46A99604}.Release|Any CPU.Build.0 = Release|Any CPU + {426D6BB0-E022-7346-0A39-5708229FA581}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {426D6BB0-E022-7346-0A39-5708229FA581}.Debug|Any CPU.Build.0 = Debug|Any CPU + {426D6BB0-E022-7346-0A39-5708229FA581}.Release|Any CPU.ActiveCfg = Release|Any CPU + {426D6BB0-E022-7346-0A39-5708229FA581}.Release|Any CPU.Build.0 = Release|Any CPU + {A053A495-BD20-6118-236F-AC8E61E5C05A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A053A495-BD20-6118-236F-AC8E61E5C05A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A053A495-BD20-6118-236F-AC8E61E5C05A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A053A495-BD20-6118-236F-AC8E61E5C05A}.Release|Any CPU.Build.0 = Release|Any CPU + {DBA236C5-087D-899B-EAE5-6FFC0C4BAFB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DBA236C5-087D-899B-EAE5-6FFC0C4BAFB1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DBA236C5-087D-899B-EAE5-6FFC0C4BAFB1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DBA236C5-087D-899B-EAE5-6FFC0C4BAFB1}.Release|Any CPU.Build.0 = Release|Any CPU + {F514D2C9-5E68-3383-866B-4EFAB5C6E8D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F514D2C9-5E68-3383-866B-4EFAB5C6E8D9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F514D2C9-5E68-3383-866B-4EFAB5C6E8D9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F514D2C9-5E68-3383-866B-4EFAB5C6E8D9}.Release|Any CPU.Build.0 = Release|Any CPU + {D45CE161-9F15-E3EA-D8E3-D32E1005A3A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D45CE161-9F15-E3EA-D8E3-D32E1005A3A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D45CE161-9F15-E3EA-D8E3-D32E1005A3A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D45CE161-9F15-E3EA-D8E3-D32E1005A3A6}.Release|Any CPU.Build.0 = Release|Any CPU + {458CC994-873E-B932-DFAC-BA1D47463452}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {458CC994-873E-B932-DFAC-BA1D47463452}.Debug|Any CPU.Build.0 = Debug|Any CPU + {458CC994-873E-B932-DFAC-BA1D47463452}.Release|Any CPU.ActiveCfg = Release|Any CPU + {458CC994-873E-B932-DFAC-BA1D47463452}.Release|Any CPU.Build.0 = Release|Any CPU + {B9622751-FE28-84F8-EB26-5F3F95EF6497}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B9622751-FE28-84F8-EB26-5F3F95EF6497}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B9622751-FE28-84F8-EB26-5F3F95EF6497}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B9622751-FE28-84F8-EB26-5F3F95EF6497}.Release|Any CPU.Build.0 = Release|Any CPU + {F9C7D214-7314-7427-227C-4D0D062CD3E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9C7D214-7314-7427-227C-4D0D062CD3E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9C7D214-7314-7427-227C-4D0D062CD3E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9C7D214-7314-7427-227C-4D0D062CD3E9}.Release|Any CPU.Build.0 = Release|Any CPU + {2B8C4A5D-723E-AC15-5905-BDBCE5C10D75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2B8C4A5D-723E-AC15-5905-BDBCE5C10D75}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2B8C4A5D-723E-AC15-5905-BDBCE5C10D75}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2B8C4A5D-723E-AC15-5905-BDBCE5C10D75}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {183ED980-C32E-C675-E55D-281EBAB34CB4} = {21D36955-95DF-189F-F462-3EA64FE19AA5} + {E304686B-213A-3A36-A534-4EE68562656A} = {21D36955-95DF-189F-F462-3EA64FE19AA5} + {BA298011-020E-89D7-9A29-3E4378A90301} = {21D36955-95DF-189F-F462-3EA64FE19AA5} + {8E928C27-5585-9913-8FA6-24A164DF3179} = {6F543814-7740-FC98-73A5-CC0A913546B8} + {9130DE36-C8E7-253F-F380-218962E462D9} = {6F543814-7740-FC98-73A5-CC0A913546B8} + {2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE} = {6F543814-7740-FC98-73A5-CC0A913546B8} + {B7E6D722-D306-C409-A1F5-6AEAFB21A281} = {183ED980-C32E-C675-E55D-281EBAB34CB4} + {2138333B-751D-1786-5AB5-04A2980BC1D6} = {183ED980-C32E-C675-E55D-281EBAB34CB4} + {47801E06-424B-AAF6-B81A-3A255896EBF7} = {183ED980-C32E-C675-E55D-281EBAB34CB4} + {ADFA4798-6BAA-6967-F813-89F0229D1B96} = {183ED980-C32E-C675-E55D-281EBAB34CB4} + {87473A0C-89A5-1C21-97E7-6F40ACD3C060} = {183ED980-C32E-C675-E55D-281EBAB34CB4} + {15015E00-900F-7BBE-4987-3CFC3042F716} = {E304686B-213A-3A36-A534-4EE68562656A} + {BA2F5788-A3EB-7034-A5F0-B3DB3950B3DD} = {E304686B-213A-3A36-A534-4EE68562656A} + {F486CC2C-3626-63E6-E2FE-02205E6ACC1C} = {E304686B-213A-3A36-A534-4EE68562656A} + {F88441FF-7433-8D05-B0D4-D04A1B5FD597} = {E304686B-213A-3A36-A534-4EE68562656A} + {8606B7BB-3F4D-C687-BBFA-13D6D10B366D} = {E304686B-213A-3A36-A534-4EE68562656A} + {E6B48ECF-D1AE-2578-8ED2-6C2F30D1EE45} = {BA298011-020E-89D7-9A29-3E4378A90301} + {3669B2E4-A2B9-6F16-C3CA-605028AA0AAB} = {BA298011-020E-89D7-9A29-3E4378A90301} + {3A7AE472-766F-98FF-6FFE-E1BF5438D9D5} = {BA298011-020E-89D7-9A29-3E4378A90301} + {72F1F8F8-6DA9-2B57-1ADC-B179DFAC534D} = {BA298011-020E-89D7-9A29-3E4378A90301} + {B0473BD1-804F-68B7-AC1B-D24EFC3E3C0F} = {BA298011-020E-89D7-9A29-3E4378A90301} + {75B40700-47BF-EE34-106B-49B693C14CD3} = {8E928C27-5585-9913-8FA6-24A164DF3179} + {CAD2530B-A4C1-61AD-CBA7-DB8548EBCCDB} = {8E928C27-5585-9913-8FA6-24A164DF3179} + {9C83E2AC-8A16-8CF6-05A1-4D24A6D37010} = {8E928C27-5585-9913-8FA6-24A164DF3179} + {6F66E7B7-3AF3-5381-0DE6-27A3F07078E8} = {8E928C27-5585-9913-8FA6-24A164DF3179} + {30677180-75CA-B378-283E-592104E900AE} = {8E928C27-5585-9913-8FA6-24A164DF3179} + {15B732AA-52FF-31FF-1FA8-B2BB46A99604} = {9130DE36-C8E7-253F-F380-218962E462D9} + {426D6BB0-E022-7346-0A39-5708229FA581} = {9130DE36-C8E7-253F-F380-218962E462D9} + {A053A495-BD20-6118-236F-AC8E61E5C05A} = {9130DE36-C8E7-253F-F380-218962E462D9} + {DBA236C5-087D-899B-EAE5-6FFC0C4BAFB1} = {9130DE36-C8E7-253F-F380-218962E462D9} + {F514D2C9-5E68-3383-866B-4EFAB5C6E8D9} = {9130DE36-C8E7-253F-F380-218962E462D9} + {D45CE161-9F15-E3EA-D8E3-D32E1005A3A6} = {2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE} + {458CC994-873E-B932-DFAC-BA1D47463452} = {2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE} + {B9622751-FE28-84F8-EB26-5F3F95EF6497} = {2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE} + {F9C7D214-7314-7427-227C-4D0D062CD3E9} = {2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE} + {2B8C4A5D-723E-AC15-5905-BDBCE5C10D75} = {2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/CS/CodeBehind/EFCore/InfiniteAsyncSource/App.config b/CS/CodeBehind/EFCore/InfiniteAsyncSource/App.config new file mode 100644 index 0000000..210a3bb --- /dev/null +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/App.config @@ -0,0 +1,63 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CS/GridControlCRUDMVVM/App.xaml b/CS/CodeBehind/EFCore/InfiniteAsyncSource/App.xaml similarity index 71% rename from CS/GridControlCRUDMVVM/App.xaml rename to CS/CodeBehind/EFCore/InfiniteAsyncSource/App.xaml index b35e1ea..cd777dc 100644 --- a/CS/GridControlCRUDMVVM/App.xaml +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/App.xaml @@ -1,7 +1,7 @@ - diff --git a/CS/CodeBehind/EFCore/InfiniteAsyncSource/App.xaml.cs b/CS/CodeBehind/EFCore/InfiniteAsyncSource/App.xaml.cs new file mode 100644 index 0000000..5263c1c --- /dev/null +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/App.xaml.cs @@ -0,0 +1,19 @@ +using EFCoreIssues.Issues; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EFCoreIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + IssuesContextInitializer.Seed(); + } + } +} diff --git a/CS/CodeBehind/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.csproj b/CS/CodeBehind/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.csproj new file mode 100644 index 0000000..f744599 --- /dev/null +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.csproj @@ -0,0 +1,215 @@ + + + + + + Debug + AnyCPU + {B7E6D722-D306-C409-A1F5-6AEAFB21A281} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + \ No newline at end of file diff --git a/CS/GridControlCRUDMVVM/GridControlCRUDMVVM.sln b/CS/CodeBehind/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.sln similarity index 55% rename from CS/GridControlCRUDMVVM/GridControlCRUDMVVM.sln rename to CS/CodeBehind/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.sln index 53bb8f0..bd6e4b4 100644 --- a/CS/GridControlCRUDMVVM/GridControlCRUDMVVM.sln +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.sln @@ -1,9 +1,9 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 -VisualStudioVersion = 16.0.29806.167 +VisualStudioVersion = 16.0.30804.86 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GridControlCRUDMVVM", "GridControlCRUDMVVM.csproj", "{69E85A61-E7D4-4C9D-A433-13E742AE30BC}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfiniteAsyncSource", "InfiniteAsyncSource.csproj", "{B7E6D722-D306-C409-A1F5-6AEAFB21A281}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,15 +11,15 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {69E85A61-E7D4-4C9D-A433-13E742AE30BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {69E85A61-E7D4-4C9D-A433-13E742AE30BC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {69E85A61-E7D4-4C9D-A433-13E742AE30BC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {69E85A61-E7D4-4C9D-A433-13E742AE30BC}.Release|Any CPU.Build.0 = Release|Any CPU + {B7E6D722-D306-C409-A1F5-6AEAFB21A281}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B7E6D722-D306-C409-A1F5-6AEAFB21A281}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B7E6D722-D306-C409-A1F5-6AEAFB21A281}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B7E6D722-D306-C409-A1F5-6AEAFB21A281}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {51597E69-ADA1-4945-9493-FC7C9FB65AD2} + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} EndGlobalSection EndGlobal diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/Issue.cs b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/Issue.cs similarity index 77% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/Issue.cs rename to CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/Issue.cs index d3f638f..c36c075 100644 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/Issue.cs +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/Issue.cs @@ -1,6 +1,6 @@ -using System; +using System; -namespace GridControlCRUDMVVMInfiniteAsyncSource { +namespace EFCoreIssues.Issues { public class Issue { public int Id { get; set; } public string Subject { get; set; } @@ -9,6 +9,9 @@ public class Issue { public DateTime Created { get; set; } public int Votes { get; set; } public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } } public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } } diff --git a/CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/IssuesContext.cs b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/IssuesContext.cs new file mode 100644 index 0000000..5ef3c63 --- /dev/null +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/IssuesContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues.Issues { + public class IssuesContext : DbContext { + static readonly DbContextOptions options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: "Test") + .Options; + public IssuesContext() + : base(options) { + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/IssuesContextInitializer.cs b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..d58b850 --- /dev/null +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/IssuesContextInitializer.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; + +namespace EFCoreIssues.Issues { + public static class IssuesContextInitializer { + public static void Seed() { + var context = new IssuesContext(); + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/OutlookDataGenerator.cs b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs similarity index 96% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/OutlookDataGenerator.cs rename to CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs index 1964397..5e35561 100644 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/OutlookDataGenerator.cs +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs @@ -1,8 +1,8 @@ -using System; +using System; -namespace GridControlCRUDMVVMInfiniteAsyncSource { +namespace EFCoreIssues.Issues { public static class OutlookDataGenerator { - static Random rnd = new Random(); + static Random rnd = new Random(0); static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/User.cs b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/User.cs similarity index 59% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/User.cs rename to CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/User.cs index 4c5a6fc..e3e8021 100644 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/User.cs +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Issues/User.cs @@ -1,11 +1,10 @@ -using System.Collections.Generic; +using System.Collections.Generic; -namespace GridControlCRUDMVVMInfiniteAsyncSource { +namespace EFCoreIssues.Issues { public class User { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } - public string FullName => FirstName + " " + LastName; public virtual ICollection Issues { get; set; } } } diff --git a/CS/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml b/CS/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..341b4d9 --- /dev/null +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml.cs b/CS/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml.cs new file mode 100644 index 0000000..9be9255 --- /dev/null +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml.cs @@ -0,0 +1,76 @@ +using System.Windows; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + var source = new InfiniteAsyncSource + { + ElementType = typeof(EFCoreIssues.Issues.Issue), + KeyProperty = nameof(EFCoreIssues.Issues.Issue.Id) + }; + source.FetchRows += OnFetchRows; + source.GetTotalSummaries += OnGetTotalSummaries; + grid.ItemsSource = source; + LoadLookupData(); + } + + void OnFetchRows(System.Object sender, DevExpress.Xpf.Data.FetchRowsAsyncEventArgs e) { + e.Result = Task.Run(() => + { + var context = new EFCoreIssues.Issues.IssuesContext(); + var queryable = context.Issues.AsNoTracking() + .SortBy(e.SortOrder, defaultUniqueSortPropertyName: nameof(EFCoreIssues.Issues.Issue.Id)) + .Where(MakeFilterExpression(e.Filter)); + return queryable.Skip(e.Skip).Take(e.Take ?? 100).ToArray(); + }); + } + + void OnGetTotalSummaries(System.Object sender, DevExpress.Xpf.Data.GetSummariesAsyncEventArgs e) { + e.Result = Task.Run(() => + { + var context = new EFCoreIssues.Issues.IssuesContext(); + var queryable = context.Issues.Where(MakeFilterExpression(e.Filter)); + return queryable.GetSummaries(e.Summaries); + }); + } + + System.Linq.Expressions.Expression> MakeFilterExpression(DevExpress.Data.Filtering.CriteriaOperator filter) { + var converter = new DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(); + return converter.Convert(filter); + } + + void OnValidateRow(System.Object sender, DevExpress.Xpf.Grid.GridRowValidationEventArgs e) { + var row = (EFCoreIssues.Issues.Issue)e.Row; + var context = new EFCoreIssues.Issues.IssuesContext(); + context.Entry(row).State = e.IsNewItem + ? EntityState.Added + : EntityState.Modified; + try { + context.SaveChanges(); + } finally { + context.Entry(row).State = EntityState.Detached; + } + } + + void OnValidateRowDeletion(System.Object sender, DevExpress.Xpf.Grid.GridDeleteRowsValidationEventArgs e) { + var row = (EFCoreIssues.Issues.Issue)e.Rows.Single(); + var context = new EFCoreIssues.Issues.IssuesContext(); + context.Entry(row).State = EntityState.Deleted; + context.SaveChanges(); + } + + void LoadLookupData() { + var context = new EFCoreIssues.Issues.IssuesContext(); + usersLookup.ItemsSource = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadLookupData(); + } + } +} diff --git a/CS/GridControlCRUDMVVM/Properties/AssemblyInfo.cs b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/AssemblyInfo.cs similarity index 92% rename from CS/GridControlCRUDMVVM/Properties/AssemblyInfo.cs rename to CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/AssemblyInfo.cs index eaeb93e..4179e62 100644 --- a/CS/GridControlCRUDMVVM/Properties/AssemblyInfo.cs +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -7,12 +7,12 @@ // 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("GridControlCRUDMVVM")] +[assembly: AssemblyTitle("EFCoreIssues")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GridControlCRUDMVVM")] -[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyProduct("EFCoreIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/CS/GridControlCRUDMVVM/Properties/Resources.Designer.cs b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/Resources.Designer.cs similarity index 72% rename from CS/GridControlCRUDMVVM/Properties/Resources.Designer.cs rename to CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/Resources.Designer.cs index 66c7063..9b965de 100644 --- a/CS/GridControlCRUDMVVM/Properties/Resources.Designer.cs +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/Resources.Designer.cs @@ -1,17 +1,7 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace GridControlCRUDMVVM.Properties { +namespace EFCoreIssues.Properties { using System; - - + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -23,39 +13,44 @@ namespace GridControlCRUDMVVM.Properties { [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("GridControlCRUDMVVM.Properties.Resources", typeof(Resources).Assembly); + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if(object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EFCoreIssues.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 { + internal static global::System.Globalization.CultureInfo Culture + { + get + { return resourceCulture; } - set { + set + { resourceCulture = value; } } diff --git a/CS/GridControlCRUDMVVM/Properties/Resources.resx b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/Resources.resx similarity index 100% rename from CS/GridControlCRUDMVVM/Properties/Resources.resx rename to CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/Resources.resx diff --git a/CS/GridControlCRUDMVVM/Properties/Settings.Designer.cs b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/Settings.Designer.cs similarity index 50% rename from CS/GridControlCRUDMVVM/Properties/Settings.Designer.cs rename to CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/Settings.Designer.cs index 5f20c9d..c156b8a 100644 --- a/CS/GridControlCRUDMVVM/Properties/Settings.Designer.cs +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/Settings.Designer.cs @@ -1,24 +1,16 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ +namespace EFCoreIssues.Properties { + -namespace GridControlCRUDMVVM.Properties { - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.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 { + + public static Settings Default + { + get + { return defaultInstance; } } diff --git a/CS/GridControlCRUDMVVM/Properties/Settings.settings b/CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/Settings.settings similarity index 100% rename from CS/GridControlCRUDMVVM/Properties/Settings.settings rename to CS/CodeBehind/EFCore/InfiniteAsyncSource/Properties/Settings.settings diff --git a/CS/CodeBehind/EFCore/InfiniteAsyncSource/packages.config b/CS/CodeBehind/EFCore/InfiniteAsyncSource/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/CS/CodeBehind/EFCore/InfiniteAsyncSource/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/App.config b/CS/CodeBehind/EFCore/InstantFeedbackMode/App.config new file mode 100644 index 0000000..210a3bb --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/App.config @@ -0,0 +1,63 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CS/GridControlCRUDSimple/App.xaml b/CS/CodeBehind/EFCore/InstantFeedbackMode/App.xaml similarity index 70% rename from CS/GridControlCRUDSimple/App.xaml rename to CS/CodeBehind/EFCore/InstantFeedbackMode/App.xaml index 447d47b..cd777dc 100644 --- a/CS/GridControlCRUDSimple/App.xaml +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/App.xaml @@ -1,7 +1,7 @@ - diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/App.xaml.cs b/CS/CodeBehind/EFCore/InstantFeedbackMode/App.xaml.cs new file mode 100644 index 0000000..5263c1c --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/App.xaml.cs @@ -0,0 +1,19 @@ +using EFCoreIssues.Issues; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EFCoreIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + IssuesContextInitializer.Seed(); + } + } +} diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/EditIssueInfo.cs b/CS/CodeBehind/EFCore/InstantFeedbackMode/EditIssueInfo.cs new file mode 100644 index 0000000..f1e718a --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/EditIssueInfo.cs @@ -0,0 +1,14 @@ +using DevExpress.Mvvm; +using System.Collections; +using EFCoreIssues.Issues; + +namespace EFCoreIssues { + public class EditIssueInfo : BindableBase { + public EditIssueInfo(IssuesContext context, IList users) { + Context = context; + Users = users; + } + public IssuesContext Context { get; } + public IList Users { get; } + } +} \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/InstantFeedbackMode.csproj b/CS/CodeBehind/EFCore/InstantFeedbackMode/InstantFeedbackMode.csproj new file mode 100644 index 0000000..0e39b2d --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/InstantFeedbackMode.csproj @@ -0,0 +1,224 @@ + + + + + + Debug + AnyCPU + {2138333B-751D-1786-5AB5-04A2980BC1D6} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + \ No newline at end of file diff --git a/CS/GridControlCRUDSimple/GridControlCRUDSimple.sln b/CS/CodeBehind/EFCore/InstantFeedbackMode/InstantFeedbackMode.sln similarity index 55% rename from CS/GridControlCRUDSimple/GridControlCRUDSimple.sln rename to CS/CodeBehind/EFCore/InstantFeedbackMode/InstantFeedbackMode.sln index 70a26c6..d6c0801 100644 --- a/CS/GridControlCRUDSimple/GridControlCRUDSimple.sln +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/InstantFeedbackMode.sln @@ -1,9 +1,9 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 -VisualStudioVersion = 16.0.29806.167 +VisualStudioVersion = 16.0.30804.86 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GridControlCRUDSimple", "GridControlCRUDSimple.csproj", "{9E2883B9-744A-48BF-B25A-EA4B2D435C9D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantFeedbackMode", "InstantFeedbackMode.csproj", "{2138333B-751D-1786-5AB5-04A2980BC1D6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,15 +11,15 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9E2883B9-744A-48BF-B25A-EA4B2D435C9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9E2883B9-744A-48BF-B25A-EA4B2D435C9D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9E2883B9-744A-48BF-B25A-EA4B2D435C9D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9E2883B9-744A-48BF-B25A-EA4B2D435C9D}.Release|Any CPU.Build.0 = Release|Any CPU + {2138333B-751D-1786-5AB5-04A2980BC1D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2138333B-751D-1786-5AB5-04A2980BC1D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2138333B-751D-1786-5AB5-04A2980BC1D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2138333B-751D-1786-5AB5-04A2980BC1D6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {51597E69-ADA1-4945-9493-FC7C9FB65AD2} + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} EndGlobalSection EndGlobal diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/IssueDetailView.xaml b/CS/CodeBehind/EFCore/InstantFeedbackMode/IssueDetailView.xaml new file mode 100644 index 0000000..d5c1fd0 --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/IssueDetailView.xaml.cs b/CS/CodeBehind/EFCore/InstantFeedbackMode/IssueDetailView.xaml.cs new file mode 100644 index 0000000..391f819 --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/IssueDetailView.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows.Controls; + +namespace EFCoreIssues { + public partial class IssueDetailView : UserControl { + public IssueDetailView() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext.DataModel/IssueData.cs b/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/Issue.cs similarity index 51% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext.DataModel/IssueData.cs rename to CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/Issue.cs index 87496bd..c36c075 100644 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext.DataModel/IssueData.cs +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/Issue.cs @@ -1,16 +1,17 @@ -using System; -using System.Linq; +using System; -namespace GridControlCRUDMVVMInfiniteAsyncSource { - public class IssueData { - public IssueData() { - Created = DateTime.Today; - } +namespace EFCoreIssues.Issues { + public class Issue { public int Id { get; set; } public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } public DateTime Created { get; set; } public int Votes { get; set; } public Priority Priority { get; set; } - public int UserId { get; set; } + public Issue() { + Created = DateTime.Now; + } } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } } diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/IssuesContext.cs b/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/IssuesContext.cs new file mode 100644 index 0000000..5ef3c63 --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/IssuesContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues.Issues { + public class IssuesContext : DbContext { + static readonly DbContextOptions options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: "Test") + .Options; + public IssuesContext() + : base(options) { + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/IssuesContextInitializer.cs b/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..d58b850 --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/IssuesContextInitializer.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; + +namespace EFCoreIssues.Issues { + public static class IssuesContextInitializer { + public static void Seed() { + var context = new IssuesContext(); + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..5e35561 --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EFCoreIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/User.cs b/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/User.cs new file mode 100644 index 0000000..e3e8021 --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EFCoreIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml b/CS/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml new file mode 100644 index 0000000..5cca301 --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml.cs b/CS/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml.cs new file mode 100644 index 0000000..f8bd9a3 --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml.cs @@ -0,0 +1,62 @@ +using System.Windows; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using EFCoreIssues.Issues; +using DevExpress.Mvvm.Xpf; +using System; +using System.Collections; + +namespace EFCoreIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + var source = new DevExpress.Data.Linq.EntityInstantFeedbackSource + { + KeyExpression = nameof(EFCoreIssues.Issues.Issue.Id) + }; + source.GetQueryable += (sender, e) => + { + var context = new EFCoreIssues.Issues.IssuesContext(); + e.QueryableSource = context.Issues.AsNoTracking(); + }; + grid.ItemsSource = source; + LoadLookupData(); + } + + void LoadLookupData() { + var context = new EFCoreIssues.Issues.IssuesContext(); + usersLookup.ItemsSource = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadLookupData(); + } + + void OnCreateEditEntityViewModel(System.Object sender, DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs e) { + var context = new IssuesContext(); + Issue item; + if(e.Key != null) + item = context.Issues.Find(e.Key); + else { + item = new Issue() { Created = DateTime.Now }; + context.Entry(item).State = EntityState.Added; + } + e.ViewModel = new EditItemViewModel(item, new EditIssueInfo(context, (IList)usersLookup.ItemsSource)); + } + + void OnValidateRow(System.Object sender, DevExpress.Mvvm.Xpf.EditFormRowValidationArgs e) { + var context = ((EditIssueInfo)e.Tag).Context; + context.SaveChanges(); + } + + void OnValidateRowDeletion(System.Object sender, DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs e) { + var key = (int)e.Keys.Single(); + var item = new Issue() { Id = key }; + var context = new IssuesContext(); + context.Entry(item).State = EntityState.Deleted; + context.SaveChanges(); + } + } +} diff --git a/CS/GridControlCRUDSimple/Properties/AssemblyInfo.cs b/CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/AssemblyInfo.cs similarity index 92% rename from CS/GridControlCRUDSimple/Properties/AssemblyInfo.cs rename to CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/AssemblyInfo.cs index ead768a..4179e62 100644 --- a/CS/GridControlCRUDSimple/Properties/AssemblyInfo.cs +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -7,12 +7,12 @@ // 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("GridControlCRUDSimple")] +[assembly: AssemblyTitle("EFCoreIssues")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GridControlCRUDSimple")] -[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyProduct("EFCoreIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/CS/GridControlCRUDSimple/Properties/Resources.Designer.cs b/CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/Resources.Designer.cs similarity index 72% rename from CS/GridControlCRUDSimple/Properties/Resources.Designer.cs rename to CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/Resources.Designer.cs index 5bb8c4e..9b965de 100644 --- a/CS/GridControlCRUDSimple/Properties/Resources.Designer.cs +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/Resources.Designer.cs @@ -1,17 +1,7 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace GridControlCRUDSimple.Properties { +namespace EFCoreIssues.Properties { using System; - - + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -23,39 +13,44 @@ namespace GridControlCRUDSimple.Properties { [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("GridControlCRUDSimple.Properties.Resources", typeof(Resources).Assembly); + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if(object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EFCoreIssues.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 { + internal static global::System.Globalization.CultureInfo Culture + { + get + { return resourceCulture; } - set { + set + { resourceCulture = value; } } diff --git a/CS/GridControlCRUDMVVMAsync/Properties/Resources.resx b/CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/Resources.resx similarity index 100% rename from CS/GridControlCRUDMVVMAsync/Properties/Resources.resx rename to CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/Resources.resx diff --git a/CS/GridControlCRUDSimple/Properties/Settings.Designer.cs b/CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/Settings.Designer.cs similarity index 50% rename from CS/GridControlCRUDSimple/Properties/Settings.Designer.cs rename to CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/Settings.Designer.cs index c69acdc..c156b8a 100644 --- a/CS/GridControlCRUDSimple/Properties/Settings.Designer.cs +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/Settings.Designer.cs @@ -1,24 +1,16 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ +namespace EFCoreIssues.Properties { + -namespace GridControlCRUDSimple.Properties { - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.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 { + + public static Settings Default + { + get + { return defaultInstance; } } diff --git a/CS/GridControlCRUDMVVMAsync/Properties/Settings.settings b/CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/Settings.settings similarity index 100% rename from CS/GridControlCRUDMVVMAsync/Properties/Settings.settings rename to CS/CodeBehind/EFCore/InstantFeedbackMode/Properties/Settings.settings diff --git a/CS/CodeBehind/EFCore/InstantFeedbackMode/packages.config b/CS/CodeBehind/EFCore/InstantFeedbackMode/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/CS/CodeBehind/EFCore/InstantFeedbackMode/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/LocalData/App.config b/CS/CodeBehind/EFCore/LocalData/App.config new file mode 100644 index 0000000..210a3bb --- /dev/null +++ b/CS/CodeBehind/EFCore/LocalData/App.config @@ -0,0 +1,63 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CS/GridControlCRUDMVVMAsync/App.xaml b/CS/CodeBehind/EFCore/LocalData/App.xaml similarity index 69% rename from CS/GridControlCRUDMVVMAsync/App.xaml rename to CS/CodeBehind/EFCore/LocalData/App.xaml index 9449ba3..cd777dc 100644 --- a/CS/GridControlCRUDMVVMAsync/App.xaml +++ b/CS/CodeBehind/EFCore/LocalData/App.xaml @@ -1,7 +1,7 @@ - diff --git a/CS/CodeBehind/EFCore/LocalData/App.xaml.cs b/CS/CodeBehind/EFCore/LocalData/App.xaml.cs new file mode 100644 index 0000000..5263c1c --- /dev/null +++ b/CS/CodeBehind/EFCore/LocalData/App.xaml.cs @@ -0,0 +1,19 @@ +using EFCoreIssues.Issues; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EFCoreIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + IssuesContextInitializer.Seed(); + } + } +} diff --git a/CS/CodeBehind/EFCore/LocalData/Issues/Issue.cs b/CS/CodeBehind/EFCore/LocalData/Issues/Issue.cs new file mode 100644 index 0000000..c36c075 --- /dev/null +++ b/CS/CodeBehind/EFCore/LocalData/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EFCoreIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/CodeBehind/EFCore/LocalData/Issues/IssuesContext.cs b/CS/CodeBehind/EFCore/LocalData/Issues/IssuesContext.cs new file mode 100644 index 0000000..5ef3c63 --- /dev/null +++ b/CS/CodeBehind/EFCore/LocalData/Issues/IssuesContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues.Issues { + public class IssuesContext : DbContext { + static readonly DbContextOptions options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: "Test") + .Options; + public IssuesContext() + : base(options) { + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/CodeBehind/EFCore/LocalData/Issues/IssuesContextInitializer.cs b/CS/CodeBehind/EFCore/LocalData/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..d58b850 --- /dev/null +++ b/CS/CodeBehind/EFCore/LocalData/Issues/IssuesContextInitializer.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; + +namespace EFCoreIssues.Issues { + public static class IssuesContextInitializer { + public static void Seed() { + var context = new IssuesContext(); + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/CodeBehind/EFCore/LocalData/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/EFCore/LocalData/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..5e35561 --- /dev/null +++ b/CS/CodeBehind/EFCore/LocalData/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EFCoreIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/EFCore/LocalData/Issues/User.cs b/CS/CodeBehind/EFCore/LocalData/Issues/User.cs new file mode 100644 index 0000000..e3e8021 --- /dev/null +++ b/CS/CodeBehind/EFCore/LocalData/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EFCoreIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/CodeBehind/EFCore/LocalData/LocalData.csproj b/CS/CodeBehind/EFCore/LocalData/LocalData.csproj new file mode 100644 index 0000000..3936cdd --- /dev/null +++ b/CS/CodeBehind/EFCore/LocalData/LocalData.csproj @@ -0,0 +1,215 @@ + + + + + + Debug + AnyCPU + {47801E06-424B-AAF6-B81A-3A255896EBF7} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + \ No newline at end of file diff --git a/CS/GridControlCRUDMVVMAsync/GridControlCRUDMVVMAsync.sln b/CS/CodeBehind/EFCore/LocalData/LocalData.sln similarity index 54% rename from CS/GridControlCRUDMVVMAsync/GridControlCRUDMVVMAsync.sln rename to CS/CodeBehind/EFCore/LocalData/LocalData.sln index 9257e81..6e65de8 100644 --- a/CS/GridControlCRUDMVVMAsync/GridControlCRUDMVVMAsync.sln +++ b/CS/CodeBehind/EFCore/LocalData/LocalData.sln @@ -1,9 +1,9 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 -VisualStudioVersion = 16.0.29806.167 +VisualStudioVersion = 16.0.30804.86 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GridControlCRUDMVVMAsync", "GridControlCRUDMVVMAsync.csproj", "{659194A7-745D-4A56-A683-B150B9170F53}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalData", "LocalData.csproj", "{47801E06-424B-AAF6-B81A-3A255896EBF7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,15 +11,15 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {659194A7-745D-4A56-A683-B150B9170F53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {659194A7-745D-4A56-A683-B150B9170F53}.Debug|Any CPU.Build.0 = Debug|Any CPU - {659194A7-745D-4A56-A683-B150B9170F53}.Release|Any CPU.ActiveCfg = Release|Any CPU - {659194A7-745D-4A56-A683-B150B9170F53}.Release|Any CPU.Build.0 = Release|Any CPU + {47801E06-424B-AAF6-B81A-3A255896EBF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47801E06-424B-AAF6-B81A-3A255896EBF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47801E06-424B-AAF6-B81A-3A255896EBF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47801E06-424B-AAF6-B81A-3A255896EBF7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {51597E69-ADA1-4945-9493-FC7C9FB65AD2} + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} EndGlobalSection EndGlobal diff --git a/CS/CodeBehind/EFCore/LocalData/MainWindow.xaml b/CS/CodeBehind/EFCore/LocalData/MainWindow.xaml new file mode 100644 index 0000000..9cd30dd --- /dev/null +++ b/CS/CodeBehind/EFCore/LocalData/MainWindow.xaml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/LocalData/MainWindow.xaml.cs b/CS/CodeBehind/EFCore/LocalData/MainWindow.xaml.cs new file mode 100644 index 0000000..1a477e6 --- /dev/null +++ b/CS/CodeBehind/EFCore/LocalData/MainWindow.xaml.cs @@ -0,0 +1,34 @@ +using System.Windows; +using System.Linq; + +namespace EFCoreIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + LoadData(); + } + EFCoreIssues.Issues.IssuesContext _Context; + + void LoadData() { + _Context = new EFCoreIssues.Issues.IssuesContext(); + grid.ItemsSource = _Context.Users.ToList(); + } + + void OnValidateRow(System.Object sender, DevExpress.Xpf.Grid.GridRowValidationEventArgs e) { + var row = (EFCoreIssues.Issues.User)e.Row; + if(e.IsNewItem) + _Context.Users.Add(row); + _Context.SaveChanges(); + } + + void OnValidateRowDeletion(System.Object sender, DevExpress.Xpf.Grid.GridDeleteRowsValidationEventArgs e) { + var row = (EFCoreIssues.Issues.User)e.Rows.Single(); + _Context.Users.Remove(row); + _Context.SaveChanges(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadData(); + } + } +} diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/AssemblyInfo.cs b/CS/CodeBehind/EFCore/LocalData/Properties/AssemblyInfo.cs similarity index 92% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/AssemblyInfo.cs rename to CS/CodeBehind/EFCore/LocalData/Properties/AssemblyInfo.cs index 4d06662..4179e62 100644 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/AssemblyInfo.cs +++ b/CS/CodeBehind/EFCore/LocalData/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -7,12 +7,12 @@ // 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("GridControlCRUDMVVMAsync")] +[assembly: AssemblyTitle("EFCoreIssues")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GridControlCRUDMVVMAsync")] -[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyProduct("EFCoreIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/CS/GridControlCRUDMVVMAsync/Properties/Resources.Designer.cs b/CS/CodeBehind/EFCore/LocalData/Properties/Resources.Designer.cs similarity index 72% rename from CS/GridControlCRUDMVVMAsync/Properties/Resources.Designer.cs rename to CS/CodeBehind/EFCore/LocalData/Properties/Resources.Designer.cs index 0629f91..9b965de 100644 --- a/CS/GridControlCRUDMVVMAsync/Properties/Resources.Designer.cs +++ b/CS/CodeBehind/EFCore/LocalData/Properties/Resources.Designer.cs @@ -1,17 +1,7 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace GridControlCRUDMVVMAsync.Properties { +namespace EFCoreIssues.Properties { using System; - - + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -23,39 +13,44 @@ namespace GridControlCRUDMVVMAsync.Properties { [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("GridControlCRUDMVVMAsync.Properties.Resources", typeof(Resources).Assembly); + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if(object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EFCoreIssues.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 { + internal static global::System.Globalization.CultureInfo Culture + { + get + { return resourceCulture; } - set { + set + { resourceCulture = value; } } diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/Resources.resx b/CS/CodeBehind/EFCore/LocalData/Properties/Resources.resx similarity index 100% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/Resources.resx rename to CS/CodeBehind/EFCore/LocalData/Properties/Resources.resx diff --git a/CS/CodeBehind/EFCore/LocalData/Properties/Settings.Designer.cs b/CS/CodeBehind/EFCore/LocalData/Properties/Settings.Designer.cs new file mode 100644 index 0000000..c156b8a --- /dev/null +++ b/CS/CodeBehind/EFCore/LocalData/Properties/Settings.Designer.cs @@ -0,0 +1,18 @@ +namespace EFCoreIssues.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.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 --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/Settings.settings b/CS/CodeBehind/EFCore/LocalData/Properties/Settings.settings similarity index 100% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/Settings.settings rename to CS/CodeBehind/EFCore/LocalData/Properties/Settings.settings diff --git a/CS/CodeBehind/EFCore/LocalData/packages.config b/CS/CodeBehind/EFCore/LocalData/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/CS/CodeBehind/EFCore/LocalData/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/App.config b/CS/CodeBehind/EFCore/PagedAsyncSource/App.config new file mode 100644 index 0000000..210a3bb --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/App.config @@ -0,0 +1,63 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/App.xaml b/CS/CodeBehind/EFCore/PagedAsyncSource/App.xaml new file mode 100644 index 0000000..cd777dc --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/App.xaml.cs b/CS/CodeBehind/EFCore/PagedAsyncSource/App.xaml.cs new file mode 100644 index 0000000..5263c1c --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/App.xaml.cs @@ -0,0 +1,19 @@ +using EFCoreIssues.Issues; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EFCoreIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + IssuesContextInitializer.Seed(); + } + } +} diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/Issue.cs b/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/Issue.cs new file mode 100644 index 0000000..c36c075 --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EFCoreIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/IssuesContext.cs b/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/IssuesContext.cs new file mode 100644 index 0000000..5ef3c63 --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/IssuesContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues.Issues { + public class IssuesContext : DbContext { + static readonly DbContextOptions options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: "Test") + .Options; + public IssuesContext() + : base(options) { + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/IssuesContextInitializer.cs b/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..d58b850 --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/IssuesContextInitializer.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; + +namespace EFCoreIssues.Issues { + public static class IssuesContextInitializer { + public static void Seed() { + var context = new IssuesContext(); + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..5e35561 --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EFCoreIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/User.cs b/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/User.cs new file mode 100644 index 0000000..e3e8021 --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EFCoreIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml b/CS/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..a6319fe --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml.cs b/CS/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml.cs new file mode 100644 index 0000000..6e422f1 --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml.cs @@ -0,0 +1,71 @@ +using System.Windows; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + var source = new PagedAsyncSource + { + ElementType = typeof(EFCoreIssues.Issues.Issue), + KeyProperty = nameof(EFCoreIssues.Issues.Issue.Id), + PageNavigationMode = PageNavigationMode.ArbitraryWithTotalPageCount + }; + source.FetchPage += OnFetchPage; + source.GetTotalSummaries += OnGetTotalSummaries; + grid.ItemsSource = source; + LoadLookupData(); + } + + void OnFetchPage(System.Object sender, DevExpress.Xpf.Data.FetchPageAsyncEventArgs e) { + const int pageTakeCount = 5; + e.Result = Task.Run(() => + { + var context = new EFCoreIssues.Issues.IssuesContext(); + var queryable = context.Issues.AsNoTracking() + .SortBy(e.SortOrder, defaultUniqueSortPropertyName: nameof(EFCoreIssues.Issues.Issue.Id)) + .Where(MakeFilterExpression(e.Filter)); + return queryable.Skip(e.Skip).Take(e.Take * pageTakeCount).ToArray(); + }); + } + + void OnGetTotalSummaries(System.Object sender, DevExpress.Xpf.Data.GetSummariesAsyncEventArgs e) { + e.Result = Task.Run(() => + { + var context = new EFCoreIssues.Issues.IssuesContext(); + var queryable = context.Issues.Where(MakeFilterExpression(e.Filter)); + return queryable.GetSummaries(e.Summaries); + }); + } + + System.Linq.Expressions.Expression> MakeFilterExpression(DevExpress.Data.Filtering.CriteriaOperator filter) { + var converter = new DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(); + return converter.Convert(filter); + } + + void OnValidateRow(System.Object sender, DevExpress.Xpf.Grid.GridRowValidationEventArgs e) { + var row = (EFCoreIssues.Issues.Issue)e.Row; + var context = new EFCoreIssues.Issues.IssuesContext(); + context.Entry(row).State = e.IsNewItem + ? EntityState.Added + : EntityState.Modified; + try { + context.SaveChanges(); + } finally { + context.Entry(row).State = EntityState.Detached; + } + } + + void LoadLookupData() { + var context = new EFCoreIssues.Issues.IssuesContext(); + usersLookup.ItemsSource = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadLookupData(); + } + } +} diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/PagedAsyncSource.csproj b/CS/CodeBehind/EFCore/PagedAsyncSource/PagedAsyncSource.csproj new file mode 100644 index 0000000..81e2cce --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/PagedAsyncSource.csproj @@ -0,0 +1,215 @@ + + + + + + Debug + AnyCPU + {ADFA4798-6BAA-6967-F813-89F0229D1B96} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + \ No newline at end of file diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/GridControlCRUDMVVMInfiniteAsyncSource.sln b/CS/CodeBehind/EFCore/PagedAsyncSource/PagedAsyncSource.sln similarity index 53% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/GridControlCRUDMVVMInfiniteAsyncSource.sln rename to CS/CodeBehind/EFCore/PagedAsyncSource/PagedAsyncSource.sln index 68dca05..9c3e54c 100644 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/GridControlCRUDMVVMInfiniteAsyncSource.sln +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/PagedAsyncSource.sln @@ -1,9 +1,9 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 -VisualStudioVersion = 16.0.29806.167 +VisualStudioVersion = 16.0.30804.86 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GridControlCRUDMVVMInfiniteAsyncSource", "GridControlCRUDMVVMInfiniteAsyncSource.csproj", "{659194A7-745D-4A56-A683-B150B9170F53}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagedAsyncSource", "PagedAsyncSource.csproj", "{ADFA4798-6BAA-6967-F813-89F0229D1B96}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,15 +11,15 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {659194A7-745D-4A56-A683-B150B9170F53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {659194A7-745D-4A56-A683-B150B9170F53}.Debug|Any CPU.Build.0 = Debug|Any CPU - {659194A7-745D-4A56-A683-B150B9170F53}.Release|Any CPU.ActiveCfg = Release|Any CPU - {659194A7-745D-4A56-A683-B150B9170F53}.Release|Any CPU.Build.0 = Release|Any CPU + {ADFA4798-6BAA-6967-F813-89F0229D1B96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ADFA4798-6BAA-6967-F813-89F0229D1B96}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ADFA4798-6BAA-6967-F813-89F0229D1B96}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ADFA4798-6BAA-6967-F813-89F0229D1B96}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {51597E69-ADA1-4945-9493-FC7C9FB65AD2} + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} EndGlobalSection EndGlobal diff --git a/CS/GridControlCRUDMVVMAsync/Properties/AssemblyInfo.cs b/CS/CodeBehind/EFCore/PagedAsyncSource/Properties/AssemblyInfo.cs similarity index 92% rename from CS/GridControlCRUDMVVMAsync/Properties/AssemblyInfo.cs rename to CS/CodeBehind/EFCore/PagedAsyncSource/Properties/AssemblyInfo.cs index 4d06662..4179e62 100644 --- a/CS/GridControlCRUDMVVMAsync/Properties/AssemblyInfo.cs +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -7,12 +7,12 @@ // 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("GridControlCRUDMVVMAsync")] +[assembly: AssemblyTitle("EFCoreIssues")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GridControlCRUDMVVMAsync")] -[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyProduct("EFCoreIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/Resources.Designer.cs b/CS/CodeBehind/EFCore/PagedAsyncSource/Properties/Resources.Designer.cs similarity index 72% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/Resources.Designer.cs rename to CS/CodeBehind/EFCore/PagedAsyncSource/Properties/Resources.Designer.cs index 0629f91..9b965de 100644 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/Resources.Designer.cs +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/Properties/Resources.Designer.cs @@ -1,17 +1,7 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace GridControlCRUDMVVMAsync.Properties { +namespace EFCoreIssues.Properties { using System; - - + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -23,39 +13,44 @@ namespace GridControlCRUDMVVMAsync.Properties { [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("GridControlCRUDMVVMAsync.Properties.Resources", typeof(Resources).Assembly); + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if(object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EFCoreIssues.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 { + internal static global::System.Globalization.CultureInfo Culture + { + get + { return resourceCulture; } - set { + set + { resourceCulture = value; } } diff --git a/CS/GridControlCRUDSimple/Properties/Resources.resx b/CS/CodeBehind/EFCore/PagedAsyncSource/Properties/Resources.resx similarity index 100% rename from CS/GridControlCRUDSimple/Properties/Resources.resx rename to CS/CodeBehind/EFCore/PagedAsyncSource/Properties/Resources.resx diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/Properties/Settings.Designer.cs b/CS/CodeBehind/EFCore/PagedAsyncSource/Properties/Settings.Designer.cs new file mode 100644 index 0000000..c156b8a --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/Properties/Settings.Designer.cs @@ -0,0 +1,18 @@ +namespace EFCoreIssues.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.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 --git a/CS/GridControlCRUDSimple/Properties/Settings.settings b/CS/CodeBehind/EFCore/PagedAsyncSource/Properties/Settings.settings similarity index 100% rename from CS/GridControlCRUDSimple/Properties/Settings.settings rename to CS/CodeBehind/EFCore/PagedAsyncSource/Properties/Settings.settings diff --git a/CS/CodeBehind/EFCore/PagedAsyncSource/packages.config b/CS/CodeBehind/EFCore/PagedAsyncSource/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/CS/CodeBehind/EFCore/PagedAsyncSource/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/ServerMode/App.config b/CS/CodeBehind/EFCore/ServerMode/App.config new file mode 100644 index 0000000..210a3bb --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/App.config @@ -0,0 +1,63 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CS/CodeBehind/EFCore/ServerMode/App.xaml b/CS/CodeBehind/EFCore/ServerMode/App.xaml new file mode 100644 index 0000000..cd777dc --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/CodeBehind/EFCore/ServerMode/App.xaml.cs b/CS/CodeBehind/EFCore/ServerMode/App.xaml.cs new file mode 100644 index 0000000..5263c1c --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/App.xaml.cs @@ -0,0 +1,19 @@ +using EFCoreIssues.Issues; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EFCoreIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + IssuesContextInitializer.Seed(); + } + } +} diff --git a/CS/CodeBehind/EFCore/ServerMode/EditIssueInfo.cs b/CS/CodeBehind/EFCore/ServerMode/EditIssueInfo.cs new file mode 100644 index 0000000..f1e718a --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/EditIssueInfo.cs @@ -0,0 +1,14 @@ +using DevExpress.Mvvm; +using System.Collections; +using EFCoreIssues.Issues; + +namespace EFCoreIssues { + public class EditIssueInfo : BindableBase { + public EditIssueInfo(IssuesContext context, IList users) { + Context = context; + Users = users; + } + public IssuesContext Context { get; } + public IList Users { get; } + } +} \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/ServerMode/IssueDetailView.xaml b/CS/CodeBehind/EFCore/ServerMode/IssueDetailView.xaml new file mode 100644 index 0000000..d5c1fd0 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/ServerMode/IssueDetailView.xaml.cs b/CS/CodeBehind/EFCore/ServerMode/IssueDetailView.xaml.cs new file mode 100644 index 0000000..391f819 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/IssueDetailView.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows.Controls; + +namespace EFCoreIssues { + public partial class IssueDetailView : UserControl { + public IssueDetailView() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/ServerMode/Issues/Issue.cs b/CS/CodeBehind/EFCore/ServerMode/Issues/Issue.cs new file mode 100644 index 0000000..c36c075 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EFCoreIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/CodeBehind/EFCore/ServerMode/Issues/IssuesContext.cs b/CS/CodeBehind/EFCore/ServerMode/Issues/IssuesContext.cs new file mode 100644 index 0000000..5ef3c63 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/Issues/IssuesContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues.Issues { + public class IssuesContext : DbContext { + static readonly DbContextOptions options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: "Test") + .Options; + public IssuesContext() + : base(options) { + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/CodeBehind/EFCore/ServerMode/Issues/IssuesContextInitializer.cs b/CS/CodeBehind/EFCore/ServerMode/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..d58b850 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/Issues/IssuesContextInitializer.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; + +namespace EFCoreIssues.Issues { + public static class IssuesContextInitializer { + public static void Seed() { + var context = new IssuesContext(); + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/CodeBehind/EFCore/ServerMode/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/EFCore/ServerMode/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..5e35561 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EFCoreIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/EFCore/ServerMode/Issues/User.cs b/CS/CodeBehind/EFCore/ServerMode/Issues/User.cs new file mode 100644 index 0000000..e3e8021 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EFCoreIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/CodeBehind/EFCore/ServerMode/MainWindow.xaml b/CS/CodeBehind/EFCore/ServerMode/MainWindow.xaml new file mode 100644 index 0000000..5cca301 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/ServerMode/MainWindow.xaml.cs b/CS/CodeBehind/EFCore/ServerMode/MainWindow.xaml.cs new file mode 100644 index 0000000..435afc3 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/MainWindow.xaml.cs @@ -0,0 +1,59 @@ +using System.Windows; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using EFCoreIssues.Issues; +using DevExpress.Mvvm.Xpf; +using System; +using System.Collections; + +namespace EFCoreIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + var context = new EFCoreIssues.Issues.IssuesContext(); + var source = new DevExpress.Data.Linq.EntityServerModeSource + { + KeyExpression = nameof(EFCoreIssues.Issues.Issue.Id), + QueryableSource = context.Issues.AsNoTracking() + }; + grid.ItemsSource = source; + LoadLookupData(); + } + + void LoadLookupData() { + var context = new EFCoreIssues.Issues.IssuesContext(); + usersLookup.ItemsSource = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadLookupData(); + } + + void OnCreateEditEntityViewModel(System.Object sender, DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs e) { + var context = new IssuesContext(); + Issue item; + if(e.Key != null) + item = context.Issues.Find(e.Key); + else { + item = new Issue() { Created = DateTime.Now }; + context.Entry(item).State = EntityState.Added; + } + e.ViewModel = new EditItemViewModel(item, new EditIssueInfo(context, (IList)usersLookup.ItemsSource)); + } + + void OnValidateRow(System.Object sender, DevExpress.Mvvm.Xpf.EditFormRowValidationArgs e) { + var context = ((EditIssueInfo)e.Tag).Context; + context.SaveChanges(); + } + + void OnValidateRowDeletion(System.Object sender, DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs e) { + var key = (int)e.Keys.Single(); + var item = new Issue() { Id = key }; + var context = new IssuesContext(); + context.Entry(item).State = EntityState.Deleted; + context.SaveChanges(); + } + } +} diff --git a/CS/CodeBehind/EFCore/ServerMode/Properties/AssemblyInfo.cs b/CS/CodeBehind/EFCore/ServerMode/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4179e62 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EFCoreIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EFCoreIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/CodeBehind/EFCore/ServerMode/Properties/Resources.Designer.cs b/CS/CodeBehind/EFCore/ServerMode/Properties/Resources.Designer.cs new file mode 100644 index 0000000..9b965de --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/Properties/Resources.Designer.cs @@ -0,0 +1,58 @@ +namespace EFCoreIssues.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", "16.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("EFCoreIssues.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 --git a/CS/CodeBehind/EFCore/ServerMode/Properties/Resources.resx b/CS/CodeBehind/EFCore/ServerMode/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/Properties/Resources.resx @@ -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 --git a/CS/CodeBehind/EFCore/ServerMode/Properties/Settings.Designer.cs b/CS/CodeBehind/EFCore/ServerMode/Properties/Settings.Designer.cs new file mode 100644 index 0000000..c156b8a --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/Properties/Settings.Designer.cs @@ -0,0 +1,18 @@ +namespace EFCoreIssues.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.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 --git a/CS/CodeBehind/EFCore/ServerMode/Properties/Settings.settings b/CS/CodeBehind/EFCore/ServerMode/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/ServerMode/ServerMode.csproj b/CS/CodeBehind/EFCore/ServerMode/ServerMode.csproj new file mode 100644 index 0000000..884ca3c --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/ServerMode.csproj @@ -0,0 +1,224 @@ + + + + + + Debug + AnyCPU + {87473A0C-89A5-1C21-97E7-6F40ACD3C060} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EFCore/ServerMode/ServerMode.sln b/CS/CodeBehind/EFCore/ServerMode/ServerMode.sln new file mode 100644 index 0000000..0c4eb75 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/ServerMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerMode", "ServerMode.csproj", "{87473A0C-89A5-1C21-97E7-6F40ACD3C060}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {87473A0C-89A5-1C21-97E7-6F40ACD3C060}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87473A0C-89A5-1C21-97E7-6F40ACD3C060}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87473A0C-89A5-1C21-97E7-6F40ACD3C060}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87473A0C-89A5-1C21-97E7-6F40ACD3C060}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/CodeBehind/EFCore/ServerMode/packages.config b/CS/CodeBehind/EFCore/ServerMode/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/CS/CodeBehind/EFCore/ServerMode/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/GridControlCRUDSimple/App.config b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/App.config similarity index 61% rename from CS/GridControlCRUDSimple/App.config rename to CS/CodeBehind/EntityFramework/InfiniteAsyncSource/App.config index 2484a16..18a536d 100644 --- a/CS/GridControlCRUDSimple/App.config +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/App.config @@ -1,15 +1,17 @@ - + -
+
- + - + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/App.xaml b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/App.xaml new file mode 100644 index 0000000..33ec22e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/App.xaml.cs b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/App.xaml.cs new file mode 100644 index 0000000..a87a8cc --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/App.xaml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EntityFrameworkIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); + } + } +} diff --git a/CS/GridControlCRUDSimple/GridControlCRUDSimple.csproj b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.csproj similarity index 63% rename from CS/GridControlCRUDSimple/GridControlCRUDSimple.csproj rename to CS/CodeBehind/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.csproj index df3c2a6..6b708da 100644 --- a/CS/GridControlCRUDSimple/GridControlCRUDSimple.csproj +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.csproj @@ -1,23 +1,23 @@ - + Debug AnyCPU - {9E2883B9-744A-48BF-B25A-EA4B2D435C9D} + {15015E00-900F-7BBE-4987-3CFC3042F716} WinExe - GridControlCRUDSimple - GridControlCRUDSimple - v4.6.1 + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 + true true true - AnyCPU @@ -39,20 +39,11 @@ 4 - - - - - - - - - - ..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.dll + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll - ..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.SqlServer.dll + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll @@ -70,29 +61,43 @@ + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + MSBuild:Compile Designer - - Nothwind\Category.cs - - - Nothwind\NorthwindContext.cs - - - Nothwind\Product.cs - - - Nothwind\NorthwindContextInitializer.cs - - - Northwind.DataModel\CategoryInfo.cs - - - Northwind.DataModel\ProductInfo.cs - MSBuild:Compile Designer @@ -101,6 +106,11 @@ App.xaml Code + + + + + MainWindow.xaml Code @@ -133,14 +143,13 @@ - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - + + - - + + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.sln b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.sln new file mode 100644 index 0000000..1241d47 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfiniteAsyncSource", "InfiniteAsyncSource.csproj", "{15015E00-900F-7BBE-4987-3CFC3042F716}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {15015E00-900F-7BBE-4987-3CFC3042F716}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15015E00-900F-7BBE-4987-3CFC3042F716}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15015E00-900F-7BBE-4987-3CFC3042F716}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15015E00-900F-7BBE-4987-3CFC3042F716}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/Issue.cs b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/Issue.cs new file mode 100644 index 0000000..e6b9876 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/IssuesContext.cs b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/IssuesContext.cs similarity index 88% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/IssuesContext.cs rename to CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/IssuesContext.cs index 359fe29..5306779 100644 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/IssuesContext.cs +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/IssuesContext.cs @@ -1,6 +1,6 @@ -using System.Data.Entity; +using System.Data.Entity; -namespace GridControlCRUDMVVMInfiniteAsyncSource { +namespace EntityFrameworkIssues.Issues { public class IssuesContext : DbContext { static IssuesContext() { Database.SetInitializer(new IssuesContextInitializer()); diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/IssuesContextInitializer.cs b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/IssuesContextInitializer.cs similarity index 62% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/IssuesContextInitializer.cs rename to CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/IssuesContextInitializer.cs index 6272e62..260c170 100644 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext/IssuesContextInitializer.cs +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/IssuesContextInitializer.cs @@ -1,32 +1,48 @@ -using System; +using System; using System.Data.Entity; using System.Linq; -namespace GridControlCRUDMVVMInfiniteAsyncSource { +namespace EntityFrameworkIssues.Issues { public class IssuesContextInitializer : DropCreateDatabaseIfModelChanges { //: DropCreateDatabaseAlways { + public static void ResetData() { + using(var context = new IssuesContext()) { + context.Users.Load(); + context.Users.RemoveRange(context.Users); + context.SaveChanges(); + CreateData(context); + } + } + protected override void Seed(IssuesContext context) { base.Seed(context); + CreateData(context); + } + + static void CreateData(IssuesContext context) { var users = OutlookDataGenerator.Users - .Select(x => { + .Select(x => + { var split = x.Split(' '); - return new User() { + return new User() + { FirstName = split[0], LastName = split[1] - }; + }; }) .ToArray(); context.Users.AddRange(users); context.SaveChanges(); - var rnd = new Random(); + var rnd = new Random(0); var issues = Enumerable.Range(0, 1000) - .Select(i => new Issue() { + .Select(i => new Issue() + { Subject = OutlookDataGenerator.GetSubject(), UserId = users[rnd.Next(users.Length)].Id, - Created = DateTime.Today.AddDays(-rnd.Next(30) - 1), + Created = DateTime.Today.AddDays(-rnd.Next(30)), Priority = OutlookDataGenerator.GetPriority(), Votes = rnd.Next(100), }) diff --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..c5a164e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/User.cs b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/User.cs new file mode 100644 index 0000000..0a2fbf6 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EntityFrameworkIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..efd13da --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.cs b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.cs new file mode 100644 index 0000000..1d1d7b4 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.cs @@ -0,0 +1,76 @@ +using System.Windows; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Data.Entity; + +namespace EntityFrameworkIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + var source = new InfiniteAsyncSource + { + ElementType = typeof(EntityFrameworkIssues.Issues.Issue), + KeyProperty = nameof(EntityFrameworkIssues.Issues.Issue.Id) + }; + source.FetchRows += OnFetchRows; + source.GetTotalSummaries += OnGetTotalSummaries; + grid.ItemsSource = source; + LoadLookupData(); + } + + void OnFetchRows(System.Object sender, DevExpress.Xpf.Data.FetchRowsAsyncEventArgs e) { + e.Result = Task.Run(() => + { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + var queryable = context.Issues.AsNoTracking() + .SortBy(e.SortOrder, defaultUniqueSortPropertyName: nameof(EntityFrameworkIssues.Issues.Issue.Id)) + .Where(MakeFilterExpression(e.Filter)); + return queryable.Skip(e.Skip).Take(e.Take ?? 100).ToArray(); + }); + } + + void OnGetTotalSummaries(System.Object sender, DevExpress.Xpf.Data.GetSummariesAsyncEventArgs e) { + e.Result = Task.Run(() => + { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + var queryable = context.Issues.Where(MakeFilterExpression(e.Filter)); + return queryable.GetSummaries(e.Summaries); + }); + } + + System.Linq.Expressions.Expression> MakeFilterExpression(DevExpress.Data.Filtering.CriteriaOperator filter) { + var converter = new DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(); + return converter.Convert(filter); + } + + void OnValidateRow(System.Object sender, DevExpress.Xpf.Grid.GridRowValidationEventArgs e) { + var row = (EntityFrameworkIssues.Issues.Issue)e.Row; + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + context.Entry(row).State = e.IsNewItem + ? EntityState.Added + : EntityState.Modified; + try { + context.SaveChanges(); + } finally { + context.Entry(row).State = EntityState.Detached; + } + } + + void OnValidateRowDeletion(System.Object sender, DevExpress.Xpf.Grid.GridDeleteRowsValidationEventArgs e) { + var row = (EntityFrameworkIssues.Issues.Issue)e.Rows.Single(); + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + context.Entry(row).State = EntityState.Deleted; + context.SaveChanges(); + } + + void LoadLookupData() { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + usersLookup.ItemsSource = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadLookupData(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/AssemblyInfo.cs b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ad2761d --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EntityFrameworkIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EntityFrameworkIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/Resources.Designer.cs b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e5eb50e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace EntityFrameworkIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EntityFrameworkIssues.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 --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/Resources.resx b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/Resources.resx @@ -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 --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/Settings.Designer.cs b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/Settings.Designer.cs new file mode 100644 index 0000000..e790c5b --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace EntityFrameworkIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/Settings.settings b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/GridControlCRUDMVVM/packages.config b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/packages.config similarity index 54% rename from CS/GridControlCRUDMVVM/packages.config rename to CS/CodeBehind/EntityFramework/InfiniteAsyncSource/packages.config index 9985587..3424f94 100644 --- a/CS/GridControlCRUDMVVM/packages.config +++ b/CS/CodeBehind/EntityFramework/InfiniteAsyncSource/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/CS/GridControlCRUDMVVM/App.config b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/App.config similarity index 61% rename from CS/GridControlCRUDMVVM/App.config rename to CS/CodeBehind/EntityFramework/InstantFeedbackMode/App.config index 2484a16..18a536d 100644 --- a/CS/GridControlCRUDMVVM/App.config +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/App.config @@ -1,15 +1,17 @@ - + -
+
- + - + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/App.xaml b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/App.xaml new file mode 100644 index 0000000..33ec22e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/App.xaml.cs b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/App.xaml.cs new file mode 100644 index 0000000..a87a8cc --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/App.xaml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EntityFrameworkIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/EditIssueInfo.cs b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/EditIssueInfo.cs new file mode 100644 index 0000000..6c86f13 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/EditIssueInfo.cs @@ -0,0 +1,14 @@ +using DevExpress.Mvvm; +using System.Collections; +using EntityFrameworkIssues.Issues; + +namespace EntityFrameworkIssues { + public class EditIssueInfo : BindableBase { + public EditIssueInfo(IssuesContext context, IList users) { + Context = context; + Users = users; + } + public IssuesContext Context { get; } + public IList Users { get; } + } +} \ No newline at end of file diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/GridControlCRUDMVVMInfiniteAsyncSource.csproj b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.csproj similarity index 54% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/GridControlCRUDMVVMInfiniteAsyncSource.csproj rename to CS/CodeBehind/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.csproj index e3f1af8..9a73bc7 100644 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/GridControlCRUDMVVMInfiniteAsyncSource.csproj +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.csproj @@ -1,23 +1,23 @@ - + - + Debug AnyCPU - {99F77CC9-A05A-4064-B0A9-63E0B93ED156} + {BA2F5788-A3EB-7034-A5F0-B3DB3950B3DD} WinExe - GridControlCRUDMVVMInfiniteAsyncSource - GridControlCRUDMVVMInfiniteAsyncSource - v4.6.1 + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 + true true true - AnyCPU @@ -39,24 +39,11 @@ 4 - - - - True - - - - - - - - - - ..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.dll + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll - ..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.SqlServer.dll + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll @@ -74,56 +61,65 @@ + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + MSBuild:Compile Designer - - Common.DataModel\DataProviderAsyncExtensions.cs - - - Common.DataModel\DesignTimeDataProvider.cs - - - Common.DataModel\EntityFrameworkDataProvider.cs - - - Common.DataModel\IDataProvider.cs - - - Common.ViewModel\CommandArgs\EntityCreateArgs.cs - - - Common.ViewModel\CommandArgs\EntityUpdateArgs.cs - - - Common.ViewModel\VirtualCollectionViewModel.cs - - - Common.ViewModel\CommandArgs\RefreshArgs.cs - - - Common.View\GridControlDeleteRefreshBehavior.cs - - - - - - - - - - - MSBuild:Compile Designer + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + App.xaml Code + + + + + MainWindow.xaml Code @@ -156,14 +152,13 @@ - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - + + - + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.sln b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.sln new file mode 100644 index 0000000..de155ca --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantFeedbackMode", "InstantFeedbackMode.csproj", "{BA2F5788-A3EB-7034-A5F0-B3DB3950B3DD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BA2F5788-A3EB-7034-A5F0-B3DB3950B3DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA2F5788-A3EB-7034-A5F0-B3DB3950B3DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA2F5788-A3EB-7034-A5F0-B3DB3950B3DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA2F5788-A3EB-7034-A5F0-B3DB3950B3DD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml new file mode 100644 index 0000000..23a72d0 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml.cs b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml.cs new file mode 100644 index 0000000..cf7d354 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows.Controls; + +namespace EntityFrameworkIssues { + public partial class IssueDetailView : UserControl { + public IssueDetailView() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/Issue.cs b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/Issue.cs new file mode 100644 index 0000000..e6b9876 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/IssuesContext.cs b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/IssuesContext.cs new file mode 100644 index 0000000..5306779 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/IssuesContext.cs @@ -0,0 +1,23 @@ +using System.Data.Entity; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContext : DbContext { + static IssuesContext() { + Database.SetInitializer(new IssuesContextInitializer()); + } + public IssuesContext() { } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .HasIndex(x => x.Created); + + modelBuilder.Entity() + .HasIndex(x => x.Votes); + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/IssuesContextInitializer.cs b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..260c170 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/IssuesContextInitializer.cs @@ -0,0 +1,55 @@ +using System; +using System.Data.Entity; +using System.Linq; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContextInitializer + : DropCreateDatabaseIfModelChanges { + //: DropCreateDatabaseAlways { + + public static void ResetData() { + using(var context = new IssuesContext()) { + context.Users.Load(); + context.Users.RemoveRange(context.Users); + context.SaveChanges(); + CreateData(context); + } + } + + protected override void Seed(IssuesContext context) { + base.Seed(context); + CreateData(context); + } + + static void CreateData(IssuesContext context) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..c5a164e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/User.cs b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/User.cs new file mode 100644 index 0000000..0a2fbf6 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EntityFrameworkIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml new file mode 100644 index 0000000..011c714 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml.cs b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml.cs new file mode 100644 index 0000000..556f4a4 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml.cs @@ -0,0 +1,62 @@ +using System.Windows; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Data.Entity; +using EntityFrameworkIssues.Issues; +using DevExpress.Mvvm.Xpf; +using System; +using System.Collections; + +namespace EntityFrameworkIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + var source = new DevExpress.Data.Linq.EntityInstantFeedbackSource + { + KeyExpression = nameof(EntityFrameworkIssues.Issues.Issue.Id) + }; + source.GetQueryable += (sender, e) => + { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + e.QueryableSource = context.Issues.AsNoTracking(); + }; + grid.ItemsSource = source; + LoadLookupData(); + } + + void LoadLookupData() { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + usersLookup.ItemsSource = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadLookupData(); + } + + void OnCreateEditEntityViewModel(System.Object sender, DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs e) { + var context = new IssuesContext(); + Issue item; + if(e.Key != null) + item = context.Issues.Find(e.Key); + else { + item = new Issue() { Created = DateTime.Now }; + context.Entry(item).State = EntityState.Added; + } + e.ViewModel = new EditItemViewModel(item, new EditIssueInfo(context, (IList)usersLookup.ItemsSource)); + } + + void OnValidateRow(System.Object sender, DevExpress.Mvvm.Xpf.EditFormRowValidationArgs e) { + var context = ((EditIssueInfo)e.Tag).Context; + context.SaveChanges(); + } + + void OnValidateRowDeletion(System.Object sender, DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs e) { + var key = (int)e.Keys.Single(); + var item = new Issue() { Id = key }; + var context = new IssuesContext(); + context.Entry(item).State = EntityState.Deleted; + context.SaveChanges(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/AssemblyInfo.cs b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ad2761d --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EntityFrameworkIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EntityFrameworkIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/Resources.Designer.cs b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e5eb50e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace EntityFrameworkIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EntityFrameworkIssues.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 --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/Resources.resx b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/Resources.resx @@ -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 --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/Settings.Designer.cs b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/Settings.Designer.cs new file mode 100644 index 0000000..e790c5b --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace EntityFrameworkIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/Settings.settings b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/GridControlCRUDMVVMAsync/packages.config b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/packages.config similarity index 54% rename from CS/GridControlCRUDMVVMAsync/packages.config rename to CS/CodeBehind/EntityFramework/InstantFeedbackMode/packages.config index 9985587..3424f94 100644 --- a/CS/GridControlCRUDMVVMAsync/packages.config +++ b/CS/CodeBehind/EntityFramework/InstantFeedbackMode/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/CS/GridControlCRUDMVVMAsync/App.config b/CS/CodeBehind/EntityFramework/LocalData/App.config similarity index 61% rename from CS/GridControlCRUDMVVMAsync/App.config rename to CS/CodeBehind/EntityFramework/LocalData/App.config index 2484a16..18a536d 100644 --- a/CS/GridControlCRUDMVVMAsync/App.config +++ b/CS/CodeBehind/EntityFramework/LocalData/App.config @@ -1,15 +1,17 @@ - + -
+
- + - + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/LocalData/App.xaml b/CS/CodeBehind/EntityFramework/LocalData/App.xaml new file mode 100644 index 0000000..33ec22e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/CodeBehind/EntityFramework/LocalData/App.xaml.cs b/CS/CodeBehind/EntityFramework/LocalData/App.xaml.cs new file mode 100644 index 0000000..a87a8cc --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/App.xaml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EntityFrameworkIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/LocalData/Issues/Issue.cs b/CS/CodeBehind/EntityFramework/LocalData/Issues/Issue.cs new file mode 100644 index 0000000..e6b9876 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/CodeBehind/EntityFramework/LocalData/Issues/IssuesContext.cs b/CS/CodeBehind/EntityFramework/LocalData/Issues/IssuesContext.cs new file mode 100644 index 0000000..5306779 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/Issues/IssuesContext.cs @@ -0,0 +1,23 @@ +using System.Data.Entity; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContext : DbContext { + static IssuesContext() { + Database.SetInitializer(new IssuesContextInitializer()); + } + public IssuesContext() { } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .HasIndex(x => x.Created); + + modelBuilder.Entity() + .HasIndex(x => x.Votes); + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/CodeBehind/EntityFramework/LocalData/Issues/IssuesContextInitializer.cs b/CS/CodeBehind/EntityFramework/LocalData/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..260c170 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/Issues/IssuesContextInitializer.cs @@ -0,0 +1,55 @@ +using System; +using System.Data.Entity; +using System.Linq; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContextInitializer + : DropCreateDatabaseIfModelChanges { + //: DropCreateDatabaseAlways { + + public static void ResetData() { + using(var context = new IssuesContext()) { + context.Users.Load(); + context.Users.RemoveRange(context.Users); + context.SaveChanges(); + CreateData(context); + } + } + + protected override void Seed(IssuesContext context) { + base.Seed(context); + CreateData(context); + } + + static void CreateData(IssuesContext context) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/LocalData/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/EntityFramework/LocalData/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..c5a164e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/LocalData/Issues/User.cs b/CS/CodeBehind/EntityFramework/LocalData/Issues/User.cs new file mode 100644 index 0000000..0a2fbf6 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EntityFrameworkIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/CodeBehind/EntityFramework/LocalData/LocalData.csproj b/CS/CodeBehind/EntityFramework/LocalData/LocalData.csproj new file mode 100644 index 0000000..425e6cc --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/LocalData.csproj @@ -0,0 +1,155 @@ + + + + + + Debug + AnyCPU + {F486CC2C-3626-63E6-E2FE-02205E6ACC1C} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/LocalData/LocalData.sln b/CS/CodeBehind/EntityFramework/LocalData/LocalData.sln new file mode 100644 index 0000000..163da8c --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/LocalData.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalData", "LocalData.csproj", "{F486CC2C-3626-63E6-E2FE-02205E6ACC1C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F486CC2C-3626-63E6-E2FE-02205E6ACC1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F486CC2C-3626-63E6-E2FE-02205E6ACC1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F486CC2C-3626-63E6-E2FE-02205E6ACC1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F486CC2C-3626-63E6-E2FE-02205E6ACC1C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/CodeBehind/EntityFramework/LocalData/MainWindow.xaml b/CS/CodeBehind/EntityFramework/LocalData/MainWindow.xaml new file mode 100644 index 0000000..b21e0ba --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/MainWindow.xaml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/LocalData/MainWindow.xaml.cs b/CS/CodeBehind/EntityFramework/LocalData/MainWindow.xaml.cs new file mode 100644 index 0000000..1d1b154 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/MainWindow.xaml.cs @@ -0,0 +1,34 @@ +using System.Windows; +using System.Linq; + +namespace EntityFrameworkIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + LoadData(); + } + EntityFrameworkIssues.Issues.IssuesContext _Context; + + void LoadData() { + _Context = new EntityFrameworkIssues.Issues.IssuesContext(); + grid.ItemsSource = _Context.Users.ToList(); + } + + void OnValidateRow(System.Object sender, DevExpress.Xpf.Grid.GridRowValidationEventArgs e) { + var row = (EntityFrameworkIssues.Issues.User)e.Row; + if(e.IsNewItem) + _Context.Users.Add(row); + _Context.SaveChanges(); + } + + void OnValidateRowDeletion(System.Object sender, DevExpress.Xpf.Grid.GridDeleteRowsValidationEventArgs e) { + var row = (EntityFrameworkIssues.Issues.User)e.Rows.Single(); + _Context.Users.Remove(row); + _Context.SaveChanges(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadData(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/LocalData/Properties/AssemblyInfo.cs b/CS/CodeBehind/EntityFramework/LocalData/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ad2761d --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EntityFrameworkIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EntityFrameworkIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/CodeBehind/EntityFramework/LocalData/Properties/Resources.Designer.cs b/CS/CodeBehind/EntityFramework/LocalData/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e5eb50e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace EntityFrameworkIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EntityFrameworkIssues.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 --git a/CS/CodeBehind/EntityFramework/LocalData/Properties/Resources.resx b/CS/CodeBehind/EntityFramework/LocalData/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/Properties/Resources.resx @@ -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 --git a/CS/CodeBehind/EntityFramework/LocalData/Properties/Settings.Designer.cs b/CS/CodeBehind/EntityFramework/LocalData/Properties/Settings.Designer.cs new file mode 100644 index 0000000..e790c5b --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace EntityFrameworkIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/CodeBehind/EntityFramework/LocalData/Properties/Settings.settings b/CS/CodeBehind/EntityFramework/LocalData/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/LocalData/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/packages.config b/CS/CodeBehind/EntityFramework/LocalData/packages.config similarity index 54% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/packages.config rename to CS/CodeBehind/EntityFramework/LocalData/packages.config index 9985587..3424f94 100644 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/packages.config +++ b/CS/CodeBehind/EntityFramework/LocalData/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/App.config b/CS/CodeBehind/EntityFramework/PagedAsyncSource/App.config similarity index 61% rename from CS/GridControlCRUDMVVMInfiniteAsyncSource/App.config rename to CS/CodeBehind/EntityFramework/PagedAsyncSource/App.config index 2484a16..18a536d 100644 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/App.config +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/App.config @@ -1,15 +1,17 @@ - + -
+
- + - + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/App.xaml b/CS/CodeBehind/EntityFramework/PagedAsyncSource/App.xaml new file mode 100644 index 0000000..33ec22e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/App.xaml.cs b/CS/CodeBehind/EntityFramework/PagedAsyncSource/App.xaml.cs new file mode 100644 index 0000000..a87a8cc --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/App.xaml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EntityFrameworkIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/Issue.cs b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/Issue.cs new file mode 100644 index 0000000..e6b9876 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/IssuesContext.cs b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/IssuesContext.cs new file mode 100644 index 0000000..5306779 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/IssuesContext.cs @@ -0,0 +1,23 @@ +using System.Data.Entity; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContext : DbContext { + static IssuesContext() { + Database.SetInitializer(new IssuesContextInitializer()); + } + public IssuesContext() { } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .HasIndex(x => x.Created); + + modelBuilder.Entity() + .HasIndex(x => x.Votes); + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/IssuesContextInitializer.cs b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..260c170 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/IssuesContextInitializer.cs @@ -0,0 +1,55 @@ +using System; +using System.Data.Entity; +using System.Linq; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContextInitializer + : DropCreateDatabaseIfModelChanges { + //: DropCreateDatabaseAlways { + + public static void ResetData() { + using(var context = new IssuesContext()) { + context.Users.Load(); + context.Users.RemoveRange(context.Users); + context.SaveChanges(); + CreateData(context); + } + } + + protected override void Seed(IssuesContext context) { + base.Seed(context); + CreateData(context); + } + + static void CreateData(IssuesContext context) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..c5a164e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/User.cs b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/User.cs new file mode 100644 index 0000000..0a2fbf6 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EntityFrameworkIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml b/CS/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..b543f13 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml.cs b/CS/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml.cs new file mode 100644 index 0000000..16a9d77 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml.cs @@ -0,0 +1,71 @@ +using System.Windows; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Data.Entity; + +namespace EntityFrameworkIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + var source = new PagedAsyncSource + { + ElementType = typeof(EntityFrameworkIssues.Issues.Issue), + KeyProperty = nameof(EntityFrameworkIssues.Issues.Issue.Id), + PageNavigationMode = PageNavigationMode.ArbitraryWithTotalPageCount + }; + source.FetchPage += OnFetchPage; + source.GetTotalSummaries += OnGetTotalSummaries; + grid.ItemsSource = source; + LoadLookupData(); + } + + void OnFetchPage(System.Object sender, DevExpress.Xpf.Data.FetchPageAsyncEventArgs e) { + const int pageTakeCount = 5; + e.Result = Task.Run(() => + { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + var queryable = context.Issues.AsNoTracking() + .SortBy(e.SortOrder, defaultUniqueSortPropertyName: nameof(EntityFrameworkIssues.Issues.Issue.Id)) + .Where(MakeFilterExpression(e.Filter)); + return queryable.Skip(e.Skip).Take(e.Take * pageTakeCount).ToArray(); + }); + } + + void OnGetTotalSummaries(System.Object sender, DevExpress.Xpf.Data.GetSummariesAsyncEventArgs e) { + e.Result = Task.Run(() => + { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + var queryable = context.Issues.Where(MakeFilterExpression(e.Filter)); + return queryable.GetSummaries(e.Summaries); + }); + } + + System.Linq.Expressions.Expression> MakeFilterExpression(DevExpress.Data.Filtering.CriteriaOperator filter) { + var converter = new DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(); + return converter.Convert(filter); + } + + void OnValidateRow(System.Object sender, DevExpress.Xpf.Grid.GridRowValidationEventArgs e) { + var row = (EntityFrameworkIssues.Issues.Issue)e.Row; + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + context.Entry(row).State = e.IsNewItem + ? EntityState.Added + : EntityState.Modified; + try { + context.SaveChanges(); + } finally { + context.Entry(row).State = EntityState.Detached; + } + } + + void LoadLookupData() { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + usersLookup.ItemsSource = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadLookupData(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/PagedAsyncSource.csproj b/CS/CodeBehind/EntityFramework/PagedAsyncSource/PagedAsyncSource.csproj new file mode 100644 index 0000000..5c15039 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/PagedAsyncSource.csproj @@ -0,0 +1,155 @@ + + + + + + Debug + AnyCPU + {F88441FF-7433-8D05-B0D4-D04A1B5FD597} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/PagedAsyncSource.sln b/CS/CodeBehind/EntityFramework/PagedAsyncSource/PagedAsyncSource.sln new file mode 100644 index 0000000..bccdf6a --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/PagedAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagedAsyncSource", "PagedAsyncSource.csproj", "{F88441FF-7433-8D05-B0D4-D04A1B5FD597}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F88441FF-7433-8D05-B0D4-D04A1B5FD597}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F88441FF-7433-8D05-B0D4-D04A1B5FD597}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F88441FF-7433-8D05-B0D4-D04A1B5FD597}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F88441FF-7433-8D05-B0D4-D04A1B5FD597}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/AssemblyInfo.cs b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ad2761d --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EntityFrameworkIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EntityFrameworkIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/Resources.Designer.cs b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e5eb50e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace EntityFrameworkIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EntityFrameworkIssues.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 --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/Resources.resx b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/Resources.resx @@ -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 --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/Settings.Designer.cs b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/Settings.Designer.cs new file mode 100644 index 0000000..e790c5b --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace EntityFrameworkIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/Settings.settings b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/GridControlCRUDSimple/packages.config b/CS/CodeBehind/EntityFramework/PagedAsyncSource/packages.config similarity index 54% rename from CS/GridControlCRUDSimple/packages.config rename to CS/CodeBehind/EntityFramework/PagedAsyncSource/packages.config index 9985587..3424f94 100644 --- a/CS/GridControlCRUDSimple/packages.config +++ b/CS/CodeBehind/EntityFramework/PagedAsyncSource/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/ServerMode/App.config b/CS/CodeBehind/EntityFramework/ServerMode/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/ServerMode/App.xaml b/CS/CodeBehind/EntityFramework/ServerMode/App.xaml new file mode 100644 index 0000000..33ec22e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/CodeBehind/EntityFramework/ServerMode/App.xaml.cs b/CS/CodeBehind/EntityFramework/ServerMode/App.xaml.cs new file mode 100644 index 0000000..a87a8cc --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/App.xaml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EntityFrameworkIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/ServerMode/EditIssueInfo.cs b/CS/CodeBehind/EntityFramework/ServerMode/EditIssueInfo.cs new file mode 100644 index 0000000..6c86f13 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/EditIssueInfo.cs @@ -0,0 +1,14 @@ +using DevExpress.Mvvm; +using System.Collections; +using EntityFrameworkIssues.Issues; + +namespace EntityFrameworkIssues { + public class EditIssueInfo : BindableBase { + public EditIssueInfo(IssuesContext context, IList users) { + Context = context; + Users = users; + } + public IssuesContext Context { get; } + public IList Users { get; } + } +} \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/ServerMode/IssueDetailView.xaml b/CS/CodeBehind/EntityFramework/ServerMode/IssueDetailView.xaml new file mode 100644 index 0000000..23a72d0 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/ServerMode/IssueDetailView.xaml.cs b/CS/CodeBehind/EntityFramework/ServerMode/IssueDetailView.xaml.cs new file mode 100644 index 0000000..cf7d354 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/IssueDetailView.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows.Controls; + +namespace EntityFrameworkIssues { + public partial class IssueDetailView : UserControl { + public IssueDetailView() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/ServerMode/Issues/Issue.cs b/CS/CodeBehind/EntityFramework/ServerMode/Issues/Issue.cs new file mode 100644 index 0000000..e6b9876 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/CodeBehind/EntityFramework/ServerMode/Issues/IssuesContext.cs b/CS/CodeBehind/EntityFramework/ServerMode/Issues/IssuesContext.cs new file mode 100644 index 0000000..5306779 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/Issues/IssuesContext.cs @@ -0,0 +1,23 @@ +using System.Data.Entity; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContext : DbContext { + static IssuesContext() { + Database.SetInitializer(new IssuesContextInitializer()); + } + public IssuesContext() { } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .HasIndex(x => x.Created); + + modelBuilder.Entity() + .HasIndex(x => x.Votes); + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/CodeBehind/EntityFramework/ServerMode/Issues/IssuesContextInitializer.cs b/CS/CodeBehind/EntityFramework/ServerMode/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..260c170 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/Issues/IssuesContextInitializer.cs @@ -0,0 +1,55 @@ +using System; +using System.Data.Entity; +using System.Linq; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContextInitializer + : DropCreateDatabaseIfModelChanges { + //: DropCreateDatabaseAlways { + + public static void ResetData() { + using(var context = new IssuesContext()) { + context.Users.Load(); + context.Users.RemoveRange(context.Users); + context.SaveChanges(); + CreateData(context); + } + } + + protected override void Seed(IssuesContext context) { + base.Seed(context); + CreateData(context); + } + + static void CreateData(IssuesContext context) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/ServerMode/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/EntityFramework/ServerMode/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..c5a164e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/ServerMode/Issues/User.cs b/CS/CodeBehind/EntityFramework/ServerMode/Issues/User.cs new file mode 100644 index 0000000..0a2fbf6 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EntityFrameworkIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml b/CS/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml new file mode 100644 index 0000000..011c714 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml.cs b/CS/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml.cs new file mode 100644 index 0000000..6706ef3 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml.cs @@ -0,0 +1,59 @@ +using System.Windows; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Data.Entity; +using EntityFrameworkIssues.Issues; +using DevExpress.Mvvm.Xpf; +using System; +using System.Collections; + +namespace EntityFrameworkIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + var source = new DevExpress.Data.Linq.EntityServerModeSource + { + KeyExpression = nameof(EntityFrameworkIssues.Issues.Issue.Id), + QueryableSource = context.Issues.AsNoTracking() + }; + grid.ItemsSource = source; + LoadLookupData(); + } + + void LoadLookupData() { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + usersLookup.ItemsSource = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadLookupData(); + } + + void OnCreateEditEntityViewModel(System.Object sender, DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs e) { + var context = new IssuesContext(); + Issue item; + if(e.Key != null) + item = context.Issues.Find(e.Key); + else { + item = new Issue() { Created = DateTime.Now }; + context.Entry(item).State = EntityState.Added; + } + e.ViewModel = new EditItemViewModel(item, new EditIssueInfo(context, (IList)usersLookup.ItemsSource)); + } + + void OnValidateRow(System.Object sender, DevExpress.Mvvm.Xpf.EditFormRowValidationArgs e) { + var context = ((EditIssueInfo)e.Tag).Context; + context.SaveChanges(); + } + + void OnValidateRowDeletion(System.Object sender, DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs e) { + var key = (int)e.Keys.Single(); + var item = new Issue() { Id = key }; + var context = new IssuesContext(); + context.Entry(item).State = EntityState.Deleted; + context.SaveChanges(); + } + } +} diff --git a/CS/CodeBehind/EntityFramework/ServerMode/Properties/AssemblyInfo.cs b/CS/CodeBehind/EntityFramework/ServerMode/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ad2761d --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EntityFrameworkIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EntityFrameworkIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/CodeBehind/EntityFramework/ServerMode/Properties/Resources.Designer.cs b/CS/CodeBehind/EntityFramework/ServerMode/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e5eb50e --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace EntityFrameworkIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EntityFrameworkIssues.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 --git a/CS/CodeBehind/EntityFramework/ServerMode/Properties/Resources.resx b/CS/CodeBehind/EntityFramework/ServerMode/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/Properties/Resources.resx @@ -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 --git a/CS/CodeBehind/EntityFramework/ServerMode/Properties/Settings.Designer.cs b/CS/CodeBehind/EntityFramework/ServerMode/Properties/Settings.Designer.cs new file mode 100644 index 0000000..e790c5b --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace EntityFrameworkIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/CodeBehind/EntityFramework/ServerMode/Properties/Settings.settings b/CS/CodeBehind/EntityFramework/ServerMode/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/GridControlCRUDMVVM/GridControlCRUDMVVM.csproj b/CS/CodeBehind/EntityFramework/ServerMode/ServerMode.csproj similarity index 53% rename from CS/GridControlCRUDMVVM/GridControlCRUDMVVM.csproj rename to CS/CodeBehind/EntityFramework/ServerMode/ServerMode.csproj index fd42eb2..0edd32d 100644 --- a/CS/GridControlCRUDMVVM/GridControlCRUDMVVM.csproj +++ b/CS/CodeBehind/EntityFramework/ServerMode/ServerMode.csproj @@ -1,23 +1,23 @@ - + - + Debug AnyCPU - {69E85A61-E7D4-4C9D-A433-13E742AE30BC} + {8606B7BB-3F4D-C687-BBFA-13D6D10B366D} WinExe - GridControlCRUDMVVM - GridControlCRUDMVVM - v4.6.1 + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 + true true true - AnyCPU @@ -39,23 +39,11 @@ 4 - - - - True - - - - - - - - - ..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.dll + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll - ..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.SqlServer.dll + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll @@ -73,62 +61,65 @@ + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + MSBuild:Compile Designer - - DataModel\DesignTimeDataProvider.cs - - - DataModel\EntityFrameworkDataProvider.cs - - - DataModel\IDataProvider.cs - - - Northwind.DataModel\CategoryInfo.cs - - - Northwind.DataModel\NorthwindDataStorage.cs - - - Northwind.DataModel\NorthwindDataStorageFactory.cs - - - Northwind.DataModel\ProductInfo.cs - - - Nothwind\Category.cs - - - Nothwind\NorthwindContext.cs - - - Nothwind\Product.cs - - - Nothwind\NorthwindContextInitializer.cs - - - Common.ViewModel\CollectionViewModel.cs - - - Common.ViewModel\CommandArgs\RefreshArgs.cs - - - View\GridControlDeleteRefreshBehavior.cs - - MSBuild:Compile Designer + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + App.xaml Code + + + + + MainWindow.xaml Code @@ -161,14 +152,13 @@ - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - + + - + \ No newline at end of file diff --git a/CS/CodeBehind/EntityFramework/ServerMode/ServerMode.sln b/CS/CodeBehind/EntityFramework/ServerMode/ServerMode.sln new file mode 100644 index 0000000..8b8b2d4 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/ServerMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerMode", "ServerMode.csproj", "{8606B7BB-3F4D-C687-BBFA-13D6D10B366D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8606B7BB-3F4D-C687-BBFA-13D6D10B366D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8606B7BB-3F4D-C687-BBFA-13D6D10B366D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8606B7BB-3F4D-C687-BBFA-13D6D10B366D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8606B7BB-3F4D-C687-BBFA-13D6D10B366D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/CodeBehind/EntityFramework/ServerMode/packages.config b/CS/CodeBehind/EntityFramework/ServerMode/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/CodeBehind/EntityFramework/ServerMode/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/App.config b/CS/CodeBehind/XPO/InfiniteAsyncSource/App.config new file mode 100644 index 0000000..f473aab --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/App.xaml b/CS/CodeBehind/XPO/InfiniteAsyncSource/App.xaml new file mode 100644 index 0000000..1e81d99 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/App.xaml.cs b/CS/CodeBehind/XPO/InfiniteAsyncSource/App.xaml.cs new file mode 100644 index 0000000..3f603e9 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/App.xaml.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using XPOIssues.Issues; + +namespace XPOIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + ConnectionHelper.Connect(); + DemoDataHelper.Seed(); + } + } +} diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/InfiniteAsyncSource.csproj b/CS/CodeBehind/XPO/InfiniteAsyncSource/InfiniteAsyncSource.csproj new file mode 100644 index 0000000..dc74ed7 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/InfiniteAsyncSource.csproj @@ -0,0 +1,159 @@ + + + + + + Debug + AnyCPU + {E6B48ECF-D1AE-2578-8ED2-6C2F30D1EE45} + WinExe + XPOIssues + XPOIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/InfiniteAsyncSource.sln b/CS/CodeBehind/XPO/InfiniteAsyncSource/InfiniteAsyncSource.sln new file mode 100644 index 0000000..55d5b45 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/InfiniteAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfiniteAsyncSource", "InfiniteAsyncSource.csproj", "{E6B48ECF-D1AE-2578-8ED2-6C2F30D1EE45}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E6B48ECF-D1AE-2578-8ED2-6C2F30D1EE45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6B48ECF-D1AE-2578-8ED2-6C2F30D1EE45}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6B48ECF-D1AE-2578-8ED2-6C2F30D1EE45}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E6B48ECF-D1AE-2578-8ED2-6C2F30D1EE45}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/ConnectionHelper.cs b/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/ConnectionHelper.cs new file mode 100644 index 0000000..01dd20a --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/ConnectionHelper.cs @@ -0,0 +1,29 @@ +using DevExpress.Xpo; +using DevExpress.Xpo.DB; +using DevExpress.Xpo.Metadata; +using System; +using System.Configuration; + +namespace XPOIssues.Issues { + public static class ConnectionHelper { + + static readonly Type[] PersistentTypes = new Type[]{ + typeof(Issue), + typeof(User) + }; + + public static void Connect() { + XpoDefault.DataLayer = CreateDataLayer(true); + } + + static IDataLayer CreateDataLayer(bool threadSafe) { + string connStr = ConfigurationManager.ConnectionStrings["XpoTutorial"]?.ConnectionString ?? "XpoProvider=InMemoryDataStore"; + //connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + ReflectionDictionary dictionary = new ReflectionDictionary(); + dictionary.GetDataStoreSchema(PersistentTypes); // Pass all of your persistent object types to this method. + AutoCreateOption autoCreateOption = AutoCreateOption.DatabaseAndSchema; // Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + IDataStore provider = XpoDefault.GetConnectionProvider(connStr, autoCreateOption); + return threadSafe ? (IDataLayer)new ThreadSafeDataLayer(dictionary, provider) : new SimpleDataLayer(dictionary, provider); + } + } +} diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/Customer.cs b/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/Customer.cs new file mode 100644 index 0000000..8e084e7 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/Customer.cs @@ -0,0 +1,27 @@ +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class User : XPObject { + public User(Session session) : base(session) { } + + string _FirstName; + public string FirstName + { + get { return _FirstName; } + set { SetPropertyValue(nameof(FirstName), ref _FirstName, value); } + } + + string _LastName; + public string LastName + { + get { return _LastName; } + set { SetPropertyValue(nameof(LastName), ref _LastName, value); } + } + + [Association("UserIssues")] + public XPCollection Issues + { + get { return GetCollection(nameof(Issues)); } + } + } +} diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/DemoDataHelper.cs b/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/DemoDataHelper.cs new file mode 100644 index 0000000..a3d71a2 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/DemoDataHelper.cs @@ -0,0 +1,37 @@ +using DevExpress.Xpo; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace XPOIssues.Issues { + public static class DemoDataHelper { + public static void Seed() { + using(var uow = new DevExpress.Xpo.UnitOfWork()) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User(uow) + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + uow.CommitChanges(); + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue(uow) + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Oid, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + uow.CommitChanges(); + } + } + } +} diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/Issue.cs b/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/Issue.cs new file mode 100644 index 0000000..44e3d22 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/Issue.cs @@ -0,0 +1,55 @@ +using System; +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class Issue : XPObject { + public Issue(Session session) : base(session) { + Created = DateTime.Now; + } + string _Subject; + [Size(200)] + public string Subject + { + get { return _Subject; } + set { SetPropertyValue(nameof(Subject), ref _Subject, value); } + } + + int _UserId; + public int UserId + { + get { return _UserId; } + set { SetPropertyValue(nameof(UserId), ref _UserId, value); } + } + + User _User; + [Association("UserIssues")] + public User User + { + get { return _User; } + set { SetPropertyValue(nameof(User), ref _User, value); } + } + + DateTime _Created; + public DateTime Created + { + get { return _Created; } + set { SetPropertyValue(nameof(Created), ref _Created, value); } + } + + int _Votes; + public int Votes + { + get { return _Votes; } + set { SetPropertyValue(nameof(Votes), ref _Votes, value); } + } + + Priority _Priority; + public Priority Priority + { + get { return _Priority; } + set { SetPropertyValue(nameof(Priority), ref _Priority, value); } + } + } + + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..ad8047e --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace XPOIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml b/CS/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..bc07e8f --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml.cs b/CS/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml.cs new file mode 100644 index 0000000..51c6d32 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml.cs @@ -0,0 +1,87 @@ +using System.Windows; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using DevExpress.Xpo; + +namespace XPOIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + using(var session = new Session()) { + var classInfo = session.GetClassInfo(); + var properties = classInfo.Members + .Where(member => member.IsPublic && member.IsPersistent) + .Select(member => member.Name) + .ToArray(); + _DetachedObjectsHelper = DetachedObjectsHelper.Create(classInfo.KeyProperty.Name, properties); + } + var source = new InfiniteAsyncSource + { + CustomProperties = _DetachedObjectsHelper.Properties, + KeyProperty = nameof(XPOIssues.Issues.Issue.Oid) + }; + source.FetchRows += OnFetchRows; + source.GetTotalSummaries += OnGetTotalSummaries; + grid.ItemsSource = source; + LoadLookupData(); + } + DetachedObjectsHelper _DetachedObjectsHelper; + + void OnFetchRows(System.Object sender, DevExpress.Xpf.Data.FetchRowsAsyncEventArgs e) { + e.Result = Task.Run(() => + { + using(var session = new DevExpress.Xpo.Session()) { + var queryable = session.Query().SortBy(e.SortOrder, defaultUniqueSortPropertyName: nameof(XPOIssues.Issues.Issue.Oid)).Where(MakeFilterExpression(e.Filter)); + var items = queryable.Skip(e.Skip).Take(e.Take ?? 100).ToArray(); + return _DetachedObjectsHelper.ConvertToDetachedObjects(items); + } + }); + } + + void OnGetTotalSummaries(System.Object sender, DevExpress.Xpf.Data.GetSummariesAsyncEventArgs e) { + e.Result = Task.Run(() => + { + using(var session = new DevExpress.Xpo.Session()) { + return session.Query().Where(MakeFilterExpression(e.Filter)).GetSummaries(e.Summaries); + } + }); + } + + System.Linq.Expressions.Expression> MakeFilterExpression(DevExpress.Data.Filtering.CriteriaOperator filter) { + var converter = new DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(); + return converter.Convert(filter); + } + + void OnValidateRow(System.Object sender, DevExpress.Xpf.Grid.GridRowValidationEventArgs e) { + using(var unitOfWork = new DevExpress.Xpo.UnitOfWork()) { + var item = e.IsNewItem + ? new XPOIssues.Issues.Issue(unitOfWork) + : unitOfWork.GetObjectByKey(_DetachedObjectsHelper.GetKey(e.Row)); + _DetachedObjectsHelper.ApplyProperties(item, e.Row); + unitOfWork.CommitChanges(); + if(e.IsNewItem) { + _DetachedObjectsHelper.SetKey(e.Row, item.Oid); + } + } + } + + void OnValidateRowDeletion(System.Object sender, DevExpress.Xpf.Grid.GridDeleteRowsValidationEventArgs e) { + using(var unitOfWork = new DevExpress.Xpo.UnitOfWork()) { + var key = _DetachedObjectsHelper.GetKey(e.Rows.Single()); + var item = unitOfWork.GetObjectByKey(key); + unitOfWork.Delete(item); + unitOfWork.CommitChanges(); + } + } + + void LoadLookupData() { + var session = new DevExpress.Xpo.Session(); + usersLookup.ItemsSource = session.Query().OrderBy(user => user.Oid).Select(user => new { Id = user.Oid, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadLookupData(); + } + } +} diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/AssemblyInfo.cs b/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f481389 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("XPOIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("XPOIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/Resources.Designer.cs b/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/Resources.Designer.cs new file mode 100644 index 0000000..4c2c340 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace XPOIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XPOIssues.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 --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/Resources.resx b/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/Resources.resx @@ -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 --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/Settings.Designer.cs b/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/Settings.Designer.cs new file mode 100644 index 0000000..486c4c6 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace XPOIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/Settings.settings b/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/InfiniteAsyncSource/packages.config b/CS/CodeBehind/XPO/InfiniteAsyncSource/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/CodeBehind/XPO/InfiniteAsyncSource/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/App.config b/CS/CodeBehind/XPO/InstantFeedbackMode/App.config new file mode 100644 index 0000000..f473aab --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/App.xaml b/CS/CodeBehind/XPO/InstantFeedbackMode/App.xaml new file mode 100644 index 0000000..1e81d99 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/App.xaml.cs b/CS/CodeBehind/XPO/InstantFeedbackMode/App.xaml.cs new file mode 100644 index 0000000..3f603e9 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/App.xaml.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using XPOIssues.Issues; + +namespace XPOIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + ConnectionHelper.Connect(); + DemoDataHelper.Seed(); + } + } +} diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/EditIssueInfo.cs b/CS/CodeBehind/XPO/InstantFeedbackMode/EditIssueInfo.cs new file mode 100644 index 0000000..77e9a52 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/EditIssueInfo.cs @@ -0,0 +1,14 @@ +using DevExpress.Mvvm; +using System.Collections; +using XPOIssues.Issues; + +namespace XPOIssues { + public class EditIssueInfo : BindableBase { + public EditIssueInfo(DevExpress.Xpo.UnitOfWork unitOfWork, IList users) { + UnitOfWork = unitOfWork; + Users = users; + } + public DevExpress.Xpo.UnitOfWork UnitOfWork { get; } + public IList Users { get; } + } +} \ No newline at end of file diff --git a/CS/GridControlCRUDMVVMAsync/GridControlCRUDMVVMAsync.csproj b/CS/CodeBehind/XPO/InstantFeedbackMode/InstantFeedbackMode.csproj similarity index 51% rename from CS/GridControlCRUDMVVMAsync/GridControlCRUDMVVMAsync.csproj rename to CS/CodeBehind/XPO/InstantFeedbackMode/InstantFeedbackMode.csproj index 91a464f..c54e529 100644 --- a/CS/GridControlCRUDMVVMAsync/GridControlCRUDMVVMAsync.csproj +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/InstantFeedbackMode.csproj @@ -1,23 +1,23 @@ - + Debug AnyCPU - {659194A7-745D-4A56-A683-B150B9170F53} + {3669B2E4-A2B9-6F16-C3CA-605028AA0AAB} WinExe - GridControlCRUDMVVMAsync - GridControlCRUDMVVMAsync - v4.6.1 + XPOIssues + XPOIssues + v4.5.2 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 + true true true - AnyCPU @@ -39,27 +39,16 @@ 4 - - - - True - - - - - - - - - ..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.dll + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll - ..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.SqlServer.dll + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + @@ -73,68 +62,68 @@ + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + MSBuild:Compile Designer - - Common.DataModel\DataProviderAsyncExtensions.cs - - - Common.DataModel\DesignTimeDataProvider.cs - - - Common.DataModel\EntityFrameworkDataProvider.cs - - - Common.DataModel\IDataProvider.cs - - - Northwind.DataModel\CategoryInfo.cs - - - Northwind.DataModel\NorthwindDataStorage.cs - - - Northwind.DataModel\NorthwindDataStorageFactory.cs - - - Northwind.DataModel\ProductInfo.cs - - - Nothwind\Category.cs - - - Nothwind\NorthwindContext.cs - - - Nothwind\Product.cs - - - Nothwind\NorthwindContextInitializer.cs - - - Common.ViewModel\AsyncCollectionViewModel.cs - - - Common.ViewModel\CommandArgs\RefreshArgs.cs - - - Common.ViewModel\CommandArgs\RowDeleteArgs.cs - - - Common.View\GridControlDeleteRefreshBehavior.cs - - MSBuild:Compile Designer + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + App.xaml Code + + + + + MainWindow.xaml Code @@ -167,14 +156,13 @@ - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - + + - - + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/InstantFeedbackMode.sln b/CS/CodeBehind/XPO/InstantFeedbackMode/InstantFeedbackMode.sln new file mode 100644 index 0000000..7d197e0 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/InstantFeedbackMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantFeedbackMode", "InstantFeedbackMode.csproj", "{3669B2E4-A2B9-6F16-C3CA-605028AA0AAB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3669B2E4-A2B9-6F16-C3CA-605028AA0AAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3669B2E4-A2B9-6F16-C3CA-605028AA0AAB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3669B2E4-A2B9-6F16-C3CA-605028AA0AAB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3669B2E4-A2B9-6F16-C3CA-605028AA0AAB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/IssueDetailView.xaml b/CS/CodeBehind/XPO/InstantFeedbackMode/IssueDetailView.xaml new file mode 100644 index 0000000..8110d2f --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/IssueDetailView.xaml.cs b/CS/CodeBehind/XPO/InstantFeedbackMode/IssueDetailView.xaml.cs new file mode 100644 index 0000000..698dbf1 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/IssueDetailView.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows.Controls; + +namespace XPOIssues { + public partial class IssueDetailView : UserControl { + public IssueDetailView() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/ConnectionHelper.cs b/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/ConnectionHelper.cs new file mode 100644 index 0000000..01dd20a --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/ConnectionHelper.cs @@ -0,0 +1,29 @@ +using DevExpress.Xpo; +using DevExpress.Xpo.DB; +using DevExpress.Xpo.Metadata; +using System; +using System.Configuration; + +namespace XPOIssues.Issues { + public static class ConnectionHelper { + + static readonly Type[] PersistentTypes = new Type[]{ + typeof(Issue), + typeof(User) + }; + + public static void Connect() { + XpoDefault.DataLayer = CreateDataLayer(true); + } + + static IDataLayer CreateDataLayer(bool threadSafe) { + string connStr = ConfigurationManager.ConnectionStrings["XpoTutorial"]?.ConnectionString ?? "XpoProvider=InMemoryDataStore"; + //connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + ReflectionDictionary dictionary = new ReflectionDictionary(); + dictionary.GetDataStoreSchema(PersistentTypes); // Pass all of your persistent object types to this method. + AutoCreateOption autoCreateOption = AutoCreateOption.DatabaseAndSchema; // Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + IDataStore provider = XpoDefault.GetConnectionProvider(connStr, autoCreateOption); + return threadSafe ? (IDataLayer)new ThreadSafeDataLayer(dictionary, provider) : new SimpleDataLayer(dictionary, provider); + } + } +} diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/Customer.cs b/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/Customer.cs new file mode 100644 index 0000000..8e084e7 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/Customer.cs @@ -0,0 +1,27 @@ +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class User : XPObject { + public User(Session session) : base(session) { } + + string _FirstName; + public string FirstName + { + get { return _FirstName; } + set { SetPropertyValue(nameof(FirstName), ref _FirstName, value); } + } + + string _LastName; + public string LastName + { + get { return _LastName; } + set { SetPropertyValue(nameof(LastName), ref _LastName, value); } + } + + [Association("UserIssues")] + public XPCollection Issues + { + get { return GetCollection(nameof(Issues)); } + } + } +} diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/DemoDataHelper.cs b/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/DemoDataHelper.cs new file mode 100644 index 0000000..a3d71a2 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/DemoDataHelper.cs @@ -0,0 +1,37 @@ +using DevExpress.Xpo; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace XPOIssues.Issues { + public static class DemoDataHelper { + public static void Seed() { + using(var uow = new DevExpress.Xpo.UnitOfWork()) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User(uow) + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + uow.CommitChanges(); + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue(uow) + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Oid, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + uow.CommitChanges(); + } + } + } +} diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/Issue.cs b/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/Issue.cs new file mode 100644 index 0000000..44e3d22 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/Issue.cs @@ -0,0 +1,55 @@ +using System; +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class Issue : XPObject { + public Issue(Session session) : base(session) { + Created = DateTime.Now; + } + string _Subject; + [Size(200)] + public string Subject + { + get { return _Subject; } + set { SetPropertyValue(nameof(Subject), ref _Subject, value); } + } + + int _UserId; + public int UserId + { + get { return _UserId; } + set { SetPropertyValue(nameof(UserId), ref _UserId, value); } + } + + User _User; + [Association("UserIssues")] + public User User + { + get { return _User; } + set { SetPropertyValue(nameof(User), ref _User, value); } + } + + DateTime _Created; + public DateTime Created + { + get { return _Created; } + set { SetPropertyValue(nameof(Created), ref _Created, value); } + } + + int _Votes; + public int Votes + { + get { return _Votes; } + set { SetPropertyValue(nameof(Votes), ref _Votes, value); } + } + + Priority _Priority; + public Priority Priority + { + get { return _Priority; } + set { SetPropertyValue(nameof(Priority), ref _Priority, value); } + } + } + + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..ad8047e --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace XPOIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml b/CS/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml new file mode 100644 index 0000000..72d6a40 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml.cs b/CS/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml.cs new file mode 100644 index 0000000..cf6b763 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml.cs @@ -0,0 +1,67 @@ +using System.Windows; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using DevExpress.Xpo; +using XPOIssues.Issues; +using DevExpress.Mvvm.Xpf; +using System; +using System.Collections; + +namespace XPOIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + var properties = new DevExpress.Xpo.ServerViewProperty[] { +new DevExpress.Xpo.ServerViewProperty("Oid", DevExpress.Xpo.SortDirection.Ascending, new DevExpress.Data.Filtering.OperandProperty("Oid")), +new DevExpress.Xpo.ServerViewProperty("Subject", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Subject")), +new DevExpress.Xpo.ServerViewProperty("UserId", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("UserId")), +new DevExpress.Xpo.ServerViewProperty("Created", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Created")), +new DevExpress.Xpo.ServerViewProperty("Votes", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Votes")), +new DevExpress.Xpo.ServerViewProperty("Priority", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Priority")) +}; + var source = new DevExpress.Xpo.XPInstantFeedbackView(typeof(XPOIssues.Issues.Issue), properties, null); + source.ResolveSession += (o, e) => + { + e.Session = new DevExpress.Xpo.Session(); + }; + grid.ItemsSource = source; + LoadLookupData(); + } + + void LoadLookupData() { + var session = new DevExpress.Xpo.Session(); + usersLookup.ItemsSource = session.Query().OrderBy(user => user.Oid).Select(user => new { Id = user.Oid, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadLookupData(); + } + + void OnCreateEditEntityViewModel(System.Object sender, DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs e) { + var unitOfWork = new UnitOfWork(); + var item = e.Key != null + ? unitOfWork.GetObjectByKey(e.Key) + : new Issue(unitOfWork); + e.ViewModel = new EditItemViewModel( + item, + new EditIssueInfo(unitOfWork, (IList)usersLookup.ItemsSource), + dispose: () => unitOfWork.Dispose() + ); + } + + void OnValidateRow(System.Object sender, DevExpress.Mvvm.Xpf.EditFormRowValidationArgs e) { + var unitOfWork = ((EditIssueInfo)e.Tag).UnitOfWork; + unitOfWork.CommitChanges(); + } + + void OnValidateRowDeletion(System.Object sender, DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs e) { + using(var unitOfWork = new UnitOfWork()) { + var key = (int)e.Keys.Single(); + var item = unitOfWork.GetObjectByKey(key); + unitOfWork.Delete(item); + unitOfWork.CommitChanges(); + } + } + } +} diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/AssemblyInfo.cs b/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f481389 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("XPOIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("XPOIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/Resources.Designer.cs b/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/Resources.Designer.cs new file mode 100644 index 0000000..4c2c340 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace XPOIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XPOIssues.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 --git a/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/Resources.resx b/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/Resources.resx @@ -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 --git a/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/Settings.Designer.cs b/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/Settings.Designer.cs new file mode 100644 index 0000000..486c4c6 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace XPOIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/Settings.settings b/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/InstantFeedbackMode/packages.config b/CS/CodeBehind/XPO/InstantFeedbackMode/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/CodeBehind/XPO/InstantFeedbackMode/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/LocalData/App.config b/CS/CodeBehind/XPO/LocalData/App.config new file mode 100644 index 0000000..f473aab --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/LocalData/App.xaml b/CS/CodeBehind/XPO/LocalData/App.xaml new file mode 100644 index 0000000..1e81d99 --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/CodeBehind/XPO/LocalData/App.xaml.cs b/CS/CodeBehind/XPO/LocalData/App.xaml.cs new file mode 100644 index 0000000..3f603e9 --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/App.xaml.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using XPOIssues.Issues; + +namespace XPOIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + ConnectionHelper.Connect(); + DemoDataHelper.Seed(); + } + } +} diff --git a/CS/CodeBehind/XPO/LocalData/Issues/ConnectionHelper.cs b/CS/CodeBehind/XPO/LocalData/Issues/ConnectionHelper.cs new file mode 100644 index 0000000..01dd20a --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/Issues/ConnectionHelper.cs @@ -0,0 +1,29 @@ +using DevExpress.Xpo; +using DevExpress.Xpo.DB; +using DevExpress.Xpo.Metadata; +using System; +using System.Configuration; + +namespace XPOIssues.Issues { + public static class ConnectionHelper { + + static readonly Type[] PersistentTypes = new Type[]{ + typeof(Issue), + typeof(User) + }; + + public static void Connect() { + XpoDefault.DataLayer = CreateDataLayer(true); + } + + static IDataLayer CreateDataLayer(bool threadSafe) { + string connStr = ConfigurationManager.ConnectionStrings["XpoTutorial"]?.ConnectionString ?? "XpoProvider=InMemoryDataStore"; + //connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + ReflectionDictionary dictionary = new ReflectionDictionary(); + dictionary.GetDataStoreSchema(PersistentTypes); // Pass all of your persistent object types to this method. + AutoCreateOption autoCreateOption = AutoCreateOption.DatabaseAndSchema; // Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + IDataStore provider = XpoDefault.GetConnectionProvider(connStr, autoCreateOption); + return threadSafe ? (IDataLayer)new ThreadSafeDataLayer(dictionary, provider) : new SimpleDataLayer(dictionary, provider); + } + } +} diff --git a/CS/CodeBehind/XPO/LocalData/Issues/Customer.cs b/CS/CodeBehind/XPO/LocalData/Issues/Customer.cs new file mode 100644 index 0000000..8e084e7 --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/Issues/Customer.cs @@ -0,0 +1,27 @@ +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class User : XPObject { + public User(Session session) : base(session) { } + + string _FirstName; + public string FirstName + { + get { return _FirstName; } + set { SetPropertyValue(nameof(FirstName), ref _FirstName, value); } + } + + string _LastName; + public string LastName + { + get { return _LastName; } + set { SetPropertyValue(nameof(LastName), ref _LastName, value); } + } + + [Association("UserIssues")] + public XPCollection Issues + { + get { return GetCollection(nameof(Issues)); } + } + } +} diff --git a/CS/CodeBehind/XPO/LocalData/Issues/DemoDataHelper.cs b/CS/CodeBehind/XPO/LocalData/Issues/DemoDataHelper.cs new file mode 100644 index 0000000..a3d71a2 --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/Issues/DemoDataHelper.cs @@ -0,0 +1,37 @@ +using DevExpress.Xpo; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace XPOIssues.Issues { + public static class DemoDataHelper { + public static void Seed() { + using(var uow = new DevExpress.Xpo.UnitOfWork()) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User(uow) + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + uow.CommitChanges(); + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue(uow) + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Oid, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + uow.CommitChanges(); + } + } + } +} diff --git a/CS/CodeBehind/XPO/LocalData/Issues/Issue.cs b/CS/CodeBehind/XPO/LocalData/Issues/Issue.cs new file mode 100644 index 0000000..44e3d22 --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/Issues/Issue.cs @@ -0,0 +1,55 @@ +using System; +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class Issue : XPObject { + public Issue(Session session) : base(session) { + Created = DateTime.Now; + } + string _Subject; + [Size(200)] + public string Subject + { + get { return _Subject; } + set { SetPropertyValue(nameof(Subject), ref _Subject, value); } + } + + int _UserId; + public int UserId + { + get { return _UserId; } + set { SetPropertyValue(nameof(UserId), ref _UserId, value); } + } + + User _User; + [Association("UserIssues")] + public User User + { + get { return _User; } + set { SetPropertyValue(nameof(User), ref _User, value); } + } + + DateTime _Created; + public DateTime Created + { + get { return _Created; } + set { SetPropertyValue(nameof(Created), ref _Created, value); } + } + + int _Votes; + public int Votes + { + get { return _Votes; } + set { SetPropertyValue(nameof(Votes), ref _Votes, value); } + } + + Priority _Priority; + public Priority Priority + { + get { return _Priority; } + set { SetPropertyValue(nameof(Priority), ref _Priority, value); } + } + } + + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/CodeBehind/XPO/LocalData/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/XPO/LocalData/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..ad8047e --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace XPOIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/XPO/LocalData/LocalData.csproj b/CS/CodeBehind/XPO/LocalData/LocalData.csproj new file mode 100644 index 0000000..6c0f3a7 --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/LocalData.csproj @@ -0,0 +1,159 @@ + + + + + + Debug + AnyCPU + {3A7AE472-766F-98FF-6FFE-E1BF5438D9D5} + WinExe + XPOIssues + XPOIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/LocalData/LocalData.sln b/CS/CodeBehind/XPO/LocalData/LocalData.sln new file mode 100644 index 0000000..a0a0c3f --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/LocalData.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalData", "LocalData.csproj", "{3A7AE472-766F-98FF-6FFE-E1BF5438D9D5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3A7AE472-766F-98FF-6FFE-E1BF5438D9D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A7AE472-766F-98FF-6FFE-E1BF5438D9D5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A7AE472-766F-98FF-6FFE-E1BF5438D9D5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A7AE472-766F-98FF-6FFE-E1BF5438D9D5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/CodeBehind/XPO/LocalData/MainWindow.xaml b/CS/CodeBehind/XPO/LocalData/MainWindow.xaml new file mode 100644 index 0000000..db77bc2 --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/MainWindow.xaml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/LocalData/MainWindow.xaml.cs b/CS/CodeBehind/XPO/LocalData/MainWindow.xaml.cs new file mode 100644 index 0000000..c33a79a --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/MainWindow.xaml.cs @@ -0,0 +1,33 @@ +using System.Windows; +using System.Linq; + +namespace XPOIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + LoadData(); + } + DevExpress.Xpo.UnitOfWork _UnitOfWork; + + void LoadData() { + _UnitOfWork = new DevExpress.Xpo.UnitOfWork(); + var xpCollection = new DevExpress.Xpo.XPCollection(_UnitOfWork); + xpCollection.Sorting.Add(new DevExpress.Xpo.SortProperty(nameof(XPOIssues.Issues.User.Oid), DevExpress.Xpo.DB.SortingDirection.Ascending)); + grid.ItemsSource = xpCollection; + } + + void OnValidateRow(System.Object sender, DevExpress.Xpf.Grid.GridRowValidationEventArgs e) { + _UnitOfWork.CommitChanges(); + } + + void OnValidateRowDeletion(System.Object sender, DevExpress.Xpf.Grid.GridDeleteRowsValidationEventArgs e) { + var row = (XPOIssues.Issues.User)e.Rows.Single(); + _UnitOfWork.Delete(row); + _UnitOfWork.CommitChanges(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadData(); + } + } +} diff --git a/CS/CodeBehind/XPO/LocalData/Properties/AssemblyInfo.cs b/CS/CodeBehind/XPO/LocalData/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f481389 --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("XPOIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("XPOIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/CodeBehind/XPO/LocalData/Properties/Resources.Designer.cs b/CS/CodeBehind/XPO/LocalData/Properties/Resources.Designer.cs new file mode 100644 index 0000000..4c2c340 --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace XPOIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XPOIssues.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 --git a/CS/CodeBehind/XPO/LocalData/Properties/Resources.resx b/CS/CodeBehind/XPO/LocalData/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/Properties/Resources.resx @@ -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 --git a/CS/CodeBehind/XPO/LocalData/Properties/Settings.Designer.cs b/CS/CodeBehind/XPO/LocalData/Properties/Settings.Designer.cs new file mode 100644 index 0000000..486c4c6 --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace XPOIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/CodeBehind/XPO/LocalData/Properties/Settings.settings b/CS/CodeBehind/XPO/LocalData/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/LocalData/packages.config b/CS/CodeBehind/XPO/LocalData/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/CodeBehind/XPO/LocalData/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/App.config b/CS/CodeBehind/XPO/PagedAsyncSource/App.config new file mode 100644 index 0000000..f473aab --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/App.xaml b/CS/CodeBehind/XPO/PagedAsyncSource/App.xaml new file mode 100644 index 0000000..1e81d99 --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/App.xaml.cs b/CS/CodeBehind/XPO/PagedAsyncSource/App.xaml.cs new file mode 100644 index 0000000..3f603e9 --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/App.xaml.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using XPOIssues.Issues; + +namespace XPOIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + ConnectionHelper.Connect(); + DemoDataHelper.Seed(); + } + } +} diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/Issues/ConnectionHelper.cs b/CS/CodeBehind/XPO/PagedAsyncSource/Issues/ConnectionHelper.cs new file mode 100644 index 0000000..01dd20a --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/Issues/ConnectionHelper.cs @@ -0,0 +1,29 @@ +using DevExpress.Xpo; +using DevExpress.Xpo.DB; +using DevExpress.Xpo.Metadata; +using System; +using System.Configuration; + +namespace XPOIssues.Issues { + public static class ConnectionHelper { + + static readonly Type[] PersistentTypes = new Type[]{ + typeof(Issue), + typeof(User) + }; + + public static void Connect() { + XpoDefault.DataLayer = CreateDataLayer(true); + } + + static IDataLayer CreateDataLayer(bool threadSafe) { + string connStr = ConfigurationManager.ConnectionStrings["XpoTutorial"]?.ConnectionString ?? "XpoProvider=InMemoryDataStore"; + //connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + ReflectionDictionary dictionary = new ReflectionDictionary(); + dictionary.GetDataStoreSchema(PersistentTypes); // Pass all of your persistent object types to this method. + AutoCreateOption autoCreateOption = AutoCreateOption.DatabaseAndSchema; // Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + IDataStore provider = XpoDefault.GetConnectionProvider(connStr, autoCreateOption); + return threadSafe ? (IDataLayer)new ThreadSafeDataLayer(dictionary, provider) : new SimpleDataLayer(dictionary, provider); + } + } +} diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/Issues/Customer.cs b/CS/CodeBehind/XPO/PagedAsyncSource/Issues/Customer.cs new file mode 100644 index 0000000..8e084e7 --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/Issues/Customer.cs @@ -0,0 +1,27 @@ +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class User : XPObject { + public User(Session session) : base(session) { } + + string _FirstName; + public string FirstName + { + get { return _FirstName; } + set { SetPropertyValue(nameof(FirstName), ref _FirstName, value); } + } + + string _LastName; + public string LastName + { + get { return _LastName; } + set { SetPropertyValue(nameof(LastName), ref _LastName, value); } + } + + [Association("UserIssues")] + public XPCollection Issues + { + get { return GetCollection(nameof(Issues)); } + } + } +} diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/Issues/DemoDataHelper.cs b/CS/CodeBehind/XPO/PagedAsyncSource/Issues/DemoDataHelper.cs new file mode 100644 index 0000000..a3d71a2 --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/Issues/DemoDataHelper.cs @@ -0,0 +1,37 @@ +using DevExpress.Xpo; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace XPOIssues.Issues { + public static class DemoDataHelper { + public static void Seed() { + using(var uow = new DevExpress.Xpo.UnitOfWork()) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User(uow) + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + uow.CommitChanges(); + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue(uow) + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Oid, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + uow.CommitChanges(); + } + } + } +} diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/Issues/Issue.cs b/CS/CodeBehind/XPO/PagedAsyncSource/Issues/Issue.cs new file mode 100644 index 0000000..44e3d22 --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/Issues/Issue.cs @@ -0,0 +1,55 @@ +using System; +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class Issue : XPObject { + public Issue(Session session) : base(session) { + Created = DateTime.Now; + } + string _Subject; + [Size(200)] + public string Subject + { + get { return _Subject; } + set { SetPropertyValue(nameof(Subject), ref _Subject, value); } + } + + int _UserId; + public int UserId + { + get { return _UserId; } + set { SetPropertyValue(nameof(UserId), ref _UserId, value); } + } + + User _User; + [Association("UserIssues")] + public User User + { + get { return _User; } + set { SetPropertyValue(nameof(User), ref _User, value); } + } + + DateTime _Created; + public DateTime Created + { + get { return _Created; } + set { SetPropertyValue(nameof(Created), ref _Created, value); } + } + + int _Votes; + public int Votes + { + get { return _Votes; } + set { SetPropertyValue(nameof(Votes), ref _Votes, value); } + } + + Priority _Priority; + public Priority Priority + { + get { return _Priority; } + set { SetPropertyValue(nameof(Priority), ref _Priority, value); } + } + } + + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/XPO/PagedAsyncSource/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..ad8047e --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace XPOIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml b/CS/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..16ed77a --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml.cs b/CS/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml.cs new file mode 100644 index 0000000..f6b5d16 --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml.cs @@ -0,0 +1,80 @@ +using System.Windows; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using DevExpress.Xpo; + +namespace XPOIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + using(var session = new Session()) { + var classInfo = session.GetClassInfo(); + var properties = classInfo.Members + .Where(member => member.IsPublic && member.IsPersistent) + .Select(member => member.Name) + .ToArray(); + _DetachedObjectsHelper = DetachedObjectsHelper.Create(classInfo.KeyProperty.Name, properties); + } + var source = new PagedAsyncSource + { + CustomProperties = _DetachedObjectsHelper.Properties, + KeyProperty = nameof(XPOIssues.Issues.Issue.Oid), + PageNavigationMode = PageNavigationMode.ArbitraryWithTotalPageCount + }; + source.FetchPage += OnFetchPage; + source.GetTotalSummaries += OnGetTotalSummaries; + grid.ItemsSource = source; + LoadLookupData(); + } + DetachedObjectsHelper _DetachedObjectsHelper; + + void OnFetchPage(System.Object sender, DevExpress.Xpf.Data.FetchPageAsyncEventArgs e) { + e.Result = Task.Run(() => + { + const int pageTakeCount = 5; + using(var session = new DevExpress.Xpo.Session()) { + var queryable = session.Query().SortBy(e.SortOrder, defaultUniqueSortPropertyName: nameof(XPOIssues.Issues.Issue.Oid)).Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)e.Filter)); + var items = queryable.Skip(e.Skip).Take(e.Take * pageTakeCount).ToArray(); + return _DetachedObjectsHelper.ConvertToDetachedObjects(items); + } + }); + } + + void OnGetTotalSummaries(System.Object sender, DevExpress.Xpf.Data.GetSummariesAsyncEventArgs e) { + e.Result = Task.Run(() => + { + using(var session = new DevExpress.Xpo.Session()) { + return session.Query().Where(MakeFilterExpression(e.Filter)).GetSummaries(e.Summaries); + } + }); + } + + System.Linq.Expressions.Expression> MakeFilterExpression(DevExpress.Data.Filtering.CriteriaOperator filter) { + var converter = new DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(); + return converter.Convert(filter); + } + + void OnValidateRow(System.Object sender, DevExpress.Xpf.Grid.GridRowValidationEventArgs e) { + using(var unitOfWork = new DevExpress.Xpo.UnitOfWork()) { + var item = e.IsNewItem + ? new XPOIssues.Issues.Issue(unitOfWork) + : unitOfWork.GetObjectByKey(_DetachedObjectsHelper.GetKey(e.Row)); + _DetachedObjectsHelper.ApplyProperties(item, e.Row); + unitOfWork.CommitChanges(); + if(e.IsNewItem) { + _DetachedObjectsHelper.SetKey(e.Row, item.Oid); + } + } + } + + void LoadLookupData() { + var session = new DevExpress.Xpo.Session(); + usersLookup.ItemsSource = session.Query().OrderBy(user => user.Oid).Select(user => new { Id = user.Oid, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadLookupData(); + } + } +} diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/PagedAsyncSource.csproj b/CS/CodeBehind/XPO/PagedAsyncSource/PagedAsyncSource.csproj new file mode 100644 index 0000000..27152af --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/PagedAsyncSource.csproj @@ -0,0 +1,159 @@ + + + + + + Debug + AnyCPU + {72F1F8F8-6DA9-2B57-1ADC-B179DFAC534D} + WinExe + XPOIssues + XPOIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/PagedAsyncSource.sln b/CS/CodeBehind/XPO/PagedAsyncSource/PagedAsyncSource.sln new file mode 100644 index 0000000..fcd2f42 --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/PagedAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagedAsyncSource", "PagedAsyncSource.csproj", "{72F1F8F8-6DA9-2B57-1ADC-B179DFAC534D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {72F1F8F8-6DA9-2B57-1ADC-B179DFAC534D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72F1F8F8-6DA9-2B57-1ADC-B179DFAC534D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72F1F8F8-6DA9-2B57-1ADC-B179DFAC534D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72F1F8F8-6DA9-2B57-1ADC-B179DFAC534D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/Properties/AssemblyInfo.cs b/CS/CodeBehind/XPO/PagedAsyncSource/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f481389 --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("XPOIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("XPOIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/CodeBehind/XPO/PagedAsyncSource/Properties/Resources.Designer.cs b/CS/CodeBehind/XPO/PagedAsyncSource/Properties/Resources.Designer.cs new file mode 100644 index 0000000..4c2c340 --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace XPOIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XPOIssues.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 --git a/CS/CodeBehind/XPO/PagedAsyncSource/Properties/Resources.resx b/CS/CodeBehind/XPO/PagedAsyncSource/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/Properties/Resources.resx @@ -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 --git a/CS/CodeBehind/XPO/PagedAsyncSource/Properties/Settings.Designer.cs b/CS/CodeBehind/XPO/PagedAsyncSource/Properties/Settings.Designer.cs new file mode 100644 index 0000000..486c4c6 --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace XPOIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/CodeBehind/XPO/PagedAsyncSource/Properties/Settings.settings b/CS/CodeBehind/XPO/PagedAsyncSource/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/PagedAsyncSource/packages.config b/CS/CodeBehind/XPO/PagedAsyncSource/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/CodeBehind/XPO/PagedAsyncSource/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/ServerMode/App.config b/CS/CodeBehind/XPO/ServerMode/App.config new file mode 100644 index 0000000..f473aab --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/ServerMode/App.xaml b/CS/CodeBehind/XPO/ServerMode/App.xaml new file mode 100644 index 0000000..1e81d99 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/CodeBehind/XPO/ServerMode/App.xaml.cs b/CS/CodeBehind/XPO/ServerMode/App.xaml.cs new file mode 100644 index 0000000..3f603e9 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/App.xaml.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using XPOIssues.Issues; + +namespace XPOIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + ConnectionHelper.Connect(); + DemoDataHelper.Seed(); + } + } +} diff --git a/CS/CodeBehind/XPO/ServerMode/EditIssueInfo.cs b/CS/CodeBehind/XPO/ServerMode/EditIssueInfo.cs new file mode 100644 index 0000000..77e9a52 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/EditIssueInfo.cs @@ -0,0 +1,14 @@ +using DevExpress.Mvvm; +using System.Collections; +using XPOIssues.Issues; + +namespace XPOIssues { + public class EditIssueInfo : BindableBase { + public EditIssueInfo(DevExpress.Xpo.UnitOfWork unitOfWork, IList users) { + UnitOfWork = unitOfWork; + Users = users; + } + public DevExpress.Xpo.UnitOfWork UnitOfWork { get; } + public IList Users { get; } + } +} \ No newline at end of file diff --git a/CS/CodeBehind/XPO/ServerMode/IssueDetailView.xaml b/CS/CodeBehind/XPO/ServerMode/IssueDetailView.xaml new file mode 100644 index 0000000..8110d2f --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/ServerMode/IssueDetailView.xaml.cs b/CS/CodeBehind/XPO/ServerMode/IssueDetailView.xaml.cs new file mode 100644 index 0000000..698dbf1 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/IssueDetailView.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows.Controls; + +namespace XPOIssues { + public partial class IssueDetailView : UserControl { + public IssueDetailView() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/CS/CodeBehind/XPO/ServerMode/Issues/ConnectionHelper.cs b/CS/CodeBehind/XPO/ServerMode/Issues/ConnectionHelper.cs new file mode 100644 index 0000000..01dd20a --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/Issues/ConnectionHelper.cs @@ -0,0 +1,29 @@ +using DevExpress.Xpo; +using DevExpress.Xpo.DB; +using DevExpress.Xpo.Metadata; +using System; +using System.Configuration; + +namespace XPOIssues.Issues { + public static class ConnectionHelper { + + static readonly Type[] PersistentTypes = new Type[]{ + typeof(Issue), + typeof(User) + }; + + public static void Connect() { + XpoDefault.DataLayer = CreateDataLayer(true); + } + + static IDataLayer CreateDataLayer(bool threadSafe) { + string connStr = ConfigurationManager.ConnectionStrings["XpoTutorial"]?.ConnectionString ?? "XpoProvider=InMemoryDataStore"; + //connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + ReflectionDictionary dictionary = new ReflectionDictionary(); + dictionary.GetDataStoreSchema(PersistentTypes); // Pass all of your persistent object types to this method. + AutoCreateOption autoCreateOption = AutoCreateOption.DatabaseAndSchema; // Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + IDataStore provider = XpoDefault.GetConnectionProvider(connStr, autoCreateOption); + return threadSafe ? (IDataLayer)new ThreadSafeDataLayer(dictionary, provider) : new SimpleDataLayer(dictionary, provider); + } + } +} diff --git a/CS/CodeBehind/XPO/ServerMode/Issues/Customer.cs b/CS/CodeBehind/XPO/ServerMode/Issues/Customer.cs new file mode 100644 index 0000000..8e084e7 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/Issues/Customer.cs @@ -0,0 +1,27 @@ +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class User : XPObject { + public User(Session session) : base(session) { } + + string _FirstName; + public string FirstName + { + get { return _FirstName; } + set { SetPropertyValue(nameof(FirstName), ref _FirstName, value); } + } + + string _LastName; + public string LastName + { + get { return _LastName; } + set { SetPropertyValue(nameof(LastName), ref _LastName, value); } + } + + [Association("UserIssues")] + public XPCollection Issues + { + get { return GetCollection(nameof(Issues)); } + } + } +} diff --git a/CS/CodeBehind/XPO/ServerMode/Issues/DemoDataHelper.cs b/CS/CodeBehind/XPO/ServerMode/Issues/DemoDataHelper.cs new file mode 100644 index 0000000..a3d71a2 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/Issues/DemoDataHelper.cs @@ -0,0 +1,37 @@ +using DevExpress.Xpo; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace XPOIssues.Issues { + public static class DemoDataHelper { + public static void Seed() { + using(var uow = new DevExpress.Xpo.UnitOfWork()) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User(uow) + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + uow.CommitChanges(); + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue(uow) + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Oid, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + uow.CommitChanges(); + } + } + } +} diff --git a/CS/CodeBehind/XPO/ServerMode/Issues/Issue.cs b/CS/CodeBehind/XPO/ServerMode/Issues/Issue.cs new file mode 100644 index 0000000..44e3d22 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/Issues/Issue.cs @@ -0,0 +1,55 @@ +using System; +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class Issue : XPObject { + public Issue(Session session) : base(session) { + Created = DateTime.Now; + } + string _Subject; + [Size(200)] + public string Subject + { + get { return _Subject; } + set { SetPropertyValue(nameof(Subject), ref _Subject, value); } + } + + int _UserId; + public int UserId + { + get { return _UserId; } + set { SetPropertyValue(nameof(UserId), ref _UserId, value); } + } + + User _User; + [Association("UserIssues")] + public User User + { + get { return _User; } + set { SetPropertyValue(nameof(User), ref _User, value); } + } + + DateTime _Created; + public DateTime Created + { + get { return _Created; } + set { SetPropertyValue(nameof(Created), ref _Created, value); } + } + + int _Votes; + public int Votes + { + get { return _Votes; } + set { SetPropertyValue(nameof(Votes), ref _Votes, value); } + } + + Priority _Priority; + public Priority Priority + { + get { return _Priority; } + set { SetPropertyValue(nameof(Priority), ref _Priority, value); } + } + } + + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/CodeBehind/XPO/ServerMode/Issues/OutlookDataGenerator.cs b/CS/CodeBehind/XPO/ServerMode/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..ad8047e --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace XPOIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/CodeBehind/XPO/ServerMode/MainWindow.xaml b/CS/CodeBehind/XPO/ServerMode/MainWindow.xaml new file mode 100644 index 0000000..72d6a40 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/ServerMode/MainWindow.xaml.cs b/CS/CodeBehind/XPO/ServerMode/MainWindow.xaml.cs new file mode 100644 index 0000000..e6eeec0 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/MainWindow.xaml.cs @@ -0,0 +1,65 @@ +using System.Windows; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using DevExpress.Xpo; +using XPOIssues.Issues; +using DevExpress.Mvvm.Xpf; +using System; +using System.Collections; + +namespace XPOIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + var properties = new DevExpress.Xpo.ServerViewProperty[] { +new DevExpress.Xpo.ServerViewProperty("Oid", DevExpress.Xpo.SortDirection.Ascending, new DevExpress.Data.Filtering.OperandProperty("Oid")), +new DevExpress.Xpo.ServerViewProperty("Subject", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Subject")), +new DevExpress.Xpo.ServerViewProperty("UserId", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("UserId")), +new DevExpress.Xpo.ServerViewProperty("Created", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Created")), +new DevExpress.Xpo.ServerViewProperty("Votes", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Votes")), +new DevExpress.Xpo.ServerViewProperty("Priority", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Priority")) +}; + var session = new DevExpress.Xpo.Session(); + var source = new DevExpress.Xpo.XPServerModeView(session, typeof(XPOIssues.Issues.Issue), null); + source.Properties.AddRange(properties); + grid.ItemsSource = source; + LoadLookupData(); + } + + void LoadLookupData() { + var session = new DevExpress.Xpo.Session(); + usersLookup.ItemsSource = session.Query().OrderBy(user => user.Oid).Select(user => new { Id = user.Oid, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + + void OnDataSourceRefresh(System.Object sender, DevExpress.Xpf.Grid.DataSourceRefreshEventArgs e) { + LoadLookupData(); + } + + void OnCreateEditEntityViewModel(System.Object sender, DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs e) { + var unitOfWork = new UnitOfWork(); + var item = e.Key != null + ? unitOfWork.GetObjectByKey(e.Key) + : new Issue(unitOfWork); + e.ViewModel = new EditItemViewModel( + item, + new EditIssueInfo(unitOfWork, (IList)usersLookup.ItemsSource), + dispose: () => unitOfWork.Dispose() + ); + } + + void OnValidateRow(System.Object sender, DevExpress.Mvvm.Xpf.EditFormRowValidationArgs e) { + var unitOfWork = ((EditIssueInfo)e.Tag).UnitOfWork; + unitOfWork.CommitChanges(); + } + + void OnValidateRowDeletion(System.Object sender, DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs e) { + using(var unitOfWork = new UnitOfWork()) { + var key = (int)e.Keys.Single(); + var item = unitOfWork.GetObjectByKey(key); + unitOfWork.Delete(item); + unitOfWork.CommitChanges(); + } + } + } +} diff --git a/CS/CodeBehind/XPO/ServerMode/Properties/AssemblyInfo.cs b/CS/CodeBehind/XPO/ServerMode/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f481389 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("XPOIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("XPOIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/CodeBehind/XPO/ServerMode/Properties/Resources.Designer.cs b/CS/CodeBehind/XPO/ServerMode/Properties/Resources.Designer.cs new file mode 100644 index 0000000..4c2c340 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace XPOIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XPOIssues.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 --git a/CS/CodeBehind/XPO/ServerMode/Properties/Resources.resx b/CS/CodeBehind/XPO/ServerMode/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/Properties/Resources.resx @@ -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 --git a/CS/CodeBehind/XPO/ServerMode/Properties/Settings.Designer.cs b/CS/CodeBehind/XPO/ServerMode/Properties/Settings.Designer.cs new file mode 100644 index 0000000..486c4c6 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace XPOIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/CodeBehind/XPO/ServerMode/Properties/Settings.settings b/CS/CodeBehind/XPO/ServerMode/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/ServerMode/ServerMode.csproj b/CS/CodeBehind/XPO/ServerMode/ServerMode.csproj new file mode 100644 index 0000000..daeb862 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/ServerMode.csproj @@ -0,0 +1,168 @@ + + + + + + Debug + AnyCPU + {B0473BD1-804F-68B7-AC1B-D24EFC3E3C0F} + WinExe + XPOIssues + XPOIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/CodeBehind/XPO/ServerMode/ServerMode.sln b/CS/CodeBehind/XPO/ServerMode/ServerMode.sln new file mode 100644 index 0000000..200a5c7 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/ServerMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerMode", "ServerMode.csproj", "{B0473BD1-804F-68B7-AC1B-D24EFC3E3C0F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B0473BD1-804F-68B7-AC1B-D24EFC3E3C0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0473BD1-804F-68B7-AC1B-D24EFC3E3C0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0473BD1-804F-68B7-AC1B-D24EFC3E3C0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0473BD1-804F-68B7-AC1B-D24EFC3E3C0F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/CodeBehind/XPO/ServerMode/packages.config b/CS/CodeBehind/XPO/ServerMode/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/CodeBehind/XPO/ServerMode/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/GridControlCRUD.Common.Northwind/Northwind.DataModel/CategoryInfo.cs b/CS/GridControlCRUD.Common.Northwind/Northwind.DataModel/CategoryInfo.cs deleted file mode 100644 index a6af5ac..0000000 --- a/CS/GridControlCRUD.Common.Northwind/Northwind.DataModel/CategoryInfo.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using System.Linq; - -namespace DevExpress.CRUD.Northwind.DataModel { - public class CategoryInfo { - public string Name { get; set; } - public long Id { get; set; } - } -} diff --git a/CS/GridControlCRUD.Common.Northwind/Northwind.DataModel/NorthwindDataStorage.cs b/CS/GridControlCRUD.Common.Northwind/Northwind.DataModel/NorthwindDataStorage.cs deleted file mode 100644 index cc6d155..0000000 --- a/CS/GridControlCRUD.Common.Northwind/Northwind.DataModel/NorthwindDataStorage.cs +++ /dev/null @@ -1,12 +0,0 @@ -using DevExpress.CRUD.DataModel; - -namespace DevExpress.CRUD.Northwind.DataModel { - public class NorthwindDataStorage { - public NorthwindDataStorage(IDataProvider categories, IDataProvider products) { - Categories = categories; - Products = products; - } - public IDataProvider Categories { get; } - public IDataProvider Products { get; } - } -} diff --git a/CS/GridControlCRUD.Common.Northwind/Northwind.DataModel/NorthwindDataStorageFactory.cs b/CS/GridControlCRUD.Common.Northwind/Northwind.DataModel/NorthwindDataStorageFactory.cs deleted file mode 100644 index a290c5a..0000000 --- a/CS/GridControlCRUD.Common.Northwind/Northwind.DataModel/NorthwindDataStorageFactory.cs +++ /dev/null @@ -1,54 +0,0 @@ -using DevExpress.CRUD.DataModel.EntityFramework; -using DevExpress.CRUD.DataModel; - -namespace DevExpress.CRUD.Northwind.DataModel { - public static class NorthwindDataStorageFactory { - public static NorthwindDataStorage Create(bool isInDesignMode) { - if(isInDesignMode) { - return new NorthwindDataStorage( - new DesignTimeDataProvider( - id => new CategoryInfo { - Id = id, - Name = "Category " + id, - } - ), - new DesignTimeDataProvider( - id => new ProductInfo { - Id = id, - Name = "Product " + id, - CategoryId = id - } - ) - ); - } - return new NorthwindDataStorage( - new EntityFrameworkDataProvider( - createContext: () => new NorthwindContext(), - getDbSet: context => context.Categories, - getEnityExpression: category => new CategoryInfo { - Id = category.Id, - Name = category.Name, - }, - keyProperty: nameof(Category.Id) - ), - new EntityFrameworkDataProvider( - createContext: () => new NorthwindContext(), - getDbSet: context => context.Products, - getEnityExpression: product => new ProductInfo { - Id = product.Id, - Name = product.Name, - CategoryId = product.CategoryId - }, - getKey: productInfo => productInfo.Id, - getEntityKey: product => product.Id, - setKey: (productInfo, id) => productInfo.Id = (long)id, - applyProperties: (productInfo, product) => { - product.Name = productInfo.Name; - product.CategoryId = productInfo.CategoryId; - }, - keyProperty: nameof(Category.Id) - ) - ); - } - } -} diff --git a/CS/GridControlCRUD.Common.Northwind/Northwind.DataModel/ProductInfo.cs b/CS/GridControlCRUD.Common.Northwind/Northwind.DataModel/ProductInfo.cs deleted file mode 100644 index 118872d..0000000 --- a/CS/GridControlCRUD.Common.Northwind/Northwind.DataModel/ProductInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Linq; - -namespace DevExpress.CRUD.Northwind.DataModel { - public class ProductInfo { - public string Name { get; set; } - public long Id { get; set; } - public long CategoryId { get; set; } - } -} diff --git a/CS/GridControlCRUD.Common.Northwind/Northwind/Category.cs b/CS/GridControlCRUD.Common.Northwind/Northwind/Category.cs deleted file mode 100644 index cd1d5fb..0000000 --- a/CS/GridControlCRUD.Common.Northwind/Northwind/Category.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace DevExpress.CRUD.Northwind { - public class Category { - public long Id { get; set; } - public string Name { get; set; } - public string Description { get; set; } - public virtual ICollection Products { get; set; } - } -} diff --git a/CS/GridControlCRUD.Common.Northwind/Northwind/NorthwindContext.cs b/CS/GridControlCRUD.Common.Northwind/Northwind/NorthwindContext.cs deleted file mode 100644 index e99e278..0000000 --- a/CS/GridControlCRUD.Common.Northwind/Northwind/NorthwindContext.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data.Entity; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DevExpress.CRUD.Northwind { - public class NorthwindContext : DbContext { - static NorthwindContext() { - Database.SetInitializer(new NorthwindContextInitializer()); - } - protected override void OnModelCreating(DbModelBuilder modelBuilder) { - modelBuilder.Entity().Property(x => x.Name).IsRequired(); - } - public DbSet Categories { get; set; } - public DbSet Products { get; set; } - } -} diff --git a/CS/GridControlCRUD.Common.Northwind/Northwind/NorthwindContextInitializer.cs b/CS/GridControlCRUD.Common.Northwind/Northwind/NorthwindContextInitializer.cs deleted file mode 100644 index 50432c7..0000000 --- a/CS/GridControlCRUD.Common.Northwind/Northwind/NorthwindContextInitializer.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Collections.Generic; -using System.Data.Entity; - -namespace DevExpress.CRUD.Northwind { - public class NorthwindContextInitializer : DropCreateDatabaseIfModelChanges { - protected override void Seed(NorthwindContext context) { - base.Seed(context); - - var categories = new List { - new Category { - Name = "Beverages", - Description = "Soft drinks, coffees, teas, beers, and ales", - Products = new List { - new Product { Name = "Chai", QuantityPerUnit = "10 boxes x 20 bags", UnitPrice = (decimal)18, UnitsInStock = 39, UnitsOnOrder = 0, ReorderLevel = 10, Discontinued = false, EAN13 = "070684900001" }, - new Product { Name = "Ipoh Coffee", QuantityPerUnit = "16 - 500 g tins", UnitPrice = (decimal)46, UnitsInStock = 17, UnitsOnOrder = 10, ReorderLevel = 25, Discontinued = false, EAN13 = "070684900043" }, - } - }, - new Category { - Name = "Condiments", - Description = "Sweet and savory sauces, relishes, spreads, and seasonings", - Products = new List { - new Product { Name = "Aniseed Syrup", QuantityPerUnit = "12 - 550 ml bottles", UnitPrice = (decimal)10, UnitsInStock = 13, UnitsOnOrder = 70, ReorderLevel = 25, Discontinued = false, EAN13 = "070684900003" }, - new Product { Name = "Louisiana Fiery Hot Pepper Sauce", QuantityPerUnit = "32 - 8 oz bottles", UnitPrice = (decimal)21.05, UnitsInStock = 76, UnitsOnOrder = 0, ReorderLevel = 0, Discontinued = false, EAN13 = "070684900065" }, - } - }, - new Category { - Name = "Grains/Cereals", - Description = "Breads, crackers, pasta, and cereal", - Products = new List { - new Product { Name = "Singaporean Hokkien Fried Mee", QuantityPerUnit = "32 - 1 kg pkgs.", UnitPrice = (decimal)14, UnitsInStock = 26, UnitsOnOrder = 0, ReorderLevel = 0, Discontinued = true, EAN13 = "070684900042" }, - new Product { Name = "Ravioli Angelo", QuantityPerUnit = "24 - 250 g pkgs.", UnitPrice = (decimal)19.5, UnitsInStock = 36, UnitsOnOrder = 0, ReorderLevel = 20, Discontinued = false, EAN13 = "070684900057" }, - } - }, - }; - - context.Categories.AddRange(categories); - context.SaveChanges(); - } - } -} diff --git a/CS/GridControlCRUD.Common.Northwind/Northwind/Product.cs b/CS/GridControlCRUD.Common.Northwind/Northwind/Product.cs deleted file mode 100644 index fe96d28..0000000 --- a/CS/GridControlCRUD.Common.Northwind/Northwind/Product.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Linq; - -namespace DevExpress.CRUD.Northwind { - public class Product { - public long Id { get; set; } - public string Name { get; set; } - public long CategoryId { get; set; } - public virtual Category Category { get; set; } - public string QuantityPerUnit { get; set; } - public decimal? UnitPrice { get; set; } - public short? UnitsInStock { get; set; } - public short? UnitsOnOrder { get; set; } - public short? ReorderLevel { get; set; } - public bool Discontinued { get; set; } - public string EAN13 { get; set; } - } -} diff --git a/CS/GridControlCRUD.Common/DataModel/DataProviderAsyncExtensions.cs b/CS/GridControlCRUD.Common/DataModel/DataProviderAsyncExtensions.cs deleted file mode 100644 index 6403c3e..0000000 --- a/CS/GridControlCRUD.Common/DataModel/DataProviderAsyncExtensions.cs +++ /dev/null @@ -1,36 +0,0 @@ -using DevExpress.CRUD.DataModel; -using DevExpress.Xpf.Data; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace DevExpress.CRUD.ViewModel { - public static class DataProviderAsyncExtensions { - public static async Task> ReadAsync(this IDataProvider dataProvider) where T : class { -#if DEBUG - await Task.Delay(500); -#endif - return await Task.Run(() => dataProvider.Read()); - } - public static async Task GetQueryableResultAsync(this IDataProvider dataProvider, Func, TResult> getResult) where T : class { -#if DEBUG - await Task.Delay(500); -#endif - return await Task.Run(() => dataProvider.GetQueryableResult(getResult)); - } - public static async Task UpdateAsync(this IDataProvider dataProvider, T entity) where T : class { -#if DEBUG - await Task.Delay(500); -#endif - await Task.Run(() => dataProvider.Update(entity)); - } - public static async Task CreateAsync(this IDataProvider dataProvider, T entity) where T : class { -#if DEBUG - await Task.Delay(500); -#endif - await Task.Run(() => dataProvider.Create(entity)); - } - } -} diff --git a/CS/GridControlCRUD.Common/DataModel/DesignTimeDataProvider.cs b/CS/GridControlCRUD.Common/DataModel/DesignTimeDataProvider.cs deleted file mode 100644 index 24906bd..0000000 --- a/CS/GridControlCRUD.Common/DataModel/DesignTimeDataProvider.cs +++ /dev/null @@ -1,38 +0,0 @@ -using DevExpress.Xpf.Data; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; - -namespace DevExpress.CRUD.DataModel { - public class DesignTimeDataProvider : IDataProvider where T : class { - readonly Func createEntity; - readonly int count; - - public DesignTimeDataProvider(Func createEntity, int count = 5) { - this.createEntity = createEntity; - this.count = count; - } - - IList IDataProvider.Read() { - return Enumerable.Range(0, count).Select(createEntity).ToList(); - } - - TResult IDataProvider.GetQueryableResult(Func, TResult> getResult) { - var queryable = ((IDataProvider)this).Read().AsQueryable(); - return getResult(queryable); - } - - void IDataProvider.Create(T obj) { - throw new NotSupportedException(); - } - void IDataProvider.Delete(T obj) { - throw new NotSupportedException(); - } - void IDataProvider.Update(T obj) { - throw new NotSupportedException(); - } - - string IDataProvider.KeyProperty => throw new NotSupportedException(); - } -} diff --git a/CS/GridControlCRUD.Common/DataModel/EntityFrameworkDataProvider.cs b/CS/GridControlCRUD.Common/DataModel/EntityFrameworkDataProvider.cs deleted file mode 100644 index bd42842..0000000 --- a/CS/GridControlCRUD.Common/DataModel/EntityFrameworkDataProvider.cs +++ /dev/null @@ -1,117 +0,0 @@ -using DevExpress.Xpf.Data; -using System; -using System.Collections.Generic; -using System.Data.Entity; -using System.Data.Entity.Validation; -using System.Linq; -using System.Linq.Expressions; -using System.Text; - -namespace DevExpress.CRUD.DataModel.EntityFramework { - public class EntityFrameworkDataProvider : IDataProvider - where TEntity : class - where T : class - where TContext : DbContext { - - protected readonly Func createContext; - protected readonly Func> getDbSet; - protected readonly Expression> getEntityExpression; - readonly string keyProperty; - - readonly Func getKey; - readonly Func getEntityKey; - readonly Action setKey; - readonly Action applyProperties; - - public EntityFrameworkDataProvider(Func createContext, Func> getDbSet, Expression> getEnityExpression, - string keyProperty = null, Func getKey = null, Func getEntityKey = null, Action setKey = null, Action applyProperties = null) { - this.createContext = createContext; - this.getDbSet = getDbSet; - this.getEntityExpression = getEnityExpression; - - this.keyProperty = keyProperty; - this.getKey = getKey ?? (_ => throw new NotSupportedException()); - this.getEntityKey = getEntityKey ?? (_ => throw new NotSupportedException()); - this.setKey = setKey ?? ((_, __) => throw new NotSupportedException()); - this.applyProperties = applyProperties ?? ((_, __) => throw new NotSupportedException()); - } - - IList IDataProvider.Read() { - using(var context = createContext()) { - var query = getDbSet(context) - .Select(getEntityExpression); - return query.ToList(); - } - } - - void IDataProvider.Delete(T obj) { - using(var context = createContext()) { - var entity = getDbSet(context).Find(getKey(obj)); - if(entity == null) { - throw new NotImplementedException("The modified row no longer exists in the database. Handle this case according to your requirements."); - } - getDbSet(context).Remove(entity); - SaveChanges(context); - } - } - - void IDataProvider.Create(T obj) { - using(var context = createContext()) { - var entity = getDbSet(context).Create(); - getDbSet(context).Add(entity); - applyProperties(obj, entity); - SaveChanges(context); - setKey(obj, getEntityKey(entity)); - } - } - - void IDataProvider.Update(T obj) { - using(var context = createContext()) { - var entity = getDbSet(context).Find(getKey(obj)); - if(entity == null) { - throw new NotImplementedException("The modified row does not exist in a database anymore. Handle this case according to your requirements."); - } - applyProperties(obj, entity); - SaveChanges(context); - } - } - - TResult IDataProvider.GetQueryableResult(Func, TResult> getResult) { - using(var context = createContext()) { - var queryable = getDbSet(context).Select(getEntityExpression); - return getResult(queryable); - } - } - - string IDataProvider.KeyProperty => keyProperty; - - static void SaveChanges(TContext context) { - try { - context.SaveChanges(); - } catch(Exception e) { - throw ConvertException(e); - } - } - - static DbException ConvertException(Exception e) { - var entityValidationException = e as DbEntityValidationException; - if(entityValidationException != null) { - var stringBuilder = new StringBuilder(); - foreach(var validationResult in entityValidationException.EntityValidationErrors) { - foreach(var error in validationResult.ValidationErrors) { - if(stringBuilder.Length > 0) - stringBuilder.AppendLine(); - stringBuilder.Append(error.PropertyName + ": " + error.ErrorMessage); - } - } - return new DbException(stringBuilder.ToString(), entityValidationException); - } - return new DbException("An error has occurred while updating the database.", entityValidationException); - } - } - public class DbException : Exception { - public DbException(string message, Exception innerException) - : base(message, innerException) { - } - } -} diff --git a/CS/GridControlCRUD.Common/DataModel/IDataProvider.cs b/CS/GridControlCRUD.Common/DataModel/IDataProvider.cs deleted file mode 100644 index 24ec875..0000000 --- a/CS/GridControlCRUD.Common/DataModel/IDataProvider.cs +++ /dev/null @@ -1,16 +0,0 @@ -using DevExpress.Xpf.Data; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; - -namespace DevExpress.CRUD.DataModel { - public interface IDataProvider where T : class { - IList Read(); - void Create(T obj); - void Update(T obj); - void Delete(T obj); - TResult GetQueryableResult(Func, TResult> getResult); //used for virtual sources - string KeyProperty { get; } - } -} diff --git a/CS/GridControlCRUD.Common/View/GridControlDeleteRefreshBehavior.cs b/CS/GridControlCRUD.Common/View/GridControlDeleteRefreshBehavior.cs deleted file mode 100644 index dc02b88..0000000 --- a/CS/GridControlCRUD.Common/View/GridControlDeleteRefreshBehavior.cs +++ /dev/null @@ -1,100 +0,0 @@ -using DevExpress.CRUD.ViewModel; -using DevExpress.Mvvm; -using DevExpress.Mvvm.UI.Interactivity; -using DevExpress.Xpf.Core; -using DevExpress.Xpf.Data; -using DevExpress.Xpf.Grid; -using System; -using System.ComponentModel; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Input; - -namespace DevExpress.CRUD.View { - public class GridControlDeleteRefreshBehavior : Behavior { - public ICommand OnRefreshCommand { - get { return (ICommand)GetValue(OnRefreshCommandProperty); } - set { SetValue(OnRefreshCommandProperty, value); } - } - public static readonly DependencyProperty OnRefreshCommandProperty = - DependencyProperty.Register("OnRefreshCommand", typeof(ICommand), typeof(GridControlDeleteRefreshBehavior), new PropertyMetadata(null)); - - public string NoRecordsErrorMessage { - get { return (string)GetValue(NoRecordsErrorMessageProperty); } - set { SetValue(NoRecordsErrorMessageProperty, value); } - } - public static readonly DependencyProperty NoRecordsErrorMessageProperty = - DependencyProperty.Register("NoRecordsErrorMessage", typeof(string), typeof(GridControlDeleteRefreshBehavior), new PropertyMetadata(null, (d, e) => { ((GridControlDeleteRefreshBehavior)d).UpdateErrorText(); })); - - - public ICommand RefreshCommand { get; } - - TableView View => AssociatedObject; - VirtualSourceBase VirtualSource => View?.DataControl?.ItemsSource as VirtualSourceBase; - - public GridControlDeleteRefreshBehavior() { - RefreshCommand = new AsyncCommand(DoRefresh, CanRefresh); - } - - protected override void OnAttached() { - base.OnAttached(); - View.PreviewKeyDown += OnPreviewKeyDown; - UpdateErrorText(); - } - - protected override void OnDetaching() { - View.PreviewKeyDown -= OnPreviewKeyDown; - UpdateErrorText(); - base.OnDetaching(); - } - - void UpdateErrorText() { - if(View == null) - return; - if(NoRecordsErrorMessage != null) { - View.ShowEmptyText = true; - View.RuntimeLocalizationStrings = new GridRuntimeStringCollection() { - new RuntimeStringIdInfo(GridControlRuntimeStringId.NoRecords, NoRecordsErrorMessage) - }; - } else { - View.ShowEmptyText = false; - View.RuntimeLocalizationStrings = null; - } - } - - async void OnPreviewKeyDown(object sender, KeyEventArgs e) { - if(e.Key == Key.F5 && CanRefresh()) { - e.Handled = true; - await DoRefresh(); - } - } - - bool isRefreshInProgress; - async Task DoRefresh() { - VirtualSource?.RefreshRows(); - var args = new RefreshArgs(); - OnRefreshCommand.Execute(args); - if(args.Result != null) { - isRefreshInProgress = true; - try { - await args.Result; - } finally { - isRefreshInProgress = false; - } - } - } - bool CanRefresh() { - var canRefreshVirtualSource = VirtualSource == null - || ((VirtualSource as InfiniteAsyncSource)?.IsResetting != true && !VirtualSource.AreRowsFetching); - return canRefreshVirtualSource - && OnRefreshCommand != null - && !IsEditingRowState() - && !isRefreshInProgress - && (View?.Grid.ItemsSource != null || NoRecordsErrorMessage != null); - } - - bool IsEditingRowState() { - return View?.AreUpdateRowButtonsShown == true; - } - } -} diff --git a/CS/GridControlCRUD.Common/View/VirtualSourceEditFormBehavior.cs b/CS/GridControlCRUD.Common/View/VirtualSourceEditFormBehavior.cs deleted file mode 100644 index 967d55a..0000000 --- a/CS/GridControlCRUD.Common/View/VirtualSourceEditFormBehavior.cs +++ /dev/null @@ -1,103 +0,0 @@ -using DevExpress.CRUD.ViewModel; -using DevExpress.Mvvm; -using DevExpress.Mvvm.UI.Interactivity; -using DevExpress.Xpf.Core; -using DevExpress.Xpf.Data; -using DevExpress.Xpf.Grid; -using System; -using System.ComponentModel; -using System.Windows; -using System.Windows.Input; - -namespace GridControlCRUDMVVMInfiniteAsyncSource { - public class VirtualSourceEditFormBehavior : Behavior { - public ICommand OnUpdateCommand { - get { return (ICommand)GetValue(OnUpdateCommandProperty); } - set { SetValue(OnUpdateCommandProperty, value); } - } - public static readonly DependencyProperty OnUpdateCommandProperty = - DependencyProperty.Register("OnUpdateCommand", typeof(ICommand), typeof(VirtualSourceEditFormBehavior), new PropertyMetadata(null)); - - public ICommand OnCreateCommand { - get { return (ICommand)GetValue(OnCreateCommandProperty); } - set { SetValue(OnCreateCommandProperty, value); } - } - public static readonly DependencyProperty OnCreateCommandProperty = - DependencyProperty.Register("OnCreateCommand", typeof(ICommand), typeof(VirtualSourceEditFormBehavior), new PropertyMetadata(null)); - - VirtualSourceBase Source => (VirtualSourceBase)AssociatedObject?.DataControl?.ItemsSource; - - public ICommand CreateCommand { get; } - public ICommand UpdateCommand { get; } - public VirtualSourceEditFormBehavior() { - CreateCommand = new DelegateCommand(DoCreate); - UpdateCommand = new DelegateCommand(() => DoUpdate(), CanUpdate); - } - - protected override void OnAttached() { - base.OnAttached(); - AssociatedObject.PreviewKeyDown += OnKeyDown; - AssociatedObject.MouseDoubleClick += OnMouseDoubleClick; - } - - protected override void OnDetaching() { - AssociatedObject.PreviewKeyDown -= OnKeyDown; - AssociatedObject.MouseDoubleClick -= OnMouseDoubleClick; - base.OnDetaching(); - } - - void OnMouseDoubleClick(object sender, MouseButtonEventArgs e) { - var row = EventArgsToDataRowConverter.GetDataRow(e); - if(row != null) - DoUpdate(row); - } - - void OnKeyDown(object sender, KeyEventArgs e) { - if(e.Key == Key.F2) { - DoUpdate(); - e.Handled = true; - } - if(e.Key == Key.N && (Keyboard.Modifiers & ModifierKeys.Control) != 0) { - DoCreate(); - e.Handled = true; - } - } - - void DoUpdate(object entity = null) { - entity = entity ?? AssociatedObject.DataControl.CurrentItem; - var args = new EntityUpdateArgs(entity); - OnUpdateCommand.Execute(args); - if(args.Updated) - ReloadRow(GetKey(entity)); - } - void ReloadRow(object key) { - if(Source is InfiniteAsyncSource) - ((InfiniteAsyncSource)Source).ReloadRows(key); - else if(Source is PagedAsyncSource) - ((PagedAsyncSource)Source).ReloadRows(key); - else - throw new InvalidOperationException(); - } - - bool CanUpdate() { - return OnUpdateCommand != null && CanChangeCurrentItem(); - } - - bool CanChangeCurrentItem() { - return AssociatedObject?.DataControl?.CurrentItem != null; - } - - void DoCreate() { - var args = new EntityCreateArgs(); - OnCreateCommand.Execute(args); - if(args.Entity != null) - Source.RefreshRows(); - } - - object GetKey(T entity) { - ITypedList typedList = Source; - var keyProperty = typedList.GetItemProperties(null)[Source.KeyProperty]; - return keyProperty.GetValue(entity); - } - } -} diff --git a/CS/GridControlCRUD.Common/ViewModel/AsyncCollectionViewModel.cs b/CS/GridControlCRUD.Common/ViewModel/AsyncCollectionViewModel.cs deleted file mode 100644 index 1d41eca..0000000 --- a/CS/GridControlCRUD.Common/ViewModel/AsyncCollectionViewModel.cs +++ /dev/null @@ -1,84 +0,0 @@ -using DevExpress.CRUD.DataModel; -using DevExpress.Mvvm; -using DevExpress.Mvvm.DataAnnotations; -using DevExpress.Mvvm.Xpf; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace DevExpress.CRUD.ViewModel { - public abstract class AsyncCollectionViewModel : ViewModelBase where T : class { - readonly IDataProvider dataProvider; - - public IMessageBoxService MessageBoxService { get { return GetService(); } } - - protected AsyncCollectionViewModel(IDataProvider dataProvider) { - this.dataProvider = dataProvider; - StartRefresh(); - } - - public IList Entities { - get => GetValue>(); - private set => SetValue(value); - } - public string EntitiesErrorMessage { - get => GetValue(); - private set => SetValue(value); - } - public bool IsLoading { - get => GetValue(); - private set => SetValue(value); - } - - async void StartRefresh() { - await OnRefreshAsync(); - } - - [Command] - public void OnRefresh(RefreshArgs args) { - args.Result = OnRefreshAsync(); - } - async Task OnRefreshAsync() { - IsLoading = true; - try { - await Task.WhenAll(RefreshEntities(), OnRefreshCoreAsync()); - } finally { - IsLoading = false; - } - } - async Task RefreshEntities() { - try { - Entities = await dataProvider.ReadAsync(); - EntitiesErrorMessage = null; - } catch { - Entities = null; - EntitiesErrorMessage = "An error has occurred while establishing a connection to the database. Press F5 to retry the connection."; - } - } - protected virtual Task OnRefreshCoreAsync() { - return Task.CompletedTask; - } - - [Command] - public void OnUpdateRow(RowValidationArgs args) { - args.ResultAsync = OnUpdateRowAsync((T)args.Item, args.IsNewItem); - } - async Task OnUpdateRowAsync(T entity, bool isNew) { - if(isNew) - await dataProvider.CreateAsync(entity); - else - await dataProvider.UpdateAsync(entity); - return null; - } - - [Command] - public void OnDeleteRow(DeleteRowsValidationArgs args) { - var row = (T)args.Items[0]; - if(row == null) - return; - if(MessageBoxService.ShowMessage("Are you sure you want to delete this row?", "Delete Row", MessageButton.OKCancel) == MessageResult.Cancel) { - args.Result = "Canceled"; - } - dataProvider.Delete(row); - } - } -} diff --git a/CS/GridControlCRUD.Common/ViewModel/CollectionViewModel.cs b/CS/GridControlCRUD.Common/ViewModel/CollectionViewModel.cs deleted file mode 100644 index 0195938..0000000 --- a/CS/GridControlCRUD.Common/ViewModel/CollectionViewModel.cs +++ /dev/null @@ -1,65 +0,0 @@ -using DevExpress.CRUD.DataModel; -using DevExpress.Mvvm; -using DevExpress.Mvvm.DataAnnotations; -using DevExpress.Mvvm.Xpf; -using System.Collections.Generic; - -namespace DevExpress.CRUD.ViewModel { - public abstract class CollectionViewModel : ViewModelBase where T : class { - readonly IDataProvider dataProvider; - - IMessageBoxService MessageBoxService { get { return GetService(); } } - - protected CollectionViewModel(IDataProvider dataProvider) { - this.dataProvider = dataProvider; - OnRefresh(); - } - - public IList Entities { - get => GetValue>(); - private set => SetValue(value); - } - public string EntitiesErrorMessage { - get => GetValue(); - private set => SetValue(value); - } - - [Command] - public void OnRefresh(RefreshArgs _) { - OnRefresh(); - } - void OnRefresh() { - try { - Entities = dataProvider.Read(); - EntitiesErrorMessage = null; - } catch { - Entities = null; - EntitiesErrorMessage = "An error has occurred while establishing a connection to the database. Press F5 to retry the connection."; - } - OnRefreshCore(); - } - - protected virtual void OnRefreshCore() { - } - - [Command] - public void OnUpdateRow(RowValidationArgs args) { - var entity = (T)args.Item; - if(args.IsNewItem) - dataProvider.Create(entity); - else - dataProvider.Update(entity); - } - - [Command] - public void OnDeleteRow(DeleteRowsValidationArgs args) { - var row = (T)args.Items[0]; - if(row == null) - return; - if(MessageBoxService.ShowMessage("Are you sure you want to delete this row?", "Delete Row", MessageButton.OKCancel) == MessageResult.Cancel) { - args.Result = "Canceled"; - } - dataProvider.Delete(row); - } - } -} diff --git a/CS/GridControlCRUD.Common/ViewModel/CommandArgs/EntityCreateArgs.cs b/CS/GridControlCRUD.Common/ViewModel/CommandArgs/EntityCreateArgs.cs deleted file mode 100644 index 8f8f842..0000000 --- a/CS/GridControlCRUD.Common/ViewModel/CommandArgs/EntityCreateArgs.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; -using System.Linq; - -namespace DevExpress.CRUD.ViewModel { - public class EntityCreateArgs { - public object Entity { get; set; } - } -} diff --git a/CS/GridControlCRUD.Common/ViewModel/CommandArgs/EntityUpdateArgs.cs b/CS/GridControlCRUD.Common/ViewModel/CommandArgs/EntityUpdateArgs.cs deleted file mode 100644 index b493ad5..0000000 --- a/CS/GridControlCRUD.Common/ViewModel/CommandArgs/EntityUpdateArgs.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Linq; - -namespace DevExpress.CRUD.ViewModel { - public class EntityUpdateArgs { - public EntityUpdateArgs(object entity) { - Entity = entity; - } - public object Entity { get; } - public bool Updated { get; set; } - } -} diff --git a/CS/GridControlCRUD.Common/ViewModel/CommandArgs/RefreshArgs.cs b/CS/GridControlCRUD.Common/ViewModel/CommandArgs/RefreshArgs.cs deleted file mode 100644 index c0cc29c..0000000 --- a/CS/GridControlCRUD.Common/ViewModel/CommandArgs/RefreshArgs.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System.Threading.Tasks; - -namespace DevExpress.CRUD.ViewModel { - public class RefreshArgs { - public Task Result { get; set; } - } -} diff --git a/CS/GridControlCRUD.Common/ViewModel/CommandArgs/RowDeleteArgs.cs b/CS/GridControlCRUD.Common/ViewModel/CommandArgs/RowDeleteArgs.cs deleted file mode 100644 index ac96e05..0000000 --- a/CS/GridControlCRUD.Common/ViewModel/CommandArgs/RowDeleteArgs.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace DevExpress.CRUD.ViewModel { - public class RowDeleteArgs { - public RowDeleteArgs(object row) { - Row = row; - } - public object Row { get; } - } -} diff --git a/CS/GridControlCRUD.Common/ViewModel/VirtualCollectionViewModel.cs b/CS/GridControlCRUD.Common/ViewModel/VirtualCollectionViewModel.cs deleted file mode 100644 index 274ef9f..0000000 --- a/CS/GridControlCRUD.Common/ViewModel/VirtualCollectionViewModel.cs +++ /dev/null @@ -1,91 +0,0 @@ -using DevExpress.CRUD.DataModel; -using DevExpress.Mvvm; -using DevExpress.Mvvm.DataAnnotations; -using DevExpress.Xpf.Data; -using DevExpress.Mvvm.Xpf; -using System; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace DevExpress.CRUD.ViewModel { - public abstract class VirtualCollectionViewModel : ViewModelBase where T : class, new() { - readonly IDataProvider dataProvider; - - public IMessageBoxService MessageBoxService { get { return GetService(); } } - - protected VirtualCollectionViewModel(IDataProvider dataProvider) { - this.dataProvider = dataProvider; - StartRefresh(); - } - - public Type FilterType => typeof(Expression>); - - [Command] - public void Fetch(FetchRowsAsyncArgs args) { - args.Result = dataProvider.GetQueryableResultAsync(queryable => { - return queryable - .SortBy(args.SortOrder, defaultUniqueSortPropertyName: dataProvider.KeyProperty) - .Where((Expression>)args.Filter) - .Skip(args.Skip) - .Take(args.Take ?? 30) - .ToArray(); - }); - } - - [Command] - public void GetTotalSummaries(GetSummariesAsyncArgs args) { - args.Result = dataProvider.GetQueryableResultAsync(queryable => { - return queryable - .Where((Expression>)args.Filter) - .GetSummaries(args.Summaries); - }); - } - - [Command] - public void GetUniqueValues(GetUniqueValuesAsyncArgs args) { - args.ResultWithCounts = dataProvider.GetQueryableResultAsync(queryable => { - return queryable - .Where((Expression>)args.Filter) - .DistinctWithCounts(args.PropertyName); - }); - } - - [Command] - public void OnCreateRow(RowValidationArgs args) { - if(args.IsNewItem) { - dataProvider.Create((T)args.Item); - } else { - dataProvider.Update((T)args.Item); - } - } - - [Command] - public void OnDeleteRow(DeleteRowsValidationArgs args) { - var row = (T)args.Items[0]; - if(row == null) - return; - if(MessageBoxService.ShowMessage("Are you sure you want to delete this row?", "Delete Row", MessageButton.OKCancel) == MessageResult.Cancel) { - args.Result = "Canceled"; - } - this.dataProvider.Delete(row); - } - - [Command] - public void OnRefresh(RefreshArgs args) { - args.Result = OnRefreshCoreAsync(); - } - async void StartRefresh() { - await OnRefreshCoreAsync(); - } - protected virtual Task OnRefreshCoreAsync() { - return Task.CompletedTask; - } - } - public class EntityViewModel : ViewModelBase { - public EntityViewModel(T entity) { - Entity = entity; - } - public T Entity { get; } - } -} diff --git a/CS/GridControlCRUD.sln b/CS/GridControlCRUD.sln deleted file mode 100644 index 10e5467..0000000 --- a/CS/GridControlCRUD.sln +++ /dev/null @@ -1,43 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29806.167 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GridControlCRUDSimple", "GridControlCRUDSimple\GridControlCRUDSimple.csproj", "{9E2883B9-744A-48BF-B25A-EA4B2D435C9D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GridControlCRUDMVVM", "GridControlCRUDMVVM\GridControlCRUDMVVM.csproj", "{69E85A61-E7D4-4C9D-A433-13E742AE30BC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GridControlCRUDMVVMAsync", "GridControlCRUDMVVMAsync\GridControlCRUDMVVMAsync.csproj", "{659194A7-745D-4A56-A683-B150B9170F53}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GridControlCRUDMVVMInfiniteAsyncSource", "GridControlCRUDMVVMInfiniteAsyncSource\GridControlCRUDMVVMInfiniteAsyncSource.csproj", "{99F77CC9-A05A-4064-B0A9-63E0B93ED156}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9E2883B9-744A-48BF-B25A-EA4B2D435C9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9E2883B9-744A-48BF-B25A-EA4B2D435C9D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9E2883B9-744A-48BF-B25A-EA4B2D435C9D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9E2883B9-744A-48BF-B25A-EA4B2D435C9D}.Release|Any CPU.Build.0 = Release|Any CPU - {69E85A61-E7D4-4C9D-A433-13E742AE30BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {69E85A61-E7D4-4C9D-A433-13E742AE30BC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {69E85A61-E7D4-4C9D-A433-13E742AE30BC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {69E85A61-E7D4-4C9D-A433-13E742AE30BC}.Release|Any CPU.Build.0 = Release|Any CPU - {659194A7-745D-4A56-A683-B150B9170F53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {659194A7-745D-4A56-A683-B150B9170F53}.Debug|Any CPU.Build.0 = Debug|Any CPU - {659194A7-745D-4A56-A683-B150B9170F53}.Release|Any CPU.ActiveCfg = Release|Any CPU - {659194A7-745D-4A56-A683-B150B9170F53}.Release|Any CPU.Build.0 = Release|Any CPU - {99F77CC9-A05A-4064-B0A9-63E0B93ED156}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {99F77CC9-A05A-4064-B0A9-63E0B93ED156}.Debug|Any CPU.Build.0 = Debug|Any CPU - {99F77CC9-A05A-4064-B0A9-63E0B93ED156}.Release|Any CPU.ActiveCfg = Release|Any CPU - {99F77CC9-A05A-4064-B0A9-63E0B93ED156}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {51597E69-ADA1-4945-9493-FC7C9FB65AD2} - EndGlobalSection -EndGlobal diff --git a/CS/GridControlCRUDMVVM/App.xaml.cs b/CS/GridControlCRUDMVVM/App.xaml.cs deleted file mode 100644 index b1d73f0..0000000 --- a/CS/GridControlCRUDMVVM/App.xaml.cs +++ /dev/null @@ -1,12 +0,0 @@ -using DevExpress.Mvvm; -using DevExpress.Xpf.Core; -using System.Windows; - -namespace GridControlCRUDMVVM { - public partial class App : Application { - public App() { - ApplicationThemeHelper.UpdateApplicationThemeName(); - DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); - } - } -} diff --git a/CS/GridControlCRUDMVVM/MainWindow.xaml b/CS/GridControlCRUDMVVM/MainWindow.xaml deleted file mode 100644 index 229649e..0000000 --- a/CS/GridControlCRUDMVVM/MainWindow.xaml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/CS/GridControlCRUDMVVM/MainWindow.xaml.cs b/CS/GridControlCRUDMVVM/MainWindow.xaml.cs deleted file mode 100644 index 6101542..0000000 --- a/CS/GridControlCRUDMVVM/MainWindow.xaml.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DevExpress.Xpf.Core; - -namespace GridControlCRUDMVVM { - public partial class MainWindow : ThemedWindow { - public MainWindow() { - InitializeComponent(); - } - } -} diff --git a/CS/GridControlCRUDMVVM/ProductCollectionViewModel.cs b/CS/GridControlCRUDMVVM/ProductCollectionViewModel.cs deleted file mode 100644 index e047450..0000000 --- a/CS/GridControlCRUDMVVM/ProductCollectionViewModel.cs +++ /dev/null @@ -1,35 +0,0 @@ -using DevExpress.CRUD.DataModel; -using DevExpress.CRUD.Northwind.DataModel; -using DevExpress.CRUD.ViewModel; -using System.Collections.Generic; - -namespace DevExpress.CRUD.Northwind.ViewModel { - public class ProductCollectionViewModel : CollectionViewModel { - public IList Categories { - get => GetValue>(); - private set => SetValue(value); - } - - readonly IDataProvider categoriesDataProvider; - - public ProductCollectionViewModel() - : this(NorthwindDataStorageFactory.Create(IsInDesignMode)) { - } - - public ProductCollectionViewModel(NorthwindDataStorage dataStorage) - : base(dataStorage.Products) { - categoriesDataProvider = dataStorage.Categories; - OnRefreshCore(); - } - - protected override void OnRefreshCore() { - if(categoriesDataProvider != null) { - try { - Categories = categoriesDataProvider.Read(); - } catch { - Categories = null; - } - } - } - } -} diff --git a/CS/GridControlCRUDMVVMAsync/App.xaml.cs b/CS/GridControlCRUDMVVMAsync/App.xaml.cs deleted file mode 100644 index 722383a..0000000 --- a/CS/GridControlCRUDMVVMAsync/App.xaml.cs +++ /dev/null @@ -1,12 +0,0 @@ -using DevExpress.Mvvm; -using DevExpress.Xpf.Core; -using System.Windows; - -namespace GridControlCRUDMVVMAsync { - public partial class App : Application { - public App() { - ApplicationThemeHelper.UpdateApplicationThemeName(); - DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); - } - } -} diff --git a/CS/GridControlCRUDMVVMAsync/MainWindow.xaml b/CS/GridControlCRUDMVVMAsync/MainWindow.xaml deleted file mode 100644 index a904dd3..0000000 --- a/CS/GridControlCRUDMVVMAsync/MainWindow.xaml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/CS/GridControlCRUDMVVMAsync/MainWindow.xaml.cs b/CS/GridControlCRUDMVVMAsync/MainWindow.xaml.cs deleted file mode 100644 index 5f4a969..0000000 --- a/CS/GridControlCRUDMVVMAsync/MainWindow.xaml.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DevExpress.Xpf.Core; - -namespace GridControlCRUDMVVMAsync { - public partial class MainWindow : ThemedWindow { - public MainWindow() { - InitializeComponent(); - } - } -} diff --git a/CS/GridControlCRUDMVVMAsync/ProductCollectionViewModel.cs b/CS/GridControlCRUDMVVMAsync/ProductCollectionViewModel.cs deleted file mode 100644 index 1902378..0000000 --- a/CS/GridControlCRUDMVVMAsync/ProductCollectionViewModel.cs +++ /dev/null @@ -1,39 +0,0 @@ -using DevExpress.CRUD.DataModel; -using DevExpress.CRUD.Northwind.DataModel; -using DevExpress.CRUD.ViewModel; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace DevExpress.CRUD.Northwind.ViewModel { - public class ProductCollectionViewModel : AsyncCollectionViewModel { - public IList Categories { - get => GetValue>(); - private set => SetValue(value); - } - - readonly IDataProvider categoriesDataProvider; - - public ProductCollectionViewModel() - : this(NorthwindDataStorageFactory.Create(IsInDesignMode)) { - } - - public ProductCollectionViewModel(NorthwindDataStorage dataStorage) - : base(dataStorage.Products) { - categoriesDataProvider = dataStorage.Categories; - RefreshCategories(); - } - - async void RefreshCategories() { - await OnRefreshCoreAsync(); - } - protected override async Task OnRefreshCoreAsync() { - if(categoriesDataProvider != null) { - try { - Categories = await categoriesDataProvider.ReadAsync(); - } catch { - Categories = null; - } - } - } - } -} diff --git a/CS/GridControlCRUDMVVMAsync/Properties/Settings.Designer.cs b/CS/GridControlCRUDMVVMAsync/Properties/Settings.Designer.cs deleted file mode 100644 index 9d32906..0000000 --- a/CS/GridControlCRUDMVVMAsync/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace GridControlCRUDMVVMAsync.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.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 --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/App.xaml b/CS/GridControlCRUDMVVMInfiniteAsyncSource/App.xaml deleted file mode 100644 index 2ba660c..0000000 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/App.xaml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/App.xaml.cs b/CS/GridControlCRUDMVVMInfiniteAsyncSource/App.xaml.cs deleted file mode 100644 index a8443de..0000000 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/App.xaml.cs +++ /dev/null @@ -1,12 +0,0 @@ -using DevExpress.Mvvm; -using DevExpress.Xpf.Core; -using System.Windows; - -namespace GridControlCRUDMVVMInfiniteAsyncSource { - public partial class App : Application { - public App() { - ApplicationThemeHelper.UpdateApplicationThemeName(); - DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); - } - } -} diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssueCollectionViewModel.cs b/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssueCollectionViewModel.cs deleted file mode 100644 index 3afe9ad..0000000 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssueCollectionViewModel.cs +++ /dev/null @@ -1,55 +0,0 @@ -using DevExpress.CRUD.DataModel; -using DevExpress.CRUD.ViewModel; -using GridControlCRUDMVVMInfiniteAsyncSource; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace GridControlCRUDMVVMInfiniteAsyncSource { - public class IssueCollectionViewModel : VirtualCollectionViewModel { - public IList Users { - get => GetValue>(); - private set => SetValue(value); - } - - readonly IDataProvider usersDataProvider; - - public IssueCollectionViewModel() - : this(IssuesDataStorageFactory.Create(IsInDesignMode)) { - } - - public IssueCollectionViewModel(IssuesDataStorage dataStorage) - : base(dataStorage.Issues) { - usersDataProvider = dataStorage.Users; - RefreshUsers(); - } - - async void RefreshUsers() { - await OnRefreshCoreAsync(); - } - protected override async Task OnRefreshCoreAsync() { - if(usersDataProvider != null) { - try { - Users = await usersDataProvider.ReadAsync(); - } catch { - Users = null; - } - } - } - } - public class IssueDataViewModel : EntityViewModel { - public IssueDataViewModel(IssueData entity, Task> usersTask) : base(entity) { - AssignUsers(usersTask); - } - async void AssignUsers(Task> usersTask) { - try { - Users = await usersTask; - } catch { - Users = null; - } - } - public IList Users { - get => GetValue>(); - private set => SetValue(value); - } - } -} diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssueDataFilterConverter.cs b/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssueDataFilterConverter.cs deleted file mode 100644 index a47c1e9..0000000 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssueDataFilterConverter.cs +++ /dev/null @@ -1,15 +0,0 @@ -using DevExpress.Data.Filtering; -using DevExpress.Xpf.Data; - -namespace GridControlCRUDMVVMInfiniteAsyncSource { - public class IssueDataFilterConverter : ExpressionFilterConverter { - protected override void SetUpConverter(GridFilterCriteriaToExpressionConverter converter) { - converter.RegisterFunctionExpressionFactory( - operatorType: FunctionOperatorType.StartsWith, - factory: (string value) => { - var toLowerValue = value.ToLower(); - return x => x.ToLower().StartsWith(toLowerValue); - }); - } - } -} diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext.DataModel/IssuesDataStorage.cs b/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext.DataModel/IssuesDataStorage.cs deleted file mode 100644 index c4d2a7e..0000000 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext.DataModel/IssuesDataStorage.cs +++ /dev/null @@ -1,12 +0,0 @@ -using DevExpress.CRUD.DataModel; - -namespace GridControlCRUDMVVMInfiniteAsyncSource { - public class IssuesDataStorage { - public IssuesDataStorage(IDataProvider issues, IDataProvider users) { - Users = users; - Issues = issues; - } - public IDataProvider Users { get; } - public IDataProvider Issues { get; } - } -} diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext.DataModel/IssuesDataStorageFactory.cs b/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext.DataModel/IssuesDataStorageFactory.cs deleted file mode 100644 index 5a5f06c..0000000 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/IssuesContext.DataModel/IssuesDataStorageFactory.cs +++ /dev/null @@ -1,56 +0,0 @@ -using DevExpress.CRUD.DataModel.EntityFramework; -using DevExpress.CRUD.DataModel; - -namespace GridControlCRUDMVVMInfiniteAsyncSource { - public static class IssuesDataStorageFactory { - public static IssuesDataStorage Create(bool isInDesignMode) { - if(isInDesignMode) { - return new IssuesDataStorage( - new DesignTimeDataProvider( - id => new IssueData { - Id = id, - Subject = "Subject " + id, - } - ), - new DesignTimeDataProvider( - id => new User { - Id = id, - FirstName = "FirstName " + id, - } - ) - ); - } - return new IssuesDataStorage( - new EntityFrameworkDataProvider( - createContext: () => new IssuesContext(), - getDbSet: context => context.Issues, - getEnityExpression: x => new IssueData() { - Id = x.Id, - Subject = x.Subject, - UserId = x.UserId, - Created = x.Created, - Votes = x.Votes, - Priority = x.Priority, - }, - getKey: ussueData => ussueData.Id, - getEntityKey: ussue => ussue.Id, - setKey: (ussueData, id) => ussueData.Id = (int)id, - applyProperties: (ussueData, issue) => { - issue.Subject = ussueData.Subject; - issue.UserId = ussueData.UserId; - issue.Created = ussueData.Created; - issue.Votes = ussueData.Votes; - issue.Priority = ussueData.Priority; - }, - keyProperty: nameof(IssueData.Id) - ), - new EntityFrameworkDataProvider( - createContext: () => new IssuesContext(), - getDbSet: context => context.Users, - getEnityExpression: user => user, - keyProperty: nameof(User.Id) - ) - ); - } - } -} diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/MainWindow.xaml b/CS/GridControlCRUDMVVMInfiniteAsyncSource/MainWindow.xaml deleted file mode 100644 index 726201e..0000000 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/MainWindow.xaml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/MainWindow.xaml.cs b/CS/GridControlCRUDMVVMInfiniteAsyncSource/MainWindow.xaml.cs deleted file mode 100644 index 5496242..0000000 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/MainWindow.xaml.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DevExpress.Xpf.Core; - -namespace GridControlCRUDMVVMInfiniteAsyncSource { - public partial class MainWindow : ThemedWindow { - public MainWindow() { - InitializeComponent(); - } - } -} diff --git a/CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/Settings.Designer.cs b/CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/Settings.Designer.cs deleted file mode 100644 index 9d32906..0000000 --- a/CS/GridControlCRUDMVVMInfiniteAsyncSource/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace GridControlCRUDMVVMAsync.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.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 --git a/CS/GridControlCRUDSimple/App.xaml.cs b/CS/GridControlCRUDSimple/App.xaml.cs deleted file mode 100644 index 2779352..0000000 --- a/CS/GridControlCRUDSimple/App.xaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using DevExpress.Xpf.Core; -using System.Windows; - -namespace GridControlCRUDSimple { - public partial class App : Application { - public App() { - ApplicationThemeHelper.UpdateApplicationThemeName(); - DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); - } - } -} diff --git a/CS/GridControlCRUDSimple/MainWindow.xaml b/CS/GridControlCRUDSimple/MainWindow.xaml deleted file mode 100644 index 5195d8f..0000000 --- a/CS/GridControlCRUDSimple/MainWindow.xaml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/CS/GridControlCRUDSimple/MainWindow.xaml.cs b/CS/GridControlCRUDSimple/MainWindow.xaml.cs deleted file mode 100644 index 45e7a01..0000000 --- a/CS/GridControlCRUDSimple/MainWindow.xaml.cs +++ /dev/null @@ -1,70 +0,0 @@ -using DevExpress.Xpf.Core; -using DevExpress.Xpf.Grid; -using DevExpress.CRUD.Northwind; -using System; -using System.Linq; -using System.Windows; -using DevExpress.CRUD.Northwind.DataModel; - -namespace GridControlCRUDSimple { - public partial class MainWindow : ThemedWindow { - public MainWindow() { - InitializeComponent(); - using(var context = new NorthwindContext()) { - grid.ItemsSource = context - .Products - .Select(product => new ProductInfo { - Id = product.Id, - Name = product.Name, - CategoryId = product.CategoryId - }) - .ToList(); - categoriesLookup.ItemsSource = context - .Categories - .Select(category => new CategoryInfo { - Id = category.Id, - Name = category.Name, - }) - .ToList(); - } - } - - void OnValidateRow(object sender, GridRowValidationEventArgs e) { - var productInfo = (ProductInfo)e.Row; - using(var context = new NorthwindContext()) { - Product product; - if(view.FocusedRowHandle == DataControlBase.NewItemRowHandle) { - product = new Product(); - context.Products.Add(product); - } else { - product = context.Products.SingleOrDefault(p => p.Id == productInfo.Id); - if(product == null) { - throw new NotImplementedException("The modified row no longer exists in the database. Handle this case according to your requirements."); - } - } - product.Name = productInfo.Name; - product.CategoryId = productInfo.CategoryId; - context.SaveChanges(); - if(view.FocusedRowHandle == DataControlBase.NewItemRowHandle) { - productInfo.Id = product.Id; - } - } - } - - void OnValidateDeleteRows(object sender, GridDeleteRowsValidationEventArgs e) { - var productInfo = (ProductInfo)e.Rows[0]; - if(DXMessageBox.Show(this, "Are you sure you want to delete this row?", "Delete Row", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel) { - e.Result = "Canceled"; - return; - } - using(var context = new NorthwindContext()) { - var result = context.Products.Find(productInfo.Id); - if(result == null) { - throw new NotImplementedException("The modified row no longer exists in the database. Handle this case according to your requirements."); - } - context.Products.Remove(result); - context.SaveChanges(); - } - } - } -} diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/App.config b/CS/ViewModel/EFCore/InfiniteAsyncSource/App.config new file mode 100644 index 0000000..210a3bb --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/App.config @@ -0,0 +1,63 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/App.xaml b/CS/ViewModel/EFCore/InfiniteAsyncSource/App.xaml new file mode 100644 index 0000000..cd777dc --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/App.xaml.cs b/CS/ViewModel/EFCore/InfiniteAsyncSource/App.xaml.cs new file mode 100644 index 0000000..5263c1c --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/App.xaml.cs @@ -0,0 +1,19 @@ +using EFCoreIssues.Issues; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EFCoreIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + IssuesContextInitializer.Seed(); + } + } +} diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.csproj b/CS/ViewModel/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.csproj new file mode 100644 index 0000000..477422f --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.csproj @@ -0,0 +1,216 @@ + + + + + + Debug + AnyCPU + {75B40700-47BF-EE34-106B-49B693C14CD3} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.sln b/CS/ViewModel/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.sln new file mode 100644 index 0000000..08f1d50 --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfiniteAsyncSource", "InfiniteAsyncSource.csproj", "{75B40700-47BF-EE34-106B-49B693C14CD3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {75B40700-47BF-EE34-106B-49B693C14CD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {75B40700-47BF-EE34-106B-49B693C14CD3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {75B40700-47BF-EE34-106B-49B693C14CD3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {75B40700-47BF-EE34-106B-49B693C14CD3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/Issue.cs b/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/Issue.cs new file mode 100644 index 0000000..c36c075 --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EFCoreIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/IssuesContext.cs b/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/IssuesContext.cs new file mode 100644 index 0000000..5ef3c63 --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/IssuesContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues.Issues { + public class IssuesContext : DbContext { + static readonly DbContextOptions options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: "Test") + .Options; + public IssuesContext() + : base(options) { + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/IssuesContextInitializer.cs b/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..d58b850 --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/IssuesContextInitializer.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; + +namespace EFCoreIssues.Issues { + public static class IssuesContextInitializer { + public static void Seed() { + var context = new IssuesContext(); + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs b/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..5e35561 --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EFCoreIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/User.cs b/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/User.cs new file mode 100644 index 0000000..e3e8021 --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EFCoreIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/MainViewModel.cs b/CS/ViewModel/EFCore/InfiniteAsyncSource/MainViewModel.cs new file mode 100644 index 0000000..6f7d74f --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/MainViewModel.cs @@ -0,0 +1,71 @@ +using DevExpress.Mvvm; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues { + public class MainViewModel : ViewModelBase { + [DevExpress.Mvvm.DataAnnotations.Command] + public void FetchRows(DevExpress.Mvvm.Xpf.FetchRowsAsyncArgs args) { + args.Result = Task.Run(() => + { + var context = new EFCoreIssues.Issues.IssuesContext(); + var queryable = context.Issues.AsNoTracking() + .SortBy(args.SortOrder, defaultUniqueSortPropertyName: nameof(EFCoreIssues.Issues.Issue.Id)) + .Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)args.Filter)); + return queryable.Skip(args.Skip).Take(args.Take ?? 100).ToArray(); + }); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void GetTotalSummaries(DevExpress.Mvvm.Xpf.GetSummariesAsyncArgs args) { + args.Result = Task.Run(() => + { + var context = new EFCoreIssues.Issues.IssuesContext(); + var queryable = context.Issues.Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)args.Filter)); + return queryable.GetSummaries(args.Summaries); + }); + } + + System.Linq.Expressions.Expression> MakeFilterExpression(DevExpress.Data.Filtering.CriteriaOperator filter) { + var converter = new DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(); + return converter.Convert(filter); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.RowValidationArgs args) { + var item = (EFCoreIssues.Issues.Issue)args.Item; + var context = new EFCoreIssues.Issues.IssuesContext(); + context.Entry(item).State = args.IsNewItem ? EntityState.Added : EntityState.Modified; + try { + context.SaveChanges(); + } finally { + context.Entry(item).State = EntityState.Detached; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRowDeletion(DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs args) { + var item = (EFCoreIssues.Issues.Issue)args.Items.Single(); + var context = new EFCoreIssues.Issues.IssuesContext(); + context.Entry(item).State = EntityState.Deleted; + context.SaveChanges(); + } + System.Collections.IList _Users; + + public System.Collections.IList Users + { + get + { + if(_Users == null && !IsInDesignMode) { + var context = new EFCoreIssues.Issues.IssuesContext(); + _Users = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + return _Users; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _Users = null; + RaisePropertyChanged(nameof(Users)); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml b/CS/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..e7ade31 --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml.cs b/CS/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml.cs new file mode 100644 index 0000000..af13819 --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace EFCoreIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/AssemblyInfo.cs b/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4179e62 --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EFCoreIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EFCoreIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/Resources.Designer.cs b/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/Resources.Designer.cs new file mode 100644 index 0000000..9b965de --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/Resources.Designer.cs @@ -0,0 +1,58 @@ +namespace EFCoreIssues.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", "16.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("EFCoreIssues.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 --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/Resources.resx b/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/Settings.Designer.cs b/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/Settings.Designer.cs new file mode 100644 index 0000000..c156b8a --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/Settings.Designer.cs @@ -0,0 +1,18 @@ +namespace EFCoreIssues.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.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 --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/Settings.settings b/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/InfiniteAsyncSource/packages.config b/CS/ViewModel/EFCore/InfiniteAsyncSource/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/CS/ViewModel/EFCore/InfiniteAsyncSource/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/App.config b/CS/ViewModel/EFCore/InstantFeedbackMode/App.config new file mode 100644 index 0000000..210a3bb --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/App.config @@ -0,0 +1,63 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/App.xaml b/CS/ViewModel/EFCore/InstantFeedbackMode/App.xaml new file mode 100644 index 0000000..cd777dc --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/App.xaml.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/App.xaml.cs new file mode 100644 index 0000000..5263c1c --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/App.xaml.cs @@ -0,0 +1,19 @@ +using EFCoreIssues.Issues; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EFCoreIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + IssuesContextInitializer.Seed(); + } + } +} diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/EditIssueInfo.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/EditIssueInfo.cs new file mode 100644 index 0000000..f1e718a --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/EditIssueInfo.cs @@ -0,0 +1,14 @@ +using DevExpress.Mvvm; +using System.Collections; +using EFCoreIssues.Issues; + +namespace EFCoreIssues { + public class EditIssueInfo : BindableBase { + public EditIssueInfo(IssuesContext context, IList users) { + Context = context; + Users = users; + } + public IssuesContext Context { get; } + public IList Users { get; } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/InstantFeedbackMode.csproj b/CS/ViewModel/EFCore/InstantFeedbackMode/InstantFeedbackMode.csproj new file mode 100644 index 0000000..4db5f10 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/InstantFeedbackMode.csproj @@ -0,0 +1,225 @@ + + + + + + Debug + AnyCPU + {CAD2530B-A4C1-61AD-CBA7-DB8548EBCCDB} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/InstantFeedbackMode.sln b/CS/ViewModel/EFCore/InstantFeedbackMode/InstantFeedbackMode.sln new file mode 100644 index 0000000..0c5a373 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/InstantFeedbackMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantFeedbackMode", "InstantFeedbackMode.csproj", "{CAD2530B-A4C1-61AD-CBA7-DB8548EBCCDB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CAD2530B-A4C1-61AD-CBA7-DB8548EBCCDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CAD2530B-A4C1-61AD-CBA7-DB8548EBCCDB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CAD2530B-A4C1-61AD-CBA7-DB8548EBCCDB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CAD2530B-A4C1-61AD-CBA7-DB8548EBCCDB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/IssueDetailView.xaml b/CS/ViewModel/EFCore/InstantFeedbackMode/IssueDetailView.xaml new file mode 100644 index 0000000..d5c1fd0 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/IssueDetailView.xaml.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/IssueDetailView.xaml.cs new file mode 100644 index 0000000..391f819 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/IssueDetailView.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows.Controls; + +namespace EFCoreIssues { + public partial class IssueDetailView : UserControl { + public IssueDetailView() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/Issue.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/Issue.cs new file mode 100644 index 0000000..c36c075 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EFCoreIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/IssuesContext.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/IssuesContext.cs new file mode 100644 index 0000000..5ef3c63 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/IssuesContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues.Issues { + public class IssuesContext : DbContext { + static readonly DbContextOptions options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: "Test") + .Options; + public IssuesContext() + : base(options) { + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/IssuesContextInitializer.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..d58b850 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/IssuesContextInitializer.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; + +namespace EFCoreIssues.Issues { + public static class IssuesContextInitializer { + public static void Seed() { + var context = new IssuesContext(); + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/OutlookDataGenerator.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..5e35561 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EFCoreIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/User.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/User.cs new file mode 100644 index 0000000..e3e8021 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EFCoreIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/MainViewModel.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/MainViewModel.cs new file mode 100644 index 0000000..a63890b --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/MainViewModel.cs @@ -0,0 +1,76 @@ +using DevExpress.Mvvm; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using EFCoreIssues.Issues; +using DevExpress.Mvvm.Xpf; +using System; + +namespace EFCoreIssues { + public class MainViewModel : ViewModelBase { + DevExpress.Data.Linq.EntityInstantFeedbackSource _InstantFeedbackSource; + + public DevExpress.Data.Linq.EntityInstantFeedbackSource InstantFeedbackSource + { + get + { + if(_InstantFeedbackSource == null) { + _InstantFeedbackSource = new DevExpress.Data.Linq.EntityInstantFeedbackSource + { + KeyExpression = nameof(EFCoreIssues.Issues.Issue.Id) + }; + _InstantFeedbackSource.GetQueryable += (sender, e) => + { + var context = new EFCoreIssues.Issues.IssuesContext(); + e.QueryableSource = context.Issues.AsNoTracking(); + }; + } + return _InstantFeedbackSource; + } + } + System.Collections.IList _Users; + + public System.Collections.IList Users + { + get + { + if(_Users == null && !IsInDesignMode) { + var context = new EFCoreIssues.Issues.IssuesContext(); + _Users = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + return _Users; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _Users = null; + RaisePropertyChanged(nameof(Users)); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void CreateEditEntityViewModel(DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs args) { + var context = new IssuesContext(); + Issue item; + if(args.Key != null) + item = context.Issues.Find(args.Key); + else { + item = new Issue() { Created = DateTime.Now }; + context.Entry(item).State = EntityState.Added; + } + args.ViewModel = new EditItemViewModel(item, new EditIssueInfo(context, Users)); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.EditFormRowValidationArgs args) { + var context = ((EditIssueInfo)args.Tag).Context; + context.SaveChanges(); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRowDeletion(DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs args) { + var key = (int)args.Keys.Single(); + var item = new Issue() { Id = key }; + var context = new IssuesContext(); + context.Entry(item).State = EntityState.Deleted; + context.SaveChanges(); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml b/CS/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml new file mode 100644 index 0000000..107c426 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml.cs new file mode 100644 index 0000000..af13819 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace EFCoreIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/AssemblyInfo.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4179e62 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EFCoreIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EFCoreIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/Resources.Designer.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/Resources.Designer.cs new file mode 100644 index 0000000..9b965de --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/Resources.Designer.cs @@ -0,0 +1,58 @@ +namespace EFCoreIssues.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", "16.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("EFCoreIssues.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 --git a/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/Resources.resx b/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/Settings.Designer.cs b/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/Settings.Designer.cs new file mode 100644 index 0000000..c156b8a --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/Settings.Designer.cs @@ -0,0 +1,18 @@ +namespace EFCoreIssues.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.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 --git a/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/Settings.settings b/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/InstantFeedbackMode/packages.config b/CS/ViewModel/EFCore/InstantFeedbackMode/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/CS/ViewModel/EFCore/InstantFeedbackMode/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/LocalData/App.config b/CS/ViewModel/EFCore/LocalData/App.config new file mode 100644 index 0000000..210a3bb --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/App.config @@ -0,0 +1,63 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CS/ViewModel/EFCore/LocalData/App.xaml b/CS/ViewModel/EFCore/LocalData/App.xaml new file mode 100644 index 0000000..cd777dc --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/EFCore/LocalData/App.xaml.cs b/CS/ViewModel/EFCore/LocalData/App.xaml.cs new file mode 100644 index 0000000..5263c1c --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/App.xaml.cs @@ -0,0 +1,19 @@ +using EFCoreIssues.Issues; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EFCoreIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + IssuesContextInitializer.Seed(); + } + } +} diff --git a/CS/ViewModel/EFCore/LocalData/Issues/Issue.cs b/CS/ViewModel/EFCore/LocalData/Issues/Issue.cs new file mode 100644 index 0000000..c36c075 --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EFCoreIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/EFCore/LocalData/Issues/IssuesContext.cs b/CS/ViewModel/EFCore/LocalData/Issues/IssuesContext.cs new file mode 100644 index 0000000..5ef3c63 --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/Issues/IssuesContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues.Issues { + public class IssuesContext : DbContext { + static readonly DbContextOptions options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: "Test") + .Options; + public IssuesContext() + : base(options) { + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/ViewModel/EFCore/LocalData/Issues/IssuesContextInitializer.cs b/CS/ViewModel/EFCore/LocalData/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..d58b850 --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/Issues/IssuesContextInitializer.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; + +namespace EFCoreIssues.Issues { + public static class IssuesContextInitializer { + public static void Seed() { + var context = new IssuesContext(); + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/ViewModel/EFCore/LocalData/Issues/OutlookDataGenerator.cs b/CS/ViewModel/EFCore/LocalData/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..5e35561 --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EFCoreIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/EFCore/LocalData/Issues/User.cs b/CS/ViewModel/EFCore/LocalData/Issues/User.cs new file mode 100644 index 0000000..e3e8021 --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EFCoreIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/ViewModel/EFCore/LocalData/LocalData.csproj b/CS/ViewModel/EFCore/LocalData/LocalData.csproj new file mode 100644 index 0000000..2e9b56c --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/LocalData.csproj @@ -0,0 +1,216 @@ + + + + + + Debug + AnyCPU + {9C83E2AC-8A16-8CF6-05A1-4D24A6D37010} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/LocalData/LocalData.sln b/CS/ViewModel/EFCore/LocalData/LocalData.sln new file mode 100644 index 0000000..1b39104 --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/LocalData.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalData", "LocalData.csproj", "{9C83E2AC-8A16-8CF6-05A1-4D24A6D37010}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9C83E2AC-8A16-8CF6-05A1-4D24A6D37010}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C83E2AC-8A16-8CF6-05A1-4D24A6D37010}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C83E2AC-8A16-8CF6-05A1-4D24A6D37010}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C83E2AC-8A16-8CF6-05A1-4D24A6D37010}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/EFCore/LocalData/MainViewModel.cs b/CS/ViewModel/EFCore/LocalData/MainViewModel.cs new file mode 100644 index 0000000..cf09f33 --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/MainViewModel.cs @@ -0,0 +1,40 @@ +using DevExpress.Mvvm; +using System.Linq; + +namespace EFCoreIssues { + public class MainViewModel : ViewModelBase { + EFCoreIssues.Issues.IssuesContext _Context; + System.Collections.Generic.IList _ItemsSource; + + public System.Collections.Generic.IList ItemsSource + { + get + { + if(_ItemsSource == null && !IsInDesignMode) { + _Context = new EFCoreIssues.Issues.IssuesContext(); + _ItemsSource = _Context.Users.ToList(); + } + return _ItemsSource; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.RowValidationArgs args) { + var item = (EFCoreIssues.Issues.User)args.Item; + if(args.IsNewItem) + _Context.Users.Add(item); + _Context.SaveChanges(); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRowDeletion(DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs args) { + var item = (EFCoreIssues.Issues.User)args.Items.Single(); + _Context.Users.Remove(item); + _Context.SaveChanges(); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _ItemsSource = null; + _Context = null; + RaisePropertyChanged(nameof(ItemsSource)); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EFCore/LocalData/MainWindow.xaml b/CS/ViewModel/EFCore/LocalData/MainWindow.xaml new file mode 100644 index 0000000..6328902 --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/MainWindow.xaml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/LocalData/MainWindow.xaml.cs b/CS/ViewModel/EFCore/LocalData/MainWindow.xaml.cs new file mode 100644 index 0000000..af13819 --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace EFCoreIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/EFCore/LocalData/Properties/AssemblyInfo.cs b/CS/ViewModel/EFCore/LocalData/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4179e62 --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EFCoreIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EFCoreIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/EFCore/LocalData/Properties/Resources.Designer.cs b/CS/ViewModel/EFCore/LocalData/Properties/Resources.Designer.cs new file mode 100644 index 0000000..9b965de --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/Properties/Resources.Designer.cs @@ -0,0 +1,58 @@ +namespace EFCoreIssues.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", "16.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("EFCoreIssues.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 --git a/CS/ViewModel/EFCore/LocalData/Properties/Resources.resx b/CS/ViewModel/EFCore/LocalData/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/EFCore/LocalData/Properties/Settings.Designer.cs b/CS/ViewModel/EFCore/LocalData/Properties/Settings.Designer.cs new file mode 100644 index 0000000..c156b8a --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/Properties/Settings.Designer.cs @@ -0,0 +1,18 @@ +namespace EFCoreIssues.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.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 --git a/CS/ViewModel/EFCore/LocalData/Properties/Settings.settings b/CS/ViewModel/EFCore/LocalData/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/LocalData/packages.config b/CS/ViewModel/EFCore/LocalData/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/CS/ViewModel/EFCore/LocalData/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/App.config b/CS/ViewModel/EFCore/PagedAsyncSource/App.config new file mode 100644 index 0000000..210a3bb --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/App.config @@ -0,0 +1,63 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/App.xaml b/CS/ViewModel/EFCore/PagedAsyncSource/App.xaml new file mode 100644 index 0000000..cd777dc --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/App.xaml.cs b/CS/ViewModel/EFCore/PagedAsyncSource/App.xaml.cs new file mode 100644 index 0000000..5263c1c --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/App.xaml.cs @@ -0,0 +1,19 @@ +using EFCoreIssues.Issues; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EFCoreIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + IssuesContextInitializer.Seed(); + } + } +} diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/Issues/Issue.cs b/CS/ViewModel/EFCore/PagedAsyncSource/Issues/Issue.cs new file mode 100644 index 0000000..c36c075 --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EFCoreIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/Issues/IssuesContext.cs b/CS/ViewModel/EFCore/PagedAsyncSource/Issues/IssuesContext.cs new file mode 100644 index 0000000..5ef3c63 --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/Issues/IssuesContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues.Issues { + public class IssuesContext : DbContext { + static readonly DbContextOptions options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: "Test") + .Options; + public IssuesContext() + : base(options) { + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/Issues/IssuesContextInitializer.cs b/CS/ViewModel/EFCore/PagedAsyncSource/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..d58b850 --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/Issues/IssuesContextInitializer.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; + +namespace EFCoreIssues.Issues { + public static class IssuesContextInitializer { + public static void Seed() { + var context = new IssuesContext(); + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/Issues/OutlookDataGenerator.cs b/CS/ViewModel/EFCore/PagedAsyncSource/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..5e35561 --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EFCoreIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/Issues/User.cs b/CS/ViewModel/EFCore/PagedAsyncSource/Issues/User.cs new file mode 100644 index 0000000..e3e8021 --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EFCoreIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/MainViewModel.cs b/CS/ViewModel/EFCore/PagedAsyncSource/MainViewModel.cs new file mode 100644 index 0000000..4c28fce --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/MainViewModel.cs @@ -0,0 +1,65 @@ +using DevExpress.Mvvm; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues { + public class MainViewModel : ViewModelBase { + [DevExpress.Mvvm.DataAnnotations.Command] + public void FetchPage(DevExpress.Mvvm.Xpf.FetchPageAsyncArgs args) { + const int pageTakeCount = 5; + args.Result = Task.Run(() => + { + var context = new EFCoreIssues.Issues.IssuesContext(); + var queryable = context.Issues.AsNoTracking() + .SortBy(args.SortOrder, defaultUniqueSortPropertyName: nameof(EFCoreIssues.Issues.Issue.Id)) + .Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)args.Filter)); + return queryable.Skip(args.Skip).Take(args.Take * pageTakeCount).ToArray(); + }); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void GetTotalSummaries(DevExpress.Mvvm.Xpf.GetSummariesAsyncArgs args) { + args.Result = Task.Run(() => + { + var context = new EFCoreIssues.Issues.IssuesContext(); + var queryable = context.Issues.Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)args.Filter)); + return queryable.GetSummaries(args.Summaries); + }); + } + + System.Linq.Expressions.Expression> MakeFilterExpression(DevExpress.Data.Filtering.CriteriaOperator filter) { + var converter = new DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(); + return converter.Convert(filter); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.RowValidationArgs args) { + var item = (EFCoreIssues.Issues.Issue)args.Item; + var context = new EFCoreIssues.Issues.IssuesContext(); + context.Entry(item).State = args.IsNewItem ? EntityState.Added : EntityState.Modified; + try { + context.SaveChanges(); + } finally { + context.Entry(item).State = EntityState.Detached; + } + } + System.Collections.IList _Users; + + public System.Collections.IList Users + { + get + { + if(_Users == null && !IsInDesignMode) { + var context = new EFCoreIssues.Issues.IssuesContext(); + _Users = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + return _Users; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _Users = null; + RaisePropertyChanged(nameof(Users)); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml b/CS/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..c2b156a --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml.cs b/CS/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml.cs new file mode 100644 index 0000000..af13819 --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace EFCoreIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/PagedAsyncSource.csproj b/CS/ViewModel/EFCore/PagedAsyncSource/PagedAsyncSource.csproj new file mode 100644 index 0000000..e27e32d --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/PagedAsyncSource.csproj @@ -0,0 +1,216 @@ + + + + + + Debug + AnyCPU + {6F66E7B7-3AF3-5381-0DE6-27A3F07078E8} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/PagedAsyncSource.sln b/CS/ViewModel/EFCore/PagedAsyncSource/PagedAsyncSource.sln new file mode 100644 index 0000000..8298815 --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/PagedAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagedAsyncSource", "PagedAsyncSource.csproj", "{6F66E7B7-3AF3-5381-0DE6-27A3F07078E8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6F66E7B7-3AF3-5381-0DE6-27A3F07078E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6F66E7B7-3AF3-5381-0DE6-27A3F07078E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6F66E7B7-3AF3-5381-0DE6-27A3F07078E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6F66E7B7-3AF3-5381-0DE6-27A3F07078E8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/Properties/AssemblyInfo.cs b/CS/ViewModel/EFCore/PagedAsyncSource/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4179e62 --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EFCoreIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EFCoreIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/EFCore/PagedAsyncSource/Properties/Resources.Designer.cs b/CS/ViewModel/EFCore/PagedAsyncSource/Properties/Resources.Designer.cs new file mode 100644 index 0000000..9b965de --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/Properties/Resources.Designer.cs @@ -0,0 +1,58 @@ +namespace EFCoreIssues.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", "16.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("EFCoreIssues.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 --git a/CS/ViewModel/EFCore/PagedAsyncSource/Properties/Resources.resx b/CS/ViewModel/EFCore/PagedAsyncSource/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/EFCore/PagedAsyncSource/Properties/Settings.Designer.cs b/CS/ViewModel/EFCore/PagedAsyncSource/Properties/Settings.Designer.cs new file mode 100644 index 0000000..c156b8a --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/Properties/Settings.Designer.cs @@ -0,0 +1,18 @@ +namespace EFCoreIssues.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.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 --git a/CS/ViewModel/EFCore/PagedAsyncSource/Properties/Settings.settings b/CS/ViewModel/EFCore/PagedAsyncSource/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/PagedAsyncSource/packages.config b/CS/ViewModel/EFCore/PagedAsyncSource/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/CS/ViewModel/EFCore/PagedAsyncSource/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/ServerMode/App.config b/CS/ViewModel/EFCore/ServerMode/App.config new file mode 100644 index 0000000..210a3bb --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/App.config @@ -0,0 +1,63 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CS/ViewModel/EFCore/ServerMode/App.xaml b/CS/ViewModel/EFCore/ServerMode/App.xaml new file mode 100644 index 0000000..cd777dc --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/EFCore/ServerMode/App.xaml.cs b/CS/ViewModel/EFCore/ServerMode/App.xaml.cs new file mode 100644 index 0000000..5263c1c --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/App.xaml.cs @@ -0,0 +1,19 @@ +using EFCoreIssues.Issues; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EFCoreIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + IssuesContextInitializer.Seed(); + } + } +} diff --git a/CS/ViewModel/EFCore/ServerMode/EditIssueInfo.cs b/CS/ViewModel/EFCore/ServerMode/EditIssueInfo.cs new file mode 100644 index 0000000..f1e718a --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/EditIssueInfo.cs @@ -0,0 +1,14 @@ +using DevExpress.Mvvm; +using System.Collections; +using EFCoreIssues.Issues; + +namespace EFCoreIssues { + public class EditIssueInfo : BindableBase { + public EditIssueInfo(IssuesContext context, IList users) { + Context = context; + Users = users; + } + public IssuesContext Context { get; } + public IList Users { get; } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EFCore/ServerMode/IssueDetailView.xaml b/CS/ViewModel/EFCore/ServerMode/IssueDetailView.xaml new file mode 100644 index 0000000..d5c1fd0 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/ServerMode/IssueDetailView.xaml.cs b/CS/ViewModel/EFCore/ServerMode/IssueDetailView.xaml.cs new file mode 100644 index 0000000..391f819 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/IssueDetailView.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows.Controls; + +namespace EFCoreIssues { + public partial class IssueDetailView : UserControl { + public IssueDetailView() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EFCore/ServerMode/Issues/Issue.cs b/CS/ViewModel/EFCore/ServerMode/Issues/Issue.cs new file mode 100644 index 0000000..c36c075 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EFCoreIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/EFCore/ServerMode/Issues/IssuesContext.cs b/CS/ViewModel/EFCore/ServerMode/Issues/IssuesContext.cs new file mode 100644 index 0000000..5ef3c63 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/Issues/IssuesContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; + +namespace EFCoreIssues.Issues { + public class IssuesContext : DbContext { + static readonly DbContextOptions options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: "Test") + .Options; + public IssuesContext() + : base(options) { + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/ViewModel/EFCore/ServerMode/Issues/IssuesContextInitializer.cs b/CS/ViewModel/EFCore/ServerMode/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..d58b850 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/Issues/IssuesContextInitializer.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; + +namespace EFCoreIssues.Issues { + public static class IssuesContextInitializer { + public static void Seed() { + var context = new IssuesContext(); + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/ViewModel/EFCore/ServerMode/Issues/OutlookDataGenerator.cs b/CS/ViewModel/EFCore/ServerMode/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..5e35561 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EFCoreIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/EFCore/ServerMode/Issues/User.cs b/CS/ViewModel/EFCore/ServerMode/Issues/User.cs new file mode 100644 index 0000000..e3e8021 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EFCoreIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/ViewModel/EFCore/ServerMode/MainViewModel.cs b/CS/ViewModel/EFCore/ServerMode/MainViewModel.cs new file mode 100644 index 0000000..d583b06 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/MainViewModel.cs @@ -0,0 +1,73 @@ +using DevExpress.Mvvm; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using EFCoreIssues.Issues; +using DevExpress.Mvvm.Xpf; +using System; + +namespace EFCoreIssues { + public class MainViewModel : ViewModelBase { + DevExpress.Data.Linq.EntityServerModeSource _ServerModeSource; + + public DevExpress.Data.Linq.EntityServerModeSource ServerModeSource + { + get + { + if(_ServerModeSource == null) { + var context = new EFCoreIssues.Issues.IssuesContext(); + _ServerModeSource = new DevExpress.Data.Linq.EntityServerModeSource + { + KeyExpression = nameof(EFCoreIssues.Issues.Issue.Id), + QueryableSource = context.Issues.AsNoTracking() + }; + } + return _ServerModeSource; + } + } + System.Collections.IList _Users; + + public System.Collections.IList Users + { + get + { + if(_Users == null && !IsInDesignMode) { + var context = new EFCoreIssues.Issues.IssuesContext(); + _Users = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + return _Users; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _Users = null; + RaisePropertyChanged(nameof(Users)); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void CreateEditEntityViewModel(DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs args) { + var context = new IssuesContext(); + Issue item; + if(args.Key != null) + item = context.Issues.Find(args.Key); + else { + item = new Issue() { Created = DateTime.Now }; + context.Entry(item).State = EntityState.Added; + } + args.ViewModel = new EditItemViewModel(item, new EditIssueInfo(context, Users)); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.EditFormRowValidationArgs args) { + var context = ((EditIssueInfo)args.Tag).Context; + context.SaveChanges(); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRowDeletion(DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs args) { + var key = (int)args.Keys.Single(); + var item = new Issue() { Id = key }; + var context = new IssuesContext(); + context.Entry(item).State = EntityState.Deleted; + context.SaveChanges(); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EFCore/ServerMode/MainWindow.xaml b/CS/ViewModel/EFCore/ServerMode/MainWindow.xaml new file mode 100644 index 0000000..107c426 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/ServerMode/MainWindow.xaml.cs b/CS/ViewModel/EFCore/ServerMode/MainWindow.xaml.cs new file mode 100644 index 0000000..af13819 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace EFCoreIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/EFCore/ServerMode/Properties/AssemblyInfo.cs b/CS/ViewModel/EFCore/ServerMode/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4179e62 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EFCoreIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EFCoreIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/EFCore/ServerMode/Properties/Resources.Designer.cs b/CS/ViewModel/EFCore/ServerMode/Properties/Resources.Designer.cs new file mode 100644 index 0000000..9b965de --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/Properties/Resources.Designer.cs @@ -0,0 +1,58 @@ +namespace EFCoreIssues.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", "16.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("EFCoreIssues.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 --git a/CS/ViewModel/EFCore/ServerMode/Properties/Resources.resx b/CS/ViewModel/EFCore/ServerMode/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/EFCore/ServerMode/Properties/Settings.Designer.cs b/CS/ViewModel/EFCore/ServerMode/Properties/Settings.Designer.cs new file mode 100644 index 0000000..c156b8a --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/Properties/Settings.Designer.cs @@ -0,0 +1,18 @@ +namespace EFCoreIssues.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.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 --git a/CS/ViewModel/EFCore/ServerMode/Properties/Settings.settings b/CS/ViewModel/EFCore/ServerMode/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/ServerMode/ServerMode.csproj b/CS/ViewModel/EFCore/ServerMode/ServerMode.csproj new file mode 100644 index 0000000..0e7edcf --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/ServerMode.csproj @@ -0,0 +1,225 @@ + + + + + + Debug + AnyCPU + {30677180-75CA-B378-283E-592104E900AE} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EFCore/ServerMode/ServerMode.sln b/CS/ViewModel/EFCore/ServerMode/ServerMode.sln new file mode 100644 index 0000000..889ca0e --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/ServerMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerMode", "ServerMode.csproj", "{30677180-75CA-B378-283E-592104E900AE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {30677180-75CA-B378-283E-592104E900AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {30677180-75CA-B378-283E-592104E900AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {30677180-75CA-B378-283E-592104E900AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {30677180-75CA-B378-283E-592104E900AE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/EFCore/ServerMode/packages.config b/CS/ViewModel/EFCore/ServerMode/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/CS/ViewModel/EFCore/ServerMode/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/App.config b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/App.xaml b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/App.xaml new file mode 100644 index 0000000..33ec22e --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/App.xaml.cs b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/App.xaml.cs new file mode 100644 index 0000000..a87a8cc --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/App.xaml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EntityFrameworkIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.csproj b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.csproj new file mode 100644 index 0000000..205c2aa --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.csproj @@ -0,0 +1,156 @@ + + + + + + Debug + AnyCPU + {15B732AA-52FF-31FF-1FA8-B2BB46A99604} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.sln b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.sln new file mode 100644 index 0000000..867cdd0 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfiniteAsyncSource", "InfiniteAsyncSource.csproj", "{15B732AA-52FF-31FF-1FA8-B2BB46A99604}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {15B732AA-52FF-31FF-1FA8-B2BB46A99604}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15B732AA-52FF-31FF-1FA8-B2BB46A99604}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15B732AA-52FF-31FF-1FA8-B2BB46A99604}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15B732AA-52FF-31FF-1FA8-B2BB46A99604}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/Issue.cs b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/Issue.cs new file mode 100644 index 0000000..e6b9876 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/IssuesContext.cs b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/IssuesContext.cs new file mode 100644 index 0000000..5306779 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/IssuesContext.cs @@ -0,0 +1,23 @@ +using System.Data.Entity; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContext : DbContext { + static IssuesContext() { + Database.SetInitializer(new IssuesContextInitializer()); + } + public IssuesContext() { } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .HasIndex(x => x.Created); + + modelBuilder.Entity() + .HasIndex(x => x.Votes); + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/IssuesContextInitializer.cs b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..260c170 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/IssuesContextInitializer.cs @@ -0,0 +1,55 @@ +using System; +using System.Data.Entity; +using System.Linq; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContextInitializer + : DropCreateDatabaseIfModelChanges { + //: DropCreateDatabaseAlways { + + public static void ResetData() { + using(var context = new IssuesContext()) { + context.Users.Load(); + context.Users.RemoveRange(context.Users); + context.SaveChanges(); + CreateData(context); + } + } + + protected override void Seed(IssuesContext context) { + base.Seed(context); + CreateData(context); + } + + static void CreateData(IssuesContext context) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..c5a164e --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/User.cs b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/User.cs new file mode 100644 index 0000000..0a2fbf6 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EntityFrameworkIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/MainViewModel.cs b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/MainViewModel.cs new file mode 100644 index 0000000..69495e6 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/MainViewModel.cs @@ -0,0 +1,71 @@ +using DevExpress.Mvvm; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Data.Entity; + +namespace EntityFrameworkIssues { + public class MainViewModel : ViewModelBase { + [DevExpress.Mvvm.DataAnnotations.Command] + public void FetchRows(DevExpress.Mvvm.Xpf.FetchRowsAsyncArgs args) { + args.Result = Task.Run(() => + { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + var queryable = context.Issues.AsNoTracking() + .SortBy(args.SortOrder, defaultUniqueSortPropertyName: nameof(EntityFrameworkIssues.Issues.Issue.Id)) + .Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)args.Filter)); + return queryable.Skip(args.Skip).Take(args.Take ?? 100).ToArray(); + }); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void GetTotalSummaries(DevExpress.Mvvm.Xpf.GetSummariesAsyncArgs args) { + args.Result = Task.Run(() => + { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + var queryable = context.Issues.Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)args.Filter)); + return queryable.GetSummaries(args.Summaries); + }); + } + + System.Linq.Expressions.Expression> MakeFilterExpression(DevExpress.Data.Filtering.CriteriaOperator filter) { + var converter = new DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(); + return converter.Convert(filter); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.RowValidationArgs args) { + var item = (EntityFrameworkIssues.Issues.Issue)args.Item; + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + context.Entry(item).State = args.IsNewItem ? EntityState.Added : EntityState.Modified; + try { + context.SaveChanges(); + } finally { + context.Entry(item).State = EntityState.Detached; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRowDeletion(DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs args) { + var item = (EntityFrameworkIssues.Issues.Issue)args.Items.Single(); + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + context.Entry(item).State = EntityState.Deleted; + context.SaveChanges(); + } + System.Collections.IList _Users; + + public System.Collections.IList Users + { + get + { + if(_Users == null && !IsInDesignMode) { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + _Users = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + return _Users; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _Users = null; + RaisePropertyChanged(nameof(Users)); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..8bab7f7 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.cs b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.cs new file mode 100644 index 0000000..1049b6a --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace EntityFrameworkIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/AssemblyInfo.cs b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ad2761d --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EntityFrameworkIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EntityFrameworkIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/Resources.Designer.cs b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e5eb50e --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace EntityFrameworkIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EntityFrameworkIssues.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 --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/Resources.resx b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/Settings.Designer.cs b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/Settings.Designer.cs new file mode 100644 index 0000000..e790c5b --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace EntityFrameworkIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/Settings.settings b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InfiniteAsyncSource/packages.config b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InfiniteAsyncSource/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/App.config b/CS/ViewModel/EntityFramework/InstantFeedbackMode/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/App.xaml b/CS/ViewModel/EntityFramework/InstantFeedbackMode/App.xaml new file mode 100644 index 0000000..33ec22e --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/App.xaml.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/App.xaml.cs new file mode 100644 index 0000000..a87a8cc --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/App.xaml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EntityFrameworkIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/EditIssueInfo.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/EditIssueInfo.cs new file mode 100644 index 0000000..6c86f13 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/EditIssueInfo.cs @@ -0,0 +1,14 @@ +using DevExpress.Mvvm; +using System.Collections; +using EntityFrameworkIssues.Issues; + +namespace EntityFrameworkIssues { + public class EditIssueInfo : BindableBase { + public EditIssueInfo(IssuesContext context, IList users) { + Context = context; + Users = users; + } + public IssuesContext Context { get; } + public IList Users { get; } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.csproj b/CS/ViewModel/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.csproj new file mode 100644 index 0000000..6c96e91 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.csproj @@ -0,0 +1,165 @@ + + + + + + Debug + AnyCPU + {426D6BB0-E022-7346-0A39-5708229FA581} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.sln b/CS/ViewModel/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.sln new file mode 100644 index 0000000..bedd330 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantFeedbackMode", "InstantFeedbackMode.csproj", "{426D6BB0-E022-7346-0A39-5708229FA581}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {426D6BB0-E022-7346-0A39-5708229FA581}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {426D6BB0-E022-7346-0A39-5708229FA581}.Debug|Any CPU.Build.0 = Debug|Any CPU + {426D6BB0-E022-7346-0A39-5708229FA581}.Release|Any CPU.ActiveCfg = Release|Any CPU + {426D6BB0-E022-7346-0A39-5708229FA581}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml b/CS/ViewModel/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml new file mode 100644 index 0000000..23a72d0 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml.cs new file mode 100644 index 0000000..cf7d354 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows.Controls; + +namespace EntityFrameworkIssues { + public partial class IssueDetailView : UserControl { + public IssueDetailView() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/Issue.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/Issue.cs new file mode 100644 index 0000000..e6b9876 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/IssuesContext.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/IssuesContext.cs new file mode 100644 index 0000000..5306779 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/IssuesContext.cs @@ -0,0 +1,23 @@ +using System.Data.Entity; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContext : DbContext { + static IssuesContext() { + Database.SetInitializer(new IssuesContextInitializer()); + } + public IssuesContext() { } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .HasIndex(x => x.Created); + + modelBuilder.Entity() + .HasIndex(x => x.Votes); + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/IssuesContextInitializer.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..260c170 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/IssuesContextInitializer.cs @@ -0,0 +1,55 @@ +using System; +using System.Data.Entity; +using System.Linq; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContextInitializer + : DropCreateDatabaseIfModelChanges { + //: DropCreateDatabaseAlways { + + public static void ResetData() { + using(var context = new IssuesContext()) { + context.Users.Load(); + context.Users.RemoveRange(context.Users); + context.SaveChanges(); + CreateData(context); + } + } + + protected override void Seed(IssuesContext context) { + base.Seed(context); + CreateData(context); + } + + static void CreateData(IssuesContext context) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/OutlookDataGenerator.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..c5a164e --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/User.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/User.cs new file mode 100644 index 0000000..0a2fbf6 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EntityFrameworkIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/MainViewModel.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/MainViewModel.cs new file mode 100644 index 0000000..49efd53 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/MainViewModel.cs @@ -0,0 +1,76 @@ +using DevExpress.Mvvm; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Data.Entity; +using EntityFrameworkIssues.Issues; +using DevExpress.Mvvm.Xpf; +using System; + +namespace EntityFrameworkIssues { + public class MainViewModel : ViewModelBase { + DevExpress.Data.Linq.EntityInstantFeedbackSource _InstantFeedbackSource; + + public DevExpress.Data.Linq.EntityInstantFeedbackSource InstantFeedbackSource + { + get + { + if(_InstantFeedbackSource == null) { + _InstantFeedbackSource = new DevExpress.Data.Linq.EntityInstantFeedbackSource + { + KeyExpression = nameof(EntityFrameworkIssues.Issues.Issue.Id) + }; + _InstantFeedbackSource.GetQueryable += (sender, e) => + { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + e.QueryableSource = context.Issues.AsNoTracking(); + }; + } + return _InstantFeedbackSource; + } + } + System.Collections.IList _Users; + + public System.Collections.IList Users + { + get + { + if(_Users == null && !IsInDesignMode) { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + _Users = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + return _Users; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _Users = null; + RaisePropertyChanged(nameof(Users)); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void CreateEditEntityViewModel(DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs args) { + var context = new IssuesContext(); + Issue item; + if(args.Key != null) + item = context.Issues.Find(args.Key); + else { + item = new Issue() { Created = DateTime.Now }; + context.Entry(item).State = EntityState.Added; + } + args.ViewModel = new EditItemViewModel(item, new EditIssueInfo(context, Users)); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.EditFormRowValidationArgs args) { + var context = ((EditIssueInfo)args.Tag).Context; + context.SaveChanges(); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRowDeletion(DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs args) { + var key = (int)args.Keys.Single(); + var item = new Issue() { Id = key }; + var context = new IssuesContext(); + context.Entry(item).State = EntityState.Deleted; + context.SaveChanges(); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml b/CS/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml new file mode 100644 index 0000000..61e5e53 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml.cs new file mode 100644 index 0000000..1049b6a --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace EntityFrameworkIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/AssemblyInfo.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ad2761d --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EntityFrameworkIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EntityFrameworkIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/Resources.Designer.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e5eb50e --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace EntityFrameworkIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EntityFrameworkIssues.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 --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/Resources.resx b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/Settings.Designer.cs b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/Settings.Designer.cs new file mode 100644 index 0000000..e790c5b --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace EntityFrameworkIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/Settings.settings b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/InstantFeedbackMode/packages.config b/CS/ViewModel/EntityFramework/InstantFeedbackMode/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/ViewModel/EntityFramework/InstantFeedbackMode/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/LocalData/App.config b/CS/ViewModel/EntityFramework/LocalData/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/LocalData/App.xaml b/CS/ViewModel/EntityFramework/LocalData/App.xaml new file mode 100644 index 0000000..33ec22e --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/EntityFramework/LocalData/App.xaml.cs b/CS/ViewModel/EntityFramework/LocalData/App.xaml.cs new file mode 100644 index 0000000..a87a8cc --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/App.xaml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EntityFrameworkIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/LocalData/Issues/Issue.cs b/CS/ViewModel/EntityFramework/LocalData/Issues/Issue.cs new file mode 100644 index 0000000..e6b9876 --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/EntityFramework/LocalData/Issues/IssuesContext.cs b/CS/ViewModel/EntityFramework/LocalData/Issues/IssuesContext.cs new file mode 100644 index 0000000..5306779 --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/Issues/IssuesContext.cs @@ -0,0 +1,23 @@ +using System.Data.Entity; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContext : DbContext { + static IssuesContext() { + Database.SetInitializer(new IssuesContextInitializer()); + } + public IssuesContext() { } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .HasIndex(x => x.Created); + + modelBuilder.Entity() + .HasIndex(x => x.Votes); + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/ViewModel/EntityFramework/LocalData/Issues/IssuesContextInitializer.cs b/CS/ViewModel/EntityFramework/LocalData/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..260c170 --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/Issues/IssuesContextInitializer.cs @@ -0,0 +1,55 @@ +using System; +using System.Data.Entity; +using System.Linq; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContextInitializer + : DropCreateDatabaseIfModelChanges { + //: DropCreateDatabaseAlways { + + public static void ResetData() { + using(var context = new IssuesContext()) { + context.Users.Load(); + context.Users.RemoveRange(context.Users); + context.SaveChanges(); + CreateData(context); + } + } + + protected override void Seed(IssuesContext context) { + base.Seed(context); + CreateData(context); + } + + static void CreateData(IssuesContext context) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/LocalData/Issues/OutlookDataGenerator.cs b/CS/ViewModel/EntityFramework/LocalData/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..c5a164e --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/EntityFramework/LocalData/Issues/User.cs b/CS/ViewModel/EntityFramework/LocalData/Issues/User.cs new file mode 100644 index 0000000..0a2fbf6 --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EntityFrameworkIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/ViewModel/EntityFramework/LocalData/LocalData.csproj b/CS/ViewModel/EntityFramework/LocalData/LocalData.csproj new file mode 100644 index 0000000..1c555ed --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/LocalData.csproj @@ -0,0 +1,156 @@ + + + + + + Debug + AnyCPU + {A053A495-BD20-6118-236F-AC8E61E5C05A} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/LocalData/LocalData.sln b/CS/ViewModel/EntityFramework/LocalData/LocalData.sln new file mode 100644 index 0000000..e999911 --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/LocalData.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalData", "LocalData.csproj", "{A053A495-BD20-6118-236F-AC8E61E5C05A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A053A495-BD20-6118-236F-AC8E61E5C05A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A053A495-BD20-6118-236F-AC8E61E5C05A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A053A495-BD20-6118-236F-AC8E61E5C05A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A053A495-BD20-6118-236F-AC8E61E5C05A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/EntityFramework/LocalData/MainViewModel.cs b/CS/ViewModel/EntityFramework/LocalData/MainViewModel.cs new file mode 100644 index 0000000..81dad5f --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/MainViewModel.cs @@ -0,0 +1,40 @@ +using DevExpress.Mvvm; +using System.Linq; + +namespace EntityFrameworkIssues { + public class MainViewModel : ViewModelBase { + EntityFrameworkIssues.Issues.IssuesContext _Context; + System.Collections.Generic.IList _ItemsSource; + + public System.Collections.Generic.IList ItemsSource + { + get + { + if(_ItemsSource == null && !IsInDesignMode) { + _Context = new EntityFrameworkIssues.Issues.IssuesContext(); + _ItemsSource = _Context.Users.ToList(); + } + return _ItemsSource; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.RowValidationArgs args) { + var item = (EntityFrameworkIssues.Issues.User)args.Item; + if(args.IsNewItem) + _Context.Users.Add(item); + _Context.SaveChanges(); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRowDeletion(DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs args) { + var item = (EntityFrameworkIssues.Issues.User)args.Items.Single(); + _Context.Users.Remove(item); + _Context.SaveChanges(); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _ItemsSource = null; + _Context = null; + RaisePropertyChanged(nameof(ItemsSource)); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/LocalData/MainWindow.xaml b/CS/ViewModel/EntityFramework/LocalData/MainWindow.xaml new file mode 100644 index 0000000..a8b2702 --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/MainWindow.xaml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/LocalData/MainWindow.xaml.cs b/CS/ViewModel/EntityFramework/LocalData/MainWindow.xaml.cs new file mode 100644 index 0000000..1049b6a --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace EntityFrameworkIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/LocalData/Properties/AssemblyInfo.cs b/CS/ViewModel/EntityFramework/LocalData/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ad2761d --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EntityFrameworkIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EntityFrameworkIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/EntityFramework/LocalData/Properties/Resources.Designer.cs b/CS/ViewModel/EntityFramework/LocalData/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e5eb50e --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace EntityFrameworkIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EntityFrameworkIssues.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 --git a/CS/ViewModel/EntityFramework/LocalData/Properties/Resources.resx b/CS/ViewModel/EntityFramework/LocalData/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/EntityFramework/LocalData/Properties/Settings.Designer.cs b/CS/ViewModel/EntityFramework/LocalData/Properties/Settings.Designer.cs new file mode 100644 index 0000000..e790c5b --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace EntityFrameworkIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/ViewModel/EntityFramework/LocalData/Properties/Settings.settings b/CS/ViewModel/EntityFramework/LocalData/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/LocalData/packages.config b/CS/ViewModel/EntityFramework/LocalData/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/ViewModel/EntityFramework/LocalData/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/App.config b/CS/ViewModel/EntityFramework/PagedAsyncSource/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/App.xaml b/CS/ViewModel/EntityFramework/PagedAsyncSource/App.xaml new file mode 100644 index 0000000..33ec22e --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/App.xaml.cs b/CS/ViewModel/EntityFramework/PagedAsyncSource/App.xaml.cs new file mode 100644 index 0000000..a87a8cc --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/App.xaml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EntityFrameworkIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/Issue.cs b/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/Issue.cs new file mode 100644 index 0000000..e6b9876 --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/IssuesContext.cs b/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/IssuesContext.cs new file mode 100644 index 0000000..5306779 --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/IssuesContext.cs @@ -0,0 +1,23 @@ +using System.Data.Entity; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContext : DbContext { + static IssuesContext() { + Database.SetInitializer(new IssuesContextInitializer()); + } + public IssuesContext() { } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .HasIndex(x => x.Created); + + modelBuilder.Entity() + .HasIndex(x => x.Votes); + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/IssuesContextInitializer.cs b/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..260c170 --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/IssuesContextInitializer.cs @@ -0,0 +1,55 @@ +using System; +using System.Data.Entity; +using System.Linq; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContextInitializer + : DropCreateDatabaseIfModelChanges { + //: DropCreateDatabaseAlways { + + public static void ResetData() { + using(var context = new IssuesContext()) { + context.Users.Load(); + context.Users.RemoveRange(context.Users); + context.SaveChanges(); + CreateData(context); + } + } + + protected override void Seed(IssuesContext context) { + base.Seed(context); + CreateData(context); + } + + static void CreateData(IssuesContext context) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/OutlookDataGenerator.cs b/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..c5a164e --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/User.cs b/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/User.cs new file mode 100644 index 0000000..0a2fbf6 --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EntityFrameworkIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/MainViewModel.cs b/CS/ViewModel/EntityFramework/PagedAsyncSource/MainViewModel.cs new file mode 100644 index 0000000..e638e32 --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/MainViewModel.cs @@ -0,0 +1,65 @@ +using DevExpress.Mvvm; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Data.Entity; + +namespace EntityFrameworkIssues { + public class MainViewModel : ViewModelBase { + [DevExpress.Mvvm.DataAnnotations.Command] + public void FetchPage(DevExpress.Mvvm.Xpf.FetchPageAsyncArgs args) { + const int pageTakeCount = 5; + args.Result = Task.Run(() => + { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + var queryable = context.Issues.AsNoTracking() + .SortBy(args.SortOrder, defaultUniqueSortPropertyName: nameof(EntityFrameworkIssues.Issues.Issue.Id)) + .Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)args.Filter)); + return queryable.Skip(args.Skip).Take(args.Take * pageTakeCount).ToArray(); + }); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void GetTotalSummaries(DevExpress.Mvvm.Xpf.GetSummariesAsyncArgs args) { + args.Result = Task.Run(() => + { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + var queryable = context.Issues.Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)args.Filter)); + return queryable.GetSummaries(args.Summaries); + }); + } + + System.Linq.Expressions.Expression> MakeFilterExpression(DevExpress.Data.Filtering.CriteriaOperator filter) { + var converter = new DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(); + return converter.Convert(filter); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.RowValidationArgs args) { + var item = (EntityFrameworkIssues.Issues.Issue)args.Item; + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + context.Entry(item).State = args.IsNewItem ? EntityState.Added : EntityState.Modified; + try { + context.SaveChanges(); + } finally { + context.Entry(item).State = EntityState.Detached; + } + } + System.Collections.IList _Users; + + public System.Collections.IList Users + { + get + { + if(_Users == null && !IsInDesignMode) { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + _Users = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + return _Users; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _Users = null; + RaisePropertyChanged(nameof(Users)); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml b/CS/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..23ac21f --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml.cs b/CS/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml.cs new file mode 100644 index 0000000..1049b6a --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace EntityFrameworkIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/PagedAsyncSource.csproj b/CS/ViewModel/EntityFramework/PagedAsyncSource/PagedAsyncSource.csproj new file mode 100644 index 0000000..bf1a2d9 --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/PagedAsyncSource.csproj @@ -0,0 +1,156 @@ + + + + + + Debug + AnyCPU + {DBA236C5-087D-899B-EAE5-6FFC0C4BAFB1} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/PagedAsyncSource.sln b/CS/ViewModel/EntityFramework/PagedAsyncSource/PagedAsyncSource.sln new file mode 100644 index 0000000..3d19002 --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/PagedAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagedAsyncSource", "PagedAsyncSource.csproj", "{DBA236C5-087D-899B-EAE5-6FFC0C4BAFB1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DBA236C5-087D-899B-EAE5-6FFC0C4BAFB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DBA236C5-087D-899B-EAE5-6FFC0C4BAFB1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DBA236C5-087D-899B-EAE5-6FFC0C4BAFB1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DBA236C5-087D-899B-EAE5-6FFC0C4BAFB1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/AssemblyInfo.cs b/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ad2761d --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EntityFrameworkIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EntityFrameworkIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/Resources.Designer.cs b/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e5eb50e --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace EntityFrameworkIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EntityFrameworkIssues.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 --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/Resources.resx b/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/Settings.Designer.cs b/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/Settings.Designer.cs new file mode 100644 index 0000000..e790c5b --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace EntityFrameworkIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/Settings.settings b/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/PagedAsyncSource/packages.config b/CS/ViewModel/EntityFramework/PagedAsyncSource/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/ViewModel/EntityFramework/PagedAsyncSource/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/ServerMode/App.config b/CS/ViewModel/EntityFramework/ServerMode/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/ServerMode/App.xaml b/CS/ViewModel/EntityFramework/ServerMode/App.xaml new file mode 100644 index 0000000..33ec22e --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/EntityFramework/ServerMode/App.xaml.cs b/CS/ViewModel/EntityFramework/ServerMode/App.xaml.cs new file mode 100644 index 0000000..a87a8cc --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/App.xaml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EntityFrameworkIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/ServerMode/EditIssueInfo.cs b/CS/ViewModel/EntityFramework/ServerMode/EditIssueInfo.cs new file mode 100644 index 0000000..6c86f13 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/EditIssueInfo.cs @@ -0,0 +1,14 @@ +using DevExpress.Mvvm; +using System.Collections; +using EntityFrameworkIssues.Issues; + +namespace EntityFrameworkIssues { + public class EditIssueInfo : BindableBase { + public EditIssueInfo(IssuesContext context, IList users) { + Context = context; + Users = users; + } + public IssuesContext Context { get; } + public IList Users { get; } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/ServerMode/IssueDetailView.xaml b/CS/ViewModel/EntityFramework/ServerMode/IssueDetailView.xaml new file mode 100644 index 0000000..23a72d0 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/ServerMode/IssueDetailView.xaml.cs b/CS/ViewModel/EntityFramework/ServerMode/IssueDetailView.xaml.cs new file mode 100644 index 0000000..cf7d354 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/IssueDetailView.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows.Controls; + +namespace EntityFrameworkIssues { + public partial class IssueDetailView : UserControl { + public IssueDetailView() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/ServerMode/Issues/Issue.cs b/CS/ViewModel/EntityFramework/ServerMode/Issues/Issue.cs new file mode 100644 index 0000000..e6b9876 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/Issues/Issue.cs @@ -0,0 +1,17 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public class Issue { + public int Id { get; set; } + public string Subject { get; set; } + public int UserId { get; set; } + public virtual User User { get; set; } + public DateTime Created { get; set; } + public int Votes { get; set; } + public Priority Priority { get; set; } + public Issue() { + Created = DateTime.Now; + } + } + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/EntityFramework/ServerMode/Issues/IssuesContext.cs b/CS/ViewModel/EntityFramework/ServerMode/Issues/IssuesContext.cs new file mode 100644 index 0000000..5306779 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/Issues/IssuesContext.cs @@ -0,0 +1,23 @@ +using System.Data.Entity; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContext : DbContext { + static IssuesContext() { + Database.SetInitializer(new IssuesContextInitializer()); + } + public IssuesContext() { } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .HasIndex(x => x.Created); + + modelBuilder.Entity() + .HasIndex(x => x.Votes); + } + + public DbSet Issues { get; set; } + public DbSet Users { get; set; } + } +} diff --git a/CS/ViewModel/EntityFramework/ServerMode/Issues/IssuesContextInitializer.cs b/CS/ViewModel/EntityFramework/ServerMode/Issues/IssuesContextInitializer.cs new file mode 100644 index 0000000..260c170 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/Issues/IssuesContextInitializer.cs @@ -0,0 +1,55 @@ +using System; +using System.Data.Entity; +using System.Linq; + +namespace EntityFrameworkIssues.Issues { + public class IssuesContextInitializer + : DropCreateDatabaseIfModelChanges { + //: DropCreateDatabaseAlways { + + public static void ResetData() { + using(var context = new IssuesContext()) { + context.Users.Load(); + context.Users.RemoveRange(context.Users); + context.SaveChanges(); + CreateData(context); + } + } + + protected override void Seed(IssuesContext context) { + base.Seed(context); + CreateData(context); + } + + static void CreateData(IssuesContext context) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User() + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + context.Users.AddRange(users); + context.SaveChanges(); + + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue() + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Id, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + context.Issues.AddRange(issues); + + context.SaveChanges(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/ServerMode/Issues/OutlookDataGenerator.cs b/CS/ViewModel/EntityFramework/ServerMode/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..c5a164e --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace EntityFrameworkIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/EntityFramework/ServerMode/Issues/User.cs b/CS/ViewModel/EntityFramework/ServerMode/Issues/User.cs new file mode 100644 index 0000000..0a2fbf6 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/Issues/User.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EntityFrameworkIssues.Issues { + public class User { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public virtual ICollection Issues { get; set; } + } +} diff --git a/CS/ViewModel/EntityFramework/ServerMode/MainViewModel.cs b/CS/ViewModel/EntityFramework/ServerMode/MainViewModel.cs new file mode 100644 index 0000000..ebe4e98 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/MainViewModel.cs @@ -0,0 +1,73 @@ +using DevExpress.Mvvm; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Data.Entity; +using EntityFrameworkIssues.Issues; +using DevExpress.Mvvm.Xpf; +using System; + +namespace EntityFrameworkIssues { + public class MainViewModel : ViewModelBase { + DevExpress.Data.Linq.EntityServerModeSource _ServerModeSource; + + public DevExpress.Data.Linq.EntityServerModeSource ServerModeSource + { + get + { + if(_ServerModeSource == null) { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + _ServerModeSource = new DevExpress.Data.Linq.EntityServerModeSource + { + KeyExpression = nameof(EntityFrameworkIssues.Issues.Issue.Id), + QueryableSource = context.Issues.AsNoTracking() + }; + } + return _ServerModeSource; + } + } + System.Collections.IList _Users; + + public System.Collections.IList Users + { + get + { + if(_Users == null && !IsInDesignMode) { + var context = new EntityFrameworkIssues.Issues.IssuesContext(); + _Users = context.Users.Select(user => new { Id = user.Id, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + return _Users; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _Users = null; + RaisePropertyChanged(nameof(Users)); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void CreateEditEntityViewModel(DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs args) { + var context = new IssuesContext(); + Issue item; + if(args.Key != null) + item = context.Issues.Find(args.Key); + else { + item = new Issue() { Created = DateTime.Now }; + context.Entry(item).State = EntityState.Added; + } + args.ViewModel = new EditItemViewModel(item, new EditIssueInfo(context, Users)); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.EditFormRowValidationArgs args) { + var context = ((EditIssueInfo)args.Tag).Context; + context.SaveChanges(); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRowDeletion(DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs args) { + var key = (int)args.Keys.Single(); + var item = new Issue() { Id = key }; + var context = new IssuesContext(); + context.Entry(item).State = EntityState.Deleted; + context.SaveChanges(); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/ServerMode/MainWindow.xaml b/CS/ViewModel/EntityFramework/ServerMode/MainWindow.xaml new file mode 100644 index 0000000..61e5e53 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/ServerMode/MainWindow.xaml.cs b/CS/ViewModel/EntityFramework/ServerMode/MainWindow.xaml.cs new file mode 100644 index 0000000..1049b6a --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace EntityFrameworkIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/EntityFramework/ServerMode/Properties/AssemblyInfo.cs b/CS/ViewModel/EntityFramework/ServerMode/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ad2761d --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("EntityFrameworkIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EntityFrameworkIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/EntityFramework/ServerMode/Properties/Resources.Designer.cs b/CS/ViewModel/EntityFramework/ServerMode/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e5eb50e --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace EntityFrameworkIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EntityFrameworkIssues.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 --git a/CS/ViewModel/EntityFramework/ServerMode/Properties/Resources.resx b/CS/ViewModel/EntityFramework/ServerMode/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/EntityFramework/ServerMode/Properties/Settings.Designer.cs b/CS/ViewModel/EntityFramework/ServerMode/Properties/Settings.Designer.cs new file mode 100644 index 0000000..e790c5b --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace EntityFrameworkIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/ViewModel/EntityFramework/ServerMode/Properties/Settings.settings b/CS/ViewModel/EntityFramework/ServerMode/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/ServerMode/ServerMode.csproj b/CS/ViewModel/EntityFramework/ServerMode/ServerMode.csproj new file mode 100644 index 0000000..1172fa9 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/ServerMode.csproj @@ -0,0 +1,165 @@ + + + + + + Debug + AnyCPU + {F514D2C9-5E68-3383-866B-4EFAB5C6E8D9} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/EntityFramework/ServerMode/ServerMode.sln b/CS/ViewModel/EntityFramework/ServerMode/ServerMode.sln new file mode 100644 index 0000000..a5b3581 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/ServerMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerMode", "ServerMode.csproj", "{F514D2C9-5E68-3383-866B-4EFAB5C6E8D9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F514D2C9-5E68-3383-866B-4EFAB5C6E8D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F514D2C9-5E68-3383-866B-4EFAB5C6E8D9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F514D2C9-5E68-3383-866B-4EFAB5C6E8D9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F514D2C9-5E68-3383-866B-4EFAB5C6E8D9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/EntityFramework/ServerMode/packages.config b/CS/ViewModel/EntityFramework/ServerMode/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/ViewModel/EntityFramework/ServerMode/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/App.config b/CS/ViewModel/XPO/InfiniteAsyncSource/App.config new file mode 100644 index 0000000..f473aab --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/App.xaml b/CS/ViewModel/XPO/InfiniteAsyncSource/App.xaml new file mode 100644 index 0000000..1e81d99 --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/App.xaml.cs b/CS/ViewModel/XPO/InfiniteAsyncSource/App.xaml.cs new file mode 100644 index 0000000..3f603e9 --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/App.xaml.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using XPOIssues.Issues; + +namespace XPOIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + ConnectionHelper.Connect(); + DemoDataHelper.Seed(); + } + } +} diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/InfiniteAsyncSource.csproj b/CS/ViewModel/XPO/InfiniteAsyncSource/InfiniteAsyncSource.csproj new file mode 100644 index 0000000..52d99de --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/InfiniteAsyncSource.csproj @@ -0,0 +1,160 @@ + + + + + + Debug + AnyCPU + {D45CE161-9F15-E3EA-D8E3-D32E1005A3A6} + WinExe + XPOIssues + XPOIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/InfiniteAsyncSource.sln b/CS/ViewModel/XPO/InfiniteAsyncSource/InfiniteAsyncSource.sln new file mode 100644 index 0000000..fe12b61 --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/InfiniteAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfiniteAsyncSource", "InfiniteAsyncSource.csproj", "{D45CE161-9F15-E3EA-D8E3-D32E1005A3A6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D45CE161-9F15-E3EA-D8E3-D32E1005A3A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D45CE161-9F15-E3EA-D8E3-D32E1005A3A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D45CE161-9F15-E3EA-D8E3-D32E1005A3A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D45CE161-9F15-E3EA-D8E3-D32E1005A3A6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/ConnectionHelper.cs b/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/ConnectionHelper.cs new file mode 100644 index 0000000..01dd20a --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/ConnectionHelper.cs @@ -0,0 +1,29 @@ +using DevExpress.Xpo; +using DevExpress.Xpo.DB; +using DevExpress.Xpo.Metadata; +using System; +using System.Configuration; + +namespace XPOIssues.Issues { + public static class ConnectionHelper { + + static readonly Type[] PersistentTypes = new Type[]{ + typeof(Issue), + typeof(User) + }; + + public static void Connect() { + XpoDefault.DataLayer = CreateDataLayer(true); + } + + static IDataLayer CreateDataLayer(bool threadSafe) { + string connStr = ConfigurationManager.ConnectionStrings["XpoTutorial"]?.ConnectionString ?? "XpoProvider=InMemoryDataStore"; + //connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + ReflectionDictionary dictionary = new ReflectionDictionary(); + dictionary.GetDataStoreSchema(PersistentTypes); // Pass all of your persistent object types to this method. + AutoCreateOption autoCreateOption = AutoCreateOption.DatabaseAndSchema; // Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + IDataStore provider = XpoDefault.GetConnectionProvider(connStr, autoCreateOption); + return threadSafe ? (IDataLayer)new ThreadSafeDataLayer(dictionary, provider) : new SimpleDataLayer(dictionary, provider); + } + } +} diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/Customer.cs b/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/Customer.cs new file mode 100644 index 0000000..8e084e7 --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/Customer.cs @@ -0,0 +1,27 @@ +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class User : XPObject { + public User(Session session) : base(session) { } + + string _FirstName; + public string FirstName + { + get { return _FirstName; } + set { SetPropertyValue(nameof(FirstName), ref _FirstName, value); } + } + + string _LastName; + public string LastName + { + get { return _LastName; } + set { SetPropertyValue(nameof(LastName), ref _LastName, value); } + } + + [Association("UserIssues")] + public XPCollection Issues + { + get { return GetCollection(nameof(Issues)); } + } + } +} diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/DemoDataHelper.cs b/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/DemoDataHelper.cs new file mode 100644 index 0000000..a3d71a2 --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/DemoDataHelper.cs @@ -0,0 +1,37 @@ +using DevExpress.Xpo; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace XPOIssues.Issues { + public static class DemoDataHelper { + public static void Seed() { + using(var uow = new DevExpress.Xpo.UnitOfWork()) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User(uow) + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + uow.CommitChanges(); + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue(uow) + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Oid, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + uow.CommitChanges(); + } + } + } +} diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/Issue.cs b/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/Issue.cs new file mode 100644 index 0000000..44e3d22 --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/Issue.cs @@ -0,0 +1,55 @@ +using System; +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class Issue : XPObject { + public Issue(Session session) : base(session) { + Created = DateTime.Now; + } + string _Subject; + [Size(200)] + public string Subject + { + get { return _Subject; } + set { SetPropertyValue(nameof(Subject), ref _Subject, value); } + } + + int _UserId; + public int UserId + { + get { return _UserId; } + set { SetPropertyValue(nameof(UserId), ref _UserId, value); } + } + + User _User; + [Association("UserIssues")] + public User User + { + get { return _User; } + set { SetPropertyValue(nameof(User), ref _User, value); } + } + + DateTime _Created; + public DateTime Created + { + get { return _Created; } + set { SetPropertyValue(nameof(Created), ref _Created, value); } + } + + int _Votes; + public int Votes + { + get { return _Votes; } + set { SetPropertyValue(nameof(Votes), ref _Votes, value); } + } + + Priority _Priority; + public Priority Priority + { + get { return _Priority; } + set { SetPropertyValue(nameof(Priority), ref _Priority, value); } + } + } + + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs b/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..ad8047e --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace XPOIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/MainViewModel.cs b/CS/ViewModel/XPO/InfiniteAsyncSource/MainViewModel.cs new file mode 100644 index 0000000..4304e0b --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/MainViewModel.cs @@ -0,0 +1,104 @@ +using DevExpress.Mvvm; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using DevExpress.Xpo; + +namespace XPOIssues { + public class MainViewModel : ViewModelBase { + DetachedObjectsHelper _DetachedObjectsHelper; + + public DetachedObjectsHelper DetachedObjectsHelper + { + get + { + if(_DetachedObjectsHelper == null) { + using(var session = new Session()) { + var classInfo = session.GetClassInfo(); + var properties = classInfo.Members + .Where(member => member.IsPublic && member.IsPersistent) + .Select(member => member.Name) + .ToArray(); + _DetachedObjectsHelper = DetachedObjectsHelper.Create(classInfo.KeyProperty.Name, properties); + } + } + return _DetachedObjectsHelper; + } + } + + public System.ComponentModel.PropertyDescriptorCollection Properties + { + get + { + return DetachedObjectsHelper.Properties; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void FetchRows(DevExpress.Mvvm.Xpf.FetchRowsAsyncArgs args) { + args.Result = Task.Run(() => + { + using(var session = new DevExpress.Xpo.Session()) { + var queryable = session.Query().SortBy(args.SortOrder, defaultUniqueSortPropertyName: nameof(XPOIssues.Issues.Issue.Oid)).Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)args.Filter)); + var items = queryable.Skip(args.Skip).Take(args.Take ?? 100).ToArray(); + return DetachedObjectsHelper.ConvertToDetachedObjects(items); + } + }); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void GetTotalSummaries(DevExpress.Mvvm.Xpf.GetSummariesAsyncArgs args) { + args.Result = Task.Run(() => + { + using(var session = new DevExpress.Xpo.Session()) { + return session.Query().Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)args.Filter)).GetSummaries(args.Summaries); + } + }); + } + + System.Linq.Expressions.Expression> MakeFilterExpression(DevExpress.Data.Filtering.CriteriaOperator filter) { + var converter = new DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(); + return converter.Convert(filter); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.RowValidationArgs args) { + using(var unitOfWork = new DevExpress.Xpo.UnitOfWork()) { + var item = args.IsNewItem + ? new XPOIssues.Issues.Issue(unitOfWork) + : unitOfWork.GetObjectByKey(DetachedObjectsHelper.GetKey(args.Item)); + DetachedObjectsHelper.ApplyProperties(item, args.Item); + unitOfWork.CommitChanges(); + if(args.IsNewItem) { + DetachedObjectsHelper.SetKey(args.Item, item.Oid); + } + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRowDeletion(DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs args) { + using(var unitOfWork = new DevExpress.Xpo.UnitOfWork()) { + var key = DetachedObjectsHelper.GetKey(args.Items.Single()); + var item = unitOfWork.GetObjectByKey(key); + unitOfWork.Delete(item); + unitOfWork.CommitChanges(); + } + } + System.Collections.IList _Users; + + public System.Collections.IList Users + { + get + { + if(_Users == null && !IsInDesignMode) { + { + var session = new DevExpress.Xpo.Session(); + _Users = session.Query().OrderBy(user => user.Oid).Select(user => new { Id = user.Oid, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + } + return _Users; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _Users = null; + RaisePropertyChanged(nameof(Users)); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml b/CS/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..329c35a --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml.cs b/CS/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml.cs new file mode 100644 index 0000000..027794a --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace XPOIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/AssemblyInfo.cs b/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f481389 --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("XPOIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("XPOIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/Resources.Designer.cs b/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/Resources.Designer.cs new file mode 100644 index 0000000..4c2c340 --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace XPOIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XPOIssues.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 --git a/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/Resources.resx b/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/Settings.Designer.cs b/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/Settings.Designer.cs new file mode 100644 index 0000000..486c4c6 --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace XPOIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/Settings.settings b/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/InfiniteAsyncSource/packages.config b/CS/ViewModel/XPO/InfiniteAsyncSource/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/ViewModel/XPO/InfiniteAsyncSource/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/App.config b/CS/ViewModel/XPO/InstantFeedbackMode/App.config new file mode 100644 index 0000000..f473aab --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/App.xaml b/CS/ViewModel/XPO/InstantFeedbackMode/App.xaml new file mode 100644 index 0000000..1e81d99 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/App.xaml.cs b/CS/ViewModel/XPO/InstantFeedbackMode/App.xaml.cs new file mode 100644 index 0000000..3f603e9 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/App.xaml.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using XPOIssues.Issues; + +namespace XPOIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + ConnectionHelper.Connect(); + DemoDataHelper.Seed(); + } + } +} diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/EditIssueInfo.cs b/CS/ViewModel/XPO/InstantFeedbackMode/EditIssueInfo.cs new file mode 100644 index 0000000..77e9a52 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/EditIssueInfo.cs @@ -0,0 +1,14 @@ +using DevExpress.Mvvm; +using System.Collections; +using XPOIssues.Issues; + +namespace XPOIssues { + public class EditIssueInfo : BindableBase { + public EditIssueInfo(DevExpress.Xpo.UnitOfWork unitOfWork, IList users) { + UnitOfWork = unitOfWork; + Users = users; + } + public DevExpress.Xpo.UnitOfWork UnitOfWork { get; } + public IList Users { get; } + } +} \ No newline at end of file diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/InstantFeedbackMode.csproj b/CS/ViewModel/XPO/InstantFeedbackMode/InstantFeedbackMode.csproj new file mode 100644 index 0000000..9edc387 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/InstantFeedbackMode.csproj @@ -0,0 +1,169 @@ + + + + + + Debug + AnyCPU + {458CC994-873E-B932-DFAC-BA1D47463452} + WinExe + XPOIssues + XPOIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/InstantFeedbackMode.sln b/CS/ViewModel/XPO/InstantFeedbackMode/InstantFeedbackMode.sln new file mode 100644 index 0000000..4895151 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/InstantFeedbackMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantFeedbackMode", "InstantFeedbackMode.csproj", "{458CC994-873E-B932-DFAC-BA1D47463452}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {458CC994-873E-B932-DFAC-BA1D47463452}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {458CC994-873E-B932-DFAC-BA1D47463452}.Debug|Any CPU.Build.0 = Debug|Any CPU + {458CC994-873E-B932-DFAC-BA1D47463452}.Release|Any CPU.ActiveCfg = Release|Any CPU + {458CC994-873E-B932-DFAC-BA1D47463452}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/IssueDetailView.xaml b/CS/ViewModel/XPO/InstantFeedbackMode/IssueDetailView.xaml new file mode 100644 index 0000000..8110d2f --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/IssueDetailView.xaml.cs b/CS/ViewModel/XPO/InstantFeedbackMode/IssueDetailView.xaml.cs new file mode 100644 index 0000000..698dbf1 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/IssueDetailView.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows.Controls; + +namespace XPOIssues { + public partial class IssueDetailView : UserControl { + public IssueDetailView() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/Issues/ConnectionHelper.cs b/CS/ViewModel/XPO/InstantFeedbackMode/Issues/ConnectionHelper.cs new file mode 100644 index 0000000..01dd20a --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/Issues/ConnectionHelper.cs @@ -0,0 +1,29 @@ +using DevExpress.Xpo; +using DevExpress.Xpo.DB; +using DevExpress.Xpo.Metadata; +using System; +using System.Configuration; + +namespace XPOIssues.Issues { + public static class ConnectionHelper { + + static readonly Type[] PersistentTypes = new Type[]{ + typeof(Issue), + typeof(User) + }; + + public static void Connect() { + XpoDefault.DataLayer = CreateDataLayer(true); + } + + static IDataLayer CreateDataLayer(bool threadSafe) { + string connStr = ConfigurationManager.ConnectionStrings["XpoTutorial"]?.ConnectionString ?? "XpoProvider=InMemoryDataStore"; + //connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + ReflectionDictionary dictionary = new ReflectionDictionary(); + dictionary.GetDataStoreSchema(PersistentTypes); // Pass all of your persistent object types to this method. + AutoCreateOption autoCreateOption = AutoCreateOption.DatabaseAndSchema; // Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + IDataStore provider = XpoDefault.GetConnectionProvider(connStr, autoCreateOption); + return threadSafe ? (IDataLayer)new ThreadSafeDataLayer(dictionary, provider) : new SimpleDataLayer(dictionary, provider); + } + } +} diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/Issues/Customer.cs b/CS/ViewModel/XPO/InstantFeedbackMode/Issues/Customer.cs new file mode 100644 index 0000000..8e084e7 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/Issues/Customer.cs @@ -0,0 +1,27 @@ +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class User : XPObject { + public User(Session session) : base(session) { } + + string _FirstName; + public string FirstName + { + get { return _FirstName; } + set { SetPropertyValue(nameof(FirstName), ref _FirstName, value); } + } + + string _LastName; + public string LastName + { + get { return _LastName; } + set { SetPropertyValue(nameof(LastName), ref _LastName, value); } + } + + [Association("UserIssues")] + public XPCollection Issues + { + get { return GetCollection(nameof(Issues)); } + } + } +} diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/Issues/DemoDataHelper.cs b/CS/ViewModel/XPO/InstantFeedbackMode/Issues/DemoDataHelper.cs new file mode 100644 index 0000000..a3d71a2 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/Issues/DemoDataHelper.cs @@ -0,0 +1,37 @@ +using DevExpress.Xpo; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace XPOIssues.Issues { + public static class DemoDataHelper { + public static void Seed() { + using(var uow = new DevExpress.Xpo.UnitOfWork()) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User(uow) + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + uow.CommitChanges(); + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue(uow) + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Oid, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + uow.CommitChanges(); + } + } + } +} diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/Issues/Issue.cs b/CS/ViewModel/XPO/InstantFeedbackMode/Issues/Issue.cs new file mode 100644 index 0000000..44e3d22 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/Issues/Issue.cs @@ -0,0 +1,55 @@ +using System; +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class Issue : XPObject { + public Issue(Session session) : base(session) { + Created = DateTime.Now; + } + string _Subject; + [Size(200)] + public string Subject + { + get { return _Subject; } + set { SetPropertyValue(nameof(Subject), ref _Subject, value); } + } + + int _UserId; + public int UserId + { + get { return _UserId; } + set { SetPropertyValue(nameof(UserId), ref _UserId, value); } + } + + User _User; + [Association("UserIssues")] + public User User + { + get { return _User; } + set { SetPropertyValue(nameof(User), ref _User, value); } + } + + DateTime _Created; + public DateTime Created + { + get { return _Created; } + set { SetPropertyValue(nameof(Created), ref _Created, value); } + } + + int _Votes; + public int Votes + { + get { return _Votes; } + set { SetPropertyValue(nameof(Votes), ref _Votes, value); } + } + + Priority _Priority; + public Priority Priority + { + get { return _Priority; } + set { SetPropertyValue(nameof(Priority), ref _Priority, value); } + } + } + + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/Issues/OutlookDataGenerator.cs b/CS/ViewModel/XPO/InstantFeedbackMode/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..ad8047e --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace XPOIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/MainViewModel.cs b/CS/ViewModel/XPO/InstantFeedbackMode/MainViewModel.cs new file mode 100644 index 0000000..bbba94b --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/MainViewModel.cs @@ -0,0 +1,83 @@ +using DevExpress.Mvvm; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using DevExpress.Xpo; +using XPOIssues.Issues; +using DevExpress.Mvvm.Xpf; +using System; + +namespace XPOIssues { + public class MainViewModel : ViewModelBase { + DevExpress.Xpo.XPInstantFeedbackView _InstantFeedbackSource; + + public DevExpress.Xpo.XPInstantFeedbackView InstantFeedbackSource + { + get + { + if(_InstantFeedbackSource == null) { + var properties = new DevExpress.Xpo.ServerViewProperty[] { +new DevExpress.Xpo.ServerViewProperty("Oid", DevExpress.Xpo.SortDirection.Ascending, new DevExpress.Data.Filtering.OperandProperty("Oid")), +new DevExpress.Xpo.ServerViewProperty("Subject", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Subject")), +new DevExpress.Xpo.ServerViewProperty("UserId", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("UserId")), +new DevExpress.Xpo.ServerViewProperty("Created", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Created")), +new DevExpress.Xpo.ServerViewProperty("Votes", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Votes")), +new DevExpress.Xpo.ServerViewProperty("Priority", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Priority")) + }; + _InstantFeedbackSource = new DevExpress.Xpo.XPInstantFeedbackView(typeof(XPOIssues.Issues.Issue), properties, null); + _InstantFeedbackSource.ResolveSession += (o, e) => + { + e.Session = new DevExpress.Xpo.Session(); + }; + } + return _InstantFeedbackSource; + } + } + System.Collections.IList _Users; + + public System.Collections.IList Users + { + get + { + if(_Users == null && !IsInDesignMode) { + { + var session = new DevExpress.Xpo.Session(); + _Users = session.Query().OrderBy(user => user.Oid).Select(user => new { Id = user.Oid, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + } + return _Users; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _Users = null; + RaisePropertyChanged(nameof(Users)); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void CreateEditEntityViewModel(DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs args) { + var unitOfWork = new UnitOfWork(); + var item = args.Key != null + ? unitOfWork.GetObjectByKey(args.Key) + : new Issue(unitOfWork); + args.ViewModel = new EditItemViewModel( + item, + new EditIssueInfo(unitOfWork, Users), + dispose: () => unitOfWork.Dispose() + ); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.EditFormRowValidationArgs args) { + var unitOfWork = ((EditIssueInfo)args.Tag).UnitOfWork; + unitOfWork.CommitChanges(); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRowDeletion(DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs args) { + using(var unitOfWork = new UnitOfWork()) { + var key = (int)args.Keys.Single(); + var item = unitOfWork.GetObjectByKey(key); + unitOfWork.Delete(item); + unitOfWork.CommitChanges(); + } + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml b/CS/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml new file mode 100644 index 0000000..a04cf72 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml.cs b/CS/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml.cs new file mode 100644 index 0000000..027794a --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace XPOIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/Properties/AssemblyInfo.cs b/CS/ViewModel/XPO/InstantFeedbackMode/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f481389 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("XPOIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("XPOIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/XPO/InstantFeedbackMode/Properties/Resources.Designer.cs b/CS/ViewModel/XPO/InstantFeedbackMode/Properties/Resources.Designer.cs new file mode 100644 index 0000000..4c2c340 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace XPOIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XPOIssues.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 --git a/CS/ViewModel/XPO/InstantFeedbackMode/Properties/Resources.resx b/CS/ViewModel/XPO/InstantFeedbackMode/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/XPO/InstantFeedbackMode/Properties/Settings.Designer.cs b/CS/ViewModel/XPO/InstantFeedbackMode/Properties/Settings.Designer.cs new file mode 100644 index 0000000..486c4c6 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace XPOIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/ViewModel/XPO/InstantFeedbackMode/Properties/Settings.settings b/CS/ViewModel/XPO/InstantFeedbackMode/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/InstantFeedbackMode/packages.config b/CS/ViewModel/XPO/InstantFeedbackMode/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/ViewModel/XPO/InstantFeedbackMode/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/LocalData/App.config b/CS/ViewModel/XPO/LocalData/App.config new file mode 100644 index 0000000..f473aab --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/LocalData/App.xaml b/CS/ViewModel/XPO/LocalData/App.xaml new file mode 100644 index 0000000..1e81d99 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/XPO/LocalData/App.xaml.cs b/CS/ViewModel/XPO/LocalData/App.xaml.cs new file mode 100644 index 0000000..3f603e9 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/App.xaml.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using XPOIssues.Issues; + +namespace XPOIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + ConnectionHelper.Connect(); + DemoDataHelper.Seed(); + } + } +} diff --git a/CS/ViewModel/XPO/LocalData/Issues/ConnectionHelper.cs b/CS/ViewModel/XPO/LocalData/Issues/ConnectionHelper.cs new file mode 100644 index 0000000..01dd20a --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/Issues/ConnectionHelper.cs @@ -0,0 +1,29 @@ +using DevExpress.Xpo; +using DevExpress.Xpo.DB; +using DevExpress.Xpo.Metadata; +using System; +using System.Configuration; + +namespace XPOIssues.Issues { + public static class ConnectionHelper { + + static readonly Type[] PersistentTypes = new Type[]{ + typeof(Issue), + typeof(User) + }; + + public static void Connect() { + XpoDefault.DataLayer = CreateDataLayer(true); + } + + static IDataLayer CreateDataLayer(bool threadSafe) { + string connStr = ConfigurationManager.ConnectionStrings["XpoTutorial"]?.ConnectionString ?? "XpoProvider=InMemoryDataStore"; + //connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + ReflectionDictionary dictionary = new ReflectionDictionary(); + dictionary.GetDataStoreSchema(PersistentTypes); // Pass all of your persistent object types to this method. + AutoCreateOption autoCreateOption = AutoCreateOption.DatabaseAndSchema; // Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + IDataStore provider = XpoDefault.GetConnectionProvider(connStr, autoCreateOption); + return threadSafe ? (IDataLayer)new ThreadSafeDataLayer(dictionary, provider) : new SimpleDataLayer(dictionary, provider); + } + } +} diff --git a/CS/ViewModel/XPO/LocalData/Issues/Customer.cs b/CS/ViewModel/XPO/LocalData/Issues/Customer.cs new file mode 100644 index 0000000..8e084e7 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/Issues/Customer.cs @@ -0,0 +1,27 @@ +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class User : XPObject { + public User(Session session) : base(session) { } + + string _FirstName; + public string FirstName + { + get { return _FirstName; } + set { SetPropertyValue(nameof(FirstName), ref _FirstName, value); } + } + + string _LastName; + public string LastName + { + get { return _LastName; } + set { SetPropertyValue(nameof(LastName), ref _LastName, value); } + } + + [Association("UserIssues")] + public XPCollection Issues + { + get { return GetCollection(nameof(Issues)); } + } + } +} diff --git a/CS/ViewModel/XPO/LocalData/Issues/DemoDataHelper.cs b/CS/ViewModel/XPO/LocalData/Issues/DemoDataHelper.cs new file mode 100644 index 0000000..a3d71a2 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/Issues/DemoDataHelper.cs @@ -0,0 +1,37 @@ +using DevExpress.Xpo; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace XPOIssues.Issues { + public static class DemoDataHelper { + public static void Seed() { + using(var uow = new DevExpress.Xpo.UnitOfWork()) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User(uow) + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + uow.CommitChanges(); + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue(uow) + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Oid, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + uow.CommitChanges(); + } + } + } +} diff --git a/CS/ViewModel/XPO/LocalData/Issues/Issue.cs b/CS/ViewModel/XPO/LocalData/Issues/Issue.cs new file mode 100644 index 0000000..44e3d22 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/Issues/Issue.cs @@ -0,0 +1,55 @@ +using System; +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class Issue : XPObject { + public Issue(Session session) : base(session) { + Created = DateTime.Now; + } + string _Subject; + [Size(200)] + public string Subject + { + get { return _Subject; } + set { SetPropertyValue(nameof(Subject), ref _Subject, value); } + } + + int _UserId; + public int UserId + { + get { return _UserId; } + set { SetPropertyValue(nameof(UserId), ref _UserId, value); } + } + + User _User; + [Association("UserIssues")] + public User User + { + get { return _User; } + set { SetPropertyValue(nameof(User), ref _User, value); } + } + + DateTime _Created; + public DateTime Created + { + get { return _Created; } + set { SetPropertyValue(nameof(Created), ref _Created, value); } + } + + int _Votes; + public int Votes + { + get { return _Votes; } + set { SetPropertyValue(nameof(Votes), ref _Votes, value); } + } + + Priority _Priority; + public Priority Priority + { + get { return _Priority; } + set { SetPropertyValue(nameof(Priority), ref _Priority, value); } + } + } + + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/XPO/LocalData/Issues/OutlookDataGenerator.cs b/CS/ViewModel/XPO/LocalData/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..ad8047e --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace XPOIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/XPO/LocalData/LocalData.csproj b/CS/ViewModel/XPO/LocalData/LocalData.csproj new file mode 100644 index 0000000..738e1e2 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/LocalData.csproj @@ -0,0 +1,160 @@ + + + + + + Debug + AnyCPU + {B9622751-FE28-84F8-EB26-5F3F95EF6497} + WinExe + XPOIssues + XPOIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/LocalData/LocalData.sln b/CS/ViewModel/XPO/LocalData/LocalData.sln new file mode 100644 index 0000000..d5f1c34 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/LocalData.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalData", "LocalData.csproj", "{B9622751-FE28-84F8-EB26-5F3F95EF6497}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B9622751-FE28-84F8-EB26-5F3F95EF6497}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B9622751-FE28-84F8-EB26-5F3F95EF6497}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B9622751-FE28-84F8-EB26-5F3F95EF6497}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B9622751-FE28-84F8-EB26-5F3F95EF6497}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/XPO/LocalData/MainViewModel.cs b/CS/ViewModel/XPO/LocalData/MainViewModel.cs new file mode 100644 index 0000000..5bf9714 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/MainViewModel.cs @@ -0,0 +1,39 @@ +using DevExpress.Mvvm; +using System.Linq; + +namespace XPOIssues { + public class MainViewModel : ViewModelBase { + DevExpress.Xpo.UnitOfWork _UnitOfWork; + System.Collections.Generic.IList _ItemsSource; + + public System.Collections.Generic.IList ItemsSource + { + get + { + if(_ItemsSource == null && !IsInDesignMode) { + _UnitOfWork = new DevExpress.Xpo.UnitOfWork(); + var xpCollection = new DevExpress.Xpo.XPCollection(_UnitOfWork); + xpCollection.Sorting.Add(new DevExpress.Xpo.SortProperty(nameof(XPOIssues.Issues.User.Oid), DevExpress.Xpo.DB.SortingDirection.Ascending)); + _ItemsSource = xpCollection; + } + return _ItemsSource; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.RowValidationArgs args) { + _UnitOfWork.CommitChanges(); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRowDeletion(DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs args) { + var item = (XPOIssues.Issues.User)args.Items.Single(); + _UnitOfWork.Delete(item); + _UnitOfWork.CommitChanges(); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _ItemsSource = null; + _UnitOfWork = null; + RaisePropertyChanged(nameof(ItemsSource)); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/XPO/LocalData/MainWindow.xaml b/CS/ViewModel/XPO/LocalData/MainWindow.xaml new file mode 100644 index 0000000..4aec421 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/MainWindow.xaml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/LocalData/MainWindow.xaml.cs b/CS/ViewModel/XPO/LocalData/MainWindow.xaml.cs new file mode 100644 index 0000000..027794a --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace XPOIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/XPO/LocalData/Properties/AssemblyInfo.cs b/CS/ViewModel/XPO/LocalData/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f481389 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("XPOIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("XPOIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/XPO/LocalData/Properties/Resources.Designer.cs b/CS/ViewModel/XPO/LocalData/Properties/Resources.Designer.cs new file mode 100644 index 0000000..4c2c340 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace XPOIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XPOIssues.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 --git a/CS/ViewModel/XPO/LocalData/Properties/Resources.resx b/CS/ViewModel/XPO/LocalData/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/XPO/LocalData/Properties/Settings.Designer.cs b/CS/ViewModel/XPO/LocalData/Properties/Settings.Designer.cs new file mode 100644 index 0000000..486c4c6 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace XPOIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/ViewModel/XPO/LocalData/Properties/Settings.settings b/CS/ViewModel/XPO/LocalData/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/LocalData/packages.config b/CS/ViewModel/XPO/LocalData/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/ViewModel/XPO/LocalData/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/PagedAsyncSource/App.config b/CS/ViewModel/XPO/PagedAsyncSource/App.config new file mode 100644 index 0000000..f473aab --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/PagedAsyncSource/App.xaml b/CS/ViewModel/XPO/PagedAsyncSource/App.xaml new file mode 100644 index 0000000..1e81d99 --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/XPO/PagedAsyncSource/App.xaml.cs b/CS/ViewModel/XPO/PagedAsyncSource/App.xaml.cs new file mode 100644 index 0000000..3f603e9 --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/App.xaml.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using XPOIssues.Issues; + +namespace XPOIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + ConnectionHelper.Connect(); + DemoDataHelper.Seed(); + } + } +} diff --git a/CS/ViewModel/XPO/PagedAsyncSource/Issues/ConnectionHelper.cs b/CS/ViewModel/XPO/PagedAsyncSource/Issues/ConnectionHelper.cs new file mode 100644 index 0000000..01dd20a --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/Issues/ConnectionHelper.cs @@ -0,0 +1,29 @@ +using DevExpress.Xpo; +using DevExpress.Xpo.DB; +using DevExpress.Xpo.Metadata; +using System; +using System.Configuration; + +namespace XPOIssues.Issues { + public static class ConnectionHelper { + + static readonly Type[] PersistentTypes = new Type[]{ + typeof(Issue), + typeof(User) + }; + + public static void Connect() { + XpoDefault.DataLayer = CreateDataLayer(true); + } + + static IDataLayer CreateDataLayer(bool threadSafe) { + string connStr = ConfigurationManager.ConnectionStrings["XpoTutorial"]?.ConnectionString ?? "XpoProvider=InMemoryDataStore"; + //connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + ReflectionDictionary dictionary = new ReflectionDictionary(); + dictionary.GetDataStoreSchema(PersistentTypes); // Pass all of your persistent object types to this method. + AutoCreateOption autoCreateOption = AutoCreateOption.DatabaseAndSchema; // Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + IDataStore provider = XpoDefault.GetConnectionProvider(connStr, autoCreateOption); + return threadSafe ? (IDataLayer)new ThreadSafeDataLayer(dictionary, provider) : new SimpleDataLayer(dictionary, provider); + } + } +} diff --git a/CS/ViewModel/XPO/PagedAsyncSource/Issues/Customer.cs b/CS/ViewModel/XPO/PagedAsyncSource/Issues/Customer.cs new file mode 100644 index 0000000..8e084e7 --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/Issues/Customer.cs @@ -0,0 +1,27 @@ +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class User : XPObject { + public User(Session session) : base(session) { } + + string _FirstName; + public string FirstName + { + get { return _FirstName; } + set { SetPropertyValue(nameof(FirstName), ref _FirstName, value); } + } + + string _LastName; + public string LastName + { + get { return _LastName; } + set { SetPropertyValue(nameof(LastName), ref _LastName, value); } + } + + [Association("UserIssues")] + public XPCollection Issues + { + get { return GetCollection(nameof(Issues)); } + } + } +} diff --git a/CS/ViewModel/XPO/PagedAsyncSource/Issues/DemoDataHelper.cs b/CS/ViewModel/XPO/PagedAsyncSource/Issues/DemoDataHelper.cs new file mode 100644 index 0000000..a3d71a2 --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/Issues/DemoDataHelper.cs @@ -0,0 +1,37 @@ +using DevExpress.Xpo; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace XPOIssues.Issues { + public static class DemoDataHelper { + public static void Seed() { + using(var uow = new DevExpress.Xpo.UnitOfWork()) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User(uow) + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + uow.CommitChanges(); + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue(uow) + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Oid, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + uow.CommitChanges(); + } + } + } +} diff --git a/CS/ViewModel/XPO/PagedAsyncSource/Issues/Issue.cs b/CS/ViewModel/XPO/PagedAsyncSource/Issues/Issue.cs new file mode 100644 index 0000000..44e3d22 --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/Issues/Issue.cs @@ -0,0 +1,55 @@ +using System; +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class Issue : XPObject { + public Issue(Session session) : base(session) { + Created = DateTime.Now; + } + string _Subject; + [Size(200)] + public string Subject + { + get { return _Subject; } + set { SetPropertyValue(nameof(Subject), ref _Subject, value); } + } + + int _UserId; + public int UserId + { + get { return _UserId; } + set { SetPropertyValue(nameof(UserId), ref _UserId, value); } + } + + User _User; + [Association("UserIssues")] + public User User + { + get { return _User; } + set { SetPropertyValue(nameof(User), ref _User, value); } + } + + DateTime _Created; + public DateTime Created + { + get { return _Created; } + set { SetPropertyValue(nameof(Created), ref _Created, value); } + } + + int _Votes; + public int Votes + { + get { return _Votes; } + set { SetPropertyValue(nameof(Votes), ref _Votes, value); } + } + + Priority _Priority; + public Priority Priority + { + get { return _Priority; } + set { SetPropertyValue(nameof(Priority), ref _Priority, value); } + } + } + + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/XPO/PagedAsyncSource/Issues/OutlookDataGenerator.cs b/CS/ViewModel/XPO/PagedAsyncSource/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..ad8047e --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace XPOIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/XPO/PagedAsyncSource/MainViewModel.cs b/CS/ViewModel/XPO/PagedAsyncSource/MainViewModel.cs new file mode 100644 index 0000000..e799e8a --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/MainViewModel.cs @@ -0,0 +1,96 @@ +using DevExpress.Mvvm; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using DevExpress.Xpo; + +namespace XPOIssues { + public class MainViewModel : ViewModelBase { + DetachedObjectsHelper _DetachedObjectsHelper; + + public DetachedObjectsHelper DetachedObjectsHelper + { + get + { + if(_DetachedObjectsHelper == null) { + using(var session = new Session()) { + var classInfo = session.GetClassInfo(); + var properties = classInfo.Members + .Where(member => member.IsPublic && member.IsPersistent) + .Select(member => member.Name) + .ToArray(); + _DetachedObjectsHelper = DetachedObjectsHelper.Create(classInfo.KeyProperty.Name, properties); + } + } + return _DetachedObjectsHelper; + } + } + + public System.ComponentModel.PropertyDescriptorCollection Properties + { + get + { + return DetachedObjectsHelper.Properties; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void FetchPage(DevExpress.Mvvm.Xpf.FetchPageAsyncArgs args) { + args.Result = Task.Run(() => + { + const int pageTakeCount = 5; + using(var session = new DevExpress.Xpo.Session()) { + var queryable = session.Query().SortBy(args.SortOrder, defaultUniqueSortPropertyName: nameof(XPOIssues.Issues.Issue.Oid)).Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)args.Filter)); + var items = queryable.Skip(args.Skip).Take(args.Take * pageTakeCount).ToArray(); + return DetachedObjectsHelper.ConvertToDetachedObjects(items); + } + }); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void GetTotalSummaries(DevExpress.Mvvm.Xpf.GetSummariesAsyncArgs args) { + args.Result = Task.Run(() => + { + using(var session = new DevExpress.Xpo.Session()) { + return session.Query().Where(MakeFilterExpression((DevExpress.Data.Filtering.CriteriaOperator)args.Filter)).GetSummaries(args.Summaries); + } + }); + } + + System.Linq.Expressions.Expression> MakeFilterExpression(DevExpress.Data.Filtering.CriteriaOperator filter) { + var converter = new DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(); + return converter.Convert(filter); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.RowValidationArgs args) { + using(var unitOfWork = new DevExpress.Xpo.UnitOfWork()) { + var item = args.IsNewItem + ? new XPOIssues.Issues.Issue(unitOfWork) + : unitOfWork.GetObjectByKey(DetachedObjectsHelper.GetKey(args.Item)); + DetachedObjectsHelper.ApplyProperties(item, args.Item); + unitOfWork.CommitChanges(); + if(args.IsNewItem) { + DetachedObjectsHelper.SetKey(args.Item, item.Oid); + } + } + } + System.Collections.IList _Users; + + public System.Collections.IList Users + { + get + { + if(_Users == null && !IsInDesignMode) { + { + var session = new DevExpress.Xpo.Session(); + _Users = session.Query().OrderBy(user => user.Oid).Select(user => new { Id = user.Oid, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + } + return _Users; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _Users = null; + RaisePropertyChanged(nameof(Users)); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml b/CS/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..0096ddb --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml.cs b/CS/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml.cs new file mode 100644 index 0000000..027794a --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace XPOIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/XPO/PagedAsyncSource/PagedAsyncSource.csproj b/CS/ViewModel/XPO/PagedAsyncSource/PagedAsyncSource.csproj new file mode 100644 index 0000000..0476beb --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/PagedAsyncSource.csproj @@ -0,0 +1,160 @@ + + + + + + Debug + AnyCPU + {F9C7D214-7314-7427-227C-4D0D062CD3E9} + WinExe + XPOIssues + XPOIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/PagedAsyncSource/PagedAsyncSource.sln b/CS/ViewModel/XPO/PagedAsyncSource/PagedAsyncSource.sln new file mode 100644 index 0000000..190a8c8 --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/PagedAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagedAsyncSource", "PagedAsyncSource.csproj", "{F9C7D214-7314-7427-227C-4D0D062CD3E9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F9C7D214-7314-7427-227C-4D0D062CD3E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9C7D214-7314-7427-227C-4D0D062CD3E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9C7D214-7314-7427-227C-4D0D062CD3E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9C7D214-7314-7427-227C-4D0D062CD3E9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/XPO/PagedAsyncSource/Properties/AssemblyInfo.cs b/CS/ViewModel/XPO/PagedAsyncSource/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f481389 --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("XPOIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("XPOIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/XPO/PagedAsyncSource/Properties/Resources.Designer.cs b/CS/ViewModel/XPO/PagedAsyncSource/Properties/Resources.Designer.cs new file mode 100644 index 0000000..4c2c340 --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace XPOIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XPOIssues.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 --git a/CS/ViewModel/XPO/PagedAsyncSource/Properties/Resources.resx b/CS/ViewModel/XPO/PagedAsyncSource/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/XPO/PagedAsyncSource/Properties/Settings.Designer.cs b/CS/ViewModel/XPO/PagedAsyncSource/Properties/Settings.Designer.cs new file mode 100644 index 0000000..486c4c6 --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace XPOIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/ViewModel/XPO/PagedAsyncSource/Properties/Settings.settings b/CS/ViewModel/XPO/PagedAsyncSource/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/PagedAsyncSource/packages.config b/CS/ViewModel/XPO/PagedAsyncSource/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/ViewModel/XPO/PagedAsyncSource/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/ServerMode/App.config b/CS/ViewModel/XPO/ServerMode/App.config new file mode 100644 index 0000000..f473aab --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/ServerMode/App.xaml b/CS/ViewModel/XPO/ServerMode/App.xaml new file mode 100644 index 0000000..1e81d99 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/CS/ViewModel/XPO/ServerMode/App.xaml.cs b/CS/ViewModel/XPO/ServerMode/App.xaml.cs new file mode 100644 index 0000000..3f603e9 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/App.xaml.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using XPOIssues.Issues; + +namespace XPOIssues { + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application { + public App() { + ConnectionHelper.Connect(); + DemoDataHelper.Seed(); + } + } +} diff --git a/CS/ViewModel/XPO/ServerMode/EditIssueInfo.cs b/CS/ViewModel/XPO/ServerMode/EditIssueInfo.cs new file mode 100644 index 0000000..77e9a52 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/EditIssueInfo.cs @@ -0,0 +1,14 @@ +using DevExpress.Mvvm; +using System.Collections; +using XPOIssues.Issues; + +namespace XPOIssues { + public class EditIssueInfo : BindableBase { + public EditIssueInfo(DevExpress.Xpo.UnitOfWork unitOfWork, IList users) { + UnitOfWork = unitOfWork; + Users = users; + } + public DevExpress.Xpo.UnitOfWork UnitOfWork { get; } + public IList Users { get; } + } +} \ No newline at end of file diff --git a/CS/ViewModel/XPO/ServerMode/IssueDetailView.xaml b/CS/ViewModel/XPO/ServerMode/IssueDetailView.xaml new file mode 100644 index 0000000..8110d2f --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/ServerMode/IssueDetailView.xaml.cs b/CS/ViewModel/XPO/ServerMode/IssueDetailView.xaml.cs new file mode 100644 index 0000000..698dbf1 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/IssueDetailView.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows.Controls; + +namespace XPOIssues { + public partial class IssueDetailView : UserControl { + public IssueDetailView() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/XPO/ServerMode/Issues/ConnectionHelper.cs b/CS/ViewModel/XPO/ServerMode/Issues/ConnectionHelper.cs new file mode 100644 index 0000000..01dd20a --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/Issues/ConnectionHelper.cs @@ -0,0 +1,29 @@ +using DevExpress.Xpo; +using DevExpress.Xpo.DB; +using DevExpress.Xpo.Metadata; +using System; +using System.Configuration; + +namespace XPOIssues.Issues { + public static class ConnectionHelper { + + static readonly Type[] PersistentTypes = new Type[]{ + typeof(Issue), + typeof(User) + }; + + public static void Connect() { + XpoDefault.DataLayer = CreateDataLayer(true); + } + + static IDataLayer CreateDataLayer(bool threadSafe) { + string connStr = ConfigurationManager.ConnectionStrings["XpoTutorial"]?.ConnectionString ?? "XpoProvider=InMemoryDataStore"; + //connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + ReflectionDictionary dictionary = new ReflectionDictionary(); + dictionary.GetDataStoreSchema(PersistentTypes); // Pass all of your persistent object types to this method. + AutoCreateOption autoCreateOption = AutoCreateOption.DatabaseAndSchema; // Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + IDataStore provider = XpoDefault.GetConnectionProvider(connStr, autoCreateOption); + return threadSafe ? (IDataLayer)new ThreadSafeDataLayer(dictionary, provider) : new SimpleDataLayer(dictionary, provider); + } + } +} diff --git a/CS/ViewModel/XPO/ServerMode/Issues/Customer.cs b/CS/ViewModel/XPO/ServerMode/Issues/Customer.cs new file mode 100644 index 0000000..8e084e7 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/Issues/Customer.cs @@ -0,0 +1,27 @@ +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class User : XPObject { + public User(Session session) : base(session) { } + + string _FirstName; + public string FirstName + { + get { return _FirstName; } + set { SetPropertyValue(nameof(FirstName), ref _FirstName, value); } + } + + string _LastName; + public string LastName + { + get { return _LastName; } + set { SetPropertyValue(nameof(LastName), ref _LastName, value); } + } + + [Association("UserIssues")] + public XPCollection Issues + { + get { return GetCollection(nameof(Issues)); } + } + } +} diff --git a/CS/ViewModel/XPO/ServerMode/Issues/DemoDataHelper.cs b/CS/ViewModel/XPO/ServerMode/Issues/DemoDataHelper.cs new file mode 100644 index 0000000..a3d71a2 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/Issues/DemoDataHelper.cs @@ -0,0 +1,37 @@ +using DevExpress.Xpo; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace XPOIssues.Issues { + public static class DemoDataHelper { + public static void Seed() { + using(var uow = new DevExpress.Xpo.UnitOfWork()) { + var users = OutlookDataGenerator.Users + .Select(x => + { + var split = x.Split(' '); + return new User(uow) + { + FirstName = split[0], + LastName = split[1] + }; + }) + .ToArray(); + uow.CommitChanges(); + var rnd = new Random(0); + var issues = Enumerable.Range(0, 1000) + .Select(i => new Issue(uow) + { + Subject = OutlookDataGenerator.GetSubject(), + UserId = users[rnd.Next(users.Length)].Oid, + Created = DateTime.Today.AddDays(-rnd.Next(30)), + Priority = OutlookDataGenerator.GetPriority(), + Votes = rnd.Next(100), + }) + .ToArray(); + uow.CommitChanges(); + } + } + } +} diff --git a/CS/ViewModel/XPO/ServerMode/Issues/Issue.cs b/CS/ViewModel/XPO/ServerMode/Issues/Issue.cs new file mode 100644 index 0000000..44e3d22 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/Issues/Issue.cs @@ -0,0 +1,55 @@ +using System; +using DevExpress.Xpo; + +namespace XPOIssues.Issues { + public class Issue : XPObject { + public Issue(Session session) : base(session) { + Created = DateTime.Now; + } + string _Subject; + [Size(200)] + public string Subject + { + get { return _Subject; } + set { SetPropertyValue(nameof(Subject), ref _Subject, value); } + } + + int _UserId; + public int UserId + { + get { return _UserId; } + set { SetPropertyValue(nameof(UserId), ref _UserId, value); } + } + + User _User; + [Association("UserIssues")] + public User User + { + get { return _User; } + set { SetPropertyValue(nameof(User), ref _User, value); } + } + + DateTime _Created; + public DateTime Created + { + get { return _Created; } + set { SetPropertyValue(nameof(Created), ref _Created, value); } + } + + int _Votes; + public int Votes + { + get { return _Votes; } + set { SetPropertyValue(nameof(Votes), ref _Votes, value); } + } + + Priority _Priority; + public Priority Priority + { + get { return _Priority; } + set { SetPropertyValue(nameof(Priority), ref _Priority, value); } + } + } + + public enum Priority { Low, BelowNormal, Normal, AboveNormal, High } +} diff --git a/CS/ViewModel/XPO/ServerMode/Issues/OutlookDataGenerator.cs b/CS/ViewModel/XPO/ServerMode/Issues/OutlookDataGenerator.cs new file mode 100644 index 0000000..ad8047e --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/Issues/OutlookDataGenerator.cs @@ -0,0 +1,59 @@ +using System; + +namespace XPOIssues.Issues { + public static class OutlookDataGenerator { + static Random rnd = new Random(0); + static string[] Subjects = new string[] { "Developer Express MasterView. Integrating the control into an Accounting System.", + "Web Edition: Data Entry Page. There is an issue with date validation.", + "Payables Due Calculator is ready for testing.", + "Web Edition: Search Page is ready for testing.", + "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", + "Receivables Calculator. Where can I find the complete specs?", + "Ledger: Inconsistency. Please fix it.", + "Receivables Printing module is ready for testing.", + "Screen Redraw. Somebody has to look at it.", + "Email System. What library are we going to use?", + "Cannot add new vendor. This module doesn't work!", + "History. Will we track sales history in our system?", + "Main Menu: Add a File menu. File menu item is missing.", + "Currency Mask. The current currency mask in completely unusable.", + "Drag & Drop operations are not available in the scheduler module.", + "Data Import. What database types will we support?", + "Reports. The list of incomplete reports.", + "Data Archiving. We still don't have this features in our application.", + "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", + "Check Register. We are using different paths for different modules.", + "Data Export. Our customers asked us for export to Microsoft Excel"}; + + public static readonly string[] Users = new string[] { + "Peter Dolan", + "Ryan Fischer", + "Richard Fisher", + "Tom Hamlett", + "Mark Hamilton", + "Steve Lee", + "Jimmy Lewis", + "Jeffrey McClain", + "Andrew Miller", + "Dave Murrel", + "Bert Parkins", + "Mike Roller", + "Ray Shipman", + "Paul Bailey", + "Brad Barnes", + "Carl Lucas", + "Jerry Campbell", + }; + + public static string GetSubject() { + return Subjects[rnd.Next(Subjects.Length - 1)]; + } + + public static string GetFrom() { + return Users[rnd.Next(Users.Length)]; + } + public static Priority GetPriority() { + return (Priority)rnd.Next(5); + } + } +} diff --git a/CS/ViewModel/XPO/ServerMode/MainViewModel.cs b/CS/ViewModel/XPO/ServerMode/MainViewModel.cs new file mode 100644 index 0000000..996c246 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/MainViewModel.cs @@ -0,0 +1,81 @@ +using DevExpress.Mvvm; +using DevExpress.Xpf.Data; +using System.Linq; +using System.Threading.Tasks; +using DevExpress.Xpo; +using XPOIssues.Issues; +using DevExpress.Mvvm.Xpf; +using System; + +namespace XPOIssues { + public class MainViewModel : ViewModelBase { + DevExpress.Xpo.XPServerModeView _ServerModeSource; + + public DevExpress.Xpo.XPServerModeView ServerModeSource + { + get + { + if(_ServerModeSource == null) { + var properties = new DevExpress.Xpo.ServerViewProperty[] { +new DevExpress.Xpo.ServerViewProperty("Oid", DevExpress.Xpo.SortDirection.Ascending, new DevExpress.Data.Filtering.OperandProperty("Oid")), +new DevExpress.Xpo.ServerViewProperty("Subject", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Subject")), +new DevExpress.Xpo.ServerViewProperty("UserId", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("UserId")), +new DevExpress.Xpo.ServerViewProperty("Created", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Created")), +new DevExpress.Xpo.ServerViewProperty("Votes", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Votes")), +new DevExpress.Xpo.ServerViewProperty("Priority", DevExpress.Xpo.SortDirection.None, new DevExpress.Data.Filtering.OperandProperty("Priority")) + }; + var session = new DevExpress.Xpo.Session(); + _ServerModeSource = new DevExpress.Xpo.XPServerModeView(session, typeof(XPOIssues.Issues.Issue), null); + _ServerModeSource.Properties.AddRange(properties); + } + return _ServerModeSource; + } + } + System.Collections.IList _Users; + + public System.Collections.IList Users + { + get + { + if(_Users == null && !IsInDesignMode) { + { + var session = new DevExpress.Xpo.Session(); + _Users = session.Query().OrderBy(user => user.Oid).Select(user => new { Id = user.Oid, Name = user.FirstName + " " + user.LastName }).ToArray(); + } + } + return _Users; + } + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void DataSourceRefresh(DevExpress.Mvvm.Xpf.DataSourceRefreshArgs args) { + _Users = null; + RaisePropertyChanged(nameof(Users)); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void CreateEditEntityViewModel(DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs args) { + var unitOfWork = new UnitOfWork(); + var item = args.Key != null + ? unitOfWork.GetObjectByKey(args.Key) + : new Issue(unitOfWork); + args.ViewModel = new EditItemViewModel( + item, + new EditIssueInfo(unitOfWork, Users), + dispose: () => unitOfWork.Dispose() + ); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRow(DevExpress.Mvvm.Xpf.EditFormRowValidationArgs args) { + var unitOfWork = ((EditIssueInfo)args.Tag).UnitOfWork; + unitOfWork.CommitChanges(); + } + [DevExpress.Mvvm.DataAnnotations.Command] + public void ValidateRowDeletion(DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs args) { + using(var unitOfWork = new UnitOfWork()) { + var key = (int)args.Keys.Single(); + var item = unitOfWork.GetObjectByKey(key); + unitOfWork.Delete(item); + unitOfWork.CommitChanges(); + } + } + } +} \ No newline at end of file diff --git a/CS/ViewModel/XPO/ServerMode/MainWindow.xaml b/CS/ViewModel/XPO/ServerMode/MainWindow.xaml new file mode 100644 index 0000000..a04cf72 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/ServerMode/MainWindow.xaml.cs b/CS/ViewModel/XPO/ServerMode/MainWindow.xaml.cs new file mode 100644 index 0000000..027794a --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/MainWindow.xaml.cs @@ -0,0 +1,9 @@ +using System.Windows; + +namespace XPOIssues { + public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } + } +} diff --git a/CS/ViewModel/XPO/ServerMode/Properties/AssemblyInfo.cs b/CS/ViewModel/XPO/ServerMode/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f481389 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("XPOIssues")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("XPOIssues")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[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)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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 --git a/CS/ViewModel/XPO/ServerMode/Properties/Resources.Designer.cs b/CS/ViewModel/XPO/ServerMode/Properties/Resources.Designer.cs new file mode 100644 index 0000000..4c2c340 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/Properties/Resources.Designer.cs @@ -0,0 +1,55 @@ +namespace XPOIssues.Properties { + /// + /// 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((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XPOIssues.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 --git a/CS/ViewModel/XPO/ServerMode/Properties/Resources.resx b/CS/ViewModel/XPO/ServerMode/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/Properties/Resources.resx @@ -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 --git a/CS/ViewModel/XPO/ServerMode/Properties/Settings.Designer.cs b/CS/ViewModel/XPO/ServerMode/Properties/Settings.Designer.cs new file mode 100644 index 0000000..486c4c6 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/Properties/Settings.Designer.cs @@ -0,0 +1,16 @@ +namespace XPOIssues.Properties { + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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 --git a/CS/ViewModel/XPO/ServerMode/Properties/Settings.settings b/CS/ViewModel/XPO/ServerMode/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/ServerMode/ServerMode.csproj b/CS/ViewModel/XPO/ServerMode/ServerMode.csproj new file mode 100644 index 0000000..ef87ab8 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/ServerMode.csproj @@ -0,0 +1,169 @@ + + + + + + Debug + AnyCPU + {2B8C4A5D-723E-AC15-5905-BDBCE5C10D75} + WinExe + XPOIssues + XPOIssues + v4.5.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + + 4.0 + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + + App.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CS/ViewModel/XPO/ServerMode/ServerMode.sln b/CS/ViewModel/XPO/ServerMode/ServerMode.sln new file mode 100644 index 0000000..f28cf74 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/ServerMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerMode", "ServerMode.csproj", "{2B8C4A5D-723E-AC15-5905-BDBCE5C10D75}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2B8C4A5D-723E-AC15-5905-BDBCE5C10D75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2B8C4A5D-723E-AC15-5905-BDBCE5C10D75}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2B8C4A5D-723E-AC15-5905-BDBCE5C10D75}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2B8C4A5D-723E-AC15-5905-BDBCE5C10D75}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D8E8433C-CD55-4F5F-AB3A-BFF61AF74889} + EndGlobalSection +EndGlobal diff --git a/CS/ViewModel/XPO/ServerMode/packages.config b/CS/ViewModel/XPO/ServerMode/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/CS/ViewModel/XPO/ServerMode/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/NuGet.Config b/NuGet.Config new file mode 100644 index 0000000..624214b --- /dev/null +++ b/NuGet.Config @@ -0,0 +1,6 @@ + + + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..124f716 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ + +# How to implement CRUD operations within the WPF Data Grid control + +The following examples demonstrate how to implement CRUD operations (create, read, update, and delete) in the [GridControl](https://documentation.devexpress.com/WPF/DevExpress.Xpf.Grid.GridControl.class) bound to different data sources. + +Refer to the [How to: Implement CRUD Operations in a Data-Bound Grid](https://docs.devexpress.com/WPF/401907/controls-and-libraries/data-grid/examples/data-editing-and-validation/how-to-crud-operations) documentation topic for more information. + +See also: [How to: Bind Data Grid control to data](https://github.com/DevExpress-Examples/how-to-bind-wpf-grid-to-data) +# C# +## CodeBehind +||Entity Framework 6 [?](https://docs.microsoft.com/en-us/ef/ef6/)|Entity Framework Core [?](https://docs.microsoft.com/en-us/ef/)|DevExpress XPO [?](https://docs.devexpress.com/XPO/1998/express-persistent-objects)| +|:---|:---:|:---:|:---:| +|Local Data [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/bind-to-local-data)|[project](CS/CodeBehind/EntityFramework/LocalData), [code](CS/CodeBehind/EntityFramework/LocalData/MainWindow.xaml.cs), [xaml](CS/CodeBehind/EntityFramework/LocalData/MainWindow.xaml)|[project](CS/CodeBehind/EFCore/LocalData), [code](CS/CodeBehind/EFCore/LocalData/MainWindow.xaml.cs), [xaml](CS/CodeBehind/EFCore/LocalData/MainWindow.xaml)|[project](CS/CodeBehind/XPO/LocalData), [code](CS/CodeBehind/XPO/LocalData/MainWindow.xaml.cs), [xaml](CS/CodeBehind/XPO/LocalData/MainWindow.xaml)| +|Infinite Async Source [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/bind-to-any-data-source-with-virtual-sources/virtual-sources-overview#infinite-source)|[project](CS/CodeBehind/EntityFramework/InfiniteAsyncSource), [code](CS/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.cs), [xaml](CS/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml)|[project](CS/CodeBehind/EFCore/InfiniteAsyncSource), [code](CS/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml.cs), [xaml](CS/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml)|[project](CS/CodeBehind/XPO/InfiniteAsyncSource), [code](CS/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml.cs), [xaml](CS/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml)| +|Paged Async Source [1](#f1) [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/bind-to-any-data-source-with-virtual-sources/virtual-sources-overview#paged-source)|[project](CS/CodeBehind/EntityFramework/PagedAsyncSource), [code](CS/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml.cs), [xaml](CS/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml)|[project](CS/CodeBehind/EFCore/PagedAsyncSource), [code](CS/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml.cs), [xaml](CS/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml)|[project](CS/CodeBehind/XPO/PagedAsyncSource), [code](CS/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml.cs), [xaml](CS/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml)| +|Instant Feedback Mode [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/server-mode-and-instant-feedback#instant-feedback-mode)|[project](CS/CodeBehind/EntityFramework/InstantFeedbackMode), [code](CS/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml.cs), [xaml](CS/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml)|[project](CS/CodeBehind/EFCore/InstantFeedbackMode), [code](CS/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml.cs), [xaml](CS/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml)|[project](CS/CodeBehind/XPO/InstantFeedbackMode), [code](CS/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml.cs), [xaml](CS/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml)| +|Server Mode [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/server-mode-and-instant-feedback#server-mode)|[project](CS/CodeBehind/EntityFramework/ServerMode), [code](CS/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml.cs), [xaml](CS/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml)|[project](CS/CodeBehind/EFCore/ServerMode), [code](CS/CodeBehind/EFCore/ServerMode/MainWindow.xaml.cs), [xaml](CS/CodeBehind/EFCore/ServerMode/MainWindow.xaml)|[project](CS/CodeBehind/XPO/ServerMode), [code](CS/CodeBehind/XPO/ServerMode/MainWindow.xaml.cs), [xaml](CS/CodeBehind/XPO/ServerMode/MainWindow.xaml)| +## ViewModel +||Entity Framework 6 [?](https://docs.microsoft.com/en-us/ef/ef6/)|Entity Framework Core [?](https://docs.microsoft.com/en-us/ef/)|DevExpress XPO [?](https://docs.devexpress.com/XPO/1998/express-persistent-objects)| +|:---|:---:|:---:|:---:| +|Local Data [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/bind-to-local-data)|[project](CS/ViewModel/EntityFramework/LocalData), [code](CS/ViewModel/EntityFramework/LocalData/MainViewModel.cs), [xaml](CS/ViewModel/EntityFramework/LocalData/MainWindow.xaml)|[project](CS/ViewModel/EFCore/LocalData), [code](CS/ViewModel/EFCore/LocalData/MainViewModel.cs), [xaml](CS/ViewModel/EFCore/LocalData/MainWindow.xaml)|[project](CS/ViewModel/XPO/LocalData), [code](CS/ViewModel/XPO/LocalData/MainViewModel.cs), [xaml](CS/ViewModel/XPO/LocalData/MainWindow.xaml)| +|Infinite Async Source [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/bind-to-any-data-source-with-virtual-sources/virtual-sources-overview#infinite-source)|[project](CS/ViewModel/EntityFramework/InfiniteAsyncSource), [code](CS/ViewModel/EntityFramework/InfiniteAsyncSource/MainViewModel.cs), [xaml](CS/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml)|[project](CS/ViewModel/EFCore/InfiniteAsyncSource), [code](CS/ViewModel/EFCore/InfiniteAsyncSource/MainViewModel.cs), [xaml](CS/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml)|[project](CS/ViewModel/XPO/InfiniteAsyncSource), [code](CS/ViewModel/XPO/InfiniteAsyncSource/MainViewModel.cs), [xaml](CS/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml)| +|Paged Async Source [1](#f1) [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/bind-to-any-data-source-with-virtual-sources/virtual-sources-overview#paged-source)|[project](CS/ViewModel/EntityFramework/PagedAsyncSource), [code](CS/ViewModel/EntityFramework/PagedAsyncSource/MainViewModel.cs), [xaml](CS/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml)|[project](CS/ViewModel/EFCore/PagedAsyncSource), [code](CS/ViewModel/EFCore/PagedAsyncSource/MainViewModel.cs), [xaml](CS/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml)|[project](CS/ViewModel/XPO/PagedAsyncSource), [code](CS/ViewModel/XPO/PagedAsyncSource/MainViewModel.cs), [xaml](CS/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml)| +|Instant Feedback Mode [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/server-mode-and-instant-feedback#instant-feedback-mode)|[project](CS/ViewModel/EntityFramework/InstantFeedbackMode), [code](CS/ViewModel/EntityFramework/InstantFeedbackMode/MainViewModel.cs), [xaml](CS/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml)|[project](CS/ViewModel/EFCore/InstantFeedbackMode), [code](CS/ViewModel/EFCore/InstantFeedbackMode/MainViewModel.cs), [xaml](CS/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml)|[project](CS/ViewModel/XPO/InstantFeedbackMode), [code](CS/ViewModel/XPO/InstantFeedbackMode/MainViewModel.cs), [xaml](CS/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml)| +|Server Mode [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/server-mode-and-instant-feedback#server-mode)|[project](CS/ViewModel/EntityFramework/ServerMode), [code](CS/ViewModel/EntityFramework/ServerMode/MainViewModel.cs), [xaml](CS/ViewModel/EntityFramework/ServerMode/MainWindow.xaml)|[project](CS/ViewModel/EFCore/ServerMode), [code](CS/ViewModel/EFCore/ServerMode/MainViewModel.cs), [xaml](CS/ViewModel/EFCore/ServerMode/MainWindow.xaml)|[project](CS/ViewModel/XPO/ServerMode), [code](CS/ViewModel/XPO/ServerMode/MainViewModel.cs), [xaml](CS/ViewModel/XPO/ServerMode/MainWindow.xaml)| +# Visual Basic +## CodeBehind +||Entity Framework 6 [?](https://docs.microsoft.com/en-us/ef/ef6/)|Entity Framework Core [?](https://docs.microsoft.com/en-us/ef/)|DevExpress XPO [?](https://docs.devexpress.com/XPO/1998/express-persistent-objects)| +|:---|:---:|:---:|:---:| +|Local Data [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/bind-to-local-data)|[project](VB/CodeBehind/EntityFramework/LocalData), [code](VB/CodeBehind/EntityFramework/LocalData/MainWindow.xaml.vb), [xaml](VB/CodeBehind/EntityFramework/LocalData/MainWindow.xaml)|[project](VB/CodeBehind/EFCore/LocalData), [code](VB/CodeBehind/EFCore/LocalData/MainWindow.xaml.vb), [xaml](VB/CodeBehind/EFCore/LocalData/MainWindow.xaml)|[project](VB/CodeBehind/XPO/LocalData), [code](VB/CodeBehind/XPO/LocalData/MainWindow.xaml.vb), [xaml](VB/CodeBehind/XPO/LocalData/MainWindow.xaml)| +|Infinite Async Source [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/bind-to-any-data-source-with-virtual-sources/virtual-sources-overview#infinite-source)|[project](VB/CodeBehind/EntityFramework/InfiniteAsyncSource), [code](VB/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.vb), [xaml](VB/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml)|[project](VB/CodeBehind/EFCore/InfiniteAsyncSource), [code](VB/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml.vb), [xaml](VB/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml)|[project](VB/CodeBehind/XPO/InfiniteAsyncSource), [code](VB/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml.vb), [xaml](VB/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml)| +|Paged Async Source [1](#f1) [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/bind-to-any-data-source-with-virtual-sources/virtual-sources-overview#paged-source)|[project](VB/CodeBehind/EntityFramework/PagedAsyncSource), [code](VB/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml.vb), [xaml](VB/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml)|[project](VB/CodeBehind/EFCore/PagedAsyncSource), [code](VB/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml.vb), [xaml](VB/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml)|[project](VB/CodeBehind/XPO/PagedAsyncSource), [code](VB/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml.vb), [xaml](VB/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml)| +|Instant Feedback Mode [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/server-mode-and-instant-feedback#instant-feedback-mode)|[project](VB/CodeBehind/EntityFramework/InstantFeedbackMode), [code](VB/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml.vb), [xaml](VB/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml)|[project](VB/CodeBehind/EFCore/InstantFeedbackMode), [code](VB/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml.vb), [xaml](VB/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml)|[project](VB/CodeBehind/XPO/InstantFeedbackMode), [code](VB/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml.vb), [xaml](VB/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml)| +|Server Mode [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/server-mode-and-instant-feedback#server-mode)|[project](VB/CodeBehind/EntityFramework/ServerMode), [code](VB/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml.vb), [xaml](VB/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml)|[project](VB/CodeBehind/EFCore/ServerMode), [code](VB/CodeBehind/EFCore/ServerMode/MainWindow.xaml.vb), [xaml](VB/CodeBehind/EFCore/ServerMode/MainWindow.xaml)|[project](VB/CodeBehind/XPO/ServerMode), [code](VB/CodeBehind/XPO/ServerMode/MainWindow.xaml.vb), [xaml](VB/CodeBehind/XPO/ServerMode/MainWindow.xaml)| +## ViewModel +||Entity Framework 6 [?](https://docs.microsoft.com/en-us/ef/ef6/)|Entity Framework Core [?](https://docs.microsoft.com/en-us/ef/)|DevExpress XPO [?](https://docs.devexpress.com/XPO/1998/express-persistent-objects)| +|:---|:---:|:---:|:---:| +|Local Data [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/bind-to-local-data)|[project](VB/ViewModel/EntityFramework/LocalData), [code](VB/ViewModel/EntityFramework/LocalData/MainViewModel.vb), [xaml](VB/ViewModel/EntityFramework/LocalData/MainWindow.xaml)|[project](VB/ViewModel/EFCore/LocalData), [code](VB/ViewModel/EFCore/LocalData/MainViewModel.vb), [xaml](VB/ViewModel/EFCore/LocalData/MainWindow.xaml)|[project](VB/ViewModel/XPO/LocalData), [code](VB/ViewModel/XPO/LocalData/MainViewModel.vb), [xaml](VB/ViewModel/XPO/LocalData/MainWindow.xaml)| +|Infinite Async Source [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/bind-to-any-data-source-with-virtual-sources/virtual-sources-overview#infinite-source)|[project](VB/ViewModel/EntityFramework/InfiniteAsyncSource), [code](VB/ViewModel/EntityFramework/InfiniteAsyncSource/MainViewModel.vb), [xaml](VB/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml)|[project](VB/ViewModel/EFCore/InfiniteAsyncSource), [code](VB/ViewModel/EFCore/InfiniteAsyncSource/MainViewModel.vb), [xaml](VB/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml)|[project](VB/ViewModel/XPO/InfiniteAsyncSource), [code](VB/ViewModel/XPO/InfiniteAsyncSource/MainViewModel.vb), [xaml](VB/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml)| +|Paged Async Source [1](#f1) [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/bind-to-any-data-source-with-virtual-sources/virtual-sources-overview#paged-source)|[project](VB/ViewModel/EntityFramework/PagedAsyncSource), [code](VB/ViewModel/EntityFramework/PagedAsyncSource/MainViewModel.vb), [xaml](VB/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml)|[project](VB/ViewModel/EFCore/PagedAsyncSource), [code](VB/ViewModel/EFCore/PagedAsyncSource/MainViewModel.vb), [xaml](VB/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml)|[project](VB/ViewModel/XPO/PagedAsyncSource), [code](VB/ViewModel/XPO/PagedAsyncSource/MainViewModel.vb), [xaml](VB/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml)| +|Instant Feedback Mode [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/server-mode-and-instant-feedback#instant-feedback-mode)|[project](VB/ViewModel/EntityFramework/InstantFeedbackMode), [code](VB/ViewModel/EntityFramework/InstantFeedbackMode/MainViewModel.vb), [xaml](VB/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml)|[project](VB/ViewModel/EFCore/InstantFeedbackMode), [code](VB/ViewModel/EFCore/InstantFeedbackMode/MainViewModel.vb), [xaml](VB/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml)|[project](VB/ViewModel/XPO/InstantFeedbackMode), [code](VB/ViewModel/XPO/InstantFeedbackMode/MainViewModel.vb), [xaml](VB/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml)| +|Server Mode [?](https://docs.devexpress.com/WPF/6090/controls-and-libraries/data-grid/bind-to-data/server-mode-and-instant-feedback#server-mode)|[project](VB/ViewModel/EntityFramework/ServerMode), [code](VB/ViewModel/EntityFramework/ServerMode/MainViewModel.vb), [xaml](VB/ViewModel/EntityFramework/ServerMode/MainWindow.xaml)|[project](VB/ViewModel/EFCore/ServerMode), [code](VB/ViewModel/EFCore/ServerMode/MainViewModel.vb), [xaml](VB/ViewModel/EFCore/ServerMode/MainWindow.xaml)|[project](VB/ViewModel/XPO/ServerMode), [code](VB/ViewModel/XPO/ServerMode/MainViewModel.vb), [xaml](VB/ViewModel/XPO/ServerMode/MainWindow.xaml)| + +1 Create and delete operations are not available with the Paged Async Source binding. diff --git a/Readme.md b/Readme.md deleted file mode 100644 index 49b6fe9..0000000 --- a/Readme.md +++ /dev/null @@ -1,10 +0,0 @@ - -![](https://img.shields.io/endpoint?url=https://codecentral.devexpress.com/api/v1/VersionRange/265491908/21.2.2%2B) -[![](https://img.shields.io/badge/Open_in_DevExpress_Support_Center-FF7200?style=flat-square&logo=DevExpress&logoColor=white)](https://supportcenter.devexpress.com/ticket/details/T899930) -[![](https://img.shields.io/badge/📖_How_to_use_DevExpress_Examples-e9f6fc?style=flat-square)](https://docs.devexpress.com/GeneralInformation/403183) - -# How to implement CRUD operations within the WPF Data Grid control - -The following examples demonstrate how to implement CRUD operations (create, read, update, and delete) in the [GridControl](https://documentation.devexpress.com/WPF/DevExpress.Xpf.Grid.GridControl.class) bound to a data source. - -Refer to the [How to: Implement CRUD Operations in a Data-Bound Grid](https://docs.devexpress.com/WPF/401907/controls-and-libraries/data-grid/examples/data-editing-and-validation/how-to-crud-operations) documentation topic for more information. diff --git a/VB.sln b/VB.sln new file mode 100644 index 0000000..7f1418d --- /dev/null +++ b/VB.sln @@ -0,0 +1,253 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CodeBehind", "CodeBehind", "{21D36955-95DF-189F-F462-3EA64FE19AA5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ViewModel", "ViewModel", "{6F543814-7740-FC98-73A5-CC0A913546B8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EFCore", "EFCore", "{183ED980-C32E-C675-E55D-281EBAB34CB4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EntityFramework", "EntityFramework", "{E304686B-213A-3A36-A534-4EE68562656A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "XPO", "XPO", "{BA298011-020E-89D7-9A29-3E4378A90301}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EFCore", "EFCore", "{8E928C27-5585-9913-8FA6-24A164DF3179}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EntityFramework", "EntityFramework", "{9130DE36-C8E7-253F-F380-218962E462D9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "XPO", "XPO", "{2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InfiniteAsyncSource", "VB\CodeBehind\EFCore\InfiniteAsyncSource\InfiniteAsyncSource.vbproj", "{E373385F-C1A8-2C3D-B855-D229F39D699F}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InstantFeedbackMode", "VB\CodeBehind\EFCore\InstantFeedbackMode\InstantFeedbackMode.vbproj", "{DBBC813A-ECBC-EDF0-A975-117D229B3BB7}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LocalData", "VB\CodeBehind\EFCore\LocalData\LocalData.vbproj", "{55FE18AD-CB42-5C59-AAF1-434C4EA209EA}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PagedAsyncSource", "VB\CodeBehind\EFCore\PagedAsyncSource\PagedAsyncSource.vbproj", "{BB2EED29-11AE-91F8-6518-D3012B0B0E98}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServerMode", "VB\CodeBehind\EFCore\ServerMode\ServerMode.vbproj", "{C7EE8E1C-0A16-F4A1-04A9-67716C9801FE}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InfiniteAsyncSource", "VB\CodeBehind\EntityFramework\InfiniteAsyncSource\InfiniteAsyncSource.vbproj", "{BEF0CF9C-FF62-0794-C130-2A0DCCA738A5}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InstantFeedbackMode", "VB\CodeBehind\EntityFramework\InstantFeedbackMode\InstantFeedbackMode.vbproj", "{4E3E7E7C-930D-23F6-59AF-8587ACE8E7DE}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LocalData", "VB\CodeBehind\EntityFramework\LocalData\LocalData.vbproj", "{8D79528C-21EE-4DA4-2C27-5550876A39B6}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PagedAsyncSource", "VB\CodeBehind\EntityFramework\PagedAsyncSource\PagedAsyncSource.vbproj", "{8B0A8DC8-777C-71D7-6446-02679BF6B155}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServerMode", "VB\CodeBehind\EntityFramework\ServerMode\ServerMode.vbproj", "{147009A6-9D5E-2A51-6623-5714C57A0F25}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InfiniteAsyncSource", "VB\CodeBehind\XPO\InfiniteAsyncSource\InfiniteAsyncSource.vbproj", "{C6952C7B-D539-EBA7-6CB2-75C16B3768B5}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InstantFeedbackMode", "VB\CodeBehind\XPO\InstantFeedbackMode\InstantFeedbackMode.vbproj", "{DDD2EA41-1B51-01B2-8E76-3E4CD3F19BDA}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LocalData", "VB\CodeBehind\XPO\LocalData\LocalData.vbproj", "{BD439146-0FFF-83E0-0633-777FD5A2991D}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PagedAsyncSource", "VB\CodeBehind\XPO\PagedAsyncSource\PagedAsyncSource.vbproj", "{448CFE97-0691-5B29-C5F9-433542936194}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServerMode", "VB\CodeBehind\XPO\ServerMode\ServerMode.vbproj", "{0F6A2BC6-1636-9D8E-6A2D-0A2C27A1C466}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InfiniteAsyncSource", "VB\ViewModel\EFCore\InfiniteAsyncSource\InfiniteAsyncSource.vbproj", "{C4F95762-ADAE-6FE2-C2EB-0F8A1B561165}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InstantFeedbackMode", "VB\ViewModel\EFCore\InstantFeedbackMode\InstantFeedbackMode.vbproj", "{9A63456D-FF25-1EC2-2583-F413CD9A3BF9}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LocalData", "VB\ViewModel\EFCore\LocalData\LocalData.vbproj", "{027E6DC6-769D-B290-7371-9707BC5DDB13}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PagedAsyncSource", "VB\ViewModel\EFCore\PagedAsyncSource\PagedAsyncSource.vbproj", "{F6189E92-A46E-25BB-D231-C9D1EAD29142}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServerMode", "VB\ViewModel\EFCore\ServerMode\ServerMode.vbproj", "{7D8E4D8A-C90F-B47D-757A-AAADD85B06C4}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InfiniteAsyncSource", "VB\ViewModel\EntityFramework\InfiniteAsyncSource\InfiniteAsyncSource.vbproj", "{2D9EB85E-6E66-2FFF-CA08-3EAA78EA7863}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InstantFeedbackMode", "VB\ViewModel\EntityFramework\InstantFeedbackMode\InstantFeedbackMode.vbproj", "{3E083351-6104-8417-782A-336F92D0CAA9}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LocalData", "VB\ViewModel\EntityFramework\LocalData\LocalData.vbproj", "{60B0BC31-2307-36F6-6218-1E56060F64A2}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PagedAsyncSource", "VB\ViewModel\EntityFramework\PagedAsyncSource\PagedAsyncSource.vbproj", "{D934199A-97C6-3537-EE16-383653D1F7F6}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServerMode", "VB\ViewModel\EntityFramework\ServerMode\ServerMode.vbproj", "{D763114E-D0F5-83CF-491D-23051B57ED9A}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InfiniteAsyncSource", "VB\ViewModel\XPO\InfiniteAsyncSource\InfiniteAsyncSource.vbproj", "{417F9E8E-532B-167E-CE23-C266F7D0A1AB}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InstantFeedbackMode", "VB\ViewModel\XPO\InstantFeedbackMode\InstantFeedbackMode.vbproj", "{6FA2435A-BFCA-A2B0-3FC5-B095F1ACF14F}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LocalData", "VB\ViewModel\XPO\LocalData\LocalData.vbproj", "{7BF3B0E7-C954-D906-C99E-95A9599F16EC}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PagedAsyncSource", "VB\ViewModel\XPO\PagedAsyncSource\PagedAsyncSource.vbproj", "{E9B003DA-11C7-8D57-34C3-945BDEBA5154}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServerMode", "VB\ViewModel\XPO\ServerMode\ServerMode.vbproj", "{E38E54C6-673E-5288-0A63-25642D9B0816}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E373385F-C1A8-2C3D-B855-D229F39D699F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E373385F-C1A8-2C3D-B855-D229F39D699F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E373385F-C1A8-2C3D-B855-D229F39D699F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E373385F-C1A8-2C3D-B855-D229F39D699F}.Release|Any CPU.Build.0 = Release|Any CPU + {DBBC813A-ECBC-EDF0-A975-117D229B3BB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DBBC813A-ECBC-EDF0-A975-117D229B3BB7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DBBC813A-ECBC-EDF0-A975-117D229B3BB7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DBBC813A-ECBC-EDF0-A975-117D229B3BB7}.Release|Any CPU.Build.0 = Release|Any CPU + {55FE18AD-CB42-5C59-AAF1-434C4EA209EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55FE18AD-CB42-5C59-AAF1-434C4EA209EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55FE18AD-CB42-5C59-AAF1-434C4EA209EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55FE18AD-CB42-5C59-AAF1-434C4EA209EA}.Release|Any CPU.Build.0 = Release|Any CPU + {BB2EED29-11AE-91F8-6518-D3012B0B0E98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB2EED29-11AE-91F8-6518-D3012B0B0E98}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB2EED29-11AE-91F8-6518-D3012B0B0E98}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB2EED29-11AE-91F8-6518-D3012B0B0E98}.Release|Any CPU.Build.0 = Release|Any CPU + {C7EE8E1C-0A16-F4A1-04A9-67716C9801FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C7EE8E1C-0A16-F4A1-04A9-67716C9801FE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C7EE8E1C-0A16-F4A1-04A9-67716C9801FE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C7EE8E1C-0A16-F4A1-04A9-67716C9801FE}.Release|Any CPU.Build.0 = Release|Any CPU + {BEF0CF9C-FF62-0794-C130-2A0DCCA738A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BEF0CF9C-FF62-0794-C130-2A0DCCA738A5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BEF0CF9C-FF62-0794-C130-2A0DCCA738A5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BEF0CF9C-FF62-0794-C130-2A0DCCA738A5}.Release|Any CPU.Build.0 = Release|Any CPU + {4E3E7E7C-930D-23F6-59AF-8587ACE8E7DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E3E7E7C-930D-23F6-59AF-8587ACE8E7DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E3E7E7C-930D-23F6-59AF-8587ACE8E7DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4E3E7E7C-930D-23F6-59AF-8587ACE8E7DE}.Release|Any CPU.Build.0 = Release|Any CPU + {8D79528C-21EE-4DA4-2C27-5550876A39B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D79528C-21EE-4DA4-2C27-5550876A39B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D79528C-21EE-4DA4-2C27-5550876A39B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D79528C-21EE-4DA4-2C27-5550876A39B6}.Release|Any CPU.Build.0 = Release|Any CPU + {8B0A8DC8-777C-71D7-6446-02679BF6B155}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8B0A8DC8-777C-71D7-6446-02679BF6B155}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8B0A8DC8-777C-71D7-6446-02679BF6B155}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8B0A8DC8-777C-71D7-6446-02679BF6B155}.Release|Any CPU.Build.0 = Release|Any CPU + {147009A6-9D5E-2A51-6623-5714C57A0F25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {147009A6-9D5E-2A51-6623-5714C57A0F25}.Debug|Any CPU.Build.0 = Debug|Any CPU + {147009A6-9D5E-2A51-6623-5714C57A0F25}.Release|Any CPU.ActiveCfg = Release|Any CPU + {147009A6-9D5E-2A51-6623-5714C57A0F25}.Release|Any CPU.Build.0 = Release|Any CPU + {C6952C7B-D539-EBA7-6CB2-75C16B3768B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6952C7B-D539-EBA7-6CB2-75C16B3768B5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6952C7B-D539-EBA7-6CB2-75C16B3768B5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6952C7B-D539-EBA7-6CB2-75C16B3768B5}.Release|Any CPU.Build.0 = Release|Any CPU + {DDD2EA41-1B51-01B2-8E76-3E4CD3F19BDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DDD2EA41-1B51-01B2-8E76-3E4CD3F19BDA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DDD2EA41-1B51-01B2-8E76-3E4CD3F19BDA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DDD2EA41-1B51-01B2-8E76-3E4CD3F19BDA}.Release|Any CPU.Build.0 = Release|Any CPU + {BD439146-0FFF-83E0-0633-777FD5A2991D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD439146-0FFF-83E0-0633-777FD5A2991D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD439146-0FFF-83E0-0633-777FD5A2991D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD439146-0FFF-83E0-0633-777FD5A2991D}.Release|Any CPU.Build.0 = Release|Any CPU + {448CFE97-0691-5B29-C5F9-433542936194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {448CFE97-0691-5B29-C5F9-433542936194}.Debug|Any CPU.Build.0 = Debug|Any CPU + {448CFE97-0691-5B29-C5F9-433542936194}.Release|Any CPU.ActiveCfg = Release|Any CPU + {448CFE97-0691-5B29-C5F9-433542936194}.Release|Any CPU.Build.0 = Release|Any CPU + {0F6A2BC6-1636-9D8E-6A2D-0A2C27A1C466}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F6A2BC6-1636-9D8E-6A2D-0A2C27A1C466}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F6A2BC6-1636-9D8E-6A2D-0A2C27A1C466}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F6A2BC6-1636-9D8E-6A2D-0A2C27A1C466}.Release|Any CPU.Build.0 = Release|Any CPU + {C4F95762-ADAE-6FE2-C2EB-0F8A1B561165}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C4F95762-ADAE-6FE2-C2EB-0F8A1B561165}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C4F95762-ADAE-6FE2-C2EB-0F8A1B561165}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C4F95762-ADAE-6FE2-C2EB-0F8A1B561165}.Release|Any CPU.Build.0 = Release|Any CPU + {9A63456D-FF25-1EC2-2583-F413CD9A3BF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A63456D-FF25-1EC2-2583-F413CD9A3BF9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A63456D-FF25-1EC2-2583-F413CD9A3BF9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A63456D-FF25-1EC2-2583-F413CD9A3BF9}.Release|Any CPU.Build.0 = Release|Any CPU + {027E6DC6-769D-B290-7371-9707BC5DDB13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {027E6DC6-769D-B290-7371-9707BC5DDB13}.Debug|Any CPU.Build.0 = Debug|Any CPU + {027E6DC6-769D-B290-7371-9707BC5DDB13}.Release|Any CPU.ActiveCfg = Release|Any CPU + {027E6DC6-769D-B290-7371-9707BC5DDB13}.Release|Any CPU.Build.0 = Release|Any CPU + {F6189E92-A46E-25BB-D231-C9D1EAD29142}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6189E92-A46E-25BB-D231-C9D1EAD29142}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6189E92-A46E-25BB-D231-C9D1EAD29142}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6189E92-A46E-25BB-D231-C9D1EAD29142}.Release|Any CPU.Build.0 = Release|Any CPU + {7D8E4D8A-C90F-B47D-757A-AAADD85B06C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D8E4D8A-C90F-B47D-757A-AAADD85B06C4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D8E4D8A-C90F-B47D-757A-AAADD85B06C4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D8E4D8A-C90F-B47D-757A-AAADD85B06C4}.Release|Any CPU.Build.0 = Release|Any CPU + {2D9EB85E-6E66-2FFF-CA08-3EAA78EA7863}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2D9EB85E-6E66-2FFF-CA08-3EAA78EA7863}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2D9EB85E-6E66-2FFF-CA08-3EAA78EA7863}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2D9EB85E-6E66-2FFF-CA08-3EAA78EA7863}.Release|Any CPU.Build.0 = Release|Any CPU + {3E083351-6104-8417-782A-336F92D0CAA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E083351-6104-8417-782A-336F92D0CAA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E083351-6104-8417-782A-336F92D0CAA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E083351-6104-8417-782A-336F92D0CAA9}.Release|Any CPU.Build.0 = Release|Any CPU + {60B0BC31-2307-36F6-6218-1E56060F64A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {60B0BC31-2307-36F6-6218-1E56060F64A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {60B0BC31-2307-36F6-6218-1E56060F64A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {60B0BC31-2307-36F6-6218-1E56060F64A2}.Release|Any CPU.Build.0 = Release|Any CPU + {D934199A-97C6-3537-EE16-383653D1F7F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D934199A-97C6-3537-EE16-383653D1F7F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D934199A-97C6-3537-EE16-383653D1F7F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D934199A-97C6-3537-EE16-383653D1F7F6}.Release|Any CPU.Build.0 = Release|Any CPU + {D763114E-D0F5-83CF-491D-23051B57ED9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D763114E-D0F5-83CF-491D-23051B57ED9A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D763114E-D0F5-83CF-491D-23051B57ED9A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D763114E-D0F5-83CF-491D-23051B57ED9A}.Release|Any CPU.Build.0 = Release|Any CPU + {417F9E8E-532B-167E-CE23-C266F7D0A1AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {417F9E8E-532B-167E-CE23-C266F7D0A1AB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {417F9E8E-532B-167E-CE23-C266F7D0A1AB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {417F9E8E-532B-167E-CE23-C266F7D0A1AB}.Release|Any CPU.Build.0 = Release|Any CPU + {6FA2435A-BFCA-A2B0-3FC5-B095F1ACF14F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6FA2435A-BFCA-A2B0-3FC5-B095F1ACF14F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6FA2435A-BFCA-A2B0-3FC5-B095F1ACF14F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6FA2435A-BFCA-A2B0-3FC5-B095F1ACF14F}.Release|Any CPU.Build.0 = Release|Any CPU + {7BF3B0E7-C954-D906-C99E-95A9599F16EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7BF3B0E7-C954-D906-C99E-95A9599F16EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7BF3B0E7-C954-D906-C99E-95A9599F16EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7BF3B0E7-C954-D906-C99E-95A9599F16EC}.Release|Any CPU.Build.0 = Release|Any CPU + {E9B003DA-11C7-8D57-34C3-945BDEBA5154}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9B003DA-11C7-8D57-34C3-945BDEBA5154}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9B003DA-11C7-8D57-34C3-945BDEBA5154}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9B003DA-11C7-8D57-34C3-945BDEBA5154}.Release|Any CPU.Build.0 = Release|Any CPU + {E38E54C6-673E-5288-0A63-25642D9B0816}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E38E54C6-673E-5288-0A63-25642D9B0816}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E38E54C6-673E-5288-0A63-25642D9B0816}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E38E54C6-673E-5288-0A63-25642D9B0816}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {183ED980-C32E-C675-E55D-281EBAB34CB4} = {21D36955-95DF-189F-F462-3EA64FE19AA5} + {E304686B-213A-3A36-A534-4EE68562656A} = {21D36955-95DF-189F-F462-3EA64FE19AA5} + {BA298011-020E-89D7-9A29-3E4378A90301} = {21D36955-95DF-189F-F462-3EA64FE19AA5} + {8E928C27-5585-9913-8FA6-24A164DF3179} = {6F543814-7740-FC98-73A5-CC0A913546B8} + {9130DE36-C8E7-253F-F380-218962E462D9} = {6F543814-7740-FC98-73A5-CC0A913546B8} + {2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE} = {6F543814-7740-FC98-73A5-CC0A913546B8} + {E373385F-C1A8-2C3D-B855-D229F39D699F} = {183ED980-C32E-C675-E55D-281EBAB34CB4} + {DBBC813A-ECBC-EDF0-A975-117D229B3BB7} = {183ED980-C32E-C675-E55D-281EBAB34CB4} + {55FE18AD-CB42-5C59-AAF1-434C4EA209EA} = {183ED980-C32E-C675-E55D-281EBAB34CB4} + {BB2EED29-11AE-91F8-6518-D3012B0B0E98} = {183ED980-C32E-C675-E55D-281EBAB34CB4} + {C7EE8E1C-0A16-F4A1-04A9-67716C9801FE} = {183ED980-C32E-C675-E55D-281EBAB34CB4} + {BEF0CF9C-FF62-0794-C130-2A0DCCA738A5} = {E304686B-213A-3A36-A534-4EE68562656A} + {4E3E7E7C-930D-23F6-59AF-8587ACE8E7DE} = {E304686B-213A-3A36-A534-4EE68562656A} + {8D79528C-21EE-4DA4-2C27-5550876A39B6} = {E304686B-213A-3A36-A534-4EE68562656A} + {8B0A8DC8-777C-71D7-6446-02679BF6B155} = {E304686B-213A-3A36-A534-4EE68562656A} + {147009A6-9D5E-2A51-6623-5714C57A0F25} = {E304686B-213A-3A36-A534-4EE68562656A} + {C6952C7B-D539-EBA7-6CB2-75C16B3768B5} = {BA298011-020E-89D7-9A29-3E4378A90301} + {DDD2EA41-1B51-01B2-8E76-3E4CD3F19BDA} = {BA298011-020E-89D7-9A29-3E4378A90301} + {BD439146-0FFF-83E0-0633-777FD5A2991D} = {BA298011-020E-89D7-9A29-3E4378A90301} + {448CFE97-0691-5B29-C5F9-433542936194} = {BA298011-020E-89D7-9A29-3E4378A90301} + {0F6A2BC6-1636-9D8E-6A2D-0A2C27A1C466} = {BA298011-020E-89D7-9A29-3E4378A90301} + {C4F95762-ADAE-6FE2-C2EB-0F8A1B561165} = {8E928C27-5585-9913-8FA6-24A164DF3179} + {9A63456D-FF25-1EC2-2583-F413CD9A3BF9} = {8E928C27-5585-9913-8FA6-24A164DF3179} + {027E6DC6-769D-B290-7371-9707BC5DDB13} = {8E928C27-5585-9913-8FA6-24A164DF3179} + {F6189E92-A46E-25BB-D231-C9D1EAD29142} = {8E928C27-5585-9913-8FA6-24A164DF3179} + {7D8E4D8A-C90F-B47D-757A-AAADD85B06C4} = {8E928C27-5585-9913-8FA6-24A164DF3179} + {2D9EB85E-6E66-2FFF-CA08-3EAA78EA7863} = {9130DE36-C8E7-253F-F380-218962E462D9} + {3E083351-6104-8417-782A-336F92D0CAA9} = {9130DE36-C8E7-253F-F380-218962E462D9} + {60B0BC31-2307-36F6-6218-1E56060F64A2} = {9130DE36-C8E7-253F-F380-218962E462D9} + {D934199A-97C6-3537-EE16-383653D1F7F6} = {9130DE36-C8E7-253F-F380-218962E462D9} + {D763114E-D0F5-83CF-491D-23051B57ED9A} = {9130DE36-C8E7-253F-F380-218962E462D9} + {417F9E8E-532B-167E-CE23-C266F7D0A1AB} = {2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE} + {6FA2435A-BFCA-A2B0-3FC5-B095F1ACF14F} = {2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE} + {7BF3B0E7-C954-D906-C99E-95A9599F16EC} = {2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE} + {E9B003DA-11C7-8D57-34C3-945BDEBA5154} = {2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE} + {E38E54C6-673E-5288-0A63-25642D9B0816} = {2F4361B4-3AD6-FBAD-85C3-977E24FC7DCE} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/App.config b/VB/CodeBehind/EFCore/InfiniteAsyncSource/App.config new file mode 100644 index 0000000..93bdfd4 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/App.config @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/Application.xaml b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Application.xaml new file mode 100644 index 0000000..1d7676b --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/Application.xaml.vb b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Application.xaml.vb new file mode 100644 index 0000000..fc1b49d --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Application.xaml.vb @@ -0,0 +1,10 @@ +Imports EFCoreIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + IssuesContextInitializer.Seed() + End Sub +End Class diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.sln b/VB/CodeBehind/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.sln new file mode 100644 index 0000000..229b9ff --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InfiniteAsyncSource", "InfiniteAsyncSource.vbproj", "{E373385F-C1A8-2C3D-B855-D229F39D699F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E373385F-C1A8-2C3D-B855-D229F39D699F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E373385F-C1A8-2C3D-B855-D229F39D699F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E373385F-C1A8-2C3D-B855-D229F39D699F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E373385F-C1A8-2C3D-B855-D229F39D699F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.vbproj b/VB/CodeBehind/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.vbproj new file mode 100644 index 0000000..4f0e566 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.vbproj @@ -0,0 +1,248 @@ + + + + Debug + AnyCPU + {E373385F-C1A8-2C3D-B855-D229F39D699F} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/Issue.vb b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/Issue.vb new file mode 100644 index 0000000..b9efd71 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/Issue.vb @@ -0,0 +1,23 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/IssuesContext.vb b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/IssuesContext.vb new file mode 100644 index 0000000..1312551 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/IssuesContext.vb @@ -0,0 +1,16 @@ +Imports Microsoft.EntityFrameworkCore + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Private Shared ReadOnly options As DbContextOptions(Of IssuesContext) = New DbContextOptionsBuilder(Of IssuesContext)().UseInMemoryDatabase(databaseName:="Test").Options + + Public Sub New() + MyBase.New(options) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/IssuesContextInitializer.vb b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..9faa303 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/IssuesContextInitializer.vb @@ -0,0 +1,29 @@ +Imports System +Imports System.Linq + +Namespace Issues + Public Module IssuesContextInitializer + Public Sub Seed() + Dim context = New IssuesContext() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/User.vb b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml b/VB/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..823eeb7 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml.vb b/VB/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml.vb new file mode 100644 index 0000000..a878180 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/MainWindow.xaml.vb @@ -0,0 +1,71 @@ +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports Microsoft.EntityFrameworkCore +Class MainWindow + Public Sub New() + InitializeComponent() + Dim source = New InfiniteAsyncSource With { + .ElementType = GetType(Issues.Issue), + .KeyProperty = NameOf(Issues.Issue.Id) + } + AddHandler source.FetchRows, AddressOf OnFetchRows + AddHandler source.GetTotalSummaries, AddressOf OnGetTotalSummaries + grid.ItemsSource = source + LoadLookupData() + End Sub + + Private Sub OnFetchRows(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Data.FetchRowsAsyncEventArgs) + e.Result = Task.Run(Of DevExpress.Xpf.Data.FetchRowsResult)(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.AsNoTracking().SortBy(e.SortOrder, defaultUniqueSortPropertyName:=NameOf(Issues.Issue.Id)).Where(MakeFilterExpression(e.Filter)) + Return queryable.Skip(e.Skip).Take(If(e.Take, 100)).ToArray() + End Function) + End Sub + + Private Sub OnGetTotalSummaries(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Data.GetSummariesAsyncEventArgs) + e.Result = Task.Run(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.Where(MakeFilterExpression(CType(e.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.GetSummaries(e.Summaries) + End Function) + End Sub + + Private Function MakeFilterExpression(ByVal filter As DevExpress.Data.Filtering.CriteriaOperator) As System.Linq.Expressions.Expression(Of System.Func(Of EFCoreIssues.Issues.Issue, Boolean)) + Dim converter = New DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(Of EFCoreIssues.Issues.Issue)() + Return converter.Convert(filter) + End Function + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridRowValidationEventArgs) + + Dim row = CType(e.Row, Issues.Issue) + Dim context = New Issues.IssuesContext() + context.Entry(row).State = If(e.IsNewItem, EntityState.Added, EntityState.Modified) + Try + context.SaveChanges() + Finally + context.Entry(row).State = EntityState.Detached + End Try + + End Sub + + Private Sub OnValidateRowDeletion(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridDeleteRowsValidationEventArgs) + Dim row = CType(e.Rows.Single(), Issues.Issue) + Dim context = New Issues.IssuesContext() + context.Entry(row).State = EntityState.Deleted + context.SaveChanges() + End Sub + + Private Sub LoadLookupData() + Dim context = New EFCoreIssues.Issues.IssuesContext() + usersLookup.ItemsSource = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadLookupData() + End Sub + +End Class diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/AssemblyInfo.vb b/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..8de8923 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/Resources.Designer.vb b/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/Resources.resx b/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/Settings.Designer.vb b/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/Settings.Designer.vb new file mode 100644 index 0000000..4e428d5 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EFCoreIssues.My.MySettings + Get + Return Global.EFCoreIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/Settings.settings b/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/InfiniteAsyncSource/packages.config b/VB/CodeBehind/EFCore/InfiniteAsyncSource/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/VB/CodeBehind/EFCore/InfiniteAsyncSource/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/App.config b/VB/CodeBehind/EFCore/InstantFeedbackMode/App.config new file mode 100644 index 0000000..93bdfd4 --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/App.config @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/Application.xaml b/VB/CodeBehind/EFCore/InstantFeedbackMode/Application.xaml new file mode 100644 index 0000000..1d7676b --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/Application.xaml.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/Application.xaml.vb new file mode 100644 index 0000000..fc1b49d --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/Application.xaml.vb @@ -0,0 +1,10 @@ +Imports EFCoreIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + IssuesContextInitializer.Seed() + End Sub +End Class diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/EditIssueInfo.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/EditIssueInfo.vb new file mode 100644 index 0000000..5ed81d2 --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/EditIssueInfo.vb @@ -0,0 +1,15 @@ +Imports DevExpress.Mvvm +Imports System.Collections.Generic +Imports EFCoreIssues.Issues + +Public Class EditIssueInfo + Inherits BindableBase + + Public Sub New(ByVal context As IssuesContext, ByVal users As IList) + Me.Context = context + Me.Users = users + End Sub + + Public ReadOnly Property Context As IssuesContext + Public ReadOnly Property Users As IList +End Class diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/InstantFeedbackMode.sln b/VB/CodeBehind/EFCore/InstantFeedbackMode/InstantFeedbackMode.sln new file mode 100644 index 0000000..042332f --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/InstantFeedbackMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InstantFeedbackMode", "InstantFeedbackMode.vbproj", "{DBBC813A-ECBC-EDF0-A975-117D229B3BB7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DBBC813A-ECBC-EDF0-A975-117D229B3BB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DBBC813A-ECBC-EDF0-A975-117D229B3BB7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DBBC813A-ECBC-EDF0-A975-117D229B3BB7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DBBC813A-ECBC-EDF0-A975-117D229B3BB7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/InstantFeedbackMode.vbproj b/VB/CodeBehind/EFCore/InstantFeedbackMode/InstantFeedbackMode.vbproj new file mode 100644 index 0000000..587a84a --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/InstantFeedbackMode.vbproj @@ -0,0 +1,257 @@ + + + + Debug + AnyCPU + {DBBC813A-ECBC-EDF0-A975-117D229B3BB7} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/IssueDetailView.xaml b/VB/CodeBehind/EFCore/InstantFeedbackMode/IssueDetailView.xaml new file mode 100644 index 0000000..058337a --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/IssueDetailView.xaml.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/IssueDetailView.xaml.vb new file mode 100644 index 0000000..a9c5107 --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/IssueDetailView.xaml.vb @@ -0,0 +1,3 @@ +Public Class IssueDetailView + +End Class \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/Issue.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/Issue.vb new file mode 100644 index 0000000..b9efd71 --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/Issue.vb @@ -0,0 +1,23 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/IssuesContext.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/IssuesContext.vb new file mode 100644 index 0000000..1312551 --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/IssuesContext.vb @@ -0,0 +1,16 @@ +Imports Microsoft.EntityFrameworkCore + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Private Shared ReadOnly options As DbContextOptions(Of IssuesContext) = New DbContextOptionsBuilder(Of IssuesContext)().UseInMemoryDatabase(databaseName:="Test").Options + + Public Sub New() + MyBase.New(options) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/IssuesContextInitializer.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..9faa303 --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/IssuesContextInitializer.vb @@ -0,0 +1,29 @@ +Imports System +Imports System.Linq + +Namespace Issues + Public Module IssuesContextInitializer + Public Sub Seed() + Dim context = New IssuesContext() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/User.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml b/VB/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml new file mode 100644 index 0000000..33fb7ce --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml.vb new file mode 100644 index 0000000..69c277e --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/MainWindow.xaml.vb @@ -0,0 +1,66 @@ +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports Microsoft.EntityFrameworkCore +Imports EFCoreIssues.Issues +Imports DevExpress.Mvvm.Xpf +Imports System +Imports System.Collections +Class MainWindow + Public Sub New() + InitializeComponent() + Dim source = New DevExpress.Data.Linq.EntityInstantFeedbackSource With { + .KeyExpression = NameOf(Issues.Issue.Id) + } + AddHandler source.GetQueryable, Sub(sender, e) + Dim context = New Issues.IssuesContext() + e.QueryableSource = context.Issues.AsNoTracking() + End Sub + grid.ItemsSource = source + LoadLookupData() + End Sub + + Private Sub LoadLookupData() + Dim context = New EFCoreIssues.Issues.IssuesContext() + usersLookup.ItemsSource = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadLookupData() + End Sub + + Private Sub OnCreateEditEntityViewModel(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs) + Dim context = New IssuesContext() + Dim item As Issue + + If e.Key IsNot Nothing Then + item = context.Issues.Find(e.Key) + Else + item = New Issue() With { + .Created = Date.Now + } + context.Entry(item).State = EntityState.Added + End If + + e.ViewModel = New EditItemViewModel(item, New EditIssueInfo(context, CType(usersLookup.ItemsSource, IList))) + End Sub + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.EditFormRowValidationArgs) + Dim context = CType(e.Tag, EditIssueInfo).Context + context.SaveChanges() + End Sub + + Private Sub OnValidateRowDeletion(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs) + Dim key = CInt(e.Keys.[Single]()) + Dim item = New Issue() With { + .Id = key + } + Dim context = New IssuesContext() + context.Entry(item).State = EntityState.Deleted + context.SaveChanges() + End Sub + +End Class diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/AssemblyInfo.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..8de8923 --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/Resources.Designer.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/Resources.resx b/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/Settings.Designer.vb b/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/Settings.Designer.vb new file mode 100644 index 0000000..4e428d5 --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EFCoreIssues.My.MySettings + Get + Return Global.EFCoreIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/Settings.settings b/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/InstantFeedbackMode/packages.config b/VB/CodeBehind/EFCore/InstantFeedbackMode/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/VB/CodeBehind/EFCore/InstantFeedbackMode/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/LocalData/App.config b/VB/CodeBehind/EFCore/LocalData/App.config new file mode 100644 index 0000000..93bdfd4 --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/App.config @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/LocalData/Application.xaml b/VB/CodeBehind/EFCore/LocalData/Application.xaml new file mode 100644 index 0000000..1d7676b --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/EFCore/LocalData/Application.xaml.vb b/VB/CodeBehind/EFCore/LocalData/Application.xaml.vb new file mode 100644 index 0000000..fc1b49d --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/Application.xaml.vb @@ -0,0 +1,10 @@ +Imports EFCoreIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + IssuesContextInitializer.Seed() + End Sub +End Class diff --git a/VB/CodeBehind/EFCore/LocalData/Issues/Issue.vb b/VB/CodeBehind/EFCore/LocalData/Issues/Issue.vb new file mode 100644 index 0000000..b9efd71 --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/Issues/Issue.vb @@ -0,0 +1,23 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace diff --git a/VB/CodeBehind/EFCore/LocalData/Issues/IssuesContext.vb b/VB/CodeBehind/EFCore/LocalData/Issues/IssuesContext.vb new file mode 100644 index 0000000..1312551 --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/Issues/IssuesContext.vb @@ -0,0 +1,16 @@ +Imports Microsoft.EntityFrameworkCore + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Private Shared ReadOnly options As DbContextOptions(Of IssuesContext) = New DbContextOptionsBuilder(Of IssuesContext)().UseInMemoryDatabase(databaseName:="Test").Options + + Public Sub New() + MyBase.New(options) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace diff --git a/VB/CodeBehind/EFCore/LocalData/Issues/IssuesContextInitializer.vb b/VB/CodeBehind/EFCore/LocalData/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..9faa303 --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/Issues/IssuesContextInitializer.vb @@ -0,0 +1,29 @@ +Imports System +Imports System.Linq + +Namespace Issues + Public Module IssuesContextInitializer + Public Sub Seed() + Dim context = New IssuesContext() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/LocalData/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/EFCore/LocalData/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/LocalData/Issues/User.vb b/VB/CodeBehind/EFCore/LocalData/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/CodeBehind/EFCore/LocalData/LocalData.sln b/VB/CodeBehind/EFCore/LocalData/LocalData.sln new file mode 100644 index 0000000..8851e1e --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/LocalData.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LocalData", "LocalData.vbproj", "{55FE18AD-CB42-5C59-AAF1-434C4EA209EA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {55FE18AD-CB42-5C59-AAF1-434C4EA209EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55FE18AD-CB42-5C59-AAF1-434C4EA209EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55FE18AD-CB42-5C59-AAF1-434C4EA209EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55FE18AD-CB42-5C59-AAF1-434C4EA209EA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/EFCore/LocalData/LocalData.vbproj b/VB/CodeBehind/EFCore/LocalData/LocalData.vbproj new file mode 100644 index 0000000..834aee6 --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/LocalData.vbproj @@ -0,0 +1,248 @@ + + + + Debug + AnyCPU + {55FE18AD-CB42-5C59-AAF1-434C4EA209EA} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/LocalData/MainWindow.xaml b/VB/CodeBehind/EFCore/LocalData/MainWindow.xaml new file mode 100644 index 0000000..4addf92 --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/MainWindow.xaml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/LocalData/MainWindow.xaml.vb b/VB/CodeBehind/EFCore/LocalData/MainWindow.xaml.vb new file mode 100644 index 0000000..ffc89be --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/MainWindow.xaml.vb @@ -0,0 +1,30 @@ +Imports System.Linq +Class MainWindow + Public Sub New() + InitializeComponent() + LoadData() + End Sub + Private _Context As Issues.IssuesContext + + Private Sub LoadData() + _Context = New Issues.IssuesContext() + grid.ItemsSource = _Context.Users.ToList() + End Sub + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridRowValidationEventArgs) + Dim row = CType(e.Row, Issues.User) + If (e.IsNewItem) Then _Context.Users.Add(row) + _Context.SaveChanges() + End Sub + + Private Sub OnValidateRowDeletion(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridDeleteRowsValidationEventArgs) + Dim row = CType(e.Rows.Single(), Issues.User) + _Context.Users.Remove(row) + _Context.SaveChanges() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadData() + End Sub + +End Class diff --git a/VB/CodeBehind/EFCore/LocalData/My Project/AssemblyInfo.vb b/VB/CodeBehind/EFCore/LocalData/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..8de8923 --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/EFCore/LocalData/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/EFCore/LocalData/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/EFCore/LocalData/My Project/Resources.Designer.vb b/VB/CodeBehind/EFCore/LocalData/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/LocalData/My Project/Resources.resx b/VB/CodeBehind/EFCore/LocalData/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/EFCore/LocalData/My Project/Settings.Designer.vb b/VB/CodeBehind/EFCore/LocalData/My Project/Settings.Designer.vb new file mode 100644 index 0000000..4e428d5 --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EFCoreIssues.My.MySettings + Get + Return Global.EFCoreIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/LocalData/My Project/Settings.settings b/VB/CodeBehind/EFCore/LocalData/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/LocalData/packages.config b/VB/CodeBehind/EFCore/LocalData/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/VB/CodeBehind/EFCore/LocalData/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/App.config b/VB/CodeBehind/EFCore/PagedAsyncSource/App.config new file mode 100644 index 0000000..93bdfd4 --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/App.config @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/Application.xaml b/VB/CodeBehind/EFCore/PagedAsyncSource/Application.xaml new file mode 100644 index 0000000..1d7676b --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/Application.xaml.vb b/VB/CodeBehind/EFCore/PagedAsyncSource/Application.xaml.vb new file mode 100644 index 0000000..fc1b49d --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/Application.xaml.vb @@ -0,0 +1,10 @@ +Imports EFCoreIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + IssuesContextInitializer.Seed() + End Sub +End Class diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/Issue.vb b/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/Issue.vb new file mode 100644 index 0000000..b9efd71 --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/Issue.vb @@ -0,0 +1,23 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/IssuesContext.vb b/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/IssuesContext.vb new file mode 100644 index 0000000..1312551 --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/IssuesContext.vb @@ -0,0 +1,16 @@ +Imports Microsoft.EntityFrameworkCore + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Private Shared ReadOnly options As DbContextOptions(Of IssuesContext) = New DbContextOptionsBuilder(Of IssuesContext)().UseInMemoryDatabase(databaseName:="Test").Options + + Public Sub New() + MyBase.New(options) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/IssuesContextInitializer.vb b/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..9faa303 --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/IssuesContextInitializer.vb @@ -0,0 +1,29 @@ +Imports System +Imports System.Linq + +Namespace Issues + Public Module IssuesContextInitializer + Public Sub Seed() + Dim context = New IssuesContext() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/User.vb b/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml b/VB/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..b3c3113 --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml.vb b/VB/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml.vb new file mode 100644 index 0000000..9cbb9bc --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/MainWindow.xaml.vb @@ -0,0 +1,66 @@ +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports Microsoft.EntityFrameworkCore +Class MainWindow + Public Sub New() + InitializeComponent() + Dim source = New PagedAsyncSource With { + .ElementType = GetType(Issues.Issue), + .KeyProperty = NameOf(Issues.Issue.Id), + .PageNavigationMode = PageNavigationMode.ArbitraryWithTotalPageCount + } + AddHandler source.FetchPage, AddressOf OnFetchPage + AddHandler source.GetTotalSummaries, AddressOf OnGetTotalSummaries + grid.ItemsSource = source + LoadLookupData() + End Sub + + Private Sub OnFetchPage(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Data.FetchPageAsyncEventArgs) + Const pageTakeCount As Integer = 5 + e.Result = Task.Run(Of DevExpress.Xpf.Data.FetchRowsResult)(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.AsNoTracking().SortBy(e.SortOrder, defaultUniqueSortPropertyName:=NameOf(Issues.Issue.Id)).Where(MakeFilterExpression(CType(e.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.Skip(e.Skip).Take(e.Take * pageTakeCount).ToArray() + End Function) + End Sub + + Private Sub OnGetTotalSummaries(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Data.GetSummariesAsyncEventArgs) + e.Result = Task.Run(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.Where(MakeFilterExpression(CType(e.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.GetSummaries(e.Summaries) + End Function) + End Sub + + Private Function MakeFilterExpression(ByVal filter As DevExpress.Data.Filtering.CriteriaOperator) As System.Linq.Expressions.Expression(Of System.Func(Of EFCoreIssues.Issues.Issue, Boolean)) + Dim converter = New DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(Of EFCoreIssues.Issues.Issue)() + Return converter.Convert(filter) + End Function + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridRowValidationEventArgs) + + Dim row = CType(e.Row, Issues.Issue) + Dim context = New Issues.IssuesContext() + context.Entry(row).State = If(e.IsNewItem, EntityState.Added, EntityState.Modified) + Try + context.SaveChanges() + Finally + context.Entry(row).State = EntityState.Detached + End Try + + End Sub + + Private Sub LoadLookupData() + Dim context = New EFCoreIssues.Issues.IssuesContext() + usersLookup.ItemsSource = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadLookupData() + End Sub + +End Class diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/AssemblyInfo.vb b/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..8de8923 --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/Resources.Designer.vb b/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/Resources.resx b/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/Settings.Designer.vb b/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/Settings.Designer.vb new file mode 100644 index 0000000..4e428d5 --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EFCoreIssues.My.MySettings + Get + Return Global.EFCoreIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/Settings.settings b/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/PagedAsyncSource.sln b/VB/CodeBehind/EFCore/PagedAsyncSource/PagedAsyncSource.sln new file mode 100644 index 0000000..ae7caac --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/PagedAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PagedAsyncSource", "PagedAsyncSource.vbproj", "{BB2EED29-11AE-91F8-6518-D3012B0B0E98}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BB2EED29-11AE-91F8-6518-D3012B0B0E98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB2EED29-11AE-91F8-6518-D3012B0B0E98}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB2EED29-11AE-91F8-6518-D3012B0B0E98}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB2EED29-11AE-91F8-6518-D3012B0B0E98}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/PagedAsyncSource.vbproj b/VB/CodeBehind/EFCore/PagedAsyncSource/PagedAsyncSource.vbproj new file mode 100644 index 0000000..a4b973d --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/PagedAsyncSource.vbproj @@ -0,0 +1,248 @@ + + + + Debug + AnyCPU + {BB2EED29-11AE-91F8-6518-D3012B0B0E98} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/PagedAsyncSource/packages.config b/VB/CodeBehind/EFCore/PagedAsyncSource/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/VB/CodeBehind/EFCore/PagedAsyncSource/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/ServerMode/App.config b/VB/CodeBehind/EFCore/ServerMode/App.config new file mode 100644 index 0000000..93bdfd4 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/App.config @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/ServerMode/Application.xaml b/VB/CodeBehind/EFCore/ServerMode/Application.xaml new file mode 100644 index 0000000..1d7676b --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/EFCore/ServerMode/Application.xaml.vb b/VB/CodeBehind/EFCore/ServerMode/Application.xaml.vb new file mode 100644 index 0000000..fc1b49d --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/Application.xaml.vb @@ -0,0 +1,10 @@ +Imports EFCoreIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + IssuesContextInitializer.Seed() + End Sub +End Class diff --git a/VB/CodeBehind/EFCore/ServerMode/EditIssueInfo.vb b/VB/CodeBehind/EFCore/ServerMode/EditIssueInfo.vb new file mode 100644 index 0000000..5ed81d2 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/EditIssueInfo.vb @@ -0,0 +1,15 @@ +Imports DevExpress.Mvvm +Imports System.Collections.Generic +Imports EFCoreIssues.Issues + +Public Class EditIssueInfo + Inherits BindableBase + + Public Sub New(ByVal context As IssuesContext, ByVal users As IList) + Me.Context = context + Me.Users = users + End Sub + + Public ReadOnly Property Context As IssuesContext + Public ReadOnly Property Users As IList +End Class diff --git a/VB/CodeBehind/EFCore/ServerMode/IssueDetailView.xaml b/VB/CodeBehind/EFCore/ServerMode/IssueDetailView.xaml new file mode 100644 index 0000000..058337a --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/ServerMode/IssueDetailView.xaml.vb b/VB/CodeBehind/EFCore/ServerMode/IssueDetailView.xaml.vb new file mode 100644 index 0000000..a9c5107 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/IssueDetailView.xaml.vb @@ -0,0 +1,3 @@ +Public Class IssueDetailView + +End Class \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/ServerMode/Issues/Issue.vb b/VB/CodeBehind/EFCore/ServerMode/Issues/Issue.vb new file mode 100644 index 0000000..b9efd71 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/Issues/Issue.vb @@ -0,0 +1,23 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace diff --git a/VB/CodeBehind/EFCore/ServerMode/Issues/IssuesContext.vb b/VB/CodeBehind/EFCore/ServerMode/Issues/IssuesContext.vb new file mode 100644 index 0000000..1312551 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/Issues/IssuesContext.vb @@ -0,0 +1,16 @@ +Imports Microsoft.EntityFrameworkCore + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Private Shared ReadOnly options As DbContextOptions(Of IssuesContext) = New DbContextOptionsBuilder(Of IssuesContext)().UseInMemoryDatabase(databaseName:="Test").Options + + Public Sub New() + MyBase.New(options) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace diff --git a/VB/CodeBehind/EFCore/ServerMode/Issues/IssuesContextInitializer.vb b/VB/CodeBehind/EFCore/ServerMode/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..9faa303 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/Issues/IssuesContextInitializer.vb @@ -0,0 +1,29 @@ +Imports System +Imports System.Linq + +Namespace Issues + Public Module IssuesContextInitializer + Public Sub Seed() + Dim context = New IssuesContext() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/ServerMode/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/EFCore/ServerMode/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/ServerMode/Issues/User.vb b/VB/CodeBehind/EFCore/ServerMode/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/CodeBehind/EFCore/ServerMode/MainWindow.xaml b/VB/CodeBehind/EFCore/ServerMode/MainWindow.xaml new file mode 100644 index 0000000..33fb7ce --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/ServerMode/MainWindow.xaml.vb b/VB/CodeBehind/EFCore/ServerMode/MainWindow.xaml.vb new file mode 100644 index 0000000..9a4b892 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/MainWindow.xaml.vb @@ -0,0 +1,64 @@ +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports Microsoft.EntityFrameworkCore +Imports EFCoreIssues.Issues +Imports DevExpress.Mvvm.Xpf +Imports System +Imports System.Collections +Class MainWindow + Public Sub New() + InitializeComponent() + Dim context = New Issues.IssuesContext() + Dim source = New DevExpress.Data.Linq.EntityServerModeSource With { + .KeyExpression = NameOf(Issues.Issue.Id), + .QueryableSource = context.Issues.AsNoTracking() + } + grid.ItemsSource = source + LoadLookupData() + End Sub + + Private Sub LoadLookupData() + Dim context = New EFCoreIssues.Issues.IssuesContext() + usersLookup.ItemsSource = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadLookupData() + End Sub + + Private Sub OnCreateEditEntityViewModel(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs) + Dim context = New IssuesContext() + Dim item As Issue + + If e.Key IsNot Nothing Then + item = context.Issues.Find(e.Key) + Else + item = New Issue() With { + .Created = Date.Now + } + context.Entry(item).State = EntityState.Added + End If + + e.ViewModel = New EditItemViewModel(item, New EditIssueInfo(context, CType(usersLookup.ItemsSource, IList))) + End Sub + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.EditFormRowValidationArgs) + Dim context = CType(e.Tag, EditIssueInfo).Context + context.SaveChanges() + End Sub + + Private Sub OnValidateRowDeletion(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs) + Dim key = CInt(e.Keys.[Single]()) + Dim item = New Issue() With { + .Id = key + } + Dim context = New IssuesContext() + context.Entry(item).State = EntityState.Deleted + context.SaveChanges() + End Sub + +End Class diff --git a/VB/CodeBehind/EFCore/ServerMode/My Project/AssemblyInfo.vb b/VB/CodeBehind/EFCore/ServerMode/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..8de8923 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/EFCore/ServerMode/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/EFCore/ServerMode/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/EFCore/ServerMode/My Project/Resources.Designer.vb b/VB/CodeBehind/EFCore/ServerMode/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/ServerMode/My Project/Resources.resx b/VB/CodeBehind/EFCore/ServerMode/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/EFCore/ServerMode/My Project/Settings.Designer.vb b/VB/CodeBehind/EFCore/ServerMode/My Project/Settings.Designer.vb new file mode 100644 index 0000000..4e428d5 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EFCoreIssues.My.MySettings + Get + Return Global.EFCoreIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EFCore/ServerMode/My Project/Settings.settings b/VB/CodeBehind/EFCore/ServerMode/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/ServerMode/ServerMode.sln b/VB/CodeBehind/EFCore/ServerMode/ServerMode.sln new file mode 100644 index 0000000..6b2e02f --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/ServerMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServerMode", "ServerMode.vbproj", "{C7EE8E1C-0A16-F4A1-04A9-67716C9801FE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C7EE8E1C-0A16-F4A1-04A9-67716C9801FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C7EE8E1C-0A16-F4A1-04A9-67716C9801FE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C7EE8E1C-0A16-F4A1-04A9-67716C9801FE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C7EE8E1C-0A16-F4A1-04A9-67716C9801FE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/EFCore/ServerMode/ServerMode.vbproj b/VB/CodeBehind/EFCore/ServerMode/ServerMode.vbproj new file mode 100644 index 0000000..024b1c2 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/ServerMode.vbproj @@ -0,0 +1,257 @@ + + + + Debug + AnyCPU + {C7EE8E1C-0A16-F4A1-04A9-67716C9801FE} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EFCore/ServerMode/packages.config b/VB/CodeBehind/EFCore/ServerMode/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/VB/CodeBehind/EFCore/ServerMode/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/App.config b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Application.xaml b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Application.xaml new file mode 100644 index 0000000..f3c3806 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Application.xaml.vb b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Application.xaml.vb new file mode 100644 index 0000000..883334e --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Application.xaml.vb @@ -0,0 +1,8 @@ +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory() + End Sub +End Class diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.sln b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.sln new file mode 100644 index 0000000..e839c56 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InfiniteAsyncSource", "InfiniteAsyncSource.vbproj", "{BEF0CF9C-FF62-0794-C130-2A0DCCA738A5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BEF0CF9C-FF62-0794-C130-2A0DCCA738A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BEF0CF9C-FF62-0794-C130-2A0DCCA738A5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BEF0CF9C-FF62-0794-C130-2A0DCCA738A5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BEF0CF9C-FF62-0794-C130-2A0DCCA738A5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {69989B09-7F8A-4739-93FF-D5AFD599722B} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.vbproj b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.vbproj new file mode 100644 index 0000000..3fbba99 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.vbproj @@ -0,0 +1,192 @@ + + + + + Debug + AnyCPU + {BEF0CF9C-FF62-0794-C130-2A0DCCA738A5} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + Custom + true + true + + + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/Issue.vb b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/Issue.vb new file mode 100644 index 0000000..38f19e4 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/Issue.vb @@ -0,0 +1,24 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/IssuesContext.vb b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/IssuesContext.vb new file mode 100644 index 0000000..67359c4 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/IssuesContext.vb @@ -0,0 +1,24 @@ +Imports System.Data.Entity + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Shared Sub New() + Database.SetInitializer(New IssuesContextInitializer()) + End Sub + + Public Sub New() + End Sub + + Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder) + MyBase.OnModelCreating(modelBuilder) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Created) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Votes) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/IssuesContextInitializer.vb b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..0a19474 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/IssuesContextInitializer.vb @@ -0,0 +1,47 @@ +Imports System +Imports System.Data.Entity +Imports System.Linq + +Namespace Issues + Public Class IssuesContextInitializer + Inherits DropCreateDatabaseIfModelChanges(Of IssuesContext) + + ': DropCreateDatabaseAlways { + + Public Shared Sub ResetData() + Using context = New IssuesContext() + context.Users.Load() + context.Users.RemoveRange(context.Users) + context.SaveChanges() + CreateData(context) + End Using + End Sub + + Protected Overrides Sub Seed(ByVal context As IssuesContext) + MyBase.Seed(context) + CreateData(context) + End Sub + + Private Shared Sub CreateData(ByVal context As IssuesContext) + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Class +End Namespace diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/User.vb b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..b732ad1 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.vb b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.vb new file mode 100644 index 0000000..d512564 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.vb @@ -0,0 +1,71 @@ +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports System.Data.Entity +Class MainWindow + Public Sub New() + InitializeComponent() + Dim source = New InfiniteAsyncSource With { + .ElementType = GetType(Issues.Issue), + .KeyProperty = NameOf(Issues.Issue.Id) + } + AddHandler source.FetchRows, AddressOf OnFetchRows + AddHandler source.GetTotalSummaries, AddressOf OnGetTotalSummaries + grid.ItemsSource = source + LoadLookupData() + End Sub + + Private Sub OnFetchRows(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Data.FetchRowsAsyncEventArgs) + e.Result = Task.Run(Of DevExpress.Xpf.Data.FetchRowsResult)(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.AsNoTracking().SortBy(e.SortOrder, defaultUniqueSortPropertyName:=NameOf(Issues.Issue.Id)).Where(MakeFilterExpression(e.Filter)) + Return queryable.Skip(e.Skip).Take(If(e.Take, 100)).ToArray() + End Function) + End Sub + + Private Sub OnGetTotalSummaries(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Data.GetSummariesAsyncEventArgs) + e.Result = Task.Run(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.Where(MakeFilterExpression(CType(e.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.GetSummaries(e.Summaries) + End Function) + End Sub + + Private Function MakeFilterExpression(ByVal filter As DevExpress.Data.Filtering.CriteriaOperator) As System.Linq.Expressions.Expression(Of System.Func(Of EntityFrameworkIssues.Issues.Issue, Boolean)) + Dim converter = New DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(Of EntityFrameworkIssues.Issues.Issue)() + Return converter.Convert(filter) + End Function + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridRowValidationEventArgs) + + Dim row = CType(e.Row, Issues.Issue) + Dim context = New Issues.IssuesContext() + context.Entry(row).State = If(e.IsNewItem, EntityState.Added, EntityState.Modified) + Try + context.SaveChanges() + Finally + context.Entry(row).State = EntityState.Detached + End Try + + End Sub + + Private Sub OnValidateRowDeletion(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridDeleteRowsValidationEventArgs) + Dim row = CType(e.Rows.Single(), Issues.Issue) + Dim context = New Issues.IssuesContext() + context.Entry(row).State = EntityState.Deleted + context.SaveChanges() + End Sub + + Private Sub LoadLookupData() + Dim context = New EntityFrameworkIssues.Issues.IssuesContext() + usersLookup.ItemsSource = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadLookupData() + End Sub + +End Class diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/AssemblyInfo.vb b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e276f20 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/Resources.Designer.vb b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/Resources.resx b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/Settings.Designer.vb b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/Settings.Designer.vb new file mode 100644 index 0000000..dbfe735 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EntityFrameworkIssues.My.MySettings + Get + Return Global.EntityFrameworkIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/Settings.settings b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/packages.config b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InfiniteAsyncSource/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/App.config b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Application.xaml b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Application.xaml new file mode 100644 index 0000000..f3c3806 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Application.xaml.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Application.xaml.vb new file mode 100644 index 0000000..883334e --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Application.xaml.vb @@ -0,0 +1,8 @@ +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory() + End Sub +End Class diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/EditIssueInfo.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/EditIssueInfo.vb new file mode 100644 index 0000000..c0e5f5f --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/EditIssueInfo.vb @@ -0,0 +1,15 @@ +Imports DevExpress.Mvvm +Imports System.Collections.Generic +Imports EntityFrameworkIssues.Issues + +Public Class EditIssueInfo + Inherits BindableBase + + Public Sub New(ByVal context As IssuesContext, ByVal users As IList) + Me.Context = context + Me.Users = users + End Sub + + Public ReadOnly Property Context As IssuesContext + Public ReadOnly Property Users As IList +End Class diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.sln b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.sln new file mode 100644 index 0000000..0373fd8 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InstantFeedbackMode", "InstantFeedbackMode.vbproj", "{4E3E7E7C-930D-23F6-59AF-8587ACE8E7DE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4E3E7E7C-930D-23F6-59AF-8587ACE8E7DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E3E7E7C-930D-23F6-59AF-8587ACE8E7DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E3E7E7C-930D-23F6-59AF-8587ACE8E7DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4E3E7E7C-930D-23F6-59AF-8587ACE8E7DE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {69989B09-7F8A-4739-93FF-D5AFD599722B} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.vbproj b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.vbproj new file mode 100644 index 0000000..9c14121 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.vbproj @@ -0,0 +1,201 @@ + + + + + Debug + AnyCPU + {4E3E7E7C-930D-23F6-59AF-8587ACE8E7DE} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + Custom + true + true + + + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml new file mode 100644 index 0000000..7bdbd7a --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml.vb new file mode 100644 index 0000000..a9c5107 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml.vb @@ -0,0 +1,3 @@ +Public Class IssueDetailView + +End Class \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/Issue.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/Issue.vb new file mode 100644 index 0000000..38f19e4 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/Issue.vb @@ -0,0 +1,24 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/IssuesContext.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/IssuesContext.vb new file mode 100644 index 0000000..67359c4 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/IssuesContext.vb @@ -0,0 +1,24 @@ +Imports System.Data.Entity + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Shared Sub New() + Database.SetInitializer(New IssuesContextInitializer()) + End Sub + + Public Sub New() + End Sub + + Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder) + MyBase.OnModelCreating(modelBuilder) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Created) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Votes) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/IssuesContextInitializer.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..0a19474 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/IssuesContextInitializer.vb @@ -0,0 +1,47 @@ +Imports System +Imports System.Data.Entity +Imports System.Linq + +Namespace Issues + Public Class IssuesContextInitializer + Inherits DropCreateDatabaseIfModelChanges(Of IssuesContext) + + ': DropCreateDatabaseAlways { + + Public Shared Sub ResetData() + Using context = New IssuesContext() + context.Users.Load() + context.Users.RemoveRange(context.Users) + context.SaveChanges() + CreateData(context) + End Using + End Sub + + Protected Overrides Sub Seed(ByVal context As IssuesContext) + MyBase.Seed(context) + CreateData(context) + End Sub + + Private Shared Sub CreateData(ByVal context As IssuesContext) + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Class +End Namespace diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/User.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml new file mode 100644 index 0000000..ed56284 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml.vb new file mode 100644 index 0000000..64ccaa6 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/MainWindow.xaml.vb @@ -0,0 +1,66 @@ +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports System.Data.Entity +Imports EntityFrameworkIssues.Issues +Imports DevExpress.Mvvm.Xpf +Imports System +Imports System.Collections +Class MainWindow + Public Sub New() + InitializeComponent() + Dim source = New DevExpress.Data.Linq.EntityInstantFeedbackSource With { + .KeyExpression = NameOf(Issues.Issue.Id) + } + AddHandler source.GetQueryable, Sub(sender, e) + Dim context = New Issues.IssuesContext() + e.QueryableSource = context.Issues.AsNoTracking() + End Sub + grid.ItemsSource = source + LoadLookupData() + End Sub + + Private Sub LoadLookupData() + Dim context = New EntityFrameworkIssues.Issues.IssuesContext() + usersLookup.ItemsSource = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadLookupData() + End Sub + + Private Sub OnCreateEditEntityViewModel(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs) + Dim context = New IssuesContext() + Dim item As Issue + + If e.Key IsNot Nothing Then + item = context.Issues.Find(e.Key) + Else + item = New Issue() With { + .Created = Date.Now + } + context.Entry(item).State = EntityState.Added + End If + + e.ViewModel = New EditItemViewModel(item, New EditIssueInfo(context, CType(usersLookup.ItemsSource, IList))) + End Sub + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.EditFormRowValidationArgs) + Dim context = CType(e.Tag, EditIssueInfo).Context + context.SaveChanges() + End Sub + + Private Sub OnValidateRowDeletion(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs) + Dim key = CInt(e.Keys.[Single]()) + Dim item = New Issue() With { + .Id = key + } + Dim context = New IssuesContext() + context.Entry(item).State = EntityState.Deleted + context.SaveChanges() + End Sub + +End Class diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/AssemblyInfo.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e276f20 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/Resources.Designer.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/Resources.resx b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/Settings.Designer.vb b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/Settings.Designer.vb new file mode 100644 index 0000000..dbfe735 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EntityFrameworkIssues.My.MySettings + Get + Return Global.EntityFrameworkIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/Settings.settings b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/InstantFeedbackMode/packages.config b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/InstantFeedbackMode/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/LocalData/App.config b/VB/CodeBehind/EntityFramework/LocalData/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/LocalData/Application.xaml b/VB/CodeBehind/EntityFramework/LocalData/Application.xaml new file mode 100644 index 0000000..f3c3806 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/EntityFramework/LocalData/Application.xaml.vb b/VB/CodeBehind/EntityFramework/LocalData/Application.xaml.vb new file mode 100644 index 0000000..883334e --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/Application.xaml.vb @@ -0,0 +1,8 @@ +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory() + End Sub +End Class diff --git a/VB/CodeBehind/EntityFramework/LocalData/Issues/Issue.vb b/VB/CodeBehind/EntityFramework/LocalData/Issues/Issue.vb new file mode 100644 index 0000000..38f19e4 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/Issues/Issue.vb @@ -0,0 +1,24 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/LocalData/Issues/IssuesContext.vb b/VB/CodeBehind/EntityFramework/LocalData/Issues/IssuesContext.vb new file mode 100644 index 0000000..67359c4 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/Issues/IssuesContext.vb @@ -0,0 +1,24 @@ +Imports System.Data.Entity + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Shared Sub New() + Database.SetInitializer(New IssuesContextInitializer()) + End Sub + + Public Sub New() + End Sub + + Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder) + MyBase.OnModelCreating(modelBuilder) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Created) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Votes) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/LocalData/Issues/IssuesContextInitializer.vb b/VB/CodeBehind/EntityFramework/LocalData/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..0a19474 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/Issues/IssuesContextInitializer.vb @@ -0,0 +1,47 @@ +Imports System +Imports System.Data.Entity +Imports System.Linq + +Namespace Issues + Public Class IssuesContextInitializer + Inherits DropCreateDatabaseIfModelChanges(Of IssuesContext) + + ': DropCreateDatabaseAlways { + + Public Shared Sub ResetData() + Using context = New IssuesContext() + context.Users.Load() + context.Users.RemoveRange(context.Users) + context.SaveChanges() + CreateData(context) + End Using + End Sub + + Protected Overrides Sub Seed(ByVal context As IssuesContext) + MyBase.Seed(context) + CreateData(context) + End Sub + + Private Shared Sub CreateData(ByVal context As IssuesContext) + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Class +End Namespace diff --git a/VB/CodeBehind/EntityFramework/LocalData/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/EntityFramework/LocalData/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/LocalData/Issues/User.vb b/VB/CodeBehind/EntityFramework/LocalData/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/LocalData/LocalData.sln b/VB/CodeBehind/EntityFramework/LocalData/LocalData.sln new file mode 100644 index 0000000..a86edbd --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/LocalData.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LocalData", "LocalData.vbproj", "{8D79528C-21EE-4DA4-2C27-5550876A39B6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8D79528C-21EE-4DA4-2C27-5550876A39B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D79528C-21EE-4DA4-2C27-5550876A39B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D79528C-21EE-4DA4-2C27-5550876A39B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D79528C-21EE-4DA4-2C27-5550876A39B6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {69989B09-7F8A-4739-93FF-D5AFD599722B} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/EntityFramework/LocalData/LocalData.vbproj b/VB/CodeBehind/EntityFramework/LocalData/LocalData.vbproj new file mode 100644 index 0000000..939a86b --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/LocalData.vbproj @@ -0,0 +1,192 @@ + + + + + Debug + AnyCPU + {8D79528C-21EE-4DA4-2C27-5550876A39B6} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + Custom + true + true + + + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/LocalData/MainWindow.xaml b/VB/CodeBehind/EntityFramework/LocalData/MainWindow.xaml new file mode 100644 index 0000000..e84cf10 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/MainWindow.xaml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/LocalData/MainWindow.xaml.vb b/VB/CodeBehind/EntityFramework/LocalData/MainWindow.xaml.vb new file mode 100644 index 0000000..ffc89be --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/MainWindow.xaml.vb @@ -0,0 +1,30 @@ +Imports System.Linq +Class MainWindow + Public Sub New() + InitializeComponent() + LoadData() + End Sub + Private _Context As Issues.IssuesContext + + Private Sub LoadData() + _Context = New Issues.IssuesContext() + grid.ItemsSource = _Context.Users.ToList() + End Sub + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridRowValidationEventArgs) + Dim row = CType(e.Row, Issues.User) + If (e.IsNewItem) Then _Context.Users.Add(row) + _Context.SaveChanges() + End Sub + + Private Sub OnValidateRowDeletion(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridDeleteRowsValidationEventArgs) + Dim row = CType(e.Rows.Single(), Issues.User) + _Context.Users.Remove(row) + _Context.SaveChanges() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadData() + End Sub + +End Class diff --git a/VB/CodeBehind/EntityFramework/LocalData/My Project/AssemblyInfo.vb b/VB/CodeBehind/EntityFramework/LocalData/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e276f20 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/EntityFramework/LocalData/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/EntityFramework/LocalData/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/EntityFramework/LocalData/My Project/Resources.Designer.vb b/VB/CodeBehind/EntityFramework/LocalData/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/LocalData/My Project/Resources.resx b/VB/CodeBehind/EntityFramework/LocalData/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/EntityFramework/LocalData/My Project/Settings.Designer.vb b/VB/CodeBehind/EntityFramework/LocalData/My Project/Settings.Designer.vb new file mode 100644 index 0000000..dbfe735 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EntityFrameworkIssues.My.MySettings + Get + Return Global.EntityFrameworkIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/LocalData/My Project/Settings.settings b/VB/CodeBehind/EntityFramework/LocalData/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/LocalData/packages.config b/VB/CodeBehind/EntityFramework/LocalData/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/LocalData/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/App.config b/VB/CodeBehind/EntityFramework/PagedAsyncSource/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/Application.xaml b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Application.xaml new file mode 100644 index 0000000..f3c3806 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/Application.xaml.vb b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Application.xaml.vb new file mode 100644 index 0000000..883334e --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Application.xaml.vb @@ -0,0 +1,8 @@ +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory() + End Sub +End Class diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/Issue.vb b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/Issue.vb new file mode 100644 index 0000000..38f19e4 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/Issue.vb @@ -0,0 +1,24 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/IssuesContext.vb b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/IssuesContext.vb new file mode 100644 index 0000000..67359c4 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/IssuesContext.vb @@ -0,0 +1,24 @@ +Imports System.Data.Entity + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Shared Sub New() + Database.SetInitializer(New IssuesContextInitializer()) + End Sub + + Public Sub New() + End Sub + + Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder) + MyBase.OnModelCreating(modelBuilder) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Created) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Votes) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/IssuesContextInitializer.vb b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..0a19474 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/IssuesContextInitializer.vb @@ -0,0 +1,47 @@ +Imports System +Imports System.Data.Entity +Imports System.Linq + +Namespace Issues + Public Class IssuesContextInitializer + Inherits DropCreateDatabaseIfModelChanges(Of IssuesContext) + + ': DropCreateDatabaseAlways { + + Public Shared Sub ResetData() + Using context = New IssuesContext() + context.Users.Load() + context.Users.RemoveRange(context.Users) + context.SaveChanges() + CreateData(context) + End Using + End Sub + + Protected Overrides Sub Seed(ByVal context As IssuesContext) + MyBase.Seed(context) + CreateData(context) + End Sub + + Private Shared Sub CreateData(ByVal context As IssuesContext) + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Class +End Namespace diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/User.vb b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml b/VB/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..58027e0 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml.vb b/VB/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml.vb new file mode 100644 index 0000000..51a35e6 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/MainWindow.xaml.vb @@ -0,0 +1,66 @@ +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports System.Data.Entity +Class MainWindow + Public Sub New() + InitializeComponent() + Dim source = New PagedAsyncSource With { + .ElementType = GetType(Issues.Issue), + .KeyProperty = NameOf(Issues.Issue.Id), + .PageNavigationMode = PageNavigationMode.ArbitraryWithTotalPageCount + } + AddHandler source.FetchPage, AddressOf OnFetchPage + AddHandler source.GetTotalSummaries, AddressOf OnGetTotalSummaries + grid.ItemsSource = source + LoadLookupData() + End Sub + + Private Sub OnFetchPage(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Data.FetchPageAsyncEventArgs) + Const pageTakeCount As Integer = 5 + e.Result = Task.Run(Of DevExpress.Xpf.Data.FetchRowsResult)(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.AsNoTracking().SortBy(e.SortOrder, defaultUniqueSortPropertyName:=NameOf(Issues.Issue.Id)).Where(MakeFilterExpression(CType(e.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.Skip(e.Skip).Take(e.Take * pageTakeCount).ToArray() + End Function) + End Sub + + Private Sub OnGetTotalSummaries(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Data.GetSummariesAsyncEventArgs) + e.Result = Task.Run(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.Where(MakeFilterExpression(CType(e.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.GetSummaries(e.Summaries) + End Function) + End Sub + + Private Function MakeFilterExpression(ByVal filter As DevExpress.Data.Filtering.CriteriaOperator) As System.Linq.Expressions.Expression(Of System.Func(Of EntityFrameworkIssues.Issues.Issue, Boolean)) + Dim converter = New DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(Of EntityFrameworkIssues.Issues.Issue)() + Return converter.Convert(filter) + End Function + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridRowValidationEventArgs) + + Dim row = CType(e.Row, Issues.Issue) + Dim context = New Issues.IssuesContext() + context.Entry(row).State = If(e.IsNewItem, EntityState.Added, EntityState.Modified) + Try + context.SaveChanges() + Finally + context.Entry(row).State = EntityState.Detached + End Try + + End Sub + + Private Sub LoadLookupData() + Dim context = New EntityFrameworkIssues.Issues.IssuesContext() + usersLookup.ItemsSource = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadLookupData() + End Sub + +End Class diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/AssemblyInfo.vb b/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e276f20 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/Resources.Designer.vb b/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/Resources.resx b/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/Settings.Designer.vb b/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/Settings.Designer.vb new file mode 100644 index 0000000..dbfe735 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EntityFrameworkIssues.My.MySettings + Get + Return Global.EntityFrameworkIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/Settings.settings b/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/PagedAsyncSource.sln b/VB/CodeBehind/EntityFramework/PagedAsyncSource/PagedAsyncSource.sln new file mode 100644 index 0000000..ef834f3 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/PagedAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PagedAsyncSource", "PagedAsyncSource.vbproj", "{8B0A8DC8-777C-71D7-6446-02679BF6B155}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8B0A8DC8-777C-71D7-6446-02679BF6B155}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8B0A8DC8-777C-71D7-6446-02679BF6B155}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8B0A8DC8-777C-71D7-6446-02679BF6B155}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8B0A8DC8-777C-71D7-6446-02679BF6B155}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {69989B09-7F8A-4739-93FF-D5AFD599722B} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/PagedAsyncSource.vbproj b/VB/CodeBehind/EntityFramework/PagedAsyncSource/PagedAsyncSource.vbproj new file mode 100644 index 0000000..b453f04 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/PagedAsyncSource.vbproj @@ -0,0 +1,192 @@ + + + + + Debug + AnyCPU + {8B0A8DC8-777C-71D7-6446-02679BF6B155} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + Custom + true + true + + + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/PagedAsyncSource/packages.config b/VB/CodeBehind/EntityFramework/PagedAsyncSource/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/PagedAsyncSource/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/ServerMode/App.config b/VB/CodeBehind/EntityFramework/ServerMode/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/ServerMode/Application.xaml b/VB/CodeBehind/EntityFramework/ServerMode/Application.xaml new file mode 100644 index 0000000..f3c3806 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/EntityFramework/ServerMode/Application.xaml.vb b/VB/CodeBehind/EntityFramework/ServerMode/Application.xaml.vb new file mode 100644 index 0000000..883334e --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/Application.xaml.vb @@ -0,0 +1,8 @@ +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory() + End Sub +End Class diff --git a/VB/CodeBehind/EntityFramework/ServerMode/EditIssueInfo.vb b/VB/CodeBehind/EntityFramework/ServerMode/EditIssueInfo.vb new file mode 100644 index 0000000..c0e5f5f --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/EditIssueInfo.vb @@ -0,0 +1,15 @@ +Imports DevExpress.Mvvm +Imports System.Collections.Generic +Imports EntityFrameworkIssues.Issues + +Public Class EditIssueInfo + Inherits BindableBase + + Public Sub New(ByVal context As IssuesContext, ByVal users As IList) + Me.Context = context + Me.Users = users + End Sub + + Public ReadOnly Property Context As IssuesContext + Public ReadOnly Property Users As IList +End Class diff --git a/VB/CodeBehind/EntityFramework/ServerMode/IssueDetailView.xaml b/VB/CodeBehind/EntityFramework/ServerMode/IssueDetailView.xaml new file mode 100644 index 0000000..7bdbd7a --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/ServerMode/IssueDetailView.xaml.vb b/VB/CodeBehind/EntityFramework/ServerMode/IssueDetailView.xaml.vb new file mode 100644 index 0000000..a9c5107 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/IssueDetailView.xaml.vb @@ -0,0 +1,3 @@ +Public Class IssueDetailView + +End Class \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/ServerMode/Issues/Issue.vb b/VB/CodeBehind/EntityFramework/ServerMode/Issues/Issue.vb new file mode 100644 index 0000000..38f19e4 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/Issues/Issue.vb @@ -0,0 +1,24 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/ServerMode/Issues/IssuesContext.vb b/VB/CodeBehind/EntityFramework/ServerMode/Issues/IssuesContext.vb new file mode 100644 index 0000000..67359c4 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/Issues/IssuesContext.vb @@ -0,0 +1,24 @@ +Imports System.Data.Entity + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Shared Sub New() + Database.SetInitializer(New IssuesContextInitializer()) + End Sub + + Public Sub New() + End Sub + + Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder) + MyBase.OnModelCreating(modelBuilder) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Created) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Votes) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/ServerMode/Issues/IssuesContextInitializer.vb b/VB/CodeBehind/EntityFramework/ServerMode/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..0a19474 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/Issues/IssuesContextInitializer.vb @@ -0,0 +1,47 @@ +Imports System +Imports System.Data.Entity +Imports System.Linq + +Namespace Issues + Public Class IssuesContextInitializer + Inherits DropCreateDatabaseIfModelChanges(Of IssuesContext) + + ': DropCreateDatabaseAlways { + + Public Shared Sub ResetData() + Using context = New IssuesContext() + context.Users.Load() + context.Users.RemoveRange(context.Users) + context.SaveChanges() + CreateData(context) + End Using + End Sub + + Protected Overrides Sub Seed(ByVal context As IssuesContext) + MyBase.Seed(context) + CreateData(context) + End Sub + + Private Shared Sub CreateData(ByVal context As IssuesContext) + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Class +End Namespace diff --git a/VB/CodeBehind/EntityFramework/ServerMode/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/EntityFramework/ServerMode/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/ServerMode/Issues/User.vb b/VB/CodeBehind/EntityFramework/ServerMode/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml b/VB/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml new file mode 100644 index 0000000..ed56284 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml.vb b/VB/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml.vb new file mode 100644 index 0000000..a3a7766 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/MainWindow.xaml.vb @@ -0,0 +1,64 @@ +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports System.Data.Entity +Imports EntityFrameworkIssues.Issues +Imports DevExpress.Mvvm.Xpf +Imports System +Imports System.Collections +Class MainWindow + Public Sub New() + InitializeComponent() + Dim context = New Issues.IssuesContext() + Dim source = New DevExpress.Data.Linq.EntityServerModeSource With { + .KeyExpression = NameOf(Issues.Issue.Id), + .QueryableSource = context.Issues.AsNoTracking() + } + grid.ItemsSource = source + LoadLookupData() + End Sub + + Private Sub LoadLookupData() + Dim context = New EntityFrameworkIssues.Issues.IssuesContext() + usersLookup.ItemsSource = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadLookupData() + End Sub + + Private Sub OnCreateEditEntityViewModel(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs) + Dim context = New IssuesContext() + Dim item As Issue + + If e.Key IsNot Nothing Then + item = context.Issues.Find(e.Key) + Else + item = New Issue() With { + .Created = Date.Now + } + context.Entry(item).State = EntityState.Added + End If + + e.ViewModel = New EditItemViewModel(item, New EditIssueInfo(context, CType(usersLookup.ItemsSource, IList))) + End Sub + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.EditFormRowValidationArgs) + Dim context = CType(e.Tag, EditIssueInfo).Context + context.SaveChanges() + End Sub + + Private Sub OnValidateRowDeletion(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs) + Dim key = CInt(e.Keys.[Single]()) + Dim item = New Issue() With { + .Id = key + } + Dim context = New IssuesContext() + context.Entry(item).State = EntityState.Deleted + context.SaveChanges() + End Sub + +End Class diff --git a/VB/CodeBehind/EntityFramework/ServerMode/My Project/AssemblyInfo.vb b/VB/CodeBehind/EntityFramework/ServerMode/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e276f20 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/EntityFramework/ServerMode/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/EntityFramework/ServerMode/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/EntityFramework/ServerMode/My Project/Resources.Designer.vb b/VB/CodeBehind/EntityFramework/ServerMode/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/ServerMode/My Project/Resources.resx b/VB/CodeBehind/EntityFramework/ServerMode/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/EntityFramework/ServerMode/My Project/Settings.Designer.vb b/VB/CodeBehind/EntityFramework/ServerMode/My Project/Settings.Designer.vb new file mode 100644 index 0000000..dbfe735 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EntityFrameworkIssues.My.MySettings + Get + Return Global.EntityFrameworkIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/EntityFramework/ServerMode/My Project/Settings.settings b/VB/CodeBehind/EntityFramework/ServerMode/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/ServerMode/ServerMode.sln b/VB/CodeBehind/EntityFramework/ServerMode/ServerMode.sln new file mode 100644 index 0000000..1104901 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/ServerMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServerMode", "ServerMode.vbproj", "{147009A6-9D5E-2A51-6623-5714C57A0F25}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {147009A6-9D5E-2A51-6623-5714C57A0F25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {147009A6-9D5E-2A51-6623-5714C57A0F25}.Debug|Any CPU.Build.0 = Debug|Any CPU + {147009A6-9D5E-2A51-6623-5714C57A0F25}.Release|Any CPU.ActiveCfg = Release|Any CPU + {147009A6-9D5E-2A51-6623-5714C57A0F25}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {69989B09-7F8A-4739-93FF-D5AFD599722B} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/EntityFramework/ServerMode/ServerMode.vbproj b/VB/CodeBehind/EntityFramework/ServerMode/ServerMode.vbproj new file mode 100644 index 0000000..0d6fb87 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/ServerMode.vbproj @@ -0,0 +1,201 @@ + + + + + Debug + AnyCPU + {147009A6-9D5E-2A51-6623-5714C57A0F25} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + Custom + true + true + + + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/EntityFramework/ServerMode/packages.config b/VB/CodeBehind/EntityFramework/ServerMode/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/VB/CodeBehind/EntityFramework/ServerMode/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/App.config b/VB/CodeBehind/XPO/InfiniteAsyncSource/App.config new file mode 100644 index 0000000..bdc9454 --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/Application.xaml b/VB/CodeBehind/XPO/InfiniteAsyncSource/Application.xaml new file mode 100644 index 0000000..e2796fa --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/Application.xaml.vb b/VB/CodeBehind/XPO/InfiniteAsyncSource/Application.xaml.vb new file mode 100644 index 0000000..a1d563c --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/Application.xaml.vb @@ -0,0 +1,11 @@ +Imports XPOIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + ConnectionHelper.Connect() + DemoDataHelper.Seed() + End Sub +End Class diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/InfiniteAsyncSource.sln b/VB/CodeBehind/XPO/InfiniteAsyncSource/InfiniteAsyncSource.sln new file mode 100644 index 0000000..2a62b27 --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/InfiniteAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InfiniteAsyncSource", "InfiniteAsyncSource.vbproj", "{C6952C7B-D539-EBA7-6CB2-75C16B3768B5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C6952C7B-D539-EBA7-6CB2-75C16B3768B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6952C7B-D539-EBA7-6CB2-75C16B3768B5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6952C7B-D539-EBA7-6CB2-75C16B3768B5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6952C7B-D539-EBA7-6CB2-75C16B3768B5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/InfiniteAsyncSource.vbproj b/VB/CodeBehind/XPO/InfiniteAsyncSource/InfiniteAsyncSource.vbproj new file mode 100644 index 0000000..f80493e --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/InfiniteAsyncSource.vbproj @@ -0,0 +1,177 @@ + + + + Debug + AnyCPU + {C6952C7B-D539-EBA7-6CB2-75C16B3768B5} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + XPOIssues + XPOIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/ConnectionHelper.vb b/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/ConnectionHelper.vb new file mode 100644 index 0000000..e05a409 --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/ConnectionHelper.vb @@ -0,0 +1,25 @@ +Imports DevExpress.Xpo +Imports DevExpress.Xpo.DB +Imports DevExpress.Xpo.Metadata +Imports System +Imports System.Configuration + +Namespace Issues + Public Module ConnectionHelper + Private ReadOnly PersistentTypes As Type() = New Type() {GetType(Issue), GetType(User)} + + Public Sub Connect() + XpoDefault.DataLayer = CreateDataLayer(True) + End Sub + + Private Function CreateDataLayer(ByVal threadSafe As Boolean) As IDataLayer + Dim connStr As String = If(ConfigurationManager.ConnectionStrings("XpoTutorial")?.ConnectionString, "XpoProvider=InMemoryDataStore") + 'connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + Dim dictionary As ReflectionDictionary = New ReflectionDictionary() + dictionary.GetDataStoreSchema(PersistentTypes) ' Pass all of your persistent object types to this method. + Dim autoCreateOption As AutoCreateOption = AutoCreateOption.DatabaseAndSchema ' Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + Dim provider As IDataStore = XpoDefault.GetConnectionProvider(connStr, autoCreateOption) + Return If(threadSafe, CType(New ThreadSafeDataLayer(dictionary, provider), IDataLayer), New SimpleDataLayer(dictionary, provider)) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/Customer.vb b/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/Customer.vb new file mode 100644 index 0000000..e3a816a --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/Customer.vb @@ -0,0 +1,40 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class User + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + End Sub + + Private _FirstName As String + + Public Property FirstName As String + Get + Return _FirstName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.FirstName), _FirstName, value) + End Set + End Property + + Private _LastName As String + + Public Property LastName As String + Get + Return _LastName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.LastName), _LastName, value) + End Set + End Property + + + Public ReadOnly Property Issues As XPCollection(Of Issue) + Get + Return GetCollection(Of Issue)(NameOf(User.Issues)) + End Get + End Property + End Class +End Namespace diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/DemoDataHelper.vb b/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/DemoDataHelper.vb new file mode 100644 index 0000000..a4fb3de --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/DemoDataHelper.vb @@ -0,0 +1,30 @@ +Imports DevExpress.Xpo +Imports System +Imports System.Linq + +Namespace Issues + Public Module DemoDataHelper + Public Sub Seed() + Using uow = New DevExpress.Xpo.UnitOfWork() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User(uow) With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + uow.CommitChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue(uow) With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Oid, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + uow.CommitChanges() + End Using + End Sub + End Module +End Namespace + diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/Issue.vb b/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/Issue.vb new file mode 100644 index 0000000..7aab998 --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/Issue.vb @@ -0,0 +1,88 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class Issue + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + Created = Date.Now + End Sub + + Private _Subject As String + + + Public Property Subject As String + Get + Return _Subject + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(Issue.Subject), _Subject, value) + End Set + End Property + + Private _UserId As Integer + + Public Property UserId As Integer + Get + Return _UserId + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.UserId), _UserId, value) + End Set + End Property + + Private _User As User + + + Public Property User As User + Get + Return _User + End Get + Set(ByVal value As User) + SetPropertyValue(NameOf(Issue.User), _User, value) + End Set + End Property + + Private _Created As Date + + Public Property Created As Date + Get + Return _Created + End Get + Set(ByVal value As Date) + SetPropertyValue(NameOf(Issue.Created), _Created, value) + End Set + End Property + + Private _Votes As Integer + + Public Property Votes As Integer + Get + Return _Votes + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.Votes), _Votes, value) + End Set + End Property + + Private _Priority As Priority + + Public Property Priority As Priority + Get + Return _Priority + End Get + Set(ByVal value As Priority) + SetPropertyValue(NameOf(Issue.Priority), _Priority, value) + End Set + End Property + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace \ No newline at end of file diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml b/VB/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..f3559e1 --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml.vb b/VB/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml.vb new file mode 100644 index 0000000..cad49a7 --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/MainWindow.xaml.vb @@ -0,0 +1,80 @@ +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports DevExpress.Xpo +Class MainWindow + Private _DetachedObjectsHelper As DetachedObjectsHelper(Of XPOIssues.Issues.Issue) + Public Sub New() + InitializeComponent() + Using session = New Session() + Dim classInfo = session.GetClassInfo(Of Issues.Issue)() + Dim properties = classInfo.Members.Where(Function(member) member.IsPublic AndAlso member.IsPersistent).[Select](Function(member) member.Name).ToArray() + _DetachedObjectsHelper = DetachedObjectsHelper(Of Issues.Issue).Create(classInfo.KeyProperty.Name, properties) + End Using + Dim source = New InfiniteAsyncSource With { + .CustomProperties = _DetachedObjectsHelper.Properties, + .KeyProperty = nameof(Issues.Issue.Oid) + } + AddHandler source.FetchRows, AddressOf OnFetchRows + AddHandler source.GetTotalSummaries, AddressOf OnGetTotalSummaries + grid.ItemsSource = source + LoadLookupData() + End Sub + + Private Sub OnFetchRows(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Data.FetchRowsAsyncEventArgs) + e.Result = Task.Run(Of DevExpress.Xpf.Data.FetchRowsResult)(Function() + Using session = New DevExpress.Xpo.Session() + Dim queryable = session.Query(Of Issues.Issue)().SortBy(e.SortOrder, defaultUniqueSortPropertyName:=NameOf(Issues.Issue.Oid)).Where(MakeFilterExpression(e.Filter)) + Dim items = queryable.Skip(e.Skip).Take(If(e.Take, 100)).ToArray() + Return _DetachedObjectsHelper.ConvertToDetachedObjects(items) + End Using + End Function) + End Sub + + Private Sub OnGetTotalSummaries(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Data.GetSummariesAsyncEventArgs) + e.Result = Task.Run(Function() + Using session = New DevExpress.Xpo.Session() + Return session.Query(Of Issues.Issue)().Where(MakeFilterExpression(e.Filter)).GetSummaries(e.Summaries) + End Using + End Function) + End Sub + + Private Function MakeFilterExpression(ByVal filter As DevExpress.Data.Filtering.CriteriaOperator) As System.Linq.Expressions.Expression(Of System.Func(Of XPOIssues.Issues.Issue, Boolean)) + Dim converter = New DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(Of XPOIssues.Issues.Issue)() + Return converter.Convert(filter) + End Function + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridRowValidationEventArgs) + Using unitOfWork = New DevExpress.Xpo.UnitOfWork() + Dim item = If(e.IsNewItem, New Issues.Issue(unitOfWork), unitOfWork.GetObjectByKey(Of Issues.Issue)(_DetachedObjectsHelper.GetKey(e.Row))) + _DetachedObjectsHelper.ApplyProperties(item, e.Row) + unitOfWork.CommitChanges() + + If e.IsNewItem Then + _DetachedObjectsHelper.SetKey(e.Row, item.Oid) + End If + End Using + End Sub + + Private Sub OnValidateRowDeletion(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridDeleteRowsValidationEventArgs) + Using unitOfWork = New DevExpress.Xpo.UnitOfWork() + Dim key = _DetachedObjectsHelper.GetKey(e.Rows.[Single]()) + Dim item = unitOfWork.GetObjectByKey(Of Issues.Issue)(key) + unitOfWork.Delete(item) + unitOfWork.CommitChanges() + End Using + End Sub + + Private Sub LoadLookupData() + Dim session = New DevExpress.Xpo.Session() + usersLookup.ItemsSource = session.Query(Of XPOIssues.Issues.User).OrderBy(Function(user) user.Oid).[Select](Function(user) New With { + .Id = user.Oid, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadLookupData() + End Sub + +End Class diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/AssemblyInfo.vb b/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e20351d --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/Resources.Designer.vb b/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/Resources.resx b/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/Settings.Designer.vb b/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/Settings.Designer.vb new file mode 100644 index 0000000..188aca7 --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.XPOIssues.My.MySettings + Get + Return Global.XPOIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/Settings.settings b/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/XPO/InfiniteAsyncSource/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/App.config b/VB/CodeBehind/XPO/InstantFeedbackMode/App.config new file mode 100644 index 0000000..bdc9454 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/Application.xaml b/VB/CodeBehind/XPO/InstantFeedbackMode/Application.xaml new file mode 100644 index 0000000..e2796fa --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/Application.xaml.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/Application.xaml.vb new file mode 100644 index 0000000..a1d563c --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/Application.xaml.vb @@ -0,0 +1,11 @@ +Imports XPOIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + ConnectionHelper.Connect() + DemoDataHelper.Seed() + End Sub +End Class diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/EditIssueInfo.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/EditIssueInfo.vb new file mode 100644 index 0000000..f410eb2 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/EditIssueInfo.vb @@ -0,0 +1,15 @@ +Imports DevExpress.Mvvm +Imports System.Collections.Generic +Imports XPOIssues.Issues + +Public Class EditIssueInfo + Inherits BindableBase + + Public Sub New(ByVal unitOfWork As DevExpress.Xpo.UnitOfWork, ByVal users As IList) + Me.UnitOfWork = unitOfWork + Me.Users = users + End Sub + + Public ReadOnly Property UnitOfWork As DevExpress.Xpo.UnitOfWork + Public ReadOnly Property Users As IList +End Class diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/InstantFeedbackMode.sln b/VB/CodeBehind/XPO/InstantFeedbackMode/InstantFeedbackMode.sln new file mode 100644 index 0000000..ce7b610 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/InstantFeedbackMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InstantFeedbackMode", "InstantFeedbackMode.vbproj", "{DDD2EA41-1B51-01B2-8E76-3E4CD3F19BDA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DDD2EA41-1B51-01B2-8E76-3E4CD3F19BDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DDD2EA41-1B51-01B2-8E76-3E4CD3F19BDA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DDD2EA41-1B51-01B2-8E76-3E4CD3F19BDA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DDD2EA41-1B51-01B2-8E76-3E4CD3F19BDA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/InstantFeedbackMode.vbproj b/VB/CodeBehind/XPO/InstantFeedbackMode/InstantFeedbackMode.vbproj new file mode 100644 index 0000000..459eb21 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/InstantFeedbackMode.vbproj @@ -0,0 +1,186 @@ + + + + Debug + AnyCPU + {DDD2EA41-1B51-01B2-8E76-3E4CD3F19BDA} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + XPOIssues + XPOIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/IssueDetailView.xaml b/VB/CodeBehind/XPO/InstantFeedbackMode/IssueDetailView.xaml new file mode 100644 index 0000000..e00f8b8 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/IssueDetailView.xaml.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/IssueDetailView.xaml.vb new file mode 100644 index 0000000..a9c5107 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/IssueDetailView.xaml.vb @@ -0,0 +1,3 @@ +Public Class IssueDetailView + +End Class \ No newline at end of file diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/ConnectionHelper.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/ConnectionHelper.vb new file mode 100644 index 0000000..e05a409 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/ConnectionHelper.vb @@ -0,0 +1,25 @@ +Imports DevExpress.Xpo +Imports DevExpress.Xpo.DB +Imports DevExpress.Xpo.Metadata +Imports System +Imports System.Configuration + +Namespace Issues + Public Module ConnectionHelper + Private ReadOnly PersistentTypes As Type() = New Type() {GetType(Issue), GetType(User)} + + Public Sub Connect() + XpoDefault.DataLayer = CreateDataLayer(True) + End Sub + + Private Function CreateDataLayer(ByVal threadSafe As Boolean) As IDataLayer + Dim connStr As String = If(ConfigurationManager.ConnectionStrings("XpoTutorial")?.ConnectionString, "XpoProvider=InMemoryDataStore") + 'connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + Dim dictionary As ReflectionDictionary = New ReflectionDictionary() + dictionary.GetDataStoreSchema(PersistentTypes) ' Pass all of your persistent object types to this method. + Dim autoCreateOption As AutoCreateOption = AutoCreateOption.DatabaseAndSchema ' Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + Dim provider As IDataStore = XpoDefault.GetConnectionProvider(connStr, autoCreateOption) + Return If(threadSafe, CType(New ThreadSafeDataLayer(dictionary, provider), IDataLayer), New SimpleDataLayer(dictionary, provider)) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/Customer.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/Customer.vb new file mode 100644 index 0000000..e3a816a --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/Customer.vb @@ -0,0 +1,40 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class User + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + End Sub + + Private _FirstName As String + + Public Property FirstName As String + Get + Return _FirstName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.FirstName), _FirstName, value) + End Set + End Property + + Private _LastName As String + + Public Property LastName As String + Get + Return _LastName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.LastName), _LastName, value) + End Set + End Property + + + Public ReadOnly Property Issues As XPCollection(Of Issue) + Get + Return GetCollection(Of Issue)(NameOf(User.Issues)) + End Get + End Property + End Class +End Namespace diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/DemoDataHelper.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/DemoDataHelper.vb new file mode 100644 index 0000000..a4fb3de --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/DemoDataHelper.vb @@ -0,0 +1,30 @@ +Imports DevExpress.Xpo +Imports System +Imports System.Linq + +Namespace Issues + Public Module DemoDataHelper + Public Sub Seed() + Using uow = New DevExpress.Xpo.UnitOfWork() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User(uow) With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + uow.CommitChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue(uow) With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Oid, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + uow.CommitChanges() + End Using + End Sub + End Module +End Namespace + diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/Issue.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/Issue.vb new file mode 100644 index 0000000..7aab998 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/Issue.vb @@ -0,0 +1,88 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class Issue + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + Created = Date.Now + End Sub + + Private _Subject As String + + + Public Property Subject As String + Get + Return _Subject + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(Issue.Subject), _Subject, value) + End Set + End Property + + Private _UserId As Integer + + Public Property UserId As Integer + Get + Return _UserId + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.UserId), _UserId, value) + End Set + End Property + + Private _User As User + + + Public Property User As User + Get + Return _User + End Get + Set(ByVal value As User) + SetPropertyValue(NameOf(Issue.User), _User, value) + End Set + End Property + + Private _Created As Date + + Public Property Created As Date + Get + Return _Created + End Get + Set(ByVal value As Date) + SetPropertyValue(NameOf(Issue.Created), _Created, value) + End Set + End Property + + Private _Votes As Integer + + Public Property Votes As Integer + Get + Return _Votes + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.Votes), _Votes, value) + End Set + End Property + + Private _Priority As Priority + + Public Property Priority As Priority + Get + Return _Priority + End Get + Set(ByVal value As Priority) + SetPropertyValue(NameOf(Issue.Priority), _Priority, value) + End Set + End Property + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace \ No newline at end of file diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml b/VB/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml new file mode 100644 index 0000000..50596c2 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml.vb new file mode 100644 index 0000000..82e5962 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/MainWindow.xaml.vb @@ -0,0 +1,58 @@ +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports DevExpress.Xpo +Imports XPOIssues.Issues +Imports DevExpress.Mvvm.Xpf +Imports System +Imports System.Collections +Class MainWindow + Public Sub New() + InitializeComponent() + Dim properties = New DevExpress.Xpo.ServerViewProperty() { + New DevExpress.Xpo.ServerViewProperty("Oid", DevExpress.Xpo.SortDirection.Ascending, New DevExpress.Data.Filtering.OperandProperty("Oid")), + New DevExpress.Xpo.ServerViewProperty("Subject", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Subject")), + New DevExpress.Xpo.ServerViewProperty("UserId", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("UserId")), + New DevExpress.Xpo.ServerViewProperty("Created", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Created")), + New DevExpress.Xpo.ServerViewProperty("Votes", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Votes")), + New DevExpress.Xpo.ServerViewProperty("Priority", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Priority")) + } + Dim source = New DevExpress.Xpo.XPInstantFeedbackView(GetType(Issues.Issue), properties, Nothing) + AddHandler source.ResolveSession, Sub(o, e) e.Session = New DevExpress.Xpo.Session() + grid.ItemsSource = source + LoadLookupData() + End Sub + + Private Sub LoadLookupData() + Dim session = New DevExpress.Xpo.Session() + usersLookup.ItemsSource = session.Query(Of XPOIssues.Issues.User).OrderBy(Function(user) user.Oid).[Select](Function(user) New With { + .Id = user.Oid, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadLookupData() + End Sub + + Private Sub OnCreateEditEntityViewModel(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs) + Dim unitOfWork = New UnitOfWork() + Dim item = If(e.Key IsNot Nothing, unitOfWork.GetObjectByKey(Of Issue)(e.Key), New Issue(unitOfWork)) + e.ViewModel = New EditItemViewModel(item, New EditIssueInfo(unitOfWork, CType(usersLookup.ItemsSource, IList)), dispose:=Sub() unitOfWork.Dispose()) + End Sub + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.EditFormRowValidationArgs) + Dim unitOfWork = CType(e.Tag, EditIssueInfo).UnitOfWork + unitOfWork.CommitChanges() + End Sub + + Private Sub OnValidateRowDeletion(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs) + Using unitOfWork = New UnitOfWork() + Dim key = CInt(e.Keys.[Single]()) + Dim item = unitOfWork.GetObjectByKey(Of Issue)(key) + unitOfWork.Delete(item) + unitOfWork.CommitChanges() + End Using + End Sub + +End Class diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/AssemblyInfo.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e20351d --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/Resources.Designer.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/Resources.resx b/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/Settings.Designer.vb b/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/Settings.Designer.vb new file mode 100644 index 0000000..188aca7 --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.XPOIssues.My.MySettings + Get + Return Global.XPOIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/Settings.settings b/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/XPO/InstantFeedbackMode/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/LocalData/App.config b/VB/CodeBehind/XPO/LocalData/App.config new file mode 100644 index 0000000..bdc9454 --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/LocalData/Application.xaml b/VB/CodeBehind/XPO/LocalData/Application.xaml new file mode 100644 index 0000000..e2796fa --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/XPO/LocalData/Application.xaml.vb b/VB/CodeBehind/XPO/LocalData/Application.xaml.vb new file mode 100644 index 0000000..a1d563c --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/Application.xaml.vb @@ -0,0 +1,11 @@ +Imports XPOIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + ConnectionHelper.Connect() + DemoDataHelper.Seed() + End Sub +End Class diff --git a/VB/CodeBehind/XPO/LocalData/Issues/ConnectionHelper.vb b/VB/CodeBehind/XPO/LocalData/Issues/ConnectionHelper.vb new file mode 100644 index 0000000..e05a409 --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/Issues/ConnectionHelper.vb @@ -0,0 +1,25 @@ +Imports DevExpress.Xpo +Imports DevExpress.Xpo.DB +Imports DevExpress.Xpo.Metadata +Imports System +Imports System.Configuration + +Namespace Issues + Public Module ConnectionHelper + Private ReadOnly PersistentTypes As Type() = New Type() {GetType(Issue), GetType(User)} + + Public Sub Connect() + XpoDefault.DataLayer = CreateDataLayer(True) + End Sub + + Private Function CreateDataLayer(ByVal threadSafe As Boolean) As IDataLayer + Dim connStr As String = If(ConfigurationManager.ConnectionStrings("XpoTutorial")?.ConnectionString, "XpoProvider=InMemoryDataStore") + 'connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + Dim dictionary As ReflectionDictionary = New ReflectionDictionary() + dictionary.GetDataStoreSchema(PersistentTypes) ' Pass all of your persistent object types to this method. + Dim autoCreateOption As AutoCreateOption = AutoCreateOption.DatabaseAndSchema ' Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + Dim provider As IDataStore = XpoDefault.GetConnectionProvider(connStr, autoCreateOption) + Return If(threadSafe, CType(New ThreadSafeDataLayer(dictionary, provider), IDataLayer), New SimpleDataLayer(dictionary, provider)) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/LocalData/Issues/Customer.vb b/VB/CodeBehind/XPO/LocalData/Issues/Customer.vb new file mode 100644 index 0000000..e3a816a --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/Issues/Customer.vb @@ -0,0 +1,40 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class User + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + End Sub + + Private _FirstName As String + + Public Property FirstName As String + Get + Return _FirstName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.FirstName), _FirstName, value) + End Set + End Property + + Private _LastName As String + + Public Property LastName As String + Get + Return _LastName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.LastName), _LastName, value) + End Set + End Property + + + Public ReadOnly Property Issues As XPCollection(Of Issue) + Get + Return GetCollection(Of Issue)(NameOf(User.Issues)) + End Get + End Property + End Class +End Namespace diff --git a/VB/CodeBehind/XPO/LocalData/Issues/DemoDataHelper.vb b/VB/CodeBehind/XPO/LocalData/Issues/DemoDataHelper.vb new file mode 100644 index 0000000..a4fb3de --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/Issues/DemoDataHelper.vb @@ -0,0 +1,30 @@ +Imports DevExpress.Xpo +Imports System +Imports System.Linq + +Namespace Issues + Public Module DemoDataHelper + Public Sub Seed() + Using uow = New DevExpress.Xpo.UnitOfWork() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User(uow) With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + uow.CommitChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue(uow) With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Oid, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + uow.CommitChanges() + End Using + End Sub + End Module +End Namespace + diff --git a/VB/CodeBehind/XPO/LocalData/Issues/Issue.vb b/VB/CodeBehind/XPO/LocalData/Issues/Issue.vb new file mode 100644 index 0000000..7aab998 --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/Issues/Issue.vb @@ -0,0 +1,88 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class Issue + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + Created = Date.Now + End Sub + + Private _Subject As String + + + Public Property Subject As String + Get + Return _Subject + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(Issue.Subject), _Subject, value) + End Set + End Property + + Private _UserId As Integer + + Public Property UserId As Integer + Get + Return _UserId + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.UserId), _UserId, value) + End Set + End Property + + Private _User As User + + + Public Property User As User + Get + Return _User + End Get + Set(ByVal value As User) + SetPropertyValue(NameOf(Issue.User), _User, value) + End Set + End Property + + Private _Created As Date + + Public Property Created As Date + Get + Return _Created + End Get + Set(ByVal value As Date) + SetPropertyValue(NameOf(Issue.Created), _Created, value) + End Set + End Property + + Private _Votes As Integer + + Public Property Votes As Integer + Get + Return _Votes + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.Votes), _Votes, value) + End Set + End Property + + Private _Priority As Priority + + Public Property Priority As Priority + Get + Return _Priority + End Get + Set(ByVal value As Priority) + SetPropertyValue(NameOf(Issue.Priority), _Priority, value) + End Set + End Property + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace \ No newline at end of file diff --git a/VB/CodeBehind/XPO/LocalData/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/XPO/LocalData/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/LocalData/LocalData.sln b/VB/CodeBehind/XPO/LocalData/LocalData.sln new file mode 100644 index 0000000..74be6d9 --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/LocalData.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LocalData", "LocalData.vbproj", "{BD439146-0FFF-83E0-0633-777FD5A2991D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BD439146-0FFF-83E0-0633-777FD5A2991D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD439146-0FFF-83E0-0633-777FD5A2991D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD439146-0FFF-83E0-0633-777FD5A2991D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD439146-0FFF-83E0-0633-777FD5A2991D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/XPO/LocalData/LocalData.vbproj b/VB/CodeBehind/XPO/LocalData/LocalData.vbproj new file mode 100644 index 0000000..dd34a4e --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/LocalData.vbproj @@ -0,0 +1,177 @@ + + + + Debug + AnyCPU + {BD439146-0FFF-83E0-0633-777FD5A2991D} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + XPOIssues + XPOIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/LocalData/MainWindow.xaml b/VB/CodeBehind/XPO/LocalData/MainWindow.xaml new file mode 100644 index 0000000..d69224d --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/MainWindow.xaml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/LocalData/MainWindow.xaml.vb b/VB/CodeBehind/XPO/LocalData/MainWindow.xaml.vb new file mode 100644 index 0000000..2c413e9 --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/MainWindow.xaml.vb @@ -0,0 +1,30 @@ +Imports System.Linq +Class MainWindow + Public Sub New() + InitializeComponent() + LoadData() + End Sub + Private _UnitOfWork As DevExpress.Xpo.UnitOfWork + + Private Sub LoadData() + _UnitOfWork = New DevExpress.Xpo.UnitOfWork() + Dim xpCollection = New DevExpress.Xpo.XPCollection(Of Issues.User)(_UnitOfWork) + xpCollection.Sorting.Add(New DevExpress.Xpo.SortProperty(NameOf(Issues.User.Oid), DevExpress.Xpo.DB.SortingDirection.Ascending)) + grid.ItemsSource = xpCollection + End Sub + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridRowValidationEventArgs) + _UnitOfWork.CommitChanges() + End Sub + + Private Sub OnValidateRowDeletion(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridDeleteRowsValidationEventArgs) + Dim row = CType(e.Rows.Single(), Issues.User) + _UnitOfWork.Delete(row) + _UnitOfWork.CommitChanges() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadData() + End Sub + +End Class diff --git a/VB/CodeBehind/XPO/LocalData/My Project/AssemblyInfo.vb b/VB/CodeBehind/XPO/LocalData/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e20351d --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/XPO/LocalData/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/XPO/LocalData/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/XPO/LocalData/My Project/Resources.Designer.vb b/VB/CodeBehind/XPO/LocalData/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/LocalData/My Project/Resources.resx b/VB/CodeBehind/XPO/LocalData/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/XPO/LocalData/My Project/Settings.Designer.vb b/VB/CodeBehind/XPO/LocalData/My Project/Settings.Designer.vb new file mode 100644 index 0000000..188aca7 --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.XPOIssues.My.MySettings + Get + Return Global.XPOIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/LocalData/My Project/Settings.settings b/VB/CodeBehind/XPO/LocalData/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/XPO/LocalData/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/App.config b/VB/CodeBehind/XPO/PagedAsyncSource/App.config new file mode 100644 index 0000000..bdc9454 --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/Application.xaml b/VB/CodeBehind/XPO/PagedAsyncSource/Application.xaml new file mode 100644 index 0000000..e2796fa --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/Application.xaml.vb b/VB/CodeBehind/XPO/PagedAsyncSource/Application.xaml.vb new file mode 100644 index 0000000..a1d563c --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/Application.xaml.vb @@ -0,0 +1,11 @@ +Imports XPOIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + ConnectionHelper.Connect() + DemoDataHelper.Seed() + End Sub +End Class diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/Issues/ConnectionHelper.vb b/VB/CodeBehind/XPO/PagedAsyncSource/Issues/ConnectionHelper.vb new file mode 100644 index 0000000..e05a409 --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/Issues/ConnectionHelper.vb @@ -0,0 +1,25 @@ +Imports DevExpress.Xpo +Imports DevExpress.Xpo.DB +Imports DevExpress.Xpo.Metadata +Imports System +Imports System.Configuration + +Namespace Issues + Public Module ConnectionHelper + Private ReadOnly PersistentTypes As Type() = New Type() {GetType(Issue), GetType(User)} + + Public Sub Connect() + XpoDefault.DataLayer = CreateDataLayer(True) + End Sub + + Private Function CreateDataLayer(ByVal threadSafe As Boolean) As IDataLayer + Dim connStr As String = If(ConfigurationManager.ConnectionStrings("XpoTutorial")?.ConnectionString, "XpoProvider=InMemoryDataStore") + 'connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + Dim dictionary As ReflectionDictionary = New ReflectionDictionary() + dictionary.GetDataStoreSchema(PersistentTypes) ' Pass all of your persistent object types to this method. + Dim autoCreateOption As AutoCreateOption = AutoCreateOption.DatabaseAndSchema ' Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + Dim provider As IDataStore = XpoDefault.GetConnectionProvider(connStr, autoCreateOption) + Return If(threadSafe, CType(New ThreadSafeDataLayer(dictionary, provider), IDataLayer), New SimpleDataLayer(dictionary, provider)) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/Issues/Customer.vb b/VB/CodeBehind/XPO/PagedAsyncSource/Issues/Customer.vb new file mode 100644 index 0000000..e3a816a --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/Issues/Customer.vb @@ -0,0 +1,40 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class User + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + End Sub + + Private _FirstName As String + + Public Property FirstName As String + Get + Return _FirstName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.FirstName), _FirstName, value) + End Set + End Property + + Private _LastName As String + + Public Property LastName As String + Get + Return _LastName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.LastName), _LastName, value) + End Set + End Property + + + Public ReadOnly Property Issues As XPCollection(Of Issue) + Get + Return GetCollection(Of Issue)(NameOf(User.Issues)) + End Get + End Property + End Class +End Namespace diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/Issues/DemoDataHelper.vb b/VB/CodeBehind/XPO/PagedAsyncSource/Issues/DemoDataHelper.vb new file mode 100644 index 0000000..a4fb3de --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/Issues/DemoDataHelper.vb @@ -0,0 +1,30 @@ +Imports DevExpress.Xpo +Imports System +Imports System.Linq + +Namespace Issues + Public Module DemoDataHelper + Public Sub Seed() + Using uow = New DevExpress.Xpo.UnitOfWork() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User(uow) With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + uow.CommitChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue(uow) With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Oid, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + uow.CommitChanges() + End Using + End Sub + End Module +End Namespace + diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/Issues/Issue.vb b/VB/CodeBehind/XPO/PagedAsyncSource/Issues/Issue.vb new file mode 100644 index 0000000..7aab998 --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/Issues/Issue.vb @@ -0,0 +1,88 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class Issue + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + Created = Date.Now + End Sub + + Private _Subject As String + + + Public Property Subject As String + Get + Return _Subject + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(Issue.Subject), _Subject, value) + End Set + End Property + + Private _UserId As Integer + + Public Property UserId As Integer + Get + Return _UserId + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.UserId), _UserId, value) + End Set + End Property + + Private _User As User + + + Public Property User As User + Get + Return _User + End Get + Set(ByVal value As User) + SetPropertyValue(NameOf(Issue.User), _User, value) + End Set + End Property + + Private _Created As Date + + Public Property Created As Date + Get + Return _Created + End Get + Set(ByVal value As Date) + SetPropertyValue(NameOf(Issue.Created), _Created, value) + End Set + End Property + + Private _Votes As Integer + + Public Property Votes As Integer + Get + Return _Votes + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.Votes), _Votes, value) + End Set + End Property + + Private _Priority As Priority + + Public Property Priority As Priority + Get + Return _Priority + End Get + Set(ByVal value As Priority) + SetPropertyValue(NameOf(Issue.Priority), _Priority, value) + End Set + End Property + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace \ No newline at end of file diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/XPO/PagedAsyncSource/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml b/VB/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..5c86287 --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml.vb b/VB/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml.vb new file mode 100644 index 0000000..865ccc1 --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/MainWindow.xaml.vb @@ -0,0 +1,73 @@ +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports DevExpress.Xpo +Class MainWindow + Private _DetachedObjectsHelper As DetachedObjectsHelper(Of XPOIssues.Issues.Issue) + Public Sub New() + InitializeComponent() + Using session = New Session() + Dim classInfo = session.GetClassInfo(Of Issues.Issue)() + Dim properties = classInfo.Members.Where(Function(member) member.IsPublic AndAlso member.IsPersistent).[Select](Function(member) member.Name).ToArray() + _DetachedObjectsHelper = DetachedObjectsHelper(Of Issues.Issue).Create(classInfo.KeyProperty.Name, properties) + End Using + Dim source = New PagedAsyncSource With { + .CustomProperties = _DetachedObjectsHelper.Properties, + .KeyProperty = nameof(Issues.Issue.Oid), + .PageNavigationMode = PageNavigationMode.ArbitraryWithTotalPageCount + } + AddHandler source.FetchPage, AddressOf OnFetchPage + AddHandler source.GetTotalSummaries, AddressOf OnGetTotalSummaries + grid.ItemsSource = source + LoadLookupData() + End Sub + + Private Sub OnFetchPage(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Data.FetchPageAsyncEventArgs) + e.Result = Task.Run(Of DevExpress.Xpf.Data.FetchRowsResult)(Function() + Const pageTakeCount As Integer = 5 + Using session = New DevExpress.Xpo.Session() + Dim queryable = session.Query(Of Issues.Issue)().SortBy(e.SortOrder, defaultUniqueSortPropertyName:=NameOf(Issues.Issue.Oid)).Where(MakeFilterExpression(CType(e.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Dim items = queryable.Skip(e.Skip).Take(e.Take * pageTakeCount).ToArray() + Return _DetachedObjectsHelper.ConvertToDetachedObjects(items) + End Using + End Function) + End Sub + + Private Sub OnGetTotalSummaries(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Data.GetSummariesAsyncEventArgs) + e.Result = Task.Run(Function() + Using session = New DevExpress.Xpo.Session() + Return session.Query(Of Issues.Issue)().Where(MakeFilterExpression(e.Filter)).GetSummaries(e.Summaries) + End Using + End Function) + End Sub + + Private Function MakeFilterExpression(ByVal filter As DevExpress.Data.Filtering.CriteriaOperator) As System.Linq.Expressions.Expression(Of System.Func(Of XPOIssues.Issues.Issue, Boolean)) + Dim converter = New DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(Of XPOIssues.Issues.Issue)() + Return converter.Convert(filter) + End Function + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.GridRowValidationEventArgs) + Using unitOfWork = New DevExpress.Xpo.UnitOfWork() + Dim item = If(e.IsNewItem, New Issues.Issue(unitOfWork), unitOfWork.GetObjectByKey(Of Issues.Issue)(_DetachedObjectsHelper.GetKey(e.Row))) + _DetachedObjectsHelper.ApplyProperties(item, e.Row) + unitOfWork.CommitChanges() + + If e.IsNewItem Then + _DetachedObjectsHelper.SetKey(e.Row, item.Oid) + End If + End Using + End Sub + + Private Sub LoadLookupData() + Dim session = New DevExpress.Xpo.Session() + usersLookup.ItemsSource = session.Query(Of XPOIssues.Issues.User).OrderBy(Function(user) user.Oid).[Select](Function(user) New With { + .Id = user.Oid, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadLookupData() + End Sub + +End Class diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/My Project/AssemblyInfo.vb b/VB/CodeBehind/XPO/PagedAsyncSource/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e20351d --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/XPO/PagedAsyncSource/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/XPO/PagedAsyncSource/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/My Project/Resources.Designer.vb b/VB/CodeBehind/XPO/PagedAsyncSource/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/My Project/Resources.resx b/VB/CodeBehind/XPO/PagedAsyncSource/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/XPO/PagedAsyncSource/My Project/Settings.Designer.vb b/VB/CodeBehind/XPO/PagedAsyncSource/My Project/Settings.Designer.vb new file mode 100644 index 0000000..188aca7 --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.XPOIssues.My.MySettings + Get + Return Global.XPOIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/My Project/Settings.settings b/VB/CodeBehind/XPO/PagedAsyncSource/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/PagedAsyncSource.sln b/VB/CodeBehind/XPO/PagedAsyncSource/PagedAsyncSource.sln new file mode 100644 index 0000000..61e7f32 --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/PagedAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PagedAsyncSource", "PagedAsyncSource.vbproj", "{448CFE97-0691-5B29-C5F9-433542936194}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {448CFE97-0691-5B29-C5F9-433542936194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {448CFE97-0691-5B29-C5F9-433542936194}.Debug|Any CPU.Build.0 = Debug|Any CPU + {448CFE97-0691-5B29-C5F9-433542936194}.Release|Any CPU.ActiveCfg = Release|Any CPU + {448CFE97-0691-5B29-C5F9-433542936194}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/XPO/PagedAsyncSource/PagedAsyncSource.vbproj b/VB/CodeBehind/XPO/PagedAsyncSource/PagedAsyncSource.vbproj new file mode 100644 index 0000000..8740ee0 --- /dev/null +++ b/VB/CodeBehind/XPO/PagedAsyncSource/PagedAsyncSource.vbproj @@ -0,0 +1,177 @@ + + + + Debug + AnyCPU + {448CFE97-0691-5B29-C5F9-433542936194} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + XPOIssues + XPOIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/ServerMode/App.config b/VB/CodeBehind/XPO/ServerMode/App.config new file mode 100644 index 0000000..bdc9454 --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/ServerMode/Application.xaml b/VB/CodeBehind/XPO/ServerMode/Application.xaml new file mode 100644 index 0000000..e2796fa --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/CodeBehind/XPO/ServerMode/Application.xaml.vb b/VB/CodeBehind/XPO/ServerMode/Application.xaml.vb new file mode 100644 index 0000000..a1d563c --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/Application.xaml.vb @@ -0,0 +1,11 @@ +Imports XPOIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + ConnectionHelper.Connect() + DemoDataHelper.Seed() + End Sub +End Class diff --git a/VB/CodeBehind/XPO/ServerMode/EditIssueInfo.vb b/VB/CodeBehind/XPO/ServerMode/EditIssueInfo.vb new file mode 100644 index 0000000..f410eb2 --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/EditIssueInfo.vb @@ -0,0 +1,15 @@ +Imports DevExpress.Mvvm +Imports System.Collections.Generic +Imports XPOIssues.Issues + +Public Class EditIssueInfo + Inherits BindableBase + + Public Sub New(ByVal unitOfWork As DevExpress.Xpo.UnitOfWork, ByVal users As IList) + Me.UnitOfWork = unitOfWork + Me.Users = users + End Sub + + Public ReadOnly Property UnitOfWork As DevExpress.Xpo.UnitOfWork + Public ReadOnly Property Users As IList +End Class diff --git a/VB/CodeBehind/XPO/ServerMode/IssueDetailView.xaml b/VB/CodeBehind/XPO/ServerMode/IssueDetailView.xaml new file mode 100644 index 0000000..e00f8b8 --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/ServerMode/IssueDetailView.xaml.vb b/VB/CodeBehind/XPO/ServerMode/IssueDetailView.xaml.vb new file mode 100644 index 0000000..a9c5107 --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/IssueDetailView.xaml.vb @@ -0,0 +1,3 @@ +Public Class IssueDetailView + +End Class \ No newline at end of file diff --git a/VB/CodeBehind/XPO/ServerMode/Issues/ConnectionHelper.vb b/VB/CodeBehind/XPO/ServerMode/Issues/ConnectionHelper.vb new file mode 100644 index 0000000..e05a409 --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/Issues/ConnectionHelper.vb @@ -0,0 +1,25 @@ +Imports DevExpress.Xpo +Imports DevExpress.Xpo.DB +Imports DevExpress.Xpo.Metadata +Imports System +Imports System.Configuration + +Namespace Issues + Public Module ConnectionHelper + Private ReadOnly PersistentTypes As Type() = New Type() {GetType(Issue), GetType(User)} + + Public Sub Connect() + XpoDefault.DataLayer = CreateDataLayer(True) + End Sub + + Private Function CreateDataLayer(ByVal threadSafe As Boolean) As IDataLayer + Dim connStr As String = If(ConfigurationManager.ConnectionStrings("XpoTutorial")?.ConnectionString, "XpoProvider=InMemoryDataStore") + 'connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + Dim dictionary As ReflectionDictionary = New ReflectionDictionary() + dictionary.GetDataStoreSchema(PersistentTypes) ' Pass all of your persistent object types to this method. + Dim autoCreateOption As AutoCreateOption = AutoCreateOption.DatabaseAndSchema ' Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + Dim provider As IDataStore = XpoDefault.GetConnectionProvider(connStr, autoCreateOption) + Return If(threadSafe, CType(New ThreadSafeDataLayer(dictionary, provider), IDataLayer), New SimpleDataLayer(dictionary, provider)) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/ServerMode/Issues/Customer.vb b/VB/CodeBehind/XPO/ServerMode/Issues/Customer.vb new file mode 100644 index 0000000..e3a816a --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/Issues/Customer.vb @@ -0,0 +1,40 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class User + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + End Sub + + Private _FirstName As String + + Public Property FirstName As String + Get + Return _FirstName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.FirstName), _FirstName, value) + End Set + End Property + + Private _LastName As String + + Public Property LastName As String + Get + Return _LastName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.LastName), _LastName, value) + End Set + End Property + + + Public ReadOnly Property Issues As XPCollection(Of Issue) + Get + Return GetCollection(Of Issue)(NameOf(User.Issues)) + End Get + End Property + End Class +End Namespace diff --git a/VB/CodeBehind/XPO/ServerMode/Issues/DemoDataHelper.vb b/VB/CodeBehind/XPO/ServerMode/Issues/DemoDataHelper.vb new file mode 100644 index 0000000..a4fb3de --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/Issues/DemoDataHelper.vb @@ -0,0 +1,30 @@ +Imports DevExpress.Xpo +Imports System +Imports System.Linq + +Namespace Issues + Public Module DemoDataHelper + Public Sub Seed() + Using uow = New DevExpress.Xpo.UnitOfWork() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User(uow) With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + uow.CommitChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue(uow) With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Oid, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + uow.CommitChanges() + End Using + End Sub + End Module +End Namespace + diff --git a/VB/CodeBehind/XPO/ServerMode/Issues/Issue.vb b/VB/CodeBehind/XPO/ServerMode/Issues/Issue.vb new file mode 100644 index 0000000..7aab998 --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/Issues/Issue.vb @@ -0,0 +1,88 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class Issue + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + Created = Date.Now + End Sub + + Private _Subject As String + + + Public Property Subject As String + Get + Return _Subject + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(Issue.Subject), _Subject, value) + End Set + End Property + + Private _UserId As Integer + + Public Property UserId As Integer + Get + Return _UserId + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.UserId), _UserId, value) + End Set + End Property + + Private _User As User + + + Public Property User As User + Get + Return _User + End Get + Set(ByVal value As User) + SetPropertyValue(NameOf(Issue.User), _User, value) + End Set + End Property + + Private _Created As Date + + Public Property Created As Date + Get + Return _Created + End Get + Set(ByVal value As Date) + SetPropertyValue(NameOf(Issue.Created), _Created, value) + End Set + End Property + + Private _Votes As Integer + + Public Property Votes As Integer + Get + Return _Votes + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.Votes), _Votes, value) + End Set + End Property + + Private _Priority As Priority + + Public Property Priority As Priority + Get + Return _Priority + End Get + Set(ByVal value As Priority) + SetPropertyValue(NameOf(Issue.Priority), _Priority, value) + End Set + End Property + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace \ No newline at end of file diff --git a/VB/CodeBehind/XPO/ServerMode/Issues/OutlookDataGenerator.vb b/VB/CodeBehind/XPO/ServerMode/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/ServerMode/MainWindow.xaml b/VB/CodeBehind/XPO/ServerMode/MainWindow.xaml new file mode 100644 index 0000000..50596c2 --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/ServerMode/MainWindow.xaml.vb b/VB/CodeBehind/XPO/ServerMode/MainWindow.xaml.vb new file mode 100644 index 0000000..0662856 --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/MainWindow.xaml.vb @@ -0,0 +1,59 @@ +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports DevExpress.Xpo +Imports XPOIssues.Issues +Imports DevExpress.Mvvm.Xpf +Imports System +Imports System.Collections +Class MainWindow + Public Sub New() + InitializeComponent() + Dim properties = New DevExpress.Xpo.ServerViewProperty() { + New DevExpress.Xpo.ServerViewProperty("Oid", DevExpress.Xpo.SortDirection.Ascending, New DevExpress.Data.Filtering.OperandProperty("Oid")), + New DevExpress.Xpo.ServerViewProperty("Subject", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Subject")), + New DevExpress.Xpo.ServerViewProperty("UserId", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("UserId")), + New DevExpress.Xpo.ServerViewProperty("Created", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Created")), + New DevExpress.Xpo.ServerViewProperty("Votes", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Votes")), + New DevExpress.Xpo.ServerViewProperty("Priority", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Priority")) + } + Dim session = New DevExpress.Xpo.Session() + Dim source = New DevExpress.Xpo.XPServerModeView(session, GetType(Issues.Issue), Nothing) + source.Properties.AddRange(properties) + grid.ItemsSource = source + LoadLookupData() + End Sub + + Private Sub LoadLookupData() + Dim session = New DevExpress.Xpo.Session() + usersLookup.ItemsSource = session.Query(Of XPOIssues.Issues.User).OrderBy(Function(user) user.Oid).[Select](Function(user) New With { + .Id = user.Oid, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End Sub + + Private Sub OnDataSourceRefresh(ByVal sender As System.Object, ByVal e As DevExpress.Xpf.Grid.DataSourceRefreshEventArgs) + LoadLookupData() + End Sub + + Private Sub OnCreateEditEntityViewModel(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs) + Dim unitOfWork = New UnitOfWork() + Dim item = If(e.Key IsNot Nothing, unitOfWork.GetObjectByKey(Of Issue)(e.Key), New Issue(unitOfWork)) + e.ViewModel = New EditItemViewModel(item, New EditIssueInfo(unitOfWork, CType(usersLookup.ItemsSource, IList)), dispose:=Sub() unitOfWork.Dispose()) + End Sub + + Private Sub OnValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.EditFormRowValidationArgs) + Dim unitOfWork = CType(e.Tag, EditIssueInfo).UnitOfWork + unitOfWork.CommitChanges() + End Sub + + Private Sub OnValidateRowDeletion(ByVal sender As System.Object, ByVal e As DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs) + Using unitOfWork = New UnitOfWork() + Dim key = CInt(e.Keys.[Single]()) + Dim item = unitOfWork.GetObjectByKey(Of Issue)(key) + unitOfWork.Delete(item) + unitOfWork.CommitChanges() + End Using + End Sub + +End Class diff --git a/VB/CodeBehind/XPO/ServerMode/My Project/AssemblyInfo.vb b/VB/CodeBehind/XPO/ServerMode/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e20351d --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/CodeBehind/XPO/ServerMode/My Project/MyExtensions/MyWpfExtension.vb b/VB/CodeBehind/XPO/ServerMode/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/CodeBehind/XPO/ServerMode/My Project/Resources.Designer.vb b/VB/CodeBehind/XPO/ServerMode/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/ServerMode/My Project/Resources.resx b/VB/CodeBehind/XPO/ServerMode/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/My Project/Resources.resx @@ -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 --git a/VB/CodeBehind/XPO/ServerMode/My Project/Settings.Designer.vb b/VB/CodeBehind/XPO/ServerMode/My Project/Settings.Designer.vb new file mode 100644 index 0000000..188aca7 --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.XPOIssues.My.MySettings + Get + Return Global.XPOIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/CodeBehind/XPO/ServerMode/My Project/Settings.settings b/VB/CodeBehind/XPO/ServerMode/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/CodeBehind/XPO/ServerMode/ServerMode.sln b/VB/CodeBehind/XPO/ServerMode/ServerMode.sln new file mode 100644 index 0000000..63516c9 --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/ServerMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServerMode", "ServerMode.vbproj", "{0F6A2BC6-1636-9D8E-6A2D-0A2C27A1C466}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0F6A2BC6-1636-9D8E-6A2D-0A2C27A1C466}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F6A2BC6-1636-9D8E-6A2D-0A2C27A1C466}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F6A2BC6-1636-9D8E-6A2D-0A2C27A1C466}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F6A2BC6-1636-9D8E-6A2D-0A2C27A1C466}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/CodeBehind/XPO/ServerMode/ServerMode.vbproj b/VB/CodeBehind/XPO/ServerMode/ServerMode.vbproj new file mode 100644 index 0000000..809b2ca --- /dev/null +++ b/VB/CodeBehind/XPO/ServerMode/ServerMode.vbproj @@ -0,0 +1,186 @@ + + + + Debug + AnyCPU + {0F6A2BC6-1636-9D8E-6A2D-0A2C27A1C466} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + XPOIssues + XPOIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/App.config b/VB/ViewModel/EFCore/InfiniteAsyncSource/App.config new file mode 100644 index 0000000..93bdfd4 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/App.config @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/Application.xaml b/VB/ViewModel/EFCore/InfiniteAsyncSource/Application.xaml new file mode 100644 index 0000000..1d7676b --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/Application.xaml.vb b/VB/ViewModel/EFCore/InfiniteAsyncSource/Application.xaml.vb new file mode 100644 index 0000000..fc1b49d --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/Application.xaml.vb @@ -0,0 +1,10 @@ +Imports EFCoreIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + IssuesContextInitializer.Seed() + End Sub +End Class diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.sln b/VB/ViewModel/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.sln new file mode 100644 index 0000000..1be85c5 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InfiniteAsyncSource", "InfiniteAsyncSource.vbproj", "{C4F95762-ADAE-6FE2-C2EB-0F8A1B561165}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C4F95762-ADAE-6FE2-C2EB-0F8A1B561165}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C4F95762-ADAE-6FE2-C2EB-0F8A1B561165}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C4F95762-ADAE-6FE2-C2EB-0F8A1B561165}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C4F95762-ADAE-6FE2-C2EB-0F8A1B561165}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.vbproj b/VB/ViewModel/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.vbproj new file mode 100644 index 0000000..5075217 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/InfiniteAsyncSource.vbproj @@ -0,0 +1,249 @@ + + + + Debug + AnyCPU + {C4F95762-ADAE-6FE2-C2EB-0F8A1B561165} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/Issue.vb b/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/Issue.vb new file mode 100644 index 0000000..b9efd71 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/Issue.vb @@ -0,0 +1,23 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/IssuesContext.vb b/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/IssuesContext.vb new file mode 100644 index 0000000..1312551 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/IssuesContext.vb @@ -0,0 +1,16 @@ +Imports Microsoft.EntityFrameworkCore + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Private Shared ReadOnly options As DbContextOptions(Of IssuesContext) = New DbContextOptionsBuilder(Of IssuesContext)().UseInMemoryDatabase(databaseName:="Test").Options + + Public Sub New() + MyBase.New(options) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/IssuesContextInitializer.vb b/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..9faa303 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/IssuesContextInitializer.vb @@ -0,0 +1,29 @@ +Imports System +Imports System.Linq + +Namespace Issues + Public Module IssuesContextInitializer + Public Sub Seed() + Dim context = New IssuesContext() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb b/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/User.vb b/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/MainViewModel.vb b/VB/ViewModel/EFCore/InfiniteAsyncSource/MainViewModel.vb new file mode 100644 index 0000000..38b187a --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/MainViewModel.vb @@ -0,0 +1,68 @@ +Imports DevExpress.Mvvm +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports Microsoft.EntityFrameworkCore + +Public Class MainViewModel + Inherits ViewModelBase + + Public Sub FetchRows(ByVal args As DevExpress.Mvvm.Xpf.FetchRowsAsyncArgs) + args.Result = Task.Run(Of DevExpress.Xpf.Data.FetchRowsResult)(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.AsNoTracking().SortBy(args.SortOrder, defaultUniqueSortPropertyName:=NameOf(Issues.Issue.Id)).Where(MakeFilterExpression(CType(args.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.Skip(args.Skip).Take(If(args.Take, 100)).ToArray() + End Function) + End Sub + + Public Sub GetTotalSummaries(ByVal args As DevExpress.Mvvm.Xpf.GetSummariesAsyncArgs) + args.Result = Task.Run(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.Where(MakeFilterExpression(CType(args.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.GetSummaries(args.Summaries) + End Function) + End Sub + + Private Function MakeFilterExpression(ByVal filter As DevExpress.Data.Filtering.CriteriaOperator) As System.Linq.Expressions.Expression(Of System.Func(Of EFCoreIssues.Issues.Issue, Boolean)) + Dim converter = New DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(Of EFCoreIssues.Issues.Issue)() + Return converter.Convert(filter) + End Function + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.RowValidationArgs) + Dim item = CType(args.Item, Issues.Issue) + Dim context = New Issues.IssuesContext() + context.Entry(item).State = If(args.IsNewItem, EntityState.Added, EntityState.Modified) + Try + context.SaveChanges() + Finally + context.Entry(item).State = EntityState.Detached + End Try + End Sub + + Public Sub ValidateRowDeletion(ByVal args As DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs) + Dim item = CType(args.Items.Single(), Issues.Issue) + Dim context = New Issues.IssuesContext() + context.Entry(item).State = EntityState.Deleted + context.SaveChanges() + End Sub + Private _Users As System.Collections.IList + + Public ReadOnly Property Users As System.Collections.IList + Get + If _Users Is Nothing AndAlso Not IsInDesignMode Then + Dim context = New EFCoreIssues.Issues.IssuesContext() + _Users = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End If + Return _Users + End Get + End Property + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _Users = Nothing + RaisePropertyChanged(Nameof(Users)) + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml b/VB/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..fcbbe8d --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml.vb b/VB/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/AssemblyInfo.vb b/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..8de8923 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/Resources.Designer.vb b/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/Resources.resx b/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/Settings.Designer.vb b/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/Settings.Designer.vb new file mode 100644 index 0000000..4e428d5 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EFCoreIssues.My.MySettings + Get + Return Global.EFCoreIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/Settings.settings b/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InfiniteAsyncSource/packages.config b/VB/ViewModel/EFCore/InfiniteAsyncSource/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/VB/ViewModel/EFCore/InfiniteAsyncSource/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/App.config b/VB/ViewModel/EFCore/InstantFeedbackMode/App.config new file mode 100644 index 0000000..93bdfd4 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/App.config @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/Application.xaml b/VB/ViewModel/EFCore/InstantFeedbackMode/Application.xaml new file mode 100644 index 0000000..1d7676b --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/Application.xaml.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/Application.xaml.vb new file mode 100644 index 0000000..fc1b49d --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/Application.xaml.vb @@ -0,0 +1,10 @@ +Imports EFCoreIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + IssuesContextInitializer.Seed() + End Sub +End Class diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/EditIssueInfo.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/EditIssueInfo.vb new file mode 100644 index 0000000..5ed81d2 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/EditIssueInfo.vb @@ -0,0 +1,15 @@ +Imports DevExpress.Mvvm +Imports System.Collections.Generic +Imports EFCoreIssues.Issues + +Public Class EditIssueInfo + Inherits BindableBase + + Public Sub New(ByVal context As IssuesContext, ByVal users As IList) + Me.Context = context + Me.Users = users + End Sub + + Public ReadOnly Property Context As IssuesContext + Public ReadOnly Property Users As IList +End Class diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/InstantFeedbackMode.sln b/VB/ViewModel/EFCore/InstantFeedbackMode/InstantFeedbackMode.sln new file mode 100644 index 0000000..c9e7d19 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/InstantFeedbackMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InstantFeedbackMode", "InstantFeedbackMode.vbproj", "{9A63456D-FF25-1EC2-2583-F413CD9A3BF9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9A63456D-FF25-1EC2-2583-F413CD9A3BF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A63456D-FF25-1EC2-2583-F413CD9A3BF9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A63456D-FF25-1EC2-2583-F413CD9A3BF9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A63456D-FF25-1EC2-2583-F413CD9A3BF9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/InstantFeedbackMode.vbproj b/VB/ViewModel/EFCore/InstantFeedbackMode/InstantFeedbackMode.vbproj new file mode 100644 index 0000000..23d63aa --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/InstantFeedbackMode.vbproj @@ -0,0 +1,258 @@ + + + + Debug + AnyCPU + {9A63456D-FF25-1EC2-2583-F413CD9A3BF9} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/IssueDetailView.xaml b/VB/ViewModel/EFCore/InstantFeedbackMode/IssueDetailView.xaml new file mode 100644 index 0000000..058337a --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/IssueDetailView.xaml.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/IssueDetailView.xaml.vb new file mode 100644 index 0000000..a9c5107 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/IssueDetailView.xaml.vb @@ -0,0 +1,3 @@ +Public Class IssueDetailView + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/Issue.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/Issue.vb new file mode 100644 index 0000000..b9efd71 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/Issue.vb @@ -0,0 +1,23 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/IssuesContext.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/IssuesContext.vb new file mode 100644 index 0000000..1312551 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/IssuesContext.vb @@ -0,0 +1,16 @@ +Imports Microsoft.EntityFrameworkCore + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Private Shared ReadOnly options As DbContextOptions(Of IssuesContext) = New DbContextOptionsBuilder(Of IssuesContext)().UseInMemoryDatabase(databaseName:="Test").Options + + Public Sub New() + MyBase.New(options) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/IssuesContextInitializer.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..9faa303 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/IssuesContextInitializer.vb @@ -0,0 +1,29 @@ +Imports System +Imports System.Linq + +Namespace Issues + Public Module IssuesContextInitializer + Public Sub Seed() + Dim context = New IssuesContext() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/OutlookDataGenerator.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/User.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/MainViewModel.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/MainViewModel.vb new file mode 100644 index 0000000..2a69c31 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/MainViewModel.vb @@ -0,0 +1,79 @@ +Imports DevExpress.Mvvm +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports Microsoft.EntityFrameworkCore +Imports EFCoreIssues.Issues +Imports DevExpress.Mvvm.Xpf +Imports System + +Public Class MainViewModel + Inherits ViewModelBase + Private _InstantFeedbackSource As DevExpress.Data.Linq.EntityInstantFeedbackSource + + Public ReadOnly Property InstantFeedbackSource As DevExpress.Data.Linq.EntityInstantFeedbackSource + Get + If _InstantFeedbackSource Is Nothing Then + _InstantFeedbackSource = New DevExpress.Data.Linq.EntityInstantFeedbackSource With { + .KeyExpression = NameOf(Issues.Issue.Id) + } + AddHandler _InstantFeedbackSource.GetQueryable, Sub(sender, e) + Dim context = New Issues.IssuesContext() + e.QueryableSource = context.Issues.AsNoTracking() + End Sub + End If + Return _InstantFeedbackSource + End Get + End Property + Private _Users As System.Collections.IList + + Public ReadOnly Property Users As System.Collections.IList + Get + If _Users Is Nothing AndAlso Not IsInDesignMode Then + Dim context = New EFCoreIssues.Issues.IssuesContext() + _Users = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End If + Return _Users + End Get + End Property + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _Users = Nothing + RaisePropertyChanged(Nameof(Users)) + End Sub + + Public Sub CreateEditEntityViewModel(ByVal args As DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs) + Dim context = New IssuesContext() + Dim item As Issue + + If args.Key IsNot Nothing Then + item = context.Issues.Find(args.Key) + Else + item = New Issue() With { + .Created = Date.Now + } + context.Entry(item).State = EntityState.Added + End If + + args.ViewModel = New EditItemViewModel(item, New EditIssueInfo(context, Users)) + End Sub + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.EditFormRowValidationArgs) + Dim context = CType(args.Tag, EditIssueInfo).Context + context.SaveChanges() + End Sub + + Public Sub ValidateRowDeletion(ByVal args As DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs) + Dim key = CInt(args.Keys.[Single]()) + Dim item = New Issue() With { + .Id = key + } + Dim context = New IssuesContext() + context.Entry(item).State = EntityState.Deleted + context.SaveChanges() + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml b/VB/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml new file mode 100644 index 0000000..1eb2f58 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/AssemblyInfo.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..8de8923 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/Resources.Designer.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/Resources.resx b/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/Settings.Designer.vb b/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/Settings.Designer.vb new file mode 100644 index 0000000..4e428d5 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EFCoreIssues.My.MySettings + Get + Return Global.EFCoreIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/Settings.settings b/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/InstantFeedbackMode/packages.config b/VB/ViewModel/EFCore/InstantFeedbackMode/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/VB/ViewModel/EFCore/InstantFeedbackMode/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/LocalData/App.config b/VB/ViewModel/EFCore/LocalData/App.config new file mode 100644 index 0000000..93bdfd4 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/App.config @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/LocalData/Application.xaml b/VB/ViewModel/EFCore/LocalData/Application.xaml new file mode 100644 index 0000000..1d7676b --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/EFCore/LocalData/Application.xaml.vb b/VB/ViewModel/EFCore/LocalData/Application.xaml.vb new file mode 100644 index 0000000..fc1b49d --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/Application.xaml.vb @@ -0,0 +1,10 @@ +Imports EFCoreIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + IssuesContextInitializer.Seed() + End Sub +End Class diff --git a/VB/ViewModel/EFCore/LocalData/Issues/Issue.vb b/VB/ViewModel/EFCore/LocalData/Issues/Issue.vb new file mode 100644 index 0000000..b9efd71 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/Issues/Issue.vb @@ -0,0 +1,23 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace diff --git a/VB/ViewModel/EFCore/LocalData/Issues/IssuesContext.vb b/VB/ViewModel/EFCore/LocalData/Issues/IssuesContext.vb new file mode 100644 index 0000000..1312551 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/Issues/IssuesContext.vb @@ -0,0 +1,16 @@ +Imports Microsoft.EntityFrameworkCore + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Private Shared ReadOnly options As DbContextOptions(Of IssuesContext) = New DbContextOptionsBuilder(Of IssuesContext)().UseInMemoryDatabase(databaseName:="Test").Options + + Public Sub New() + MyBase.New(options) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace diff --git a/VB/ViewModel/EFCore/LocalData/Issues/IssuesContextInitializer.vb b/VB/ViewModel/EFCore/LocalData/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..9faa303 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/Issues/IssuesContextInitializer.vb @@ -0,0 +1,29 @@ +Imports System +Imports System.Linq + +Namespace Issues + Public Module IssuesContextInitializer + Public Sub Seed() + Dim context = New IssuesContext() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/LocalData/Issues/OutlookDataGenerator.vb b/VB/ViewModel/EFCore/LocalData/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/LocalData/Issues/User.vb b/VB/ViewModel/EFCore/LocalData/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/ViewModel/EFCore/LocalData/LocalData.sln b/VB/ViewModel/EFCore/LocalData/LocalData.sln new file mode 100644 index 0000000..3633f89 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/LocalData.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LocalData", "LocalData.vbproj", "{027E6DC6-769D-B290-7371-9707BC5DDB13}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {027E6DC6-769D-B290-7371-9707BC5DDB13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {027E6DC6-769D-B290-7371-9707BC5DDB13}.Debug|Any CPU.Build.0 = Debug|Any CPU + {027E6DC6-769D-B290-7371-9707BC5DDB13}.Release|Any CPU.ActiveCfg = Release|Any CPU + {027E6DC6-769D-B290-7371-9707BC5DDB13}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/EFCore/LocalData/LocalData.vbproj b/VB/ViewModel/EFCore/LocalData/LocalData.vbproj new file mode 100644 index 0000000..e146ebb --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/LocalData.vbproj @@ -0,0 +1,249 @@ + + + + Debug + AnyCPU + {027E6DC6-769D-B290-7371-9707BC5DDB13} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/LocalData/MainViewModel.vb b/VB/ViewModel/EFCore/LocalData/MainViewModel.vb new file mode 100644 index 0000000..98f0a5e --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/MainViewModel.vb @@ -0,0 +1,37 @@ +Imports DevExpress.Mvvm +Imports System.Linq + +Public Class MainViewModel + Inherits ViewModelBase + Private _Context As Issues.IssuesContext + Private _ItemsSource As System.Collections.Generic.IList(Of EFCoreIssues.Issues.User) + + Public ReadOnly Property ItemsSource As System.Collections.Generic.IList(Of EFCoreIssues.Issues.User) + Get + If _ItemsSource Is Nothing AndAlso Not IsInDesignMode Then + _Context = New Issues.IssuesContext() + _ItemsSource = _Context.Users.ToList() + End If + Return _ItemsSource + End Get + End Property + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.RowValidationArgs) + Dim item = CType(args.Item, Issues.User) + If args.IsNewItem Then _Context.Users.Add(item) + _Context.SaveChanges() + End Sub + + Public Sub ValidateRowDeletion(ByVal args As DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs) + Dim item = CType(args.Items.Single(), Issues.User) + _Context.Users.Remove(item) + _Context.SaveChanges() + End Sub + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _ItemsSource = Nothing + _Context = Nothing + RaisePropertyChanged(Nameof(ItemsSource)) + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EFCore/LocalData/MainWindow.xaml b/VB/ViewModel/EFCore/LocalData/MainWindow.xaml new file mode 100644 index 0000000..0b69bc4 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/MainWindow.xaml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/LocalData/MainWindow.xaml.vb b/VB/ViewModel/EFCore/LocalData/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/EFCore/LocalData/My Project/AssemblyInfo.vb b/VB/ViewModel/EFCore/LocalData/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..8de8923 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/EFCore/LocalData/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/EFCore/LocalData/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/EFCore/LocalData/My Project/Resources.Designer.vb b/VB/ViewModel/EFCore/LocalData/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/LocalData/My Project/Resources.resx b/VB/ViewModel/EFCore/LocalData/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/EFCore/LocalData/My Project/Settings.Designer.vb b/VB/ViewModel/EFCore/LocalData/My Project/Settings.Designer.vb new file mode 100644 index 0000000..4e428d5 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EFCoreIssues.My.MySettings + Get + Return Global.EFCoreIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/LocalData/My Project/Settings.settings b/VB/ViewModel/EFCore/LocalData/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/LocalData/packages.config b/VB/ViewModel/EFCore/LocalData/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/VB/ViewModel/EFCore/LocalData/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/App.config b/VB/ViewModel/EFCore/PagedAsyncSource/App.config new file mode 100644 index 0000000..93bdfd4 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/App.config @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/Application.xaml b/VB/ViewModel/EFCore/PagedAsyncSource/Application.xaml new file mode 100644 index 0000000..1d7676b --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/Application.xaml.vb b/VB/ViewModel/EFCore/PagedAsyncSource/Application.xaml.vb new file mode 100644 index 0000000..fc1b49d --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/Application.xaml.vb @@ -0,0 +1,10 @@ +Imports EFCoreIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + IssuesContextInitializer.Seed() + End Sub +End Class diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/Issues/Issue.vb b/VB/ViewModel/EFCore/PagedAsyncSource/Issues/Issue.vb new file mode 100644 index 0000000..b9efd71 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/Issues/Issue.vb @@ -0,0 +1,23 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/Issues/IssuesContext.vb b/VB/ViewModel/EFCore/PagedAsyncSource/Issues/IssuesContext.vb new file mode 100644 index 0000000..1312551 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/Issues/IssuesContext.vb @@ -0,0 +1,16 @@ +Imports Microsoft.EntityFrameworkCore + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Private Shared ReadOnly options As DbContextOptions(Of IssuesContext) = New DbContextOptionsBuilder(Of IssuesContext)().UseInMemoryDatabase(databaseName:="Test").Options + + Public Sub New() + MyBase.New(options) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/Issues/IssuesContextInitializer.vb b/VB/ViewModel/EFCore/PagedAsyncSource/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..9faa303 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/Issues/IssuesContextInitializer.vb @@ -0,0 +1,29 @@ +Imports System +Imports System.Linq + +Namespace Issues + Public Module IssuesContextInitializer + Public Sub Seed() + Dim context = New IssuesContext() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/Issues/OutlookDataGenerator.vb b/VB/ViewModel/EFCore/PagedAsyncSource/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/Issues/User.vb b/VB/ViewModel/EFCore/PagedAsyncSource/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/MainViewModel.vb b/VB/ViewModel/EFCore/PagedAsyncSource/MainViewModel.vb new file mode 100644 index 0000000..2beeb1a --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/MainViewModel.vb @@ -0,0 +1,62 @@ +Imports DevExpress.Mvvm +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports Microsoft.EntityFrameworkCore + +Public Class MainViewModel + Inherits ViewModelBase + + Public Sub FetchPage(ByVal args As DevExpress.Mvvm.Xpf.FetchPageAsyncArgs) + Const pageTakeCount As Integer = 5 + args.Result = Task.Run(Of DevExpress.Xpf.Data.FetchRowsResult)(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.AsNoTracking().SortBy(args.SortOrder, defaultUniqueSortPropertyName:=NameOf(Issues.Issue.Id)).Where(MakeFilterExpression(CType(args.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.Skip(args.Skip).Take(args.Take * pageTakeCount).ToArray() + End Function) + End Sub + + Public Sub GetTotalSummaries(ByVal args As DevExpress.Mvvm.Xpf.GetSummariesAsyncArgs) + args.Result = Task.Run(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.Where(MakeFilterExpression(CType(args.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.GetSummaries(args.Summaries) + End Function) + End Sub + + Private Function MakeFilterExpression(ByVal filter As DevExpress.Data.Filtering.CriteriaOperator) As System.Linq.Expressions.Expression(Of System.Func(Of EFCoreIssues.Issues.Issue, Boolean)) + Dim converter = New DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(Of EFCoreIssues.Issues.Issue)() + Return converter.Convert(filter) + End Function + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.RowValidationArgs) + Dim item = CType(args.Item, Issues.Issue) + Dim context = New Issues.IssuesContext() + context.Entry(item).State = If(args.IsNewItem, EntityState.Added, EntityState.Modified) + Try + context.SaveChanges() + Finally + context.Entry(item).State = EntityState.Detached + End Try + End Sub + Private _Users As System.Collections.IList + + Public ReadOnly Property Users As System.Collections.IList + Get + If _Users Is Nothing AndAlso Not IsInDesignMode Then + Dim context = New EFCoreIssues.Issues.IssuesContext() + _Users = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End If + Return _Users + End Get + End Property + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _Users = Nothing + RaisePropertyChanged(Nameof(Users)) + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml b/VB/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..a3aa5c7 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml.vb b/VB/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/My Project/AssemblyInfo.vb b/VB/ViewModel/EFCore/PagedAsyncSource/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..8de8923 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/EFCore/PagedAsyncSource/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/EFCore/PagedAsyncSource/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/My Project/Resources.Designer.vb b/VB/ViewModel/EFCore/PagedAsyncSource/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/My Project/Resources.resx b/VB/ViewModel/EFCore/PagedAsyncSource/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/EFCore/PagedAsyncSource/My Project/Settings.Designer.vb b/VB/ViewModel/EFCore/PagedAsyncSource/My Project/Settings.Designer.vb new file mode 100644 index 0000000..4e428d5 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EFCoreIssues.My.MySettings + Get + Return Global.EFCoreIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/My Project/Settings.settings b/VB/ViewModel/EFCore/PagedAsyncSource/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/PagedAsyncSource.sln b/VB/ViewModel/EFCore/PagedAsyncSource/PagedAsyncSource.sln new file mode 100644 index 0000000..ca3fbad --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/PagedAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PagedAsyncSource", "PagedAsyncSource.vbproj", "{F6189E92-A46E-25BB-D231-C9D1EAD29142}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F6189E92-A46E-25BB-D231-C9D1EAD29142}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6189E92-A46E-25BB-D231-C9D1EAD29142}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6189E92-A46E-25BB-D231-C9D1EAD29142}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6189E92-A46E-25BB-D231-C9D1EAD29142}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/PagedAsyncSource.vbproj b/VB/ViewModel/EFCore/PagedAsyncSource/PagedAsyncSource.vbproj new file mode 100644 index 0000000..32b6a57 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/PagedAsyncSource.vbproj @@ -0,0 +1,249 @@ + + + + Debug + AnyCPU + {F6189E92-A46E-25BB-D231-C9D1EAD29142} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/PagedAsyncSource/packages.config b/VB/ViewModel/EFCore/PagedAsyncSource/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/VB/ViewModel/EFCore/PagedAsyncSource/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/ServerMode/App.config b/VB/ViewModel/EFCore/ServerMode/App.config new file mode 100644 index 0000000..93bdfd4 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/App.config @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/ServerMode/Application.xaml b/VB/ViewModel/EFCore/ServerMode/Application.xaml new file mode 100644 index 0000000..1d7676b --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/EFCore/ServerMode/Application.xaml.vb b/VB/ViewModel/EFCore/ServerMode/Application.xaml.vb new file mode 100644 index 0000000..fc1b49d --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/Application.xaml.vb @@ -0,0 +1,10 @@ +Imports EFCoreIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + IssuesContextInitializer.Seed() + End Sub +End Class diff --git a/VB/ViewModel/EFCore/ServerMode/EditIssueInfo.vb b/VB/ViewModel/EFCore/ServerMode/EditIssueInfo.vb new file mode 100644 index 0000000..5ed81d2 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/EditIssueInfo.vb @@ -0,0 +1,15 @@ +Imports DevExpress.Mvvm +Imports System.Collections.Generic +Imports EFCoreIssues.Issues + +Public Class EditIssueInfo + Inherits BindableBase + + Public Sub New(ByVal context As IssuesContext, ByVal users As IList) + Me.Context = context + Me.Users = users + End Sub + + Public ReadOnly Property Context As IssuesContext + Public ReadOnly Property Users As IList +End Class diff --git a/VB/ViewModel/EFCore/ServerMode/IssueDetailView.xaml b/VB/ViewModel/EFCore/ServerMode/IssueDetailView.xaml new file mode 100644 index 0000000..058337a --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/ServerMode/IssueDetailView.xaml.vb b/VB/ViewModel/EFCore/ServerMode/IssueDetailView.xaml.vb new file mode 100644 index 0000000..a9c5107 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/IssueDetailView.xaml.vb @@ -0,0 +1,3 @@ +Public Class IssueDetailView + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EFCore/ServerMode/Issues/Issue.vb b/VB/ViewModel/EFCore/ServerMode/Issues/Issue.vb new file mode 100644 index 0000000..b9efd71 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/Issues/Issue.vb @@ -0,0 +1,23 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace diff --git a/VB/ViewModel/EFCore/ServerMode/Issues/IssuesContext.vb b/VB/ViewModel/EFCore/ServerMode/Issues/IssuesContext.vb new file mode 100644 index 0000000..1312551 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/Issues/IssuesContext.vb @@ -0,0 +1,16 @@ +Imports Microsoft.EntityFrameworkCore + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Private Shared ReadOnly options As DbContextOptions(Of IssuesContext) = New DbContextOptionsBuilder(Of IssuesContext)().UseInMemoryDatabase(databaseName:="Test").Options + + Public Sub New() + MyBase.New(options) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace diff --git a/VB/ViewModel/EFCore/ServerMode/Issues/IssuesContextInitializer.vb b/VB/ViewModel/EFCore/ServerMode/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..9faa303 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/Issues/IssuesContextInitializer.vb @@ -0,0 +1,29 @@ +Imports System +Imports System.Linq + +Namespace Issues + Public Module IssuesContextInitializer + Public Sub Seed() + Dim context = New IssuesContext() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/ServerMode/Issues/OutlookDataGenerator.vb b/VB/ViewModel/EFCore/ServerMode/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/ServerMode/Issues/User.vb b/VB/ViewModel/EFCore/ServerMode/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/ViewModel/EFCore/ServerMode/MainViewModel.vb b/VB/ViewModel/EFCore/ServerMode/MainViewModel.vb new file mode 100644 index 0000000..195d4cb --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/MainViewModel.vb @@ -0,0 +1,77 @@ +Imports DevExpress.Mvvm +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports Microsoft.EntityFrameworkCore +Imports EFCoreIssues.Issues +Imports DevExpress.Mvvm.Xpf +Imports System + +Public Class MainViewModel + Inherits ViewModelBase + Private _ServerModeSource As DevExpress.Data.Linq.EntityServerModeSource + + Public ReadOnly Property ServerModeSource As DevExpress.Data.Linq.EntityServerModeSource + Get + If _ServerModeSource Is Nothing Then + Dim context = New Issues.IssuesContext() + _ServerModeSource = New DevExpress.Data.Linq.EntityServerModeSource With { + .KeyExpression = NameOf(Issues.Issue.Id), + .QueryableSource = context.Issues.AsNoTracking() + } + End If + Return _ServerModeSource + End Get + End Property + Private _Users As System.Collections.IList + + Public ReadOnly Property Users As System.Collections.IList + Get + If _Users Is Nothing AndAlso Not IsInDesignMode Then + Dim context = New EFCoreIssues.Issues.IssuesContext() + _Users = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End If + Return _Users + End Get + End Property + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _Users = Nothing + RaisePropertyChanged(Nameof(Users)) + End Sub + + Public Sub CreateEditEntityViewModel(ByVal args As DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs) + Dim context = New IssuesContext() + Dim item As Issue + + If args.Key IsNot Nothing Then + item = context.Issues.Find(args.Key) + Else + item = New Issue() With { + .Created = Date.Now + } + context.Entry(item).State = EntityState.Added + End If + + args.ViewModel = New EditItemViewModel(item, New EditIssueInfo(context, Users)) + End Sub + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.EditFormRowValidationArgs) + Dim context = CType(args.Tag, EditIssueInfo).Context + context.SaveChanges() + End Sub + + Public Sub ValidateRowDeletion(ByVal args As DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs) + Dim key = CInt(args.Keys.[Single]()) + Dim item = New Issue() With { + .Id = key + } + Dim context = New IssuesContext() + context.Entry(item).State = EntityState.Deleted + context.SaveChanges() + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EFCore/ServerMode/MainWindow.xaml b/VB/ViewModel/EFCore/ServerMode/MainWindow.xaml new file mode 100644 index 0000000..1eb2f58 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/ServerMode/MainWindow.xaml.vb b/VB/ViewModel/EFCore/ServerMode/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/EFCore/ServerMode/My Project/AssemblyInfo.vb b/VB/ViewModel/EFCore/ServerMode/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..8de8923 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/EFCore/ServerMode/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/EFCore/ServerMode/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/EFCore/ServerMode/My Project/Resources.Designer.vb b/VB/ViewModel/EFCore/ServerMode/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/ServerMode/My Project/Resources.resx b/VB/ViewModel/EFCore/ServerMode/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/EFCore/ServerMode/My Project/Settings.Designer.vb b/VB/ViewModel/EFCore/ServerMode/My Project/Settings.Designer.vb new file mode 100644 index 0000000..4e428d5 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EFCoreIssues.My.MySettings + Get + Return Global.EFCoreIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EFCore/ServerMode/My Project/Settings.settings b/VB/ViewModel/EFCore/ServerMode/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/ServerMode/ServerMode.sln b/VB/ViewModel/EFCore/ServerMode/ServerMode.sln new file mode 100644 index 0000000..7b76b5c --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/ServerMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServerMode", "ServerMode.vbproj", "{7D8E4D8A-C90F-B47D-757A-AAADD85B06C4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7D8E4D8A-C90F-B47D-757A-AAADD85B06C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D8E4D8A-C90F-B47D-757A-AAADD85B06C4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D8E4D8A-C90F-B47D-757A-AAADD85B06C4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D8E4D8A-C90F-B47D-757A-AAADD85B06C4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/EFCore/ServerMode/ServerMode.vbproj b/VB/ViewModel/EFCore/ServerMode/ServerMode.vbproj new file mode 100644 index 0000000..9de962b --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/ServerMode.vbproj @@ -0,0 +1,258 @@ + + + + Debug + AnyCPU + {7D8E4D8A-C90F-B47D-757A-AAADD85B06C4} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EFCoreIssues + EFCoreIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EFCoreIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\..\..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.EntityFrameworkCore.InMemory.3.1.18\lib\netstandard2.0\Microsoft.EntityFrameworkCore.InMemory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Caching.Memory.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Configuration.Binder.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.3.1.18\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Options.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\..\..\packages\Microsoft.Extensions.Primitives.3.1.18\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + + + ..\..\..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\..\..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll + + + ..\..\..\..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + ..\..\..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EFCore/ServerMode/packages.config b/VB/ViewModel/EFCore/ServerMode/packages.config new file mode 100644 index 0000000..dcfb455 --- /dev/null +++ b/VB/ViewModel/EFCore/ServerMode/packages.config @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/App.config b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Application.xaml b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Application.xaml new file mode 100644 index 0000000..f3c3806 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Application.xaml.vb b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Application.xaml.vb new file mode 100644 index 0000000..883334e --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Application.xaml.vb @@ -0,0 +1,8 @@ +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory() + End Sub +End Class diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.sln b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.sln new file mode 100644 index 0000000..004e16a --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InfiniteAsyncSource", "InfiniteAsyncSource.vbproj", "{2D9EB85E-6E66-2FFF-CA08-3EAA78EA7863}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2D9EB85E-6E66-2FFF-CA08-3EAA78EA7863}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2D9EB85E-6E66-2FFF-CA08-3EAA78EA7863}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2D9EB85E-6E66-2FFF-CA08-3EAA78EA7863}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2D9EB85E-6E66-2FFF-CA08-3EAA78EA7863}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {69989B09-7F8A-4739-93FF-D5AFD599722B} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.vbproj b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.vbproj new file mode 100644 index 0000000..42dd353 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/InfiniteAsyncSource.vbproj @@ -0,0 +1,193 @@ + + + + + Debug + AnyCPU + {2D9EB85E-6E66-2FFF-CA08-3EAA78EA7863} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + Custom + true + true + + + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/Issue.vb b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/Issue.vb new file mode 100644 index 0000000..38f19e4 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/Issue.vb @@ -0,0 +1,24 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace + diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/IssuesContext.vb b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/IssuesContext.vb new file mode 100644 index 0000000..67359c4 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/IssuesContext.vb @@ -0,0 +1,24 @@ +Imports System.Data.Entity + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Shared Sub New() + Database.SetInitializer(New IssuesContextInitializer()) + End Sub + + Public Sub New() + End Sub + + Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder) + MyBase.OnModelCreating(modelBuilder) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Created) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Votes) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace + diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/IssuesContextInitializer.vb b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..0a19474 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/IssuesContextInitializer.vb @@ -0,0 +1,47 @@ +Imports System +Imports System.Data.Entity +Imports System.Linq + +Namespace Issues + Public Class IssuesContextInitializer + Inherits DropCreateDatabaseIfModelChanges(Of IssuesContext) + + ': DropCreateDatabaseAlways { + + Public Shared Sub ResetData() + Using context = New IssuesContext() + context.Users.Load() + context.Users.RemoveRange(context.Users) + context.SaveChanges() + CreateData(context) + End Using + End Sub + + Protected Overrides Sub Seed(ByVal context As IssuesContext) + MyBase.Seed(context) + CreateData(context) + End Sub + + Private Shared Sub CreateData(ByVal context As IssuesContext) + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Class +End Namespace diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/User.vb b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/MainViewModel.vb b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/MainViewModel.vb new file mode 100644 index 0000000..1f12f02 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/MainViewModel.vb @@ -0,0 +1,68 @@ +Imports DevExpress.Mvvm +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports System.Data.Entity + +Public Class MainViewModel + Inherits ViewModelBase + + Public Sub FetchRows(ByVal args As DevExpress.Mvvm.Xpf.FetchRowsAsyncArgs) + args.Result = Task.Run(Of DevExpress.Xpf.Data.FetchRowsResult)(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.AsNoTracking().SortBy(args.SortOrder, defaultUniqueSortPropertyName:=NameOf(Issues.Issue.Id)).Where(MakeFilterExpression(CType(args.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.Skip(args.Skip).Take(If(args.Take, 100)).ToArray() + End Function) + End Sub + + Public Sub GetTotalSummaries(ByVal args As DevExpress.Mvvm.Xpf.GetSummariesAsyncArgs) + args.Result = Task.Run(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.Where(MakeFilterExpression(CType(args.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.GetSummaries(args.Summaries) + End Function) + End Sub + + Private Function MakeFilterExpression(ByVal filter As DevExpress.Data.Filtering.CriteriaOperator) As System.Linq.Expressions.Expression(Of System.Func(Of EntityFrameworkIssues.Issues.Issue, Boolean)) + Dim converter = New DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(Of EntityFrameworkIssues.Issues.Issue)() + Return converter.Convert(filter) + End Function + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.RowValidationArgs) + Dim item = CType(args.Item, Issues.Issue) + Dim context = New Issues.IssuesContext() + context.Entry(item).State = If(args.IsNewItem, EntityState.Added, EntityState.Modified) + Try + context.SaveChanges() + Finally + context.Entry(item).State = EntityState.Detached + End Try + End Sub + + Public Sub ValidateRowDeletion(ByVal args As DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs) + Dim item = CType(args.Items.Single(), Issues.Issue) + Dim context = New Issues.IssuesContext() + context.Entry(item).State = EntityState.Deleted + context.SaveChanges() + End Sub + Private _Users As System.Collections.IList + + Public ReadOnly Property Users As System.Collections.IList + Get + If _Users Is Nothing AndAlso Not IsInDesignMode Then + Dim context = New EntityFrameworkIssues.Issues.IssuesContext() + _Users = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End If + Return _Users + End Get + End Property + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _Users = Nothing + RaisePropertyChanged(Nameof(Users)) + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..be01420 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.vb b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/AssemblyInfo.vb b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e276f20 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/Resources.Designer.vb b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/Resources.resx b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/Settings.Designer.vb b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/Settings.Designer.vb new file mode 100644 index 0000000..dbfe735 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EntityFrameworkIssues.My.MySettings + Get + Return Global.EntityFrameworkIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/Settings.settings b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InfiniteAsyncSource/packages.config b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InfiniteAsyncSource/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/App.config b/VB/ViewModel/EntityFramework/InstantFeedbackMode/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/Application.xaml b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Application.xaml new file mode 100644 index 0000000..f3c3806 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/Application.xaml.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Application.xaml.vb new file mode 100644 index 0000000..883334e --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Application.xaml.vb @@ -0,0 +1,8 @@ +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory() + End Sub +End Class diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/EditIssueInfo.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/EditIssueInfo.vb new file mode 100644 index 0000000..c0e5f5f --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/EditIssueInfo.vb @@ -0,0 +1,15 @@ +Imports DevExpress.Mvvm +Imports System.Collections.Generic +Imports EntityFrameworkIssues.Issues + +Public Class EditIssueInfo + Inherits BindableBase + + Public Sub New(ByVal context As IssuesContext, ByVal users As IList) + Me.Context = context + Me.Users = users + End Sub + + Public ReadOnly Property Context As IssuesContext + Public ReadOnly Property Users As IList +End Class diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.sln b/VB/ViewModel/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.sln new file mode 100644 index 0000000..d31478a --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InstantFeedbackMode", "InstantFeedbackMode.vbproj", "{3E083351-6104-8417-782A-336F92D0CAA9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3E083351-6104-8417-782A-336F92D0CAA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E083351-6104-8417-782A-336F92D0CAA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E083351-6104-8417-782A-336F92D0CAA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E083351-6104-8417-782A-336F92D0CAA9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {69989B09-7F8A-4739-93FF-D5AFD599722B} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.vbproj b/VB/ViewModel/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.vbproj new file mode 100644 index 0000000..ec273ce --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/InstantFeedbackMode.vbproj @@ -0,0 +1,202 @@ + + + + + Debug + AnyCPU + {3E083351-6104-8417-782A-336F92D0CAA9} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + Custom + true + true + + + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml b/VB/ViewModel/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml new file mode 100644 index 0000000..7bdbd7a --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml.vb new file mode 100644 index 0000000..a9c5107 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/IssueDetailView.xaml.vb @@ -0,0 +1,3 @@ +Public Class IssueDetailView + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/Issue.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/Issue.vb new file mode 100644 index 0000000..38f19e4 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/Issue.vb @@ -0,0 +1,24 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace + diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/IssuesContext.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/IssuesContext.vb new file mode 100644 index 0000000..67359c4 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/IssuesContext.vb @@ -0,0 +1,24 @@ +Imports System.Data.Entity + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Shared Sub New() + Database.SetInitializer(New IssuesContextInitializer()) + End Sub + + Public Sub New() + End Sub + + Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder) + MyBase.OnModelCreating(modelBuilder) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Created) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Votes) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace + diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/IssuesContextInitializer.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..0a19474 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/IssuesContextInitializer.vb @@ -0,0 +1,47 @@ +Imports System +Imports System.Data.Entity +Imports System.Linq + +Namespace Issues + Public Class IssuesContextInitializer + Inherits DropCreateDatabaseIfModelChanges(Of IssuesContext) + + ': DropCreateDatabaseAlways { + + Public Shared Sub ResetData() + Using context = New IssuesContext() + context.Users.Load() + context.Users.RemoveRange(context.Users) + context.SaveChanges() + CreateData(context) + End Using + End Sub + + Protected Overrides Sub Seed(ByVal context As IssuesContext) + MyBase.Seed(context) + CreateData(context) + End Sub + + Private Shared Sub CreateData(ByVal context As IssuesContext) + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Class +End Namespace diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/OutlookDataGenerator.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/User.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/MainViewModel.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/MainViewModel.vb new file mode 100644 index 0000000..b19c6b6 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/MainViewModel.vb @@ -0,0 +1,79 @@ +Imports DevExpress.Mvvm +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports System.Data.Entity +Imports EntityFrameworkIssues.Issues +Imports DevExpress.Mvvm.Xpf +Imports System + +Public Class MainViewModel + Inherits ViewModelBase + Private _InstantFeedbackSource As DevExpress.Data.Linq.EntityInstantFeedbackSource + + Public ReadOnly Property InstantFeedbackSource As DevExpress.Data.Linq.EntityInstantFeedbackSource + Get + If _InstantFeedbackSource Is Nothing Then + _InstantFeedbackSource = New DevExpress.Data.Linq.EntityInstantFeedbackSource With { + .KeyExpression = NameOf(Issues.Issue.Id) + } + AddHandler _InstantFeedbackSource.GetQueryable, Sub(sender, e) + Dim context = New Issues.IssuesContext() + e.QueryableSource = context.Issues.AsNoTracking() + End Sub + End If + Return _InstantFeedbackSource + End Get + End Property + Private _Users As System.Collections.IList + + Public ReadOnly Property Users As System.Collections.IList + Get + If _Users Is Nothing AndAlso Not IsInDesignMode Then + Dim context = New EntityFrameworkIssues.Issues.IssuesContext() + _Users = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End If + Return _Users + End Get + End Property + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _Users = Nothing + RaisePropertyChanged(Nameof(Users)) + End Sub + + Public Sub CreateEditEntityViewModel(ByVal args As DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs) + Dim context = New IssuesContext() + Dim item As Issue + + If args.Key IsNot Nothing Then + item = context.Issues.Find(args.Key) + Else + item = New Issue() With { + .Created = Date.Now + } + context.Entry(item).State = EntityState.Added + End If + + args.ViewModel = New EditItemViewModel(item, New EditIssueInfo(context, Users)) + End Sub + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.EditFormRowValidationArgs) + Dim context = CType(args.Tag, EditIssueInfo).Context + context.SaveChanges() + End Sub + + Public Sub ValidateRowDeletion(ByVal args As DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs) + Dim key = CInt(args.Keys.[Single]()) + Dim item = New Issue() With { + .Id = key + } + Dim context = New IssuesContext() + context.Entry(item).State = EntityState.Deleted + context.SaveChanges() + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml b/VB/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml new file mode 100644 index 0000000..65c78bd --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/AssemblyInfo.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e276f20 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/Resources.Designer.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/Resources.resx b/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/Settings.Designer.vb b/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/Settings.Designer.vb new file mode 100644 index 0000000..dbfe735 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EntityFrameworkIssues.My.MySettings + Get + Return Global.EntityFrameworkIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/Settings.settings b/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/InstantFeedbackMode/packages.config b/VB/ViewModel/EntityFramework/InstantFeedbackMode/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/VB/ViewModel/EntityFramework/InstantFeedbackMode/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/LocalData/App.config b/VB/ViewModel/EntityFramework/LocalData/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/LocalData/Application.xaml b/VB/ViewModel/EntityFramework/LocalData/Application.xaml new file mode 100644 index 0000000..f3c3806 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/EntityFramework/LocalData/Application.xaml.vb b/VB/ViewModel/EntityFramework/LocalData/Application.xaml.vb new file mode 100644 index 0000000..883334e --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/Application.xaml.vb @@ -0,0 +1,8 @@ +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory() + End Sub +End Class diff --git a/VB/ViewModel/EntityFramework/LocalData/Issues/Issue.vb b/VB/ViewModel/EntityFramework/LocalData/Issues/Issue.vb new file mode 100644 index 0000000..38f19e4 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/Issues/Issue.vb @@ -0,0 +1,24 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace + diff --git a/VB/ViewModel/EntityFramework/LocalData/Issues/IssuesContext.vb b/VB/ViewModel/EntityFramework/LocalData/Issues/IssuesContext.vb new file mode 100644 index 0000000..67359c4 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/Issues/IssuesContext.vb @@ -0,0 +1,24 @@ +Imports System.Data.Entity + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Shared Sub New() + Database.SetInitializer(New IssuesContextInitializer()) + End Sub + + Public Sub New() + End Sub + + Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder) + MyBase.OnModelCreating(modelBuilder) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Created) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Votes) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace + diff --git a/VB/ViewModel/EntityFramework/LocalData/Issues/IssuesContextInitializer.vb b/VB/ViewModel/EntityFramework/LocalData/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..0a19474 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/Issues/IssuesContextInitializer.vb @@ -0,0 +1,47 @@ +Imports System +Imports System.Data.Entity +Imports System.Linq + +Namespace Issues + Public Class IssuesContextInitializer + Inherits DropCreateDatabaseIfModelChanges(Of IssuesContext) + + ': DropCreateDatabaseAlways { + + Public Shared Sub ResetData() + Using context = New IssuesContext() + context.Users.Load() + context.Users.RemoveRange(context.Users) + context.SaveChanges() + CreateData(context) + End Using + End Sub + + Protected Overrides Sub Seed(ByVal context As IssuesContext) + MyBase.Seed(context) + CreateData(context) + End Sub + + Private Shared Sub CreateData(ByVal context As IssuesContext) + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Class +End Namespace diff --git a/VB/ViewModel/EntityFramework/LocalData/Issues/OutlookDataGenerator.vb b/VB/ViewModel/EntityFramework/LocalData/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/LocalData/Issues/User.vb b/VB/ViewModel/EntityFramework/LocalData/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/ViewModel/EntityFramework/LocalData/LocalData.sln b/VB/ViewModel/EntityFramework/LocalData/LocalData.sln new file mode 100644 index 0000000..31354cf --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/LocalData.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LocalData", "LocalData.vbproj", "{60B0BC31-2307-36F6-6218-1E56060F64A2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {60B0BC31-2307-36F6-6218-1E56060F64A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {60B0BC31-2307-36F6-6218-1E56060F64A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {60B0BC31-2307-36F6-6218-1E56060F64A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {60B0BC31-2307-36F6-6218-1E56060F64A2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {69989B09-7F8A-4739-93FF-D5AFD599722B} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/EntityFramework/LocalData/LocalData.vbproj b/VB/ViewModel/EntityFramework/LocalData/LocalData.vbproj new file mode 100644 index 0000000..34e9c8b --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/LocalData.vbproj @@ -0,0 +1,193 @@ + + + + + Debug + AnyCPU + {60B0BC31-2307-36F6-6218-1E56060F64A2} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + Custom + true + true + + + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/LocalData/MainViewModel.vb b/VB/ViewModel/EntityFramework/LocalData/MainViewModel.vb new file mode 100644 index 0000000..8d55840 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/MainViewModel.vb @@ -0,0 +1,37 @@ +Imports DevExpress.Mvvm +Imports System.Linq + +Public Class MainViewModel + Inherits ViewModelBase + Private _Context As Issues.IssuesContext + Private _ItemsSource As System.Collections.Generic.IList(Of EntityFrameworkIssues.Issues.User) + + Public ReadOnly Property ItemsSource As System.Collections.Generic.IList(Of EntityFrameworkIssues.Issues.User) + Get + If _ItemsSource Is Nothing AndAlso Not IsInDesignMode Then + _Context = New Issues.IssuesContext() + _ItemsSource = _Context.Users.ToList() + End If + Return _ItemsSource + End Get + End Property + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.RowValidationArgs) + Dim item = CType(args.Item, Issues.User) + If args.IsNewItem Then _Context.Users.Add(item) + _Context.SaveChanges() + End Sub + + Public Sub ValidateRowDeletion(ByVal args As DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs) + Dim item = CType(args.Items.Single(), Issues.User) + _Context.Users.Remove(item) + _Context.SaveChanges() + End Sub + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _ItemsSource = Nothing + _Context = Nothing + RaisePropertyChanged(Nameof(ItemsSource)) + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/LocalData/MainWindow.xaml b/VB/ViewModel/EntityFramework/LocalData/MainWindow.xaml new file mode 100644 index 0000000..dbb5686 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/MainWindow.xaml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/LocalData/MainWindow.xaml.vb b/VB/ViewModel/EntityFramework/LocalData/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/EntityFramework/LocalData/My Project/AssemblyInfo.vb b/VB/ViewModel/EntityFramework/LocalData/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e276f20 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/EntityFramework/LocalData/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/EntityFramework/LocalData/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/EntityFramework/LocalData/My Project/Resources.Designer.vb b/VB/ViewModel/EntityFramework/LocalData/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/LocalData/My Project/Resources.resx b/VB/ViewModel/EntityFramework/LocalData/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/EntityFramework/LocalData/My Project/Settings.Designer.vb b/VB/ViewModel/EntityFramework/LocalData/My Project/Settings.Designer.vb new file mode 100644 index 0000000..dbfe735 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EntityFrameworkIssues.My.MySettings + Get + Return Global.EntityFrameworkIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/LocalData/My Project/Settings.settings b/VB/ViewModel/EntityFramework/LocalData/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/LocalData/packages.config b/VB/ViewModel/EntityFramework/LocalData/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/VB/ViewModel/EntityFramework/LocalData/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/App.config b/VB/ViewModel/EntityFramework/PagedAsyncSource/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/Application.xaml b/VB/ViewModel/EntityFramework/PagedAsyncSource/Application.xaml new file mode 100644 index 0000000..f3c3806 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/Application.xaml.vb b/VB/ViewModel/EntityFramework/PagedAsyncSource/Application.xaml.vb new file mode 100644 index 0000000..883334e --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/Application.xaml.vb @@ -0,0 +1,8 @@ +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory() + End Sub +End Class diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/Issue.vb b/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/Issue.vb new file mode 100644 index 0000000..38f19e4 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/Issue.vb @@ -0,0 +1,24 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace + diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/IssuesContext.vb b/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/IssuesContext.vb new file mode 100644 index 0000000..67359c4 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/IssuesContext.vb @@ -0,0 +1,24 @@ +Imports System.Data.Entity + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Shared Sub New() + Database.SetInitializer(New IssuesContextInitializer()) + End Sub + + Public Sub New() + End Sub + + Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder) + MyBase.OnModelCreating(modelBuilder) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Created) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Votes) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace + diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/IssuesContextInitializer.vb b/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..0a19474 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/IssuesContextInitializer.vb @@ -0,0 +1,47 @@ +Imports System +Imports System.Data.Entity +Imports System.Linq + +Namespace Issues + Public Class IssuesContextInitializer + Inherits DropCreateDatabaseIfModelChanges(Of IssuesContext) + + ': DropCreateDatabaseAlways { + + Public Shared Sub ResetData() + Using context = New IssuesContext() + context.Users.Load() + context.Users.RemoveRange(context.Users) + context.SaveChanges() + CreateData(context) + End Using + End Sub + + Protected Overrides Sub Seed(ByVal context As IssuesContext) + MyBase.Seed(context) + CreateData(context) + End Sub + + Private Shared Sub CreateData(ByVal context As IssuesContext) + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Class +End Namespace diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/OutlookDataGenerator.vb b/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/User.vb b/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/MainViewModel.vb b/VB/ViewModel/EntityFramework/PagedAsyncSource/MainViewModel.vb new file mode 100644 index 0000000..b884c28 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/MainViewModel.vb @@ -0,0 +1,62 @@ +Imports DevExpress.Mvvm +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports System.Data.Entity + +Public Class MainViewModel + Inherits ViewModelBase + + Public Sub FetchPage(ByVal args As DevExpress.Mvvm.Xpf.FetchPageAsyncArgs) + Const pageTakeCount As Integer = 5 + args.Result = Task.Run(Of DevExpress.Xpf.Data.FetchRowsResult)(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.AsNoTracking().SortBy(args.SortOrder, defaultUniqueSortPropertyName:=NameOf(Issues.Issue.Id)).Where(MakeFilterExpression(CType(args.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.Skip(args.Skip).Take(args.Take * pageTakeCount).ToArray() + End Function) + End Sub + + Public Sub GetTotalSummaries(ByVal args As DevExpress.Mvvm.Xpf.GetSummariesAsyncArgs) + args.Result = Task.Run(Function() + Dim context = New Issues.IssuesContext() + Dim queryable = context.Issues.Where(MakeFilterExpression(CType(args.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Return queryable.GetSummaries(args.Summaries) + End Function) + End Sub + + Private Function MakeFilterExpression(ByVal filter As DevExpress.Data.Filtering.CriteriaOperator) As System.Linq.Expressions.Expression(Of System.Func(Of EntityFrameworkIssues.Issues.Issue, Boolean)) + Dim converter = New DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(Of EntityFrameworkIssues.Issues.Issue)() + Return converter.Convert(filter) + End Function + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.RowValidationArgs) + Dim item = CType(args.Item, Issues.Issue) + Dim context = New Issues.IssuesContext() + context.Entry(item).State = If(args.IsNewItem, EntityState.Added, EntityState.Modified) + Try + context.SaveChanges() + Finally + context.Entry(item).State = EntityState.Detached + End Try + End Sub + Private _Users As System.Collections.IList + + Public ReadOnly Property Users As System.Collections.IList + Get + If _Users Is Nothing AndAlso Not IsInDesignMode Then + Dim context = New EntityFrameworkIssues.Issues.IssuesContext() + _Users = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End If + Return _Users + End Get + End Property + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _Users = Nothing + RaisePropertyChanged(Nameof(Users)) + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml b/VB/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..ec18906 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml.vb b/VB/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/AssemblyInfo.vb b/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e276f20 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/Resources.Designer.vb b/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/Resources.resx b/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/Settings.Designer.vb b/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/Settings.Designer.vb new file mode 100644 index 0000000..dbfe735 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EntityFrameworkIssues.My.MySettings + Get + Return Global.EntityFrameworkIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/Settings.settings b/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/PagedAsyncSource.sln b/VB/ViewModel/EntityFramework/PagedAsyncSource/PagedAsyncSource.sln new file mode 100644 index 0000000..ea1b02b --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/PagedAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PagedAsyncSource", "PagedAsyncSource.vbproj", "{D934199A-97C6-3537-EE16-383653D1F7F6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D934199A-97C6-3537-EE16-383653D1F7F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D934199A-97C6-3537-EE16-383653D1F7F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D934199A-97C6-3537-EE16-383653D1F7F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D934199A-97C6-3537-EE16-383653D1F7F6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {69989B09-7F8A-4739-93FF-D5AFD599722B} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/PagedAsyncSource.vbproj b/VB/ViewModel/EntityFramework/PagedAsyncSource/PagedAsyncSource.vbproj new file mode 100644 index 0000000..c4785b7 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/PagedAsyncSource.vbproj @@ -0,0 +1,193 @@ + + + + + Debug + AnyCPU + {D934199A-97C6-3537-EE16-383653D1F7F6} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + Custom + true + true + + + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/PagedAsyncSource/packages.config b/VB/ViewModel/EntityFramework/PagedAsyncSource/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/VB/ViewModel/EntityFramework/PagedAsyncSource/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/ServerMode/App.config b/VB/ViewModel/EntityFramework/ServerMode/App.config new file mode 100644 index 0000000..18a536d --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/ServerMode/Application.xaml b/VB/ViewModel/EntityFramework/ServerMode/Application.xaml new file mode 100644 index 0000000..f3c3806 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/EntityFramework/ServerMode/Application.xaml.vb b/VB/ViewModel/EntityFramework/ServerMode/Application.xaml.vb new file mode 100644 index 0000000..883334e --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/Application.xaml.vb @@ -0,0 +1,8 @@ +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + DevExpress.Internal.DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory() + End Sub +End Class diff --git a/VB/ViewModel/EntityFramework/ServerMode/EditIssueInfo.vb b/VB/ViewModel/EntityFramework/ServerMode/EditIssueInfo.vb new file mode 100644 index 0000000..c0e5f5f --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/EditIssueInfo.vb @@ -0,0 +1,15 @@ +Imports DevExpress.Mvvm +Imports System.Collections.Generic +Imports EntityFrameworkIssues.Issues + +Public Class EditIssueInfo + Inherits BindableBase + + Public Sub New(ByVal context As IssuesContext, ByVal users As IList) + Me.Context = context + Me.Users = users + End Sub + + Public ReadOnly Property Context As IssuesContext + Public ReadOnly Property Users As IList +End Class diff --git a/VB/ViewModel/EntityFramework/ServerMode/IssueDetailView.xaml b/VB/ViewModel/EntityFramework/ServerMode/IssueDetailView.xaml new file mode 100644 index 0000000..7bdbd7a --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/ServerMode/IssueDetailView.xaml.vb b/VB/ViewModel/EntityFramework/ServerMode/IssueDetailView.xaml.vb new file mode 100644 index 0000000..a9c5107 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/IssueDetailView.xaml.vb @@ -0,0 +1,3 @@ +Public Class IssueDetailView + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/ServerMode/Issues/Issue.vb b/VB/ViewModel/EntityFramework/ServerMode/Issues/Issue.vb new file mode 100644 index 0000000..38f19e4 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/Issues/Issue.vb @@ -0,0 +1,24 @@ +Namespace Issues + Public Class Issue + Public Property Id As Integer + Public Property Subject As String + Public Property UserId As Integer + Public Overridable Property User As User + Public Property Created As Date + Public Property Votes As Integer + Public Property Priority As Priority + + Public Sub New() + Created = Date.Now + End Sub + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace + diff --git a/VB/ViewModel/EntityFramework/ServerMode/Issues/IssuesContext.vb b/VB/ViewModel/EntityFramework/ServerMode/Issues/IssuesContext.vb new file mode 100644 index 0000000..67359c4 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/Issues/IssuesContext.vb @@ -0,0 +1,24 @@ +Imports System.Data.Entity + +Namespace Issues + Public Class IssuesContext + Inherits DbContext + + Shared Sub New() + Database.SetInitializer(New IssuesContextInitializer()) + End Sub + + Public Sub New() + End Sub + + Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder) + MyBase.OnModelCreating(modelBuilder) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Created) + modelBuilder.Entity(Of Issue)().HasIndex(Function(x) x.Votes) + End Sub + + Public Property Issues As DbSet(Of Issue) + Public Property Users As DbSet(Of User) + End Class +End Namespace + diff --git a/VB/ViewModel/EntityFramework/ServerMode/Issues/IssuesContextInitializer.vb b/VB/ViewModel/EntityFramework/ServerMode/Issues/IssuesContextInitializer.vb new file mode 100644 index 0000000..0a19474 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/Issues/IssuesContextInitializer.vb @@ -0,0 +1,47 @@ +Imports System +Imports System.Data.Entity +Imports System.Linq + +Namespace Issues + Public Class IssuesContextInitializer + Inherits DropCreateDatabaseIfModelChanges(Of IssuesContext) + + ': DropCreateDatabaseAlways { + + Public Shared Sub ResetData() + Using context = New IssuesContext() + context.Users.Load() + context.Users.RemoveRange(context.Users) + context.SaveChanges() + CreateData(context) + End Using + End Sub + + Protected Overrides Sub Seed(ByVal context As IssuesContext) + MyBase.Seed(context) + CreateData(context) + End Sub + + Private Shared Sub CreateData(ByVal context As IssuesContext) + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User() With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + context.Users.AddRange(users) + context.SaveChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue() With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Id, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + context.Issues.AddRange(issues) + context.SaveChanges() + End Sub + End Class +End Namespace diff --git a/VB/ViewModel/EntityFramework/ServerMode/Issues/OutlookDataGenerator.vb b/VB/ViewModel/EntityFramework/ServerMode/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/ServerMode/Issues/User.vb b/VB/ViewModel/EntityFramework/ServerMode/Issues/User.vb new file mode 100644 index 0000000..e72b242 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/Issues/User.vb @@ -0,0 +1,11 @@ +Imports System.Collections.Generic + +Namespace Issues + Public Class User + Public Property Id As Integer + Public Property FirstName As String + Public Property LastName As String + Public Overridable Property Issues As ICollection(Of Issue) + End Class +End Namespace + diff --git a/VB/ViewModel/EntityFramework/ServerMode/MainViewModel.vb b/VB/ViewModel/EntityFramework/ServerMode/MainViewModel.vb new file mode 100644 index 0000000..2a8a03d --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/MainViewModel.vb @@ -0,0 +1,77 @@ +Imports DevExpress.Mvvm +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports System.Data.Entity +Imports EntityFrameworkIssues.Issues +Imports DevExpress.Mvvm.Xpf +Imports System + +Public Class MainViewModel + Inherits ViewModelBase + Private _ServerModeSource As DevExpress.Data.Linq.EntityServerModeSource + + Public ReadOnly Property ServerModeSource As DevExpress.Data.Linq.EntityServerModeSource + Get + If _ServerModeSource Is Nothing Then + Dim context = New Issues.IssuesContext() + _ServerModeSource = New DevExpress.Data.Linq.EntityServerModeSource With { + .KeyExpression = NameOf(Issues.Issue.Id), + .QueryableSource = context.Issues.AsNoTracking() + } + End If + Return _ServerModeSource + End Get + End Property + Private _Users As System.Collections.IList + + Public ReadOnly Property Users As System.Collections.IList + Get + If _Users Is Nothing AndAlso Not IsInDesignMode Then + Dim context = New EntityFrameworkIssues.Issues.IssuesContext() + _Users = context.Users.[Select](Function(user) New With { + .Id = user.Id, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End If + Return _Users + End Get + End Property + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _Users = Nothing + RaisePropertyChanged(Nameof(Users)) + End Sub + + Public Sub CreateEditEntityViewModel(ByVal args As DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs) + Dim context = New IssuesContext() + Dim item As Issue + + If args.Key IsNot Nothing Then + item = context.Issues.Find(args.Key) + Else + item = New Issue() With { + .Created = Date.Now + } + context.Entry(item).State = EntityState.Added + End If + + args.ViewModel = New EditItemViewModel(item, New EditIssueInfo(context, Users)) + End Sub + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.EditFormRowValidationArgs) + Dim context = CType(args.Tag, EditIssueInfo).Context + context.SaveChanges() + End Sub + + Public Sub ValidateRowDeletion(ByVal args As DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs) + Dim key = CInt(args.Keys.[Single]()) + Dim item = New Issue() With { + .Id = key + } + Dim context = New IssuesContext() + context.Entry(item).State = EntityState.Deleted + context.SaveChanges() + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/ServerMode/MainWindow.xaml b/VB/ViewModel/EntityFramework/ServerMode/MainWindow.xaml new file mode 100644 index 0000000..65c78bd --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/ServerMode/MainWindow.xaml.vb b/VB/ViewModel/EntityFramework/ServerMode/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/EntityFramework/ServerMode/My Project/AssemblyInfo.vb b/VB/ViewModel/EntityFramework/ServerMode/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e276f20 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/EntityFramework/ServerMode/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/EntityFramework/ServerMode/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/EntityFramework/ServerMode/My Project/Resources.Designer.vb b/VB/ViewModel/EntityFramework/ServerMode/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/ServerMode/My Project/Resources.resx b/VB/ViewModel/EntityFramework/ServerMode/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/EntityFramework/ServerMode/My Project/Settings.Designer.vb b/VB/ViewModel/EntityFramework/ServerMode/My Project/Settings.Designer.vb new file mode 100644 index 0000000..dbfe735 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EntityFrameworkIssues.My.MySettings + Get + Return Global.EntityFrameworkIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/EntityFramework/ServerMode/My Project/Settings.settings b/VB/ViewModel/EntityFramework/ServerMode/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/ServerMode/ServerMode.sln b/VB/ViewModel/EntityFramework/ServerMode/ServerMode.sln new file mode 100644 index 0000000..da17e36 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/ServerMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServerMode", "ServerMode.vbproj", "{D763114E-D0F5-83CF-491D-23051B57ED9A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D763114E-D0F5-83CF-491D-23051B57ED9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D763114E-D0F5-83CF-491D-23051B57ED9A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D763114E-D0F5-83CF-491D-23051B57ED9A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D763114E-D0F5-83CF-491D-23051B57ED9A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {69989B09-7F8A-4739-93FF-D5AFD599722B} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/EntityFramework/ServerMode/ServerMode.vbproj b/VB/ViewModel/EntityFramework/ServerMode/ServerMode.vbproj new file mode 100644 index 0000000..ad1d7ec --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/ServerMode.vbproj @@ -0,0 +1,202 @@ + + + + + Debug + AnyCPU + {D763114E-D0F5-83CF-491D-23051B57ED9A} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + EntityFrameworkIssues + EntityFrameworkIssues + v4.5.2 + Custom + true + true + + + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + EntityFrameworkIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\..\..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/EntityFramework/ServerMode/packages.config b/VB/ViewModel/EntityFramework/ServerMode/packages.config new file mode 100644 index 0000000..3424f94 --- /dev/null +++ b/VB/ViewModel/EntityFramework/ServerMode/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/App.config b/VB/ViewModel/XPO/InfiniteAsyncSource/App.config new file mode 100644 index 0000000..bdc9454 --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/Application.xaml b/VB/ViewModel/XPO/InfiniteAsyncSource/Application.xaml new file mode 100644 index 0000000..e2796fa --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/Application.xaml.vb b/VB/ViewModel/XPO/InfiniteAsyncSource/Application.xaml.vb new file mode 100644 index 0000000..a1d563c --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/Application.xaml.vb @@ -0,0 +1,11 @@ +Imports XPOIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + ConnectionHelper.Connect() + DemoDataHelper.Seed() + End Sub +End Class diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/InfiniteAsyncSource.sln b/VB/ViewModel/XPO/InfiniteAsyncSource/InfiniteAsyncSource.sln new file mode 100644 index 0000000..9bfec2b --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/InfiniteAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InfiniteAsyncSource", "InfiniteAsyncSource.vbproj", "{417F9E8E-532B-167E-CE23-C266F7D0A1AB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {417F9E8E-532B-167E-CE23-C266F7D0A1AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {417F9E8E-532B-167E-CE23-C266F7D0A1AB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {417F9E8E-532B-167E-CE23-C266F7D0A1AB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {417F9E8E-532B-167E-CE23-C266F7D0A1AB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/InfiniteAsyncSource.vbproj b/VB/ViewModel/XPO/InfiniteAsyncSource/InfiniteAsyncSource.vbproj new file mode 100644 index 0000000..a8fd3ab --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/InfiniteAsyncSource.vbproj @@ -0,0 +1,178 @@ + + + + Debug + AnyCPU + {417F9E8E-532B-167E-CE23-C266F7D0A1AB} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + XPOIssues + XPOIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/ConnectionHelper.vb b/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/ConnectionHelper.vb new file mode 100644 index 0000000..e05a409 --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/ConnectionHelper.vb @@ -0,0 +1,25 @@ +Imports DevExpress.Xpo +Imports DevExpress.Xpo.DB +Imports DevExpress.Xpo.Metadata +Imports System +Imports System.Configuration + +Namespace Issues + Public Module ConnectionHelper + Private ReadOnly PersistentTypes As Type() = New Type() {GetType(Issue), GetType(User)} + + Public Sub Connect() + XpoDefault.DataLayer = CreateDataLayer(True) + End Sub + + Private Function CreateDataLayer(ByVal threadSafe As Boolean) As IDataLayer + Dim connStr As String = If(ConfigurationManager.ConnectionStrings("XpoTutorial")?.ConnectionString, "XpoProvider=InMemoryDataStore") + 'connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + Dim dictionary As ReflectionDictionary = New ReflectionDictionary() + dictionary.GetDataStoreSchema(PersistentTypes) ' Pass all of your persistent object types to this method. + Dim autoCreateOption As AutoCreateOption = AutoCreateOption.DatabaseAndSchema ' Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + Dim provider As IDataStore = XpoDefault.GetConnectionProvider(connStr, autoCreateOption) + Return If(threadSafe, CType(New ThreadSafeDataLayer(dictionary, provider), IDataLayer), New SimpleDataLayer(dictionary, provider)) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/Customer.vb b/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/Customer.vb new file mode 100644 index 0000000..e3a816a --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/Customer.vb @@ -0,0 +1,40 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class User + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + End Sub + + Private _FirstName As String + + Public Property FirstName As String + Get + Return _FirstName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.FirstName), _FirstName, value) + End Set + End Property + + Private _LastName As String + + Public Property LastName As String + Get + Return _LastName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.LastName), _LastName, value) + End Set + End Property + + + Public ReadOnly Property Issues As XPCollection(Of Issue) + Get + Return GetCollection(Of Issue)(NameOf(User.Issues)) + End Get + End Property + End Class +End Namespace diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/DemoDataHelper.vb b/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/DemoDataHelper.vb new file mode 100644 index 0000000..a4fb3de --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/DemoDataHelper.vb @@ -0,0 +1,30 @@ +Imports DevExpress.Xpo +Imports System +Imports System.Linq + +Namespace Issues + Public Module DemoDataHelper + Public Sub Seed() + Using uow = New DevExpress.Xpo.UnitOfWork() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User(uow) With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + uow.CommitChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue(uow) With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Oid, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + uow.CommitChanges() + End Using + End Sub + End Module +End Namespace + diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/Issue.vb b/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/Issue.vb new file mode 100644 index 0000000..7aab998 --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/Issue.vb @@ -0,0 +1,88 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class Issue + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + Created = Date.Now + End Sub + + Private _Subject As String + + + Public Property Subject As String + Get + Return _Subject + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(Issue.Subject), _Subject, value) + End Set + End Property + + Private _UserId As Integer + + Public Property UserId As Integer + Get + Return _UserId + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.UserId), _UserId, value) + End Set + End Property + + Private _User As User + + + Public Property User As User + Get + Return _User + End Get + Set(ByVal value As User) + SetPropertyValue(NameOf(Issue.User), _User, value) + End Set + End Property + + Private _Created As Date + + Public Property Created As Date + Get + Return _Created + End Get + Set(ByVal value As Date) + SetPropertyValue(NameOf(Issue.Created), _Created, value) + End Set + End Property + + Private _Votes As Integer + + Public Property Votes As Integer + Get + Return _Votes + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.Votes), _Votes, value) + End Set + End Property + + Private _Priority As Priority + + Public Property Priority As Priority + Get + Return _Priority + End Get + Set(ByVal value As Priority) + SetPropertyValue(NameOf(Issue.Priority), _Priority, value) + End Set + End Property + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace \ No newline at end of file diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb b/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/MainViewModel.vb b/VB/ViewModel/XPO/InfiniteAsyncSource/MainViewModel.vb new file mode 100644 index 0000000..aa7ddae --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/MainViewModel.vb @@ -0,0 +1,93 @@ +Imports DevExpress.Mvvm +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports DevExpress.Xpo + +Public Class MainViewModel + Inherits ViewModelBase + Private _DetachedObjectsHelper As DetachedObjectsHelper(Of XPOIssues.Issues.Issue) + + Public ReadOnly Property DetachedObjectsHelper As DetachedObjectsHelper(Of XPOIssues.Issues.Issue) + Get + If _DetachedObjectsHelper Is Nothing Then + Using session = New Session() + Dim classInfo = session.GetClassInfo(Of XPOIssues.Issues.Issue)() + Dim properties = classInfo.Members.Where(Function(member) member.IsPublic AndAlso member.IsPersistent).[Select](Function(member) member.Name).ToArray() + _DetachedObjectsHelper = DevExpress.Xpf.Data.DetachedObjectsHelper(Of XPOIssues.Issues.Issue).Create(classInfo.KeyProperty.Name, properties) + End Using + End If + Return _DetachedObjectsHelper + End Get + End Property + + Public ReadOnly Property Properties As System.ComponentModel.PropertyDescriptorCollection + Get + Return DetachedObjectsHelper.Properties + End Get + End Property + + Public Sub FetchRows(ByVal args As DevExpress.Mvvm.Xpf.FetchRowsAsyncArgs) + args.Result = Task.Run(Of DevExpress.Xpf.Data.FetchRowsResult)(Function() + Using session = New DevExpress.Xpo.Session() + Dim queryable = session.Query(Of Issues.Issue)().SortBy(args.SortOrder, defaultUniqueSortPropertyName:=NameOf(Issues.Issue.Oid)).Where(MakeFilterExpression(CType(args.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Dim items = queryable.Skip(args.Skip).Take(If(args.Take, 100)).ToArray() + Return DetachedObjectsHelper.ConvertToDetachedObjects(items) + End Using + End Function) + End Sub + + Public Sub GetTotalSummaries(ByVal args As DevExpress.Mvvm.Xpf.GetSummariesAsyncArgs) + args.Result = Task.Run(Function() + Using session = New DevExpress.Xpo.Session() + Return session.Query(Of Issues.Issue)().Where(MakeFilterExpression(CType(args.Filter, DevExpress.Data.Filtering.CriteriaOperator))).GetSummaries(args.Summaries) + End Using + End Function) + End Sub + + Private Function MakeFilterExpression(ByVal filter As DevExpress.Data.Filtering.CriteriaOperator) As System.Linq.Expressions.Expression(Of System.Func(Of XPOIssues.Issues.Issue, Boolean)) + Dim converter = New DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(Of XPOIssues.Issues.Issue)() + Return converter.Convert(filter) + End Function + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.RowValidationArgs) + Using unitOfWork = New DevExpress.Xpo.UnitOfWork() + Dim item = If(args.IsNewItem, New Issues.Issue(unitOfWork), unitOfWork.GetObjectByKey(Of Issues.Issue)(DetachedObjectsHelper.GetKey(args.Item))) + DetachedObjectsHelper.ApplyProperties(item, args.Item) + unitOfWork.CommitChanges() + + If args.IsNewItem Then + DetachedObjectsHelper.SetKey(args.Item, item.Oid) + End If + End Using + End Sub + + Public Sub ValidateRowDeletion(ByVal args As DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs) + Using unitOfWork = New DevExpress.Xpo.UnitOfWork() + Dim key = DetachedObjectsHelper.GetKey(args.Items.[Single]()) + Dim item = unitOfWork.GetObjectByKey(Of Issues.Issue)(key) + unitOfWork.Delete(item) + unitOfWork.CommitChanges() + End Using + End Sub + Private _Users As System.Collections.IList + + Public ReadOnly Property Users As System.Collections.IList + Get + If _Users Is Nothing AndAlso Not IsInDesignMode Then + Dim session = New DevExpress.Xpo.Session() + _Users = session.Query(Of XPOIssues.Issues.User).OrderBy(Function(user) user.Oid).[Select](Function(user) New With { + .Id = user.Oid, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End If + Return _Users + End Get + End Property + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _Users = Nothing + RaisePropertyChanged(Nameof(Users)) + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml b/VB/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..049894b --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml.vb b/VB/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/AssemblyInfo.vb b/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e20351d --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/Resources.Designer.vb b/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/Resources.resx b/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/Settings.Designer.vb b/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/Settings.Designer.vb new file mode 100644 index 0000000..188aca7 --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.XPOIssues.My.MySettings + Get + Return Global.XPOIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/Settings.settings b/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/XPO/InfiniteAsyncSource/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/App.config b/VB/ViewModel/XPO/InstantFeedbackMode/App.config new file mode 100644 index 0000000..bdc9454 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/Application.xaml b/VB/ViewModel/XPO/InstantFeedbackMode/Application.xaml new file mode 100644 index 0000000..e2796fa --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/Application.xaml.vb b/VB/ViewModel/XPO/InstantFeedbackMode/Application.xaml.vb new file mode 100644 index 0000000..a1d563c --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/Application.xaml.vb @@ -0,0 +1,11 @@ +Imports XPOIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + ConnectionHelper.Connect() + DemoDataHelper.Seed() + End Sub +End Class diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/EditIssueInfo.vb b/VB/ViewModel/XPO/InstantFeedbackMode/EditIssueInfo.vb new file mode 100644 index 0000000..f410eb2 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/EditIssueInfo.vb @@ -0,0 +1,15 @@ +Imports DevExpress.Mvvm +Imports System.Collections.Generic +Imports XPOIssues.Issues + +Public Class EditIssueInfo + Inherits BindableBase + + Public Sub New(ByVal unitOfWork As DevExpress.Xpo.UnitOfWork, ByVal users As IList) + Me.UnitOfWork = unitOfWork + Me.Users = users + End Sub + + Public ReadOnly Property UnitOfWork As DevExpress.Xpo.UnitOfWork + Public ReadOnly Property Users As IList +End Class diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/InstantFeedbackMode.sln b/VB/ViewModel/XPO/InstantFeedbackMode/InstantFeedbackMode.sln new file mode 100644 index 0000000..1e202e2 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/InstantFeedbackMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InstantFeedbackMode", "InstantFeedbackMode.vbproj", "{6FA2435A-BFCA-A2B0-3FC5-B095F1ACF14F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6FA2435A-BFCA-A2B0-3FC5-B095F1ACF14F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6FA2435A-BFCA-A2B0-3FC5-B095F1ACF14F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6FA2435A-BFCA-A2B0-3FC5-B095F1ACF14F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6FA2435A-BFCA-A2B0-3FC5-B095F1ACF14F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/InstantFeedbackMode.vbproj b/VB/ViewModel/XPO/InstantFeedbackMode/InstantFeedbackMode.vbproj new file mode 100644 index 0000000..101c737 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/InstantFeedbackMode.vbproj @@ -0,0 +1,187 @@ + + + + Debug + AnyCPU + {6FA2435A-BFCA-A2B0-3FC5-B095F1ACF14F} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + XPOIssues + XPOIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/IssueDetailView.xaml b/VB/ViewModel/XPO/InstantFeedbackMode/IssueDetailView.xaml new file mode 100644 index 0000000..e00f8b8 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/IssueDetailView.xaml.vb b/VB/ViewModel/XPO/InstantFeedbackMode/IssueDetailView.xaml.vb new file mode 100644 index 0000000..a9c5107 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/IssueDetailView.xaml.vb @@ -0,0 +1,3 @@ +Public Class IssueDetailView + +End Class \ No newline at end of file diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/Issues/ConnectionHelper.vb b/VB/ViewModel/XPO/InstantFeedbackMode/Issues/ConnectionHelper.vb new file mode 100644 index 0000000..e05a409 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/Issues/ConnectionHelper.vb @@ -0,0 +1,25 @@ +Imports DevExpress.Xpo +Imports DevExpress.Xpo.DB +Imports DevExpress.Xpo.Metadata +Imports System +Imports System.Configuration + +Namespace Issues + Public Module ConnectionHelper + Private ReadOnly PersistentTypes As Type() = New Type() {GetType(Issue), GetType(User)} + + Public Sub Connect() + XpoDefault.DataLayer = CreateDataLayer(True) + End Sub + + Private Function CreateDataLayer(ByVal threadSafe As Boolean) As IDataLayer + Dim connStr As String = If(ConfigurationManager.ConnectionStrings("XpoTutorial")?.ConnectionString, "XpoProvider=InMemoryDataStore") + 'connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + Dim dictionary As ReflectionDictionary = New ReflectionDictionary() + dictionary.GetDataStoreSchema(PersistentTypes) ' Pass all of your persistent object types to this method. + Dim autoCreateOption As AutoCreateOption = AutoCreateOption.DatabaseAndSchema ' Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + Dim provider As IDataStore = XpoDefault.GetConnectionProvider(connStr, autoCreateOption) + Return If(threadSafe, CType(New ThreadSafeDataLayer(dictionary, provider), IDataLayer), New SimpleDataLayer(dictionary, provider)) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/Issues/Customer.vb b/VB/ViewModel/XPO/InstantFeedbackMode/Issues/Customer.vb new file mode 100644 index 0000000..e3a816a --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/Issues/Customer.vb @@ -0,0 +1,40 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class User + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + End Sub + + Private _FirstName As String + + Public Property FirstName As String + Get + Return _FirstName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.FirstName), _FirstName, value) + End Set + End Property + + Private _LastName As String + + Public Property LastName As String + Get + Return _LastName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.LastName), _LastName, value) + End Set + End Property + + + Public ReadOnly Property Issues As XPCollection(Of Issue) + Get + Return GetCollection(Of Issue)(NameOf(User.Issues)) + End Get + End Property + End Class +End Namespace diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/Issues/DemoDataHelper.vb b/VB/ViewModel/XPO/InstantFeedbackMode/Issues/DemoDataHelper.vb new file mode 100644 index 0000000..a4fb3de --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/Issues/DemoDataHelper.vb @@ -0,0 +1,30 @@ +Imports DevExpress.Xpo +Imports System +Imports System.Linq + +Namespace Issues + Public Module DemoDataHelper + Public Sub Seed() + Using uow = New DevExpress.Xpo.UnitOfWork() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User(uow) With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + uow.CommitChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue(uow) With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Oid, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + uow.CommitChanges() + End Using + End Sub + End Module +End Namespace + diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/Issues/Issue.vb b/VB/ViewModel/XPO/InstantFeedbackMode/Issues/Issue.vb new file mode 100644 index 0000000..7aab998 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/Issues/Issue.vb @@ -0,0 +1,88 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class Issue + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + Created = Date.Now + End Sub + + Private _Subject As String + + + Public Property Subject As String + Get + Return _Subject + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(Issue.Subject), _Subject, value) + End Set + End Property + + Private _UserId As Integer + + Public Property UserId As Integer + Get + Return _UserId + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.UserId), _UserId, value) + End Set + End Property + + Private _User As User + + + Public Property User As User + Get + Return _User + End Get + Set(ByVal value As User) + SetPropertyValue(NameOf(Issue.User), _User, value) + End Set + End Property + + Private _Created As Date + + Public Property Created As Date + Get + Return _Created + End Get + Set(ByVal value As Date) + SetPropertyValue(NameOf(Issue.Created), _Created, value) + End Set + End Property + + Private _Votes As Integer + + Public Property Votes As Integer + Get + Return _Votes + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.Votes), _Votes, value) + End Set + End Property + + Private _Priority As Priority + + Public Property Priority As Priority + Get + Return _Priority + End Get + Set(ByVal value As Priority) + SetPropertyValue(NameOf(Issue.Priority), _Priority, value) + End Set + End Property + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace \ No newline at end of file diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/Issues/OutlookDataGenerator.vb b/VB/ViewModel/XPO/InstantFeedbackMode/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/MainViewModel.vb b/VB/ViewModel/XPO/InstantFeedbackMode/MainViewModel.vb new file mode 100644 index 0000000..61aa630 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/MainViewModel.vb @@ -0,0 +1,71 @@ +Imports DevExpress.Mvvm +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports DevExpress.Xpo +Imports XPOIssues.Issues +Imports DevExpress.Mvvm.Xpf +Imports System + +Public Class MainViewModel + Inherits ViewModelBase + Private _InstantFeedbackSource As DevExpress.Xpo.XPInstantFeedbackView + + Public ReadOnly Property InstantFeedbackSource As DevExpress.Xpo.XPInstantFeedbackView + Get + If _InstantFeedbackSource Is Nothing Then + Dim properties = New DevExpress.Xpo.ServerViewProperty() { + New DevExpress.Xpo.ServerViewProperty("Oid", DevExpress.Xpo.SortDirection.Ascending, New DevExpress.Data.Filtering.OperandProperty("Oid")), + New DevExpress.Xpo.ServerViewProperty("Subject", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Subject")), + New DevExpress.Xpo.ServerViewProperty("UserId", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("UserId")), + New DevExpress.Xpo.ServerViewProperty("Created", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Created")), + New DevExpress.Xpo.ServerViewProperty("Votes", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Votes")), + New DevExpress.Xpo.ServerViewProperty("Priority", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Priority")) + } + _InstantFeedbackSource = New DevExpress.Xpo.XPInstantFeedbackView(GetType(Issues.Issue), properties, Nothing) + AddHandler _InstantFeedbackSource.ResolveSession, Sub(o, e) e.Session = New DevExpress.Xpo.Session() + End If + Return _InstantFeedbackSource + End Get + End Property + Private _Users As System.Collections.IList + + Public ReadOnly Property Users As System.Collections.IList + Get + If _Users Is Nothing AndAlso Not IsInDesignMode Then + Dim session = New DevExpress.Xpo.Session() + _Users = session.Query(Of XPOIssues.Issues.User).OrderBy(Function(user) user.Oid).[Select](Function(user) New With { + .Id = user.Oid, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End If + Return _Users + End Get + End Property + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _Users = Nothing + RaisePropertyChanged(Nameof(Users)) + End Sub + + Public Sub CreateEditEntityViewModel(ByVal args As DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs) + Dim unitOfWork = New UnitOfWork() + Dim item = If(args.Key IsNot Nothing, unitOfWork.GetObjectByKey(Of Issue)(args.Key), New Issue(unitOfWork)) + args.ViewModel = New EditItemViewModel(item, New EditIssueInfo(unitOfWork, Users), dispose:=Sub() unitOfWork.Dispose()) + End Sub + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.EditFormRowValidationArgs) + Dim unitOfWork = CType(args.Tag, EditIssueInfo).UnitOfWork + unitOfWork.CommitChanges() + End Sub + + Public Sub ValidateRowDeletion(ByVal args As DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs) + Using unitOfWork = New UnitOfWork() + Dim key = CInt(args.Keys.[Single]()) + Dim item = unitOfWork.GetObjectByKey(Of Issue)(key) + unitOfWork.Delete(item) + unitOfWork.CommitChanges() + End Using + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml b/VB/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml new file mode 100644 index 0000000..9305d30 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml.vb b/VB/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/My Project/AssemblyInfo.vb b/VB/ViewModel/XPO/InstantFeedbackMode/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e20351d --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/XPO/InstantFeedbackMode/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/XPO/InstantFeedbackMode/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/My Project/Resources.Designer.vb b/VB/ViewModel/XPO/InstantFeedbackMode/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/My Project/Resources.resx b/VB/ViewModel/XPO/InstantFeedbackMode/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/XPO/InstantFeedbackMode/My Project/Settings.Designer.vb b/VB/ViewModel/XPO/InstantFeedbackMode/My Project/Settings.Designer.vb new file mode 100644 index 0000000..188aca7 --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.XPOIssues.My.MySettings + Get + Return Global.XPOIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/XPO/InstantFeedbackMode/My Project/Settings.settings b/VB/ViewModel/XPO/InstantFeedbackMode/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/XPO/InstantFeedbackMode/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/LocalData/App.config b/VB/ViewModel/XPO/LocalData/App.config new file mode 100644 index 0000000..bdc9454 --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/LocalData/Application.xaml b/VB/ViewModel/XPO/LocalData/Application.xaml new file mode 100644 index 0000000..e2796fa --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/XPO/LocalData/Application.xaml.vb b/VB/ViewModel/XPO/LocalData/Application.xaml.vb new file mode 100644 index 0000000..a1d563c --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/Application.xaml.vb @@ -0,0 +1,11 @@ +Imports XPOIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + ConnectionHelper.Connect() + DemoDataHelper.Seed() + End Sub +End Class diff --git a/VB/ViewModel/XPO/LocalData/Issues/ConnectionHelper.vb b/VB/ViewModel/XPO/LocalData/Issues/ConnectionHelper.vb new file mode 100644 index 0000000..e05a409 --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/Issues/ConnectionHelper.vb @@ -0,0 +1,25 @@ +Imports DevExpress.Xpo +Imports DevExpress.Xpo.DB +Imports DevExpress.Xpo.Metadata +Imports System +Imports System.Configuration + +Namespace Issues + Public Module ConnectionHelper + Private ReadOnly PersistentTypes As Type() = New Type() {GetType(Issue), GetType(User)} + + Public Sub Connect() + XpoDefault.DataLayer = CreateDataLayer(True) + End Sub + + Private Function CreateDataLayer(ByVal threadSafe As Boolean) As IDataLayer + Dim connStr As String = If(ConfigurationManager.ConnectionStrings("XpoTutorial")?.ConnectionString, "XpoProvider=InMemoryDataStore") + 'connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + Dim dictionary As ReflectionDictionary = New ReflectionDictionary() + dictionary.GetDataStoreSchema(PersistentTypes) ' Pass all of your persistent object types to this method. + Dim autoCreateOption As AutoCreateOption = AutoCreateOption.DatabaseAndSchema ' Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + Dim provider As IDataStore = XpoDefault.GetConnectionProvider(connStr, autoCreateOption) + Return If(threadSafe, CType(New ThreadSafeDataLayer(dictionary, provider), IDataLayer), New SimpleDataLayer(dictionary, provider)) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/XPO/LocalData/Issues/Customer.vb b/VB/ViewModel/XPO/LocalData/Issues/Customer.vb new file mode 100644 index 0000000..e3a816a --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/Issues/Customer.vb @@ -0,0 +1,40 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class User + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + End Sub + + Private _FirstName As String + + Public Property FirstName As String + Get + Return _FirstName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.FirstName), _FirstName, value) + End Set + End Property + + Private _LastName As String + + Public Property LastName As String + Get + Return _LastName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.LastName), _LastName, value) + End Set + End Property + + + Public ReadOnly Property Issues As XPCollection(Of Issue) + Get + Return GetCollection(Of Issue)(NameOf(User.Issues)) + End Get + End Property + End Class +End Namespace diff --git a/VB/ViewModel/XPO/LocalData/Issues/DemoDataHelper.vb b/VB/ViewModel/XPO/LocalData/Issues/DemoDataHelper.vb new file mode 100644 index 0000000..a4fb3de --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/Issues/DemoDataHelper.vb @@ -0,0 +1,30 @@ +Imports DevExpress.Xpo +Imports System +Imports System.Linq + +Namespace Issues + Public Module DemoDataHelper + Public Sub Seed() + Using uow = New DevExpress.Xpo.UnitOfWork() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User(uow) With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + uow.CommitChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue(uow) With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Oid, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + uow.CommitChanges() + End Using + End Sub + End Module +End Namespace + diff --git a/VB/ViewModel/XPO/LocalData/Issues/Issue.vb b/VB/ViewModel/XPO/LocalData/Issues/Issue.vb new file mode 100644 index 0000000..7aab998 --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/Issues/Issue.vb @@ -0,0 +1,88 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class Issue + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + Created = Date.Now + End Sub + + Private _Subject As String + + + Public Property Subject As String + Get + Return _Subject + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(Issue.Subject), _Subject, value) + End Set + End Property + + Private _UserId As Integer + + Public Property UserId As Integer + Get + Return _UserId + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.UserId), _UserId, value) + End Set + End Property + + Private _User As User + + + Public Property User As User + Get + Return _User + End Get + Set(ByVal value As User) + SetPropertyValue(NameOf(Issue.User), _User, value) + End Set + End Property + + Private _Created As Date + + Public Property Created As Date + Get + Return _Created + End Get + Set(ByVal value As Date) + SetPropertyValue(NameOf(Issue.Created), _Created, value) + End Set + End Property + + Private _Votes As Integer + + Public Property Votes As Integer + Get + Return _Votes + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.Votes), _Votes, value) + End Set + End Property + + Private _Priority As Priority + + Public Property Priority As Priority + Get + Return _Priority + End Get + Set(ByVal value As Priority) + SetPropertyValue(NameOf(Issue.Priority), _Priority, value) + End Set + End Property + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace \ No newline at end of file diff --git a/VB/ViewModel/XPO/LocalData/Issues/OutlookDataGenerator.vb b/VB/ViewModel/XPO/LocalData/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/XPO/LocalData/LocalData.sln b/VB/ViewModel/XPO/LocalData/LocalData.sln new file mode 100644 index 0000000..d3ddb2f --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/LocalData.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LocalData", "LocalData.vbproj", "{7BF3B0E7-C954-D906-C99E-95A9599F16EC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7BF3B0E7-C954-D906-C99E-95A9599F16EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7BF3B0E7-C954-D906-C99E-95A9599F16EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7BF3B0E7-C954-D906-C99E-95A9599F16EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7BF3B0E7-C954-D906-C99E-95A9599F16EC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/XPO/LocalData/LocalData.vbproj b/VB/ViewModel/XPO/LocalData/LocalData.vbproj new file mode 100644 index 0000000..ba5ef9a --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/LocalData.vbproj @@ -0,0 +1,178 @@ + + + + Debug + AnyCPU + {7BF3B0E7-C954-D906-C99E-95A9599F16EC} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + XPOIssues + XPOIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/LocalData/MainViewModel.vb b/VB/ViewModel/XPO/LocalData/MainViewModel.vb new file mode 100644 index 0000000..fd4baca --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/MainViewModel.vb @@ -0,0 +1,37 @@ +Imports DevExpress.Mvvm +Imports System.Linq + +Public Class MainViewModel + Inherits ViewModelBase + Private _UnitOfWork As DevExpress.Xpo.UnitOfWork + Private _ItemsSource As System.Collections.Generic.IList(Of XPOIssues.Issues.User) + + Public ReadOnly Property ItemsSource As System.Collections.Generic.IList(Of XPOIssues.Issues.User) + Get + If _ItemsSource Is Nothing AndAlso Not IsInDesignMode Then + _UnitOfWork = New DevExpress.Xpo.UnitOfWork() + Dim xpCollection = New DevExpress.Xpo.XPCollection(Of Issues.User)(_UnitOfWork) + xpCollection.Sorting.Add(New DevExpress.Xpo.SortProperty(NameOf(Issues.User.Oid), DevExpress.Xpo.DB.SortingDirection.Ascending)) + _ItemsSource = xpCollection + End If + Return _ItemsSource + End Get + End Property + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.RowValidationArgs) + _UnitOfWork.CommitChanges() + End Sub + + Public Sub ValidateRowDeletion(ByVal args As DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs) + Dim item = CType(args.Items.Single(), Issues.User) + _UnitOfWork.Delete(item) + _UnitOfWork.CommitChanges() + End Sub + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _ItemsSource = Nothing + _UnitOfWork = Nothing + RaisePropertyChanged(Nameof(ItemsSource)) + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/XPO/LocalData/MainWindow.xaml b/VB/ViewModel/XPO/LocalData/MainWindow.xaml new file mode 100644 index 0000000..5a333f8 --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/MainWindow.xaml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/LocalData/MainWindow.xaml.vb b/VB/ViewModel/XPO/LocalData/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/XPO/LocalData/My Project/AssemblyInfo.vb b/VB/ViewModel/XPO/LocalData/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e20351d --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/XPO/LocalData/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/XPO/LocalData/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/XPO/LocalData/My Project/Resources.Designer.vb b/VB/ViewModel/XPO/LocalData/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/XPO/LocalData/My Project/Resources.resx b/VB/ViewModel/XPO/LocalData/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/XPO/LocalData/My Project/Settings.Designer.vb b/VB/ViewModel/XPO/LocalData/My Project/Settings.Designer.vb new file mode 100644 index 0000000..188aca7 --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.XPOIssues.My.MySettings + Get + Return Global.XPOIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/XPO/LocalData/My Project/Settings.settings b/VB/ViewModel/XPO/LocalData/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/XPO/LocalData/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/PagedAsyncSource/App.config b/VB/ViewModel/XPO/PagedAsyncSource/App.config new file mode 100644 index 0000000..bdc9454 --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/PagedAsyncSource/Application.xaml b/VB/ViewModel/XPO/PagedAsyncSource/Application.xaml new file mode 100644 index 0000000..e2796fa --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/XPO/PagedAsyncSource/Application.xaml.vb b/VB/ViewModel/XPO/PagedAsyncSource/Application.xaml.vb new file mode 100644 index 0000000..a1d563c --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/Application.xaml.vb @@ -0,0 +1,11 @@ +Imports XPOIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + ConnectionHelper.Connect() + DemoDataHelper.Seed() + End Sub +End Class diff --git a/VB/ViewModel/XPO/PagedAsyncSource/Issues/ConnectionHelper.vb b/VB/ViewModel/XPO/PagedAsyncSource/Issues/ConnectionHelper.vb new file mode 100644 index 0000000..e05a409 --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/Issues/ConnectionHelper.vb @@ -0,0 +1,25 @@ +Imports DevExpress.Xpo +Imports DevExpress.Xpo.DB +Imports DevExpress.Xpo.Metadata +Imports System +Imports System.Configuration + +Namespace Issues + Public Module ConnectionHelper + Private ReadOnly PersistentTypes As Type() = New Type() {GetType(Issue), GetType(User)} + + Public Sub Connect() + XpoDefault.DataLayer = CreateDataLayer(True) + End Sub + + Private Function CreateDataLayer(ByVal threadSafe As Boolean) As IDataLayer + Dim connStr As String = If(ConfigurationManager.ConnectionStrings("XpoTutorial")?.ConnectionString, "XpoProvider=InMemoryDataStore") + 'connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + Dim dictionary As ReflectionDictionary = New ReflectionDictionary() + dictionary.GetDataStoreSchema(PersistentTypes) ' Pass all of your persistent object types to this method. + Dim autoCreateOption As AutoCreateOption = AutoCreateOption.DatabaseAndSchema ' Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + Dim provider As IDataStore = XpoDefault.GetConnectionProvider(connStr, autoCreateOption) + Return If(threadSafe, CType(New ThreadSafeDataLayer(dictionary, provider), IDataLayer), New SimpleDataLayer(dictionary, provider)) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/XPO/PagedAsyncSource/Issues/Customer.vb b/VB/ViewModel/XPO/PagedAsyncSource/Issues/Customer.vb new file mode 100644 index 0000000..e3a816a --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/Issues/Customer.vb @@ -0,0 +1,40 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class User + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + End Sub + + Private _FirstName As String + + Public Property FirstName As String + Get + Return _FirstName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.FirstName), _FirstName, value) + End Set + End Property + + Private _LastName As String + + Public Property LastName As String + Get + Return _LastName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.LastName), _LastName, value) + End Set + End Property + + + Public ReadOnly Property Issues As XPCollection(Of Issue) + Get + Return GetCollection(Of Issue)(NameOf(User.Issues)) + End Get + End Property + End Class +End Namespace diff --git a/VB/ViewModel/XPO/PagedAsyncSource/Issues/DemoDataHelper.vb b/VB/ViewModel/XPO/PagedAsyncSource/Issues/DemoDataHelper.vb new file mode 100644 index 0000000..a4fb3de --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/Issues/DemoDataHelper.vb @@ -0,0 +1,30 @@ +Imports DevExpress.Xpo +Imports System +Imports System.Linq + +Namespace Issues + Public Module DemoDataHelper + Public Sub Seed() + Using uow = New DevExpress.Xpo.UnitOfWork() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User(uow) With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + uow.CommitChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue(uow) With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Oid, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + uow.CommitChanges() + End Using + End Sub + End Module +End Namespace + diff --git a/VB/ViewModel/XPO/PagedAsyncSource/Issues/Issue.vb b/VB/ViewModel/XPO/PagedAsyncSource/Issues/Issue.vb new file mode 100644 index 0000000..7aab998 --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/Issues/Issue.vb @@ -0,0 +1,88 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class Issue + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + Created = Date.Now + End Sub + + Private _Subject As String + + + Public Property Subject As String + Get + Return _Subject + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(Issue.Subject), _Subject, value) + End Set + End Property + + Private _UserId As Integer + + Public Property UserId As Integer + Get + Return _UserId + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.UserId), _UserId, value) + End Set + End Property + + Private _User As User + + + Public Property User As User + Get + Return _User + End Get + Set(ByVal value As User) + SetPropertyValue(NameOf(Issue.User), _User, value) + End Set + End Property + + Private _Created As Date + + Public Property Created As Date + Get + Return _Created + End Get + Set(ByVal value As Date) + SetPropertyValue(NameOf(Issue.Created), _Created, value) + End Set + End Property + + Private _Votes As Integer + + Public Property Votes As Integer + Get + Return _Votes + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.Votes), _Votes, value) + End Set + End Property + + Private _Priority As Priority + + Public Property Priority As Priority + Get + Return _Priority + End Get + Set(ByVal value As Priority) + SetPropertyValue(NameOf(Issue.Priority), _Priority, value) + End Set + End Property + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace \ No newline at end of file diff --git a/VB/ViewModel/XPO/PagedAsyncSource/Issues/OutlookDataGenerator.vb b/VB/ViewModel/XPO/PagedAsyncSource/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/XPO/PagedAsyncSource/MainViewModel.vb b/VB/ViewModel/XPO/PagedAsyncSource/MainViewModel.vb new file mode 100644 index 0000000..ef425e7 --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/MainViewModel.vb @@ -0,0 +1,86 @@ +Imports DevExpress.Mvvm +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports DevExpress.Xpo + +Public Class MainViewModel + Inherits ViewModelBase + Private _DetachedObjectsHelper As DetachedObjectsHelper(Of XPOIssues.Issues.Issue) + + Public ReadOnly Property DetachedObjectsHelper As DetachedObjectsHelper(Of XPOIssues.Issues.Issue) + Get + If _DetachedObjectsHelper Is Nothing Then + Using session = New Session() + Dim classInfo = session.GetClassInfo(Of XPOIssues.Issues.Issue)() + Dim properties = classInfo.Members.Where(Function(member) member.IsPublic AndAlso member.IsPersistent).[Select](Function(member) member.Name).ToArray() + _DetachedObjectsHelper = DevExpress.Xpf.Data.DetachedObjectsHelper(Of XPOIssues.Issues.Issue).Create(classInfo.KeyProperty.Name, properties) + End Using + End If + Return _DetachedObjectsHelper + End Get + End Property + + Public ReadOnly Property Properties As System.ComponentModel.PropertyDescriptorCollection + Get + Return DetachedObjectsHelper.Properties + End Get + End Property + + Public Sub FetchPage(ByVal args As DevExpress.Mvvm.Xpf.FetchPageAsyncArgs) + args.Result = Task.Run(Of DevExpress.Xpf.Data.FetchRowsResult)(Function() + Const pageTakeCount As Integer = 5 + + Using session = New DevExpress.Xpo.Session() + Dim queryable = session.Query(Of Issues.Issue)().SortBy(args.SortOrder, defaultUniqueSortPropertyName:=NameOf(Issues.Issue.Oid)).Where(MakeFilterExpression(CType(args.Filter, DevExpress.Data.Filtering.CriteriaOperator))) + Dim items = queryable.Skip(args.Skip).Take(args.Take * pageTakeCount).ToArray() + Return DetachedObjectsHelper.ConvertToDetachedObjects(items) + End Using + End Function) + End Sub + + Public Sub GetTotalSummaries(ByVal args As DevExpress.Mvvm.Xpf.GetSummariesAsyncArgs) + args.Result = Task.Run(Function() + Using session = New DevExpress.Xpo.Session() + Return session.Query(Of Issues.Issue)().Where(MakeFilterExpression(CType(args.Filter, DevExpress.Data.Filtering.CriteriaOperator))).GetSummaries(args.Summaries) + End Using + End Function) + End Sub + + Private Function MakeFilterExpression(ByVal filter As DevExpress.Data.Filtering.CriteriaOperator) As System.Linq.Expressions.Expression(Of System.Func(Of XPOIssues.Issues.Issue, Boolean)) + Dim converter = New DevExpress.Xpf.Data.GridFilterCriteriaToExpressionConverter(Of XPOIssues.Issues.Issue)() + Return converter.Convert(filter) + End Function + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.RowValidationArgs) + Using unitOfWork = New DevExpress.Xpo.UnitOfWork() + Dim item = If(args.IsNewItem, New Issues.Issue(unitOfWork), unitOfWork.GetObjectByKey(Of Issues.Issue)(DetachedObjectsHelper.GetKey(args.Item))) + DetachedObjectsHelper.ApplyProperties(item, args.Item) + unitOfWork.CommitChanges() + + If args.IsNewItem Then + DetachedObjectsHelper.SetKey(args.Item, item.Oid) + End If + End Using + End Sub + Private _Users As System.Collections.IList + + Public ReadOnly Property Users As System.Collections.IList + Get + If _Users Is Nothing AndAlso Not IsInDesignMode Then + Dim session = New DevExpress.Xpo.Session() + _Users = session.Query(Of XPOIssues.Issues.User).OrderBy(Function(user) user.Oid).[Select](Function(user) New With { + .Id = user.Oid, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End If + Return _Users + End Get + End Property + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _Users = Nothing + RaisePropertyChanged(Nameof(Users)) + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml b/VB/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml new file mode 100644 index 0000000..3fe3a3c --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml.vb b/VB/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/XPO/PagedAsyncSource/My Project/AssemblyInfo.vb b/VB/ViewModel/XPO/PagedAsyncSource/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e20351d --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/XPO/PagedAsyncSource/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/XPO/PagedAsyncSource/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/XPO/PagedAsyncSource/My Project/Resources.Designer.vb b/VB/ViewModel/XPO/PagedAsyncSource/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/XPO/PagedAsyncSource/My Project/Resources.resx b/VB/ViewModel/XPO/PagedAsyncSource/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/XPO/PagedAsyncSource/My Project/Settings.Designer.vb b/VB/ViewModel/XPO/PagedAsyncSource/My Project/Settings.Designer.vb new file mode 100644 index 0000000..188aca7 --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.XPOIssues.My.MySettings + Get + Return Global.XPOIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/XPO/PagedAsyncSource/My Project/Settings.settings b/VB/ViewModel/XPO/PagedAsyncSource/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/PagedAsyncSource/PagedAsyncSource.sln b/VB/ViewModel/XPO/PagedAsyncSource/PagedAsyncSource.sln new file mode 100644 index 0000000..58e4832 --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/PagedAsyncSource.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PagedAsyncSource", "PagedAsyncSource.vbproj", "{E9B003DA-11C7-8D57-34C3-945BDEBA5154}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E9B003DA-11C7-8D57-34C3-945BDEBA5154}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9B003DA-11C7-8D57-34C3-945BDEBA5154}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9B003DA-11C7-8D57-34C3-945BDEBA5154}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9B003DA-11C7-8D57-34C3-945BDEBA5154}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/XPO/PagedAsyncSource/PagedAsyncSource.vbproj b/VB/ViewModel/XPO/PagedAsyncSource/PagedAsyncSource.vbproj new file mode 100644 index 0000000..13af006 --- /dev/null +++ b/VB/ViewModel/XPO/PagedAsyncSource/PagedAsyncSource.vbproj @@ -0,0 +1,178 @@ + + + + Debug + AnyCPU + {E9B003DA-11C7-8D57-34C3-945BDEBA5154} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + XPOIssues + XPOIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/ServerMode/App.config b/VB/ViewModel/XPO/ServerMode/App.config new file mode 100644 index 0000000..bdc9454 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/ServerMode/Application.xaml b/VB/ViewModel/XPO/ServerMode/Application.xaml new file mode 100644 index 0000000..e2796fa --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/VB/ViewModel/XPO/ServerMode/Application.xaml.vb b/VB/ViewModel/XPO/ServerMode/Application.xaml.vb new file mode 100644 index 0000000..a1d563c --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/Application.xaml.vb @@ -0,0 +1,11 @@ +Imports XPOIssues.Issues + +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + Public Sub New() + ConnectionHelper.Connect() + DemoDataHelper.Seed() + End Sub +End Class diff --git a/VB/ViewModel/XPO/ServerMode/EditIssueInfo.vb b/VB/ViewModel/XPO/ServerMode/EditIssueInfo.vb new file mode 100644 index 0000000..f410eb2 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/EditIssueInfo.vb @@ -0,0 +1,15 @@ +Imports DevExpress.Mvvm +Imports System.Collections.Generic +Imports XPOIssues.Issues + +Public Class EditIssueInfo + Inherits BindableBase + + Public Sub New(ByVal unitOfWork As DevExpress.Xpo.UnitOfWork, ByVal users As IList) + Me.UnitOfWork = unitOfWork + Me.Users = users + End Sub + + Public ReadOnly Property UnitOfWork As DevExpress.Xpo.UnitOfWork + Public ReadOnly Property Users As IList +End Class diff --git a/VB/ViewModel/XPO/ServerMode/IssueDetailView.xaml b/VB/ViewModel/XPO/ServerMode/IssueDetailView.xaml new file mode 100644 index 0000000..e00f8b8 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/IssueDetailView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/ServerMode/IssueDetailView.xaml.vb b/VB/ViewModel/XPO/ServerMode/IssueDetailView.xaml.vb new file mode 100644 index 0000000..a9c5107 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/IssueDetailView.xaml.vb @@ -0,0 +1,3 @@ +Public Class IssueDetailView + +End Class \ No newline at end of file diff --git a/VB/ViewModel/XPO/ServerMode/Issues/ConnectionHelper.vb b/VB/ViewModel/XPO/ServerMode/Issues/ConnectionHelper.vb new file mode 100644 index 0000000..e05a409 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/Issues/ConnectionHelper.vb @@ -0,0 +1,25 @@ +Imports DevExpress.Xpo +Imports DevExpress.Xpo.DB +Imports DevExpress.Xpo.Metadata +Imports System +Imports System.Configuration + +Namespace Issues + Public Module ConnectionHelper + Private ReadOnly PersistentTypes As Type() = New Type() {GetType(Issue), GetType(User)} + + Public Sub Connect() + XpoDefault.DataLayer = CreateDataLayer(True) + End Sub + + Private Function CreateDataLayer(ByVal threadSafe As Boolean) As IDataLayer + Dim connStr As String = If(ConfigurationManager.ConnectionStrings("XpoTutorial")?.ConnectionString, "XpoProvider=InMemoryDataStore") + 'connStr = XpoDefault.GetConnectionPoolString(connStr); // Uncomment this line if you use a database server like SQL Server, Oracle, PostgreSql etc. + Dim dictionary As ReflectionDictionary = New ReflectionDictionary() + dictionary.GetDataStoreSchema(PersistentTypes) ' Pass all of your persistent object types to this method. + Dim autoCreateOption As AutoCreateOption = AutoCreateOption.DatabaseAndSchema ' Use AutoCreateOption.DatabaseAndSchema if the database or tables do not exist. Use AutoCreateOption.SchemaAlreadyExists if the database already exists. + Dim provider As IDataStore = XpoDefault.GetConnectionProvider(connStr, autoCreateOption) + Return If(threadSafe, CType(New ThreadSafeDataLayer(dictionary, provider), IDataLayer), New SimpleDataLayer(dictionary, provider)) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/XPO/ServerMode/Issues/Customer.vb b/VB/ViewModel/XPO/ServerMode/Issues/Customer.vb new file mode 100644 index 0000000..e3a816a --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/Issues/Customer.vb @@ -0,0 +1,40 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class User + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + End Sub + + Private _FirstName As String + + Public Property FirstName As String + Get + Return _FirstName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.FirstName), _FirstName, value) + End Set + End Property + + Private _LastName As String + + Public Property LastName As String + Get + Return _LastName + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(User.LastName), _LastName, value) + End Set + End Property + + + Public ReadOnly Property Issues As XPCollection(Of Issue) + Get + Return GetCollection(Of Issue)(NameOf(User.Issues)) + End Get + End Property + End Class +End Namespace diff --git a/VB/ViewModel/XPO/ServerMode/Issues/DemoDataHelper.vb b/VB/ViewModel/XPO/ServerMode/Issues/DemoDataHelper.vb new file mode 100644 index 0000000..a4fb3de --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/Issues/DemoDataHelper.vb @@ -0,0 +1,30 @@ +Imports DevExpress.Xpo +Imports System +Imports System.Linq + +Namespace Issues + Public Module DemoDataHelper + Public Sub Seed() + Using uow = New DevExpress.Xpo.UnitOfWork() + Dim users = OutlookDataGenerator.Users.[Select](Function(x) + Dim split = x.Split(" "c) + Return New User(uow) With { + .FirstName = split(0), + .LastName = split(1) + } + End Function).ToArray() + uow.CommitChanges() + Dim rnd = New Random(0) + Dim issues = Enumerable.Range(0, 1000).[Select](Function(i) New Issue(uow) With { + .Subject = OutlookDataGenerator.GetSubject(), + .UserId = users(rnd.Next(users.Length)).Oid, + .Created = Date.Today.AddDays(-rnd.Next(30)), + .Priority = OutlookDataGenerator.GetPriority(), + .Votes = rnd.Next(100) + }).ToArray() + uow.CommitChanges() + End Using + End Sub + End Module +End Namespace + diff --git a/VB/ViewModel/XPO/ServerMode/Issues/Issue.vb b/VB/ViewModel/XPO/ServerMode/Issues/Issue.vb new file mode 100644 index 0000000..7aab998 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/Issues/Issue.vb @@ -0,0 +1,88 @@ +Imports DevExpress.Xpo + +Namespace Issues + Public Class Issue + Inherits XPObject + + Public Sub New(ByVal session As Session) + MyBase.New(session) + Created = Date.Now + End Sub + + Private _Subject As String + + + Public Property Subject As String + Get + Return _Subject + End Get + Set(ByVal value As String) + SetPropertyValue(NameOf(Issue.Subject), _Subject, value) + End Set + End Property + + Private _UserId As Integer + + Public Property UserId As Integer + Get + Return _UserId + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.UserId), _UserId, value) + End Set + End Property + + Private _User As User + + + Public Property User As User + Get + Return _User + End Get + Set(ByVal value As User) + SetPropertyValue(NameOf(Issue.User), _User, value) + End Set + End Property + + Private _Created As Date + + Public Property Created As Date + Get + Return _Created + End Get + Set(ByVal value As Date) + SetPropertyValue(NameOf(Issue.Created), _Created, value) + End Set + End Property + + Private _Votes As Integer + + Public Property Votes As Integer + Get + Return _Votes + End Get + Set(ByVal value As Integer) + SetPropertyValue(NameOf(Issue.Votes), _Votes, value) + End Set + End Property + + Private _Priority As Priority + + Public Property Priority As Priority + Get + Return _Priority + End Get + Set(ByVal value As Priority) + SetPropertyValue(NameOf(Issue.Priority), _Priority, value) + End Set + End Property + End Class + + Public Enum Priority + Low + BelowNormal + Normal + AboveNormal + High + End Enum +End Namespace \ No newline at end of file diff --git a/VB/ViewModel/XPO/ServerMode/Issues/OutlookDataGenerator.vb b/VB/ViewModel/XPO/ServerMode/Issues/OutlookDataGenerator.vb new file mode 100644 index 0000000..ea23e06 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/Issues/OutlookDataGenerator.vb @@ -0,0 +1,21 @@ +Imports System + +Namespace Issues + Public Module OutlookDataGenerator + Private rnd As Random = New Random(0) + Private Subjects As String() = New String() {"Developer Express MasterView. Integrating the control into an Accounting System.", "Web Edition: Data Entry Page. There is an issue with date validation.", "Payables Due Calculator is ready for testing.", "Web Edition: Search Page is ready for testing.", "Main Menu: Duplicate Items. Somebody has to review all menu items in the system.", "Receivables Calculator. Where can I find the complete specs?", "Ledger: Inconsistency. Please fix it.", "Receivables Printing module is ready for testing.", "Screen Redraw. Somebody has to look at it.", "Email System. What library are we going to use?", "Cannot add new vendor. This module doesn't work!", "History. Will we track sales history in our system?", "Main Menu: Add a File menu. File menu item is missing.", "Currency Mask. The current currency mask in completely unusable.", "Drag & Drop operations are not available in the scheduler module.", "Data Import. What database types will we support?", "Reports. The list of incomplete reports.", "Data Archiving. We still don't have this features in our application.", "Email Attachments. Is it possible to add multiple attachments? I haven't found a way to do this.", "Check Register. We are using different paths for different modules.", "Data Export. Our customers asked us for export to Microsoft Excel"} + Public ReadOnly Users As String() = New String() {"Peter Dolan", "Ryan Fischer", "Richard Fisher", "Tom Hamlett", "Mark Hamilton", "Steve Lee", "Jimmy Lewis", "Jeffrey McClain", "Andrew Miller", "Dave Murrel", "Bert Parkins", "Mike Roller", "Ray Shipman", "Paul Bailey", "Brad Barnes", "Carl Lucas", "Jerry Campbell"} + + Public Function GetSubject() As String + Return Subjects(rnd.Next(Subjects.Length - 1)) + End Function + + Public Function GetFrom() As String + Return Users(rnd.Next(Users.Length)) + End Function + + Public Function GetPriority() As Priority + Return CType(rnd.Next(5), Priority) + End Function + End Module +End Namespace diff --git a/VB/ViewModel/XPO/ServerMode/MainViewModel.vb b/VB/ViewModel/XPO/ServerMode/MainViewModel.vb new file mode 100644 index 0000000..68f33b9 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/MainViewModel.vb @@ -0,0 +1,73 @@ +Imports DevExpress.Mvvm +Imports DevExpress.Xpf.Data +Imports System.Linq +Imports System.Threading.Tasks +Imports DevExpress.Xpo +Imports XPOIssues.Issues +Imports DevExpress.Mvvm.Xpf +Imports System + +Public Class MainViewModel + Inherits ViewModelBase + Private _ServerModeSource As DevExpress.Xpo.XPServerModeView + + Public ReadOnly Property ServerModeSource As DevExpress.Xpo.XPServerModeView + Get + If _ServerModeSource Is Nothing Then + Dim properties = New DevExpress.Xpo.ServerViewProperty() { + New DevExpress.Xpo.ServerViewProperty("Oid", DevExpress.Xpo.SortDirection.Ascending, New DevExpress.Data.Filtering.OperandProperty("Oid")), + New DevExpress.Xpo.ServerViewProperty("Subject", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Subject")), + New DevExpress.Xpo.ServerViewProperty("UserId", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("UserId")), + New DevExpress.Xpo.ServerViewProperty("Created", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Created")), + New DevExpress.Xpo.ServerViewProperty("Votes", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Votes")), + New DevExpress.Xpo.ServerViewProperty("Priority", DevExpress.Xpo.SortDirection.None, New DevExpress.Data.Filtering.OperandProperty("Priority")) + } + Dim session = New DevExpress.Xpo.Session() + _ServerModeSource = New DevExpress.Xpo.XPServerModeView(session, GetType(Issues.Issue), Nothing) + _ServerModeSource.Properties.AddRange(properties) + End If + + Return _ServerModeSource + End Get + End Property + Private _Users As System.Collections.IList + + Public ReadOnly Property Users As System.Collections.IList + Get + If _Users Is Nothing AndAlso Not IsInDesignMode Then + Dim session = New DevExpress.Xpo.Session() + _Users = session.Query(Of XPOIssues.Issues.User).OrderBy(Function(user) user.Oid).[Select](Function(user) New With { + .Id = user.Oid, + .Name = user.FirstName & " " + user.LastName + }).ToArray() + End If + Return _Users + End Get + End Property + + Public Sub DataSourceRefresh(ByVal args As DevExpress.Mvvm.Xpf.DataSourceRefreshArgs) + _Users = Nothing + RaisePropertyChanged(Nameof(Users)) + End Sub + + Public Sub CreateEditEntityViewModel(ByVal args As DevExpress.Mvvm.Xpf.CreateEditItemViewModelArgs) + Dim unitOfWork = New UnitOfWork() + Dim item = If(args.Key IsNot Nothing, unitOfWork.GetObjectByKey(Of Issue)(args.Key), New Issue(unitOfWork)) + args.ViewModel = New EditItemViewModel(item, New EditIssueInfo(unitOfWork, Users), dispose:=Sub() unitOfWork.Dispose()) + End Sub + + Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.EditFormRowValidationArgs) + Dim unitOfWork = CType(args.Tag, EditIssueInfo).UnitOfWork + unitOfWork.CommitChanges() + End Sub + + Public Sub ValidateRowDeletion(ByVal args As DevExpress.Mvvm.Xpf.EditFormDeleteRowsValidationArgs) + Using unitOfWork = New UnitOfWork() + Dim key = CInt(args.Keys.[Single]()) + Dim item = unitOfWork.GetObjectByKey(Of Issue)(key) + unitOfWork.Delete(item) + unitOfWork.CommitChanges() + End Using + End Sub + +End Class \ No newline at end of file diff --git a/VB/ViewModel/XPO/ServerMode/MainWindow.xaml b/VB/ViewModel/XPO/ServerMode/MainWindow.xaml new file mode 100644 index 0000000..9305d30 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/ServerMode/MainWindow.xaml.vb b/VB/ViewModel/XPO/ServerMode/MainWindow.xaml.vb new file mode 100644 index 0000000..5b11700 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/MainWindow.xaml.vb @@ -0,0 +1,3 @@ +Class MainWindow + +End Class diff --git a/VB/ViewModel/XPO/ServerMode/My Project/AssemblyInfo.vb b/VB/ViewModel/XPO/ServerMode/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..e20351d --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/My Project/AssemblyInfo.vb @@ -0,0 +1,59 @@ +Imports System +Imports System.Globalization +Imports System.Reflection +Imports System.Resources +Imports System.Runtime.InteropServices +Imports System.Windows + +' 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 + + + + + + + + + +'In order to begin building localizable applications, set +'CultureYouAreCodingWith in your .vbproj file +'inside a . For example, if you are using US english +'in your source files, set the to "en-US". Then uncomment the +'NeutralResourceLanguage attribute below. Update the "en-US" in the line +'below to match the UICulture setting in the project file. + +' + + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + + + + +'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 --git a/VB/ViewModel/XPO/ServerMode/My Project/MyExtensions/MyWpfExtension.vb b/VB/ViewModel/XPO/ServerMode/My Project/MyExtensions/MyWpfExtension.vb new file mode 100644 index 0000000..e69de29 diff --git a/VB/ViewModel/XPO/ServerMode/My Project/Resources.Designer.vb b/VB/ViewModel/XPO/ServerMode/My Project/Resources.Designer.vb new file mode 100644 index 0000000..a968282 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/My Project/Resources.Designer.vb @@ -0,0 +1,52 @@ +Option Strict On +Option Explicit On + + +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("$safeprojectname$.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(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/VB/ViewModel/XPO/ServerMode/My Project/Resources.resx b/VB/ViewModel/XPO/ServerMode/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/My Project/Resources.resx @@ -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 --git a/VB/ViewModel/XPO/ServerMode/My Project/Settings.Designer.vb b/VB/ViewModel/XPO/ServerMode/My Project/Settings.Designer.vb new file mode 100644 index 0000000..188aca7 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/My Project/Settings.Designer.vb @@ -0,0 +1,63 @@ +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#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 MySettings + 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 +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.XPOIssues.My.MySettings + Get + Return Global.XPOIssues.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/VB/ViewModel/XPO/ServerMode/My Project/Settings.settings b/VB/ViewModel/XPO/ServerMode/My Project/Settings.settings new file mode 100644 index 0000000..40ed9fd --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/VB/ViewModel/XPO/ServerMode/ServerMode.sln b/VB/ViewModel/XPO/ServerMode/ServerMode.sln new file mode 100644 index 0000000..eabde1f --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/ServerMode.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServerMode", "ServerMode.vbproj", "{E38E54C6-673E-5288-0A63-25642D9B0816}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E38E54C6-673E-5288-0A63-25642D9B0816}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E38E54C6-673E-5288-0A63-25642D9B0816}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E38E54C6-673E-5288-0A63-25642D9B0816}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E38E54C6-673E-5288-0A63-25642D9B0816}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2985FFC-1732-4AAE-8982-66F17CE560A5} + EndGlobalSection +EndGlobal diff --git a/VB/ViewModel/XPO/ServerMode/ServerMode.vbproj b/VB/ViewModel/XPO/ServerMode/ServerMode.vbproj new file mode 100644 index 0000000..b9d0347 --- /dev/null +++ b/VB/ViewModel/XPO/ServerMode/ServerMode.vbproj @@ -0,0 +1,187 @@ + + + + Debug + AnyCPU + {E38E54C6-673E-5288-0A63-25642D9B0816} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + WinExe + XPOIssues + XPOIssues + v4.7.2 + Custom + true + true + true + + + AnyCPU + true + full + true + true + true + bin\Debug\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + AnyCPU + pdbonly + false + false + true + false + true + bin\Release\ + XPOIssues.xml + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314 + + + On + + + Binary + + + Off + + + On + + + + + + + + + + + 4.0 + + + + + + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + IssueDetailView.xaml + Code + + + + Application.xaml + Code + + + + + + + + MainWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Microsoft.VisualBasic.WPF.MyExtension + 1.0.0.0 + + + True + True + Resources.resx + + + True + Settings.settings + True + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + + + SettingsSingleFileGenerator + Settings.Designer.vb + + + + + + + \ No newline at end of file