1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 |
Connection 객체 - 데이터 소스와의 물리적인 연결 - 객체 속성은 데이터 공급자, 연결하고자 하는 데이터 소스, 연결 문자열로 구성 - 객체 메소드는 연결의 Open 및 Close, 데이터베이스 변경 및 트랜잭션을 관리 - 데이터공급자만 다를뿐 객체생성방법이나 속성, 메소드 이용방법은 같다. - 주요속성 * ConnectionString : 연결 문자열을 지정하거나 받음 * ConnectionTimeout : Timeout을 받음(기본 15초) * DataBase : 연결한 데이터베이스 이름 * DataSource OleDb : 데이타베이스 소스의 위치와 파일명 SQL : 연결할 SQL 서버 인스턴스 이름 * Provider : OLE DB 공급자 이름 * ServerVersion : 데이터베이스의 서버 버전 * State : 연결상태 (Broken/Closed/Connecting/Executing /Fetching/Open) * WorkstationId : 연결한 클라이언트 ID - 주요메서드 * Open : 데이터베이스에 연결 * ChangeDatabase : 연결된 데이터베이스 변경 * BeginTransaction : DB의 트랜잭션 시작을 지정 * CreateCommand : Command 객체 생성 * Close : 데이터베이스 연결 해제 - 이벤트 * StateChange : .NET data provider에 의한 연결 상태 변경 시 발생 * InfoMessage : SQL Server가 경고나 정보 제공 메시지를 반환할 때 발생 - Connection string parameters * Provider (OLE DB only) Access : Microsoft.JET.OLEDB.4.0 Oracle - MSDAORA MS SQL - SQLOLEDB * Data Source(server) : 데이터베이스 위치 (Domain or IPAddress) * Initial Catalog (database): 데이터 베이스 이름 * User ID/Password : 인증 정보 - OleDbConnection예제 using System; using System.Data; using System.Data.OleDb; namespace Connection { class Class1 { static void Main(string[] args) { string strConn ="Provider=Microsoft.Jet.OLEDB.4.0;" + @"Data Source=C:\Inetpub\iissamples\sdk\asp\database\authors.mdb;"; OleDbConnection conn = new OleDbConnection(strConn); // or // OleDbConnection conn = new OleDbConnection(); // conn.ConnectionString = strConn; conn.Open(); Console.WriteLine("Database = \t\t" + conn.Database); Console.WriteLine("DataSource = \t\t" + conn.DataSource); Console.WriteLine("DataServerVersion = \t" + conn.ServerVersion); Console.WriteLine("State = \t\t" + conn.State); conn.Close(); Console.WriteLine("State = \t\t" + conn.State); Console.ReadLine(); } } } - SqlConnection예제 using System; using System.Data; using System.Data.SqlClient; namespace Connection { class Class1 { static void Main(string[] args) { string strConn; strConn = "Data Source=localhost;Initial Catalog=northwind;" + "User ID=sa;Password=sy230;Integrated Security=SSPI;"; //strConn = "Server=localhost;Database=NorthWind;Uid=sa;Pwd=1111"; SqlConnection conn = new SqlConnection(strConn); // or // SqlConnection conn = new SqlConnection(); // conn.ConnectionString = strConn; conn.Open(); Console.WriteLine("Database = \t\t" + conn.Database); Console.WriteLine("DataSource = \t\t" + conn.DataSource); Console.WriteLine("DataServerVersion = \t" + conn.ServerVersion); Console.WriteLine("State = \t\t" + conn.State); Console.WriteLine("WorkstationID = \t" + conn.WorkstationId +"\n"); conn.ChangeDatabase("pubs"); Console.WriteLine("Database = \t\t" + conn.Database); conn.Close(); Console.WriteLine("State = \t\t" + conn.State); Console.ReadLine(); } } } Command 객체 - 데이터 입력, 수정, 삭제 등의 모든 명령을 처리 - 데이터 소스에 대한 SQL문, Stored procedure를 표시 - Connection 객체와 상관없이 생성하고 실행 가능 - 데이터 소스와 DataSet과의 통신을 위해 DataAdapter 객체가 Command 객체 사용 - 데이터공급자만 다를뿐 객체생성방법이나 속성, 메소드 이용방법은 같다. - 생성자 * SQL Server 7.0 : SqlCommand comm = SqlCommand(cmdTxt, sqlCon); //or SqlCommand comm = new SqlCommand(cmdTxt); comm.Connection = sqlCon; //or SqlCommand comm = new SqlCommand(); comm.Connection = sqlCon; comm.CommandText = cmdTxt; //or SqlCommand comm = sqlCon.CreateComand(); comm.CommandText = cmdTxt; * OLEDB OleDbCommand comm = OleDbCommand(cmdTxt, oleDbCon); //or OleDbCommand comm = new OleDbCommand(cmdTxt); comm.Connection = oleDbCon; //or OleDbCommand comm = new OleDbCommand(); comm.Connection = oleDbCon; comm.CommandText = cmdTxt; //or OleDbCommand comm = sqlCon.CreateComand(); comm.CommandText = cmdTxt; - 주요속성 * Connection : Command 객체가 사용한 Connection 개체 반환 및 설정. * CommandTimeOut : 명령어가 걸리는 시간 지정 또는 받음(Default : 30초) * Transaction : 명령어 실행에 트랜잭션을 지정하거나 받음 * UpdateRowSource : 업데이트 중인 행에 쿼리 명령 결과를 적용하는 방법을 지정. - Both : 출력 매개 변수와 처음 반환된 행은 모두 DataSet의 변경된 행에 매핑. - FirstReturnedRecord : 처음 반환된 행의 데이터는 DataSet의 변경된 행에 매핑. - None : 반환된 매개 변수와 행이 무시. - OutputParameters : 출력 매개 변수는 DataSet의 변경된 행에 매핑. //명령이 자동으로 생성되지 않는 한 기본 UpdateRowSource 값은 Both. // 명령이 자동으로 생성되면 기본값은 None * CommandText : SQL 문이나 저장 프로시저 반환 및 설정. SQL : myCom.CommandText = "SELECT * FROM authors WHERE au_id = @id"; OLEDB, ODBC : myCom.CommandText = "SELECT * FROM authors WHERE au_id = ?"; - OLEDB, ODBC를 사용할 경우 실행할 명령문의 ?순서와 파라미터 추가하는 순서는 같아야 한다. * Parameters : Transact-SQL 문이나 지정 프로시저의 매개 변수 - ParameterName : 매개변수 이름 - SqlDBType: 매개변수의 데이타베이스의 필드타입 - Value : 매개변수의 값 설정 및 확인 - Direction : Input/Output/InputOutput. Default는 Input. * CommandType - CommandText 속성을 해석하는 방법을 나타내는 값을 가져오거나 설정. - Text : SQL 텍스트 명령, Default - StoredProcedure : 저장 프로시저의 이름 - TableDirect : 테이블명 [Text 사용예제] SqlCommand cmd=new SqlCommand("delete emp where id=@id", conn); cmd.Parameters.Add("@id", SqlDbType.NVarChar, 15).Value = "London"; [StoredProcedure 사용예제] sqlCom.CommandText = "sp_ReturnName"; sqlCom.CommandType = CommandType.StoredProcedure; sqlCom.Parameters.Add("@au_id",SqlDbType.VarChar,20).Value="527-72-3246"; [TableDirect 사용예제] sqlCom.CommandText = "Users"; sqlCom.CommandType = CommandType.TableDirect; - TableDirect는 .NET Framework Data Provider for OLE DB에서만 지원. - Execute 메서드 중 하나를 호출하면 명명된 테이블의 행과 열이 모두 반환. - 여러 테이블에 액세스하려면 공백없이 테이블의 이름이 쉼표로 연결된 목록 사용. - 여러테이블의 이름을 지정하면 지정된 테이블이 조인이 반환. - 메소드 * Cancel : 명령어 취소 * Prepare : 데이터 소스에 명령의 준비 버전이나 컴파일 버전을 만듭니다 * ExecuteNonQuery : 명령어 실행 * ExecuteReader : 명령어를 Connection 통해 보내고 SqlDataReader 바인딩 * ExecuteScalar : 명령어 실행, Sum(), Avg()와 같이 값이 하나만 반환될 경우 사용 * ExecuteXmlReader : 명령어를 Connection을 통해 보내고 XmlReader 바인딩 // 더 자세한 내용은 DataReader 참고 - ExecuteNonQuery를 사용한 예제 private void CommandEx() { string sqlStr = "Data Source=localhost;Initial Catalog=northwind;" + "User ID=sa;Password=1111;"; SqlConnection sqlCon = new SqlConnection(sqlStr); try { sqlCon.Open(); MessageBox.Show("현재 상태 :" + sqlCon.State); } catch(SqlException ex) { MessageBox.Show(ex.Message); } try { SqlCommand sqlCom = sqlCon.CreateCommand(); sqlCom.CommandText="update region set regiondescription = @name1 " + " where regiondescription = @name2"; sqlCom.Parameters.Add("@name1", SqlDbType.VarChar, 50).Value = "name1Value"; sqlCom.Parameters.Add("@name2", SqlDbType.VarChar, 20).Value = "name2Value"; sqlCom.Prepare(); int result = sqlCom.ExecuteNonQuery(); Console.WriteLine("영향받는 행의 개수는 : {0}", result); } catch(SqlException ex) { MessageBox.Show(ex.Message); } finally { sqlCon.Close(); } } DataReader 객체 - 데이터 소스의 데이터를 읽기 전용으로 포함하기 위한 빠르고 오버헤드가 적은 객체 - WinForm or WebForm에 데이타베이스 쿼리를 통해 얻은 결과를 출력 - Command 객체의 ExcuteReader 메소드로만 객체 생성 - 연결지향, 빠른 속도, 읽기전용, 한 테이블만 이용 - 쿼리에서 리턴된 구조 데이터 레코드 제공 [참고] Read 메서드를 호출하면 요청할 때까지 클라이언트의 네트워크 버퍼에 저장, 쿼리의 전체 결과가 반환될 때까지 기다리는 것이 아니라 사용이 가능해 지면 곧바로 데이터를 검색하는 동시에 기본적으로 메모리에 한 번에 행 하나씩만 저장하여 시스템 오버헤드를 줄임으로써 응용 프로그램의 성능을 향상시킬 수 있습니다. DataReader는 프로시저 논리가 데이터 소스에서 순차적으로 가져오는 결과를 효율적으로 처리할 수 있도록 버퍼링되지 않은 데이터 스트림을 제공합니다. 대량의 데이터를 검색할 때에는 데이터가 메모리에 캐싱되지 않으므로 DataReader를 선택하는 것이 좋습니다. ● 주요속성 * HasRows : DataReader에서 읽기 전에 결과가 반환되는지 여부를 판별 * FieldCount : 현재 행의 열개수 * IsClosed : 데이터 판독기가 닫혔는지 여부 * RecordsAffected : Transact-SQL 문의 실행에 의해 변경, 삽입 및 삭제된 행의 개수 * Depth : 현재 행의 중첩 수준을 나타내는 값 ● 주요메소드 * Close : DataReader 개체를 닫습니다. * GetDataTypeName : 소스 데이터 형식의 이름을 가져온다. * GetFieldType : 개체의 데이터 형식인 Type을 가져온다. * GetName : 지정된 열의 이름을 가져온다. * GetOrdinal : 열 이름이 지정된 경우 열 서수를 가져온다. * GetSchemaTable : DataReader의 열 메타데이터를 설명하는 DataTable을 반환. * IsDBNull : 열이 존재하지 않거나 없는 값을 포함하는지 여부를 나타내는 값을 가져온다. * NextResult : 여러개의 테이블을 Transact-SQL 문의 결과를 읽을 때, 데이터 판독기를 다음 결과 테이블로 이동. * Read : 각 Record를 읽기 위한 메소드, record가 없을 때는 false 리턴, 있을때는 true 이면서 레코드값을 가짐. [필드 접근방법] * 객체명["필드명"] * 객체명[필드순서] * Get 메소드를 이용하여 네이티브 데이터 형식의 열 값에 액세스 : (GetChar, GetDateTime, GetInt32, GetFloat, GetString, GetGuid, …) : 객체명.GetString(필드순서) -> 필드순서에 해당하는 열값의 자료형을 String형식으로 가져온다. : 열값을 검색할 때 필요한 형식 변환의 양이 줄어듬으로 성능향상에 도움이 된다. ● DataReader 객체를 이용한 데이터 접근 예 string strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\data\myDB.mdb"; string strSQL = "SELECT LastName, Age From User"; OleDbConnection conn = New OleDbConnection(strConn); OleDbCommand comm = new OleDbComand(strSQL, conn); try{ conn.Open(); Console.WriteLine("DB연결상태 : "+conn.State); OleDbDataReader reader = comm.ExcuteReader(); while(reader.Read() == true) { Console.WriteLine(reader["LastName"] + " " + reader["Age"]); //Console.WriteLine(reader.GetString(0) +" " + reader.GetInt32(1)); //Console.WriteLine(reader[0] + " " + reader[0]); } reader.Close(); conn.Close(); } catch (Exception e) { Console.WriteLine("데이터베이스 열기 실패")l } ● DataReader 객체를 이용하여 여러 결과 집합가져오기 string cmdTxt = "SELECT CategoryID, CategoryName FROM Categories;" + "SELECT EmployeeID, LastName FROM Employees"; SqlCommand comm = new SqlCommand(cmdTxt, conn); conn.Open(); SqlDataReader myReader = comm.ExecuteReader(); do{ Console.WriteLine("\t{0}\t{1}", myReader.GetName(0), myReader.GetName(1)); while (myReader.Read()) Console.WriteLine("\t{0}\t{1}", myReader.GetInt32(0), myReader.GetString(1)); }while (myReader.NextResult()); myReader.Close(); conn.Close(); ● DataReader에서 스키마 정보 가져오기 /* DataReader가 열려 있는 동안에는 GetSchemaTable 메서드를 사용하여 현재 결과 집합에 대한 스키마 정보를 검색할 수 있습니다. GetSchemaTable은 현재 결과 집합에 대한 스키마 정보를 포함하는 행과 열로 채워진 DataTable 개체를 반환합니다. DataTable은 결과 집합의 각 열마다 한 행씩 포함하게 됩니다. 스키마 테이블 행의 각 열은 결과 집합에 반환된 열의 속성에 매핑됩니다. 여기서 ColumnName은 속성 이름이고 열 값은 속성 값입니다. */ DataTable schemaTable = myReader.GetSchemaTable(); foreach (DataRow myRow in schemaTable.Rows) { foreach (DataColumn myCol in schemaTable.Columns) Console.WriteLine(myCol.ColumnName + " = " + myRow[myCol]); Console.WriteLine(); } using System; using System.Data; using System.Data.SqlClient; namespace ADO.NET.STUDY { class MainClass { private string ConString = null; private SqlConnection SqlCon = null; private SqlCommand SqlCom = null; private SqlDataReader sReader = null; public MainClass() { this.ConString = "Server=Localhost;database=Pubs;UID=sa;PWD=1111"; } [STAThread] static void Main(string[] args) { MainClass main = new MainClass(); main.use_ExcuteReader(); main.use_ExecuteScalar(); main.use_getSqlReturnValue(); main.use_Transaction(); Console.Read(); //실행화면 확인을 위한 일시중지 } private void DBConnect() { if(SqlCon == null) SqlCon = new SqlConnection(ConString); if(SqlCon.State == ConnectionState.Closed) try { SqlCon.Open(); } catch(Exception e) { Console.WriteLine(e.Message); } } private void DBClose() { if(SqlCon.State != ConnectionState.Closed) SqlCon.Close(); } // 저장프로시저를 이용한 ExcuteReader, ExecuteNonQuery사용예제 // 저장프로시저 매개변수 사용법 및 OUTPUT, RETRUN값 받는 예제 포함. private void use_ExcuteReader() { this.DBConnect(); string strSQLSel = "sp_getUser"; //string strSQLUpdate = "UPDATE authors SET au_fname = @fname TEL = @tel WHERE au_lname = @lname"; /* * 프로시저 sp_getUesr의 내용 * create proc sp_getUser(@state varchar(20), @Cnt int output) as * SELECT au_id, phone FROM authors WHERE state = @state * SET @Cnt = @@rowcount */ try { this.DBConnect(); // DB연결하는 메소드 SqlCom = new SqlCommand(); SqlCom.Connection = SqlCon; SqlCom.CommandTimeout = 15; // 명령 실행을 종료하고 오류를 생성하기 전 대기 시간, 기본값은 30초 //SqlCom.CommandText = "SELECT au_id, phone FROM authors WHERE state = @state"; SqlCom.CommandText = strSQLSel; SqlCom.CommandType = CommandType.StoredProcedure; //명령줄의 형식은 프로시저임, //일반쿼리문임을 나타내는 Text타입를 제외한 나머지 타입인 경우는 꼭 기재해야함. SqlCom.Parameters.Add("@state", SqlDbType.VarChar, 20).Value = "CA"; //프로시저의 @state매개변수의 값에 "CA"라는 이름을 넣는다 SqlCom.Parameters.Add("@cnt", SqlDbType.Int, 4); SqlCom.Parameters["@cnt"].Direction = ParameterDirection.Output; /* 또는 * SqlParameter spName = new SqlParameter (); * spName.ParameterName = "@state"; * spName.SqlDbType = SqlDbType.VarChar; * spName.Size = 20; * spName.Value = "CA"; * spName.SourceVersion = DataRowVersion.Current; * SqlCom.Parameters.Add(spName); */ int cnt = SqlCom.ExecuteNonQuery(); /* ExecuteNonQuery : 해당쿼리문에 적용된 레코드의 개수 반환 * * SQL 문에서는 기본적으로 해당 명령(INSERT, DELETE, UPDATE)문의 * 영향을 받은 레코드 수를 나타내는 정수 값이 반환이 되는데 ExecuteNonQuery에서 * 바로 그 값을 받는것이다. * * 참고 : INSERT, DELETE, UPDATE문이 아닌 다른 명령문(SELECT), 또는 롤백이 일어났을 경우 -1이 리턴. */ Console.WriteLine("ExecuteNonQuery에서 적용받은 레코드의 수 : {0}", cnt); // SELECT문을 이용했기때문에 기본적으로 return되는 값은 -1 Console.WriteLine("Output으로 받은 레크드의 개수 :" + SqlCom.Parameters["@cnt"].Value); // SELECT한 레코드의 수를 가져오기위해서는 위처럼 OUTPUT파라미터 이용 /* * System.SqlClient.SqlCommand.ExecuteReader를 호출하여 반환되는 * Output, InputOut 및 ReturnValue 매개 변수에 액세스하려면 SqlDataReader에서 * System.SqlClient.SqlDataReader.Close 또는 Dispose를 호출해야 합니다.(도움말) * * 위 명령의 경우 ExecuteNonQuery는 Close를 할 필요가 없기때문에 매개변수값이 출력됩니다. * 이 소스의 아래부분에 있는 출력매개변수 출력부분을 sReader.Close() 명령이 일어나기 전에 넣어서 테스트해보세요. * * 참고 : 반환되는 값이 출력매개변수 값 하나이면 Close를 먼저 하지 않아도 결과값을 받을수 있습니다. */ sReader = SqlCom.ExecuteReader(); //authors테이블에서 state열 값이 "CA"인 레코드 반환 while (sReader.Read()) { Console.WriteLine(sReader.GetString(0) + ", " + sReader.GetString(1)); // 반환된 레코드중 첫번째필드(au_id)와 두번째필드(phone)값 콘솔에 출력 } sReader.Close(); // DataReader사용후 꼭 닫아줘어야 함. Console.WriteLine("Output으로 받은 레크드의 개수 : " + SqlCom.Parameters["@cnt"].Value); // SELECT한 레코드의 수를 가져오기위해서는 위처럼 OUTPUT파라미터 이용 this.DBClose(); // DB연결을 닫는 메소드 } catch (Exception ec) { Console.WriteLine(ec.Message); } } /* ExecuteScalar 이용한 간단한 예제 */ private void use_ExecuteScalar() { SqlCon = new SqlConnection(ConString); try { SqlCon.Open(); } catch(Exception ec) { Console.WriteLine(ec.Message); } SqlCom = SqlCon.CreateCommand(); SqlCom.CommandText = "select count(au_id) from authors"; SqlCom.CommandType = CommandType.Text; // Default, 생략가능 int result = (int) SqlCom.ExecuteScalar(); Console.WriteLine("authors테이블의 레크드 개수 : "+ result.ToString()); this.DBClose(); } /* SQL의 사용자정의 함수의 Return값 받는 예제 */ private void use_getSqlReturnValue() { this.DBConnect(); SqlCom = SqlCon.CreateCommand(); SqlCom.CommandText = "sp_ReturnName"; SqlCom.CommandType = CommandType.StoredProcedure; /* * create function sp_ReturnName(@au_id varchar(20)) * returns varchar(30) * as * begin * declare @name varchar(30) * select @name = au_fname + ' ' + au_lname from authors where au_id=@au_id * return(@name) * end * go */ SqlCom.Parameters.Add("@au_id", SqlDbType.VarChar, 20).Value = "527-72-3246"; SqlParameter sampParm = SqlCom.Parameters.Add("ReturnValue", SqlDbType.VarChar, 30); sampParm.Direction = ParameterDirection.ReturnValue; // ExecuteReader를 호출하여 매개변수를 반환받는다. // ParameterDirection 이 출력이면, 관련 SqlCommand의 실행은 값을 반환하지 않으며, // SqlParameter는 null 값을 포함하지 않습니다. sReader = SqlCom.ExecuteReader(); string result = (string) SqlCom.Parameters["ReturnValue"].Value; Console.WriteLine("프로시저의 리턴값: {0}", result); result = "이세영"; sReader.Close(); this.DBClose(); } /* 트랜잭션사용예제 */ private void use_Transaction() { this.DBConnect(); SqlTransaction myTrans = SqlCon.BeginTransaction(); // 트랜잭션 처리 시작 SqlCom = SqlCon.CreateCommand(); SqlCom.Transaction = myTrans; try { SqlCom.CommandText = "update titleauthor set au_ord = 3 where au_id = '172-32-1176'"; int updateCnt = (int) SqlCom.ExecuteNonQuery(); Console.WriteLine("업데이트수행 결과 : " + updateCnt); // myTrans.Save("SavePointPosition"); // 트랜잭션의 흐름 중에서 전체를 롤백하고 싶지 않을 경우 표시한 부분까지만 롤백하고자 할 때 SqlCom.CommandText = "insert into titleauthor (au_id, title_id, au_ord, royaltyper) values('111-11-1111', 'AB0001', 3, 50)"; int insertCnt = (int) SqlCom.ExecuteNonQuery(); Console.WriteLine("업데이트수행 결과 : " + insertCnt); myTrans.Commit(); // 현재 위 쿼리가 모두 수행되었을때만 트랜젝션 완료. // 하나라도 오류발생하면 수행했던 모든 실행 취소 Console.WriteLine("update와 insert가 정상적으로 완료되었습니다."); } catch(Exception e) { try { myTrans.Rollback(); // myTrans.Rollback("SavePointPosition"); // SavePointPosition의 위치까지만 Rollback한다고 선언. // Savepoint 이전의 명령들은 처리가 된다 } catch (SqlException ex) { if (myTrans.Connection != null) { Console.WriteLine(ex.GetType()); } } Console.WriteLine(e.GetType()); Console.WriteLine("update와 insert명령이 둘다 완료되지 못했습니다."); } finally { this.DBClose(); } } } } DataTable.Select Method 필터 조건 및 지정된 상태와 일치하는 모든 DataRow 개체의 배열을 정렬 순서대로 가져옵니다. [C#] public DataRow[] Select( string filterexpression!!, // 행을 필터링하기 위해 사용하는 조건입니다. string sort, // 열과 정렬 방향을 지정하는 문자열입니다. DataViewRowState recordStates //DataViewRowState 값 중 하나로 DataRow의 버전. ); * 반환값 : DataRow 개체로 이루어진 배열입니다. * 행을 필터링하기 위한 조건식은 DataColumn 클래스의 expression!! 속성을 참조하십시오. private static void GetRowsByFilter() { DataTable customerTable = new DataTable( "Customers" ); customerTable.Columns.Add( "id", typeof(int) ); customerTable.Columns.Add( "name", typeof(string) ); customerTable.Columns[ "id" ].Unique = true; customerTable.PrimaryKey = new DataColumn[] { customerTable.Columns["id"] }; for( int id=1; id<=10; id++ ) { customerTable.Rows.Add( new object[] { id, string.Format("customer{0}", id) } ); } customerTable.AcceptChanges(); for( int id=11; id<=20; id++ ) { customerTable.Rows.Add( new object[] { id, string.Format("customer{0}", id) } ); } string strExpr; string strSort; strExpr = "id > 5"; // Sort descending by column named CompanyName. strSort = "name DESC"; // Use the Select method to find all rows matching the filter. DataRow[] foundRows = customerTable.Select( strExpr, strSort, DataViewRowState.Added ); // id>5 조건에 맞는 행만 찾아서 name컬럼을 내림차순으로 정렬하여 가져온다. PrintRows( foundRows, "filtered rows" ); foundRows = customerTable.Select(); //DataTable의 모든 행을 가져온다. PrintRows( foundRows, "all rows" ); } private static void PrintRows( DataRow[] rows, string label ) { Console.WriteLine( "\n{0}", label ); if( rows.Length <= 0 ) { Console.WriteLine( "no rows found" ); return; } foreach( DataRow r in rows ) { foreach( DataColumn c in r.Table.Columns ) { Console.Write( "\t {0}", r[c] ); } Console.WriteLine(); } } DataColumn.expression!! 속성 행을 필터링하거나 열의 값을 계산하거나 집계 열을 만드는 데 사용되는 식을 가져오거나 설정합니다. expression!! 속성을 사용하는 경우 중 하나는 계산 열을 만들 때입니다. 예를 들어, 과세 가격을 계산하려면 단가에 해당 지역의 세율을 곱합니다. 세율은 지역에 따라 다르기 때문에 열에 단일 세율을 넣기가 불가능하므로 아래 Visual Basic 코드에 표시된 것처럼 expression!! 속성을 사용하여 값을 계산합니다. DataSet1.Tables("Products").Columns("tax").expression!! = "UnitPrice * 0.086" 또 다른 경우는 집계 열을 만들 때입니다. 계산 값과 마찬가지로 집계도 DataTable의 전체 행 집합을 기반으로 작업을 수행합니다. 간단한 예로는 집합에 반환되는 행의 수 계산이 있으며, 다음 Visual Basic 코드에 표시된 것처럼 특정 판매원이 완료한 거래의 수를 계산할 때 사용하는 메서드입니다. DataSet1.Tables("Orders").Columns("OrderCount").expression!! = "Count(OrderID)" 식 구문 식을 만드는 경우 ColumnName 속성을 사용하여 열을 참조합니다. 예를 들어, 두 열의 ColumnName 이 각각 "UnitPrice"와 "Quantity"인 경우 식은 다음과 같습니다. "UnitPrice * Quantity" 필터에 대한 식을 만드는 경우 문자열을 작은따옴표로 묶습니다. "LastName = 'Jones'" 다음 문자들은 특수 문자이며 아래에 설명된 것처럼 열 이름에 사용할 경우 이스케이프되어야 합니다. \n(줄 바꿈), \t(탭), \r(캐리지 리턴), ~, (, ), #, \, /, =, >, <, +, -, *, %, &, |, ^, ', ", [, ] 열 이름에 위 문자 중 하나가 있는 경우 해당 이름은 대괄호로 묶어야 합니다. 예를 들어, 식에 열 이름 "Column#"을 사용하려면 "[Column#]"이라고 쓰면 됩니다. Total * [Column#] 대괄호는 특수 문자이기 때문에 열 이름에 포함되는 경우 슬래시("\")를 사용하여 이스케이프해야 합니다. 예를 들어, 열 이름이 "Column[]"이면 다음과 같이 씁니다. Total * [Column[\]] 둘째 대괄호만 이스케이프해야 합니다. 사용자 정의 값 사용자 정의 값은 열 값을 비교하는 식에 사용될 수 있습니다. 문자열 값은 작은따옴표로 묶어야 합니다. 날짜 값은 파운드 기호(#)로 묶어야 합니다. 10진수 및 지수 표기법으로 숫자 값을 표시할 수 있습니다. 예를 들면 다음과 같습니다. "FirstName = 'John'" "Price <= 50.00" "Birthdate < #1/31/82#" 열거형 값이 포함된 열에서는 값을 정수 데이터 형식으로 캐스팅합니다. 예를 들면 다음과 같습니다. "EnumColumn = 5" 연산자 Boolean AND, OR 및 NOT 연산자를 사용하여 연결할 수 있습니다. 괄호를 사용하여 절을 묶어서 우선 순위를 적용할 수 있습니다. AND 연산자는 다른 연산자에 우선합니다. 예를 들면 다음과 같습니다. (LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John' 비교식을 만들 때 허용되는 연산자는 다음과 같습니다. < , > , <= , >= , <> , = , IN , LIKE 또한 다음과 같은 산술 연산자가 지원됩니다. +(더하기) , -(빼기) , *(곱하기) , /(나누기) , %(나머지) 문자열 연산자 문자열을 연결하려면 + 문자를 사용합니다. 문자열 비교 시 대/소문자 구별 여부는 DataSet 클래스의 CaseSensitive 속성 값에 의해 결정되지만 DataTable 클래스의 CaseSensitive 속성이 이 값에 우선합니다. 와일드카드 문자 *와 %는 모두 LIKE 비교에서 와일드카드로 교대로 사용할 수 있습니다. LIKE 절의 문자열에 * 또는 %가 있으면 이들 문자는 대괄호([])로 이스케이프해야 합니다. 대괄호가 절에 있으면 대괄호 문자를 대괄호로 이스케이프해야 합니다. (예: [[] 또는 []]). 와일드카드는 패턴의 시작과 끝 부분, 패턴의 끝 부분 또는 패턴의 시작 부분에 사용할 수 있습니다. 예를 들면 다음과 같습니다. "ItemName LIKE '*product*'" "ItemName LIKE '*product'" "ItemName LIKE 'product*'" 문자열의 중간에는 와일드카드를 사용할 수 없습니다. 예를 들어 'te*xt'는 사용할 수 없습니다. 부모/자식 관계 참조 열 이름 앞에 Parent를 붙여 식에서 부모 테이블을 참조할 수 있습니다. 예를 들어, Parent.Price 는 이름이 Price 인 부모 테이블의 열을 참조합니다. 열 이름 앞에 Child를 붙여 식에서 자식 테이블에 있는 열을 참조할 수 있습니다. 그러나 자식 관계는 여러 행을 반환할 수 있으므로 자식 열에 대한 참조를 집계 함수에 포함시켜야 합니다. 예를 들어, Sum(Child.Price) 은 자식 테이블에서 이름이 Price 인 열의 합을 반환합니다. 테이블에 여러 자식이 있는 경우 구문은 Child(RelationName)입니다. 예를 들어, 테이블에 이름이 Customers 및 Orders 인 자식 테이블과 Customers2Orders 라는 DataRelation 개체가 있으면 참조는 다음과 같습니다. Avg(Child(Customers2Orders).Quantity) 집계 다음과 같은 집계 형식이 지원됩니다. Sum(합계), Avg(평균), Min(최소값), Max(최대값), Count(개수), StDev(통계적 표준 편차), Var(통계적 분산) 집계는 일반적으로 관계를 따라 수행됩니다. 위에 나열한 함수 중 하나와 위의 부모/자식 관계 참조에서 설명한 자식 테이블 열 하나를 사용하여 집계식을 만듭니다. 예를 들면 다음과 같습니다. Avg(Child.Price) Avg(Child(Orders2Details).Price) 단일 테이블에서 집계를 수행할 수도 있습니다. 예를 들어, 이름이 "Price"인 열의 수치 집계를 만드는 식은 다음과 같습니다. Sum(Price) 단일 테이블을 사용하여 집계를 만드는 경우 그룹화 기능이 없는 대신 열의 모든 행에 같은 값이 표시됩니다. 테이블에 행이 없으면 집계 함수는 null 참조(Visual Basic의 Nothing)을 반환합니다. DataTable.Compute 메서드 필터 조건을 전달하는 현재 행에서 지정된 식을 계산합니다. public object Compute ( string expression!!, // 계산할 식 string filter // 식에서 계산하는 행을 제한할 필터 ); *반환 값 : 계산 결과로 설정된 Object를 반환 expression!! 매개 변수에는 집계 함수가 필요합니다. 예를 들어, 다음은 올바른 식입니다. Count(Quantity) 그러나 다음은 잘못된 식입니다. Sum (Quantity * UnitPrice) 두 개 이상의 열에서 작업을 수행해야 하는 경우, DataColumn을 만들고 해당 expression!! 속성을 적절한 식으로 설정한 다음 결과 열에 집계식을 사용해야 합니다. 예를 들어, DataColumn의 이름이 "total"이고 expression!! 속성이 다음과 같이 설정된 것으로 가정합니다. "Quantity * UnitPrice" 이러한 경우 Compute 메서드에 대한 식 인수는 다음과 같습니다. Sum(total) 두 번째 매개 변수 filter 는 식에서 사용될 행을 결정합니다. 예를 들어, 테이블에 "colDate"라는 이름의 날짜 열이 있으면 다음 식을 사용하여 행을 제한할 수 있습니다. colDate > 1/1/99 AND colDate < 17/1/99 두 매개 변수에 대한 식을 만드는 규칙에 대한 자세한 내용은 DataColumn 클래스의 expression!! 속성을 참조하십시오. 다음 예제에서는 ID 번호가 5인 판매 사원에 대해 "Total" 열 값의 합계를 구합니다. private void ComputeBySalesSalesID(DataSet myDataSet) { // Presumes a DataTable named "Orders" that has a column named "Total." DataTable myTable; myTable = myDataSet.Tables["Orders"]; // Declare an object variable. object objSum; objSum = myTable.Compute("Sum(Total)", "EmpID = 5"); } DataRelation 은 DataColumn 개체를 통해 두 개의 DataTable 개체를 서로 연결하는 데 사용됩니다. 예를 들어 Customer/Orders 관계에서 Customers 테이블은 부모이고 Orders 테이블은 관계의 자식입니다. 기본 키/외래 키 관계와 비슷합니다. 부모 및 자식 테이블의 일치하는 열 간에 관계가 만들어집니다. 즉, 두 개의 열에 대한 DataType 값이 동일해야 합니다. DataRelation의 주요한 기능 중 하나는 DataSet 내의 한 DataTable에서 다른 DataTable로 이동을 허용한다는 것입니다. 따라서, 연관된 DataTable의 DataRow가 하나 주어지면 연관된 다른 DataTable에 있는 모든 연관된 DataRow 개체를 검색할 수 있습니다. 예를 들어, 고객 테이블과 주문 테이블 사이에 DataRelation을 만든 다음 DataRow.GetChildRows를 사용하여 특정 고객 행에 대한 모든 주문 행을 검색할 수 있습니다. DataRelation custOrderRel = custDS.Relations.Add("CustOrders", custDS.Tables["Customers"].Columns["CustomerID"], custDS.Tables["Orders"].Columns["CustomerID"]); foreach (DataRow custRow in custDS.Tables["Customers"].Rows) { Console.WriteLine(custRow["CustomerID"]); foreach (DataRow orderRow in custRow.GetChildRows(custOrderRel)) Console.WriteLine(orderRow["OrderID"]); } Customers 및 Orders 테이블에 대해 DataRelation을 만들면 createConstraints 플래그(기본값은 true)의 값이 지정되지 않습니다. 이런 경우에는 Orders 테이블의 모든 행이 부모 테이블인 Customers에 존재하는 CustomerID 값을 가지고 있다고 가정합니다. Customers 테이블에 없는 CustomerID가 Orders 테이블에 있으면 ForeignKeyConstraint에 의해 예외가 throw됩니다. 부모 열에 포함되어 있지 않은 값이 자식 열에 있는 경우 DataRelation을 추가할 때 createConstraints 플래그를 false로 설정합니다. 아래 예제에서는 Orders 테이블과 OrderDetails 테이블 사이의 DataRelation에 대해 createConstraints 플래그가 false로 설정됩니다. 이렇게 되면 응용 프로그램에서는 런타임에 예외를 발생시키지 않고 OrderDetails 테이블의 모든 레코드와 Orders 테이블 레코드의 일부분만 반환할 수 있습니다. DataRelation orderDetailRel = custDS.Relations.Add("OrderDetail", custDS.Tables["Orders"].Columns["OrderID"], custDS.Tables["OrderDetails"].Columns["OrderID"], false); [에러내용] ********************************************************* 이 열에는 현재 고유 값이 없습니다. 설명: 현재 웹 요청을 실행하는 동안 처리되지 않은 예외가 발생했습니다. 스택 추적을 검토하여 발생한 오류 및 코드에서 오류가 발생한 위치에 대한 자세한 정보를 확인하십시오. 예외 정보: System.ArgumentException: 이 열에는 현재 고유 값이 없습니다. 인자를 가지는 메소드 - 입력인자(Argument, parameter)매개변수 - 메소드 호출시 전달할 값이 있을 경우 인자를 통해 전달 return문 - 메소드의 연산결과를 반환하기 위해 사용 - 객체 or 변수변환가능 - 값 변환시 제어도 같이 이동(즉, return문 이후 코드는 접근 불가 코드) - 리턴형이 void가 아닌경우를 제외하곤 반드시 return문을 가져야 한다. - 리턴값은 단일값만 가능 - 반드시 데이터 타입이 같거나 암시적으로 형변환이 가능한 데이터 반환 인자사용 - 값으로 전달(Call by Balue) : 입력 전용인자 - 참조로 전달(Call by Reference) : 입출력 겸용 인자 - 출력 파라미터(Output parameter): 출력 전용인자 - 가변 인자 리스트 값으로 전달 - 메소드 호출시 변수의 값을 복사해서 메소드로 전달 - 메소드 내에서 인자값이 변경될수 있다.(Side Effect)가 없다. - 메소드 안의 값은 밖에서 확인 불가능 - 인자값은 호환가능(암시적 형변환 가능) 참조에 의한 전달 - 값을 전달하는 것이 아니라 변수의 메모리 주소를 전달 - ref키워드 사용 - 인자의 데이터형이 일치해야 한다(암시적으로 형변환 불가능) - 참조 전달시 반드시 변수값 초기화 public static void callrefTest() { int i = 3; refTest(ref i); Console.WriteLine("Main출력 : " + i); } public static void refTest(ref int i) { Console.WriteLine("Test출력"+i); i =100; Console.WriteLine(i); } 출력파라미터 - 메소드 호출시 값을 넘겨줄 필요가 없을 경우 - 메커니즘은 ref와 유사 - ref처럼 변수를 초기화 시키지 않아도 된다. - out키워드 사용 public static void callTest() { int i = 3; int j = 10; Console.WriteLine("{0}, {1}",i, j); Test(out i, out j); Console.WriteLine("{0}, {1}",i, j); } public static void Test(out int i, out int j) { //out으로 참조한 변수에는 값이 할당되지 않은상태이다. //때문에 변수값이 한번이상 변경 되지 않는 상태에서 사용하려 하면 오류발생 i =100; j =200; Console.WriteLine("{0}, {1}",i, j); } 인자사용 가이드 라인 - value > out > ref - 값으로 인자를 전달하는 경우가 일반적 - 함수가 반환할 값이 하나일 경우 value - 함수가 반환할 값이 둘 이상일 경우 ref, out - 인자가 함수에 대한 입력과 출력 두가지 목적으로 사용될때 ref 가변길이 파라미터 - 여러 개의 파라미터를 전달 할 경우 - Call by Value 형식이다. - 메소드명(params int[] x) - 인자 앞에 params키워드를 붙여 주면 가변인자됨. 배열 처럼 사용. - 가변인자와 일반인자를 같이 사용할 경우 : 예) 메소드명(string str, params int[] x) -> 반드시 가변인자를 마지막에 명시 using System; class Class1 { public static int Method1(params int[] x) { int z=0; for(int i = 0; i < x.Length; i++) { z += x[i]; } return z; } public static void Main() { int y = Method1(10,15,20,35); Console.WriteLine("y의 값은 {0}입니다.",y); } } 재귀메소드(Recursive Method) - 자기자신을 호출하는 메소드 - 무한 루프 주의 public static void callMethod() { long factNumber = 0; long number = 4; factNumber = Factorial(number); Console.WriteLine("{0}의 팩토리얼 값은 {1}입니다.", number, factNumber); } public static long Factorial(long number) { if(number>1) return number*Factorial(number-1); else return 1; } 메소드 오버로딩(Method Overloading) - 한 클래스 내에서 같은 이름을 가지지만 다른 동작을 하는 메소드들 - Meshod Signature - 다양한 종류의 파라미터를 갖는 동일한 이름의 메소드 선언 방식 - 파라미터 형식을 기반으로 내부적으로 별개의 메소드로 인식 - 실제 호출이 되는 메소드는 인자리스트에 의해서 결정(메소드 서명) - 메소드 서명이 될수 있는 요소 : 메소드명, 인자의 타입, 인자의 갯수, out, ref, params키워드 - 메소드 서명이 될 수 없는 요소 : 인자의 이름, 리턴 타입 1. public static void WriteLine(); 2. public static void WriteLine(int i); 3. public static void WriteLine(int j); // 2번과 동일한 메소드로 본다. 4. public static void WriteLine(int i, int j); 5. public static int WriteLine(int i); // 2번과 동일하게 본다. 6. public static void WriteLine(ref int i); 7. public static void WriteLine(out int i); //인자수가 같은경우 ref나 out는 둘중에 하나만 사용가능 8. public static void WriteLine(string i); 9. public static void WriteLine(out int i, int j); //ref나 out 둘다 사용시 인자수가 다르다면 가능 메소드 오버로딩 가이드 라인 - 서로 다른 인자 리스트를 가지는 비슷한 메소드를 정의할 경우(이름이 같다 -> 하는일이 비슷) - 기존의 코드에 새로운 기능을 추가하는 경우 - 메소드 오버로딩의 되도록 자재 -> 디버깅, 유지보수 문제. 배열 - 같은 데이터형을 갖는 데이터 집합 - 하나의 변수명을 가지고 여러개의 동일한 데이터 형식을 포함 - 컬렉션(Collection)은 서로 다른 데이터를 묶는 집합 - Call by Reference 배열선언 - 배열은 System.Array를 상속받는 객체 - 인스턴스화를 해야 사용가능 - 자료형[차원] 배열명 = new 자료형[요소갯수]{초기화 리스트}; - 첨자는 항상 0부터 시작 1. int [] result; 2. long result; 3. long result [3]; // X, result 와 [3] 자리가 바꼈고, 숫자도 들어가면 안됨. 4. [] long result; // X, 자료형과 []가 바뀜 5. char[,] result; 6. int [,,]; // X, 배열명이 바뀜 7. float [10,2] result; // X, 숫자가 들어가면 안됨 8. result = {1,2,3,4,5}; // X, 형식이 틀림 배열선언 예제 int[] result; //배열을 선언만 한 것. 메모리에 배열변수가 생성, 배열에 대한 요소의 메모리는 생성하지 않음. int[] result={1,2,3,4,5}; //선언과 동시에 값을 할당 int[] result=new int[5]; //선언을 하고 배열을 생성, 크기는 브래킷안의 숫자 만큼의 요소가 생성 int[] result=new int[5] {1,2,3,4,5}; //이 방식을 줄여서 두 번째 처럼 사용가능 배열 인스턴스화 - 배열의 크기가 지정된다. - Value Type배열은 자동초기화 (정수형->0, 실수형->0.0, bool->false, char->space) - 초기화리스트 : 초기화 리스트의 수와 배열의 요소의 수가 일치 1차원 배열 인스턴스화 & 초기화 int [] nums = new int[3] {1,2,3}; int [] nums = new int[] {1,2,3}; int [] nums = {1,2,3}; 2차원 배열 인스턴스화 & 초기화 int [,] nums = new int [2,2] {{1,2},{3,4}}; int [,] nums = new int [,] {{1,2},{3,4}}; int [,] nums = {{1,2},{3,4}}; 배열의 크기 - 1차원 배열 : 배열명.Length - 2차원 배열 : GetLength public static void ArraySeek() { //1차원 배열탐색 int[] row = new int[10] {1,2,3,4,5,6,7,8,9,10}; //for문 for(int i=0;i<row.Length;i++) Console.Write("{0}\t", row[i]); Console.WriteLine(); //foreach문 foreach(int item in row) Console.Write("{0}\t", item); Console.WriteLine(); //2차원 배열탐색 int [,] table = new int[2,5] {{2,5,7,8,4},{9,3,6,4,2}}; //int rank = table.Rank;//배열의 차원 : 2 //int index = table.Length; // 값: 10, 전체배열크기값이 들어감, for문에서 Exception발생 // -> 올바른 예제 int index = table.Length/rank; //위처럼 반복할 횟수를 변수에 담아서 사용할수도 있지만 번거로움때문에 대부분 GetLength사용. //for문 for(int i=0; i<table.GetLength(0); i++) //2차원배열에서의 1차원방의 갯수(행갯수)만큼 실행 for(int j=0; j<table.GetLength(1); j++) //1차원배열의 방수(열갯수)만큼 실행 Console.Write("{0}\t", table[i,j]); Console.WriteLine(); //foreach문 foreach(int item in table) Console.Write("{0}\t",item); Console.WriteLine(); //배열을 생성하면 2차원이상도 실제로는 한줄에 모두 생성되므로 위처럼 실행하면 배열의 모든값들이 출력 //배열의 차원과는 상관없이 배열값들만 필요하다고 생각될때 사용용이. } 배열의 차원 - Rank : Array의 차수(차원의 수)를 가져옵니다. 불규칙 배열(Jagged Array) - 하나의 배열 안에 여러 크기를 가지는 배열이 내장 - 배열선언 : 데이터형[ ][ ] 배열명 = new 데이터형[크기][ ]; - 사용의 필요성 : 배열의 배열을 선언해야 할 경우, 메모리를 효율적으로 관리해야 할 경우 public static void jaggedArray() { //불규칙 배열 선언 int[][] jaggedArray = new int[5][]; jaggedArray[0] = new int[] {1,15}; jaggedArray[1] = new int[] {3,5,7}; jaggedArray[2] = new int[] {10,20,30,40,50}; jaggedArray[3] = new int[] {80,100}; jaggedArray[4] = new int[] {2,5,150,9}; //불규칙 배열요소 접근 for(int i=0; i<jaggedArray.Length;i++) { for(int j=0; j<jaggedArray[i].Length; j++) Console.Write("***");//jaggedArray[i],[j]; Console.WriteLine(); } } //불규칙배열과 2차원 배열을 함께 사용 public class JaggedArrayTest{ public static void Main(){ int[ ][,] jagArray=new int[3][,]; jagArray[0]=new int[2,2] {{3,4},{5,6}}; jagArray[1]=new int[3,2]; jagArray[1][0,0]=-1; jagArray[1][0,1]=-2; jagArray[1][1,0]=-3; jagArray[1][1,1]=-4; jagArray[1][2,0]=-5; jagArray[1][2,1]=-6; jagArray[2] = new int[3,3]{ {3,4,6}, {4,5,7}, {7,8,6}}; for(int a=0; a<jagArray.Length; a++){ //3회 실행 for(int b=0; b<jagArray[a].GetLength(0); b++){ //2차원배월의 행만큼 실행 : 2회 for(int c=0; c<jagArray[a].GetLength(1); c++){ //2차원배열 각행별 컬럼 배열값 출력 Console.Write("jagArray["+a+"]["+b+","+c+"]:"+jagArray[a][b,c]+'\t'); } Console.WriteLine(); } Console.WriteLine(); } } } *실행결과 jagArray[0][0,0]:3 jagArray[0][0,1]:4 jagArray[0][1,0]:5 jagArray[0][1,1]:6 jagArray[1][0,0]:-1 jagArray[1][0,1]:-2 jagArray[1][1,0]:-3 jagArray[1][1,1]:-4 jagArray[1][2,0]:-5 jagArray[1][2,1]:-6 jagArray[2][0,0]:3 jagArray[2][0,1]:4 jagArray[2][0,2]:6 jagArray[2][1,0]:4 jagArray[2][1,1]:5 jagArray[2][1,2]:7 jagArray[2][2,0]:7 jagArray[2][2,1]:8 jagArray[2][2,2]:6 배열복사(배열변수복사) - 배열이 참조형 변수라 번지수를 공유 int[ ] mydream = new int[ ]{1,2,3,4,5,6}; int[ ] myref1 = mydream; int[ ] myref2 = myref1; // 배열 변수들이 모두 하나의 메모리를 참조하고 있기 때문에 아무리 값을 할당해도 하나의 메모리를 그 대상으로 한다. //mydream == myref1 == myref2 //참 배열비교 예제 int[] array_1=new int[5] {1,2,3,4,5}; int[] array_2; array_2 = array_1; if(arrray_1 == array_2); //참 int[] array_1=new int[5] {1,2,3,4,5}; int[] array_2 = new int[5] {1,2,3,4,5}; if(array_1 == array_2); //거짓, new 키워드로 서로 다른 배열개체를 선언, 배열 요소들의 값은 같을 지언정 다른 개체가 되는 것이다. if(array_1[0] == array_2[0]); //참, 값을 비교 Sort / Reverse - 배열의 항목을 오름차순 or 내림차순으로 정렬 - 정적메소드 - System.Array.Sort(배열객체) - System.Array.Reverse(배열객체) public static void ArrayMethod() { int[] row = new int[10] {23,45,1,4,98,22,6,16,23,48}; Console.Write("Source : \t\t"); ArrayPrint(row); //오름차순정렬 Array.Sort(row); Console.Write("Sort : \t\t"); ArrayPrint(row); //내림차순정렬 Array.Reverse(row); Console.Write("Reverse : \t\t"); ArrayPrint(row); } public static void ArrayPrint(int[] row) { for(int i=0;i<row.Length;i++) { Console.Write("{0,3}", row[i]); } Console.WriteLine(); } Clear - 배열의 요소들을 0 or null로 초기화 - 배열자체는 남아있다. - System.Array.Clear(배열명, 시작인덱스, 길이) int[] row = new int[10] {23,45,1,4,98,22,6,16,23,48}; Console.Write("Source :\t"); for(int i=0;i<row.Length;i++) { Console.Write("{0,3}", row[i]); } Console.WriteLine(); //Clear Array.Clear(row,3,1); //3번째부터 1개 clear //Array.Clear(row,6,5); //6번째부터 5개 clear -> 인덱스가 배열을 넘어가므로 에러 Console.Write("3-1 :\t\t"); for(int i=0;i<row.Length;i++) { Console.Write("{0,3}", row[i]); } Console.WriteLine(); Array.Clear(row,0,row.Length); Console.Write("0-Length :\t"); for(int i=0;i<row.Length;i++) { Console.Write("{0,3}", row[i]); } Console.WriteLine(); Clone - 배열의 복사본 생성(전체복사) - 동일한 요소를 가지는 또 하나이 배열 객체 생성 //배열복사 public static void arrayClone() { int [] row = {0,1,2,3}; int [] copyRow = (int[]) row.Clone(); //원본을 복사해서 또하나의 다른 배열을 만든다. row와 copyRow는 별개. //int [] copyRow = row.Clone(); //에러, Clone자체가 오브젝트로 반환을 시키기 때문에 형변환을 꼭 해주어야 한다. /* * int [] copyArray = row; * row배열의 참조변수를 복사하기 때문에 row와 copyArray는 같은 배열을 가르킴 * copyArray[0] = 100; * 복사본의 값을 변경시키면 row와 copyArray의 배열값은 같이 변경됨 */ Console.Write("\nSource :\t"); for(int i=0;i<row.Length;i++) { Console.Write("{0,3}", row[i]); } Console.WriteLine(); Console.Write("\nCopy :\t"); for(int i=0;i<copyRow.Length;i++) { Console.Write("{0,3}", copyRow[i]); } Console.WriteLine(); } GetLength : 해당차원의 길이 변환 GetLowerBound : 해당차원의 시작첨자 반환 GetUpperBound : 해당차원의 끝 첨자 반환 int [] row = {0,1,2,3}; Console.WriteLine("GetLength : {0}", row.GetLength(0)); // 4 Console.WriteLine("GetLowerUbound : {0}", row.GetLowerBound(0)); // 0 Console.WriteLine("GetUpperUbound : {0}", row.GetUpperBound(0)); // 3 IndexOf / LastIndexOf - 배열에서 지정된 값을 검색, 위치값을 돌려준다. - 검색된 값이 없거나 실패하면 -1리턴 - IndexOf(배열명, 검색인자) - LastIndexOf(배열명, 검색인자) public static void arrayIndexOf() { //배열안에서 특정위치값 찾기 int[] row = new int[10] {23,45,1,4,32,22,6,32,23,48}; int firstSearch, lastSearch; firstSearch = Array.IndexOf(row, 32); //배열의 앞에서 부터 찾는다. 결과 : 4 lastSearch = Array.LastIndexOf(row, 32); //배열의 뒤에서 부터 찾는다. 결과 : 7 Console.Write("Source : "); for(int i=0;i<row.Length;i++) { Console.Write("{0,3}", row[i]); } Console.WriteLine(); Console.WriteLine("IndexOf : 32의 위치값은 {0}", firstSearch); Console.WriteLine("LastIndexOf : 32의 위치값은 {0}", lastSearch); } 메소드에서의 배열사용 - 배열의 입력 인자로 사용 참조형이라 Call By Reference로 적용 - 메소드의 반환값으로 사용 하나이상의 값을 반환시... public static void MethodArrary() { int [] row = {1,2,3,4,5}; Console.WriteLine("Main내 메소드 실행전 : " + row[0]); callArrayMethod(row); Console.WriteLine("Main내 메소드 실행후 : " + row[0]); Console.WriteLine("--------------------------------------"); Console.WriteLine("Main내 메소드 실행전 : " + row[0]); callArrayMethod((int[])row.Clone()); Console.WriteLine("Main내 메소드 실행후 : " + row[0]); Console.WriteLine("--------------------------------------"); callArrayMethod(new int[4] {2,3,4,5}); } public static void callArrayMethod(int[] row2) { row2[0]++; Console.WriteLine("배열의 Clone하여 메소드로 넘겼을때 메소드 내 : " + row2[0]); } 커맨드 라인 입력 인자 - 콘솔에서 실행파일 다음에 인자전달(Main에게...) - 보통옵션값으로 사용한다. - static void Main(string[] args){ for(int i=0; i<args.Length;i++) { Console.WriteLine(args[i]); } } ex) c:\csc Test.cs 배열예외처리 - 보통 배열첨자 범위를 벗아난 예외발생 - IndexOutOfRangeException 문자열 - 모든 문자열은 System.String로부터 상속 - 닷넷에서 string객체는 한번 인스턴스화가 되면 불편 -> StringBuilder사용 string선언 - 다른 참조형과 다르게 new연산자 이용X - 모든 string형은 유니코드 문자열 길이 - 객체명.Length - 읽기전용 문자열의 각 요소 접근하기 - 인덱서(indexer) : 문자열을 배열처럼 취급 - 읽기 전용 문자열의 추가 - Insert : 지정위치에 문자열추가 - Concat. + : 문자열합치기 - 자기자신에게 영향X 대소문자 변환 - ToLower : 소문자로 치환 - ToUpper : 대문자로 치환 공백 문자열 지우기 - Trim, TrimStart, TrimEnd - 공백삭제 문자열치환 - Replace - 문자열 내에 원하는 문자열을 바꾸고자 하는 문자열로 치환 문자열 검색, 추출 - IndexOf, LastIndexOf : 문자열 검색, 찾고자하는 문자열의 첫번째 글자 위치값 리턴 (0부터시작) - Substring : 문자열추출 문자열 포맷지정 - Console.WriteLine()에서 사용한 양식 문자열과 동일 - String.Format(); 문자열 분할 - Split - 구분자를 중심으로 문자열을 분할, 배열 형태로 반환 Equals - 두문자열이 같은지 비교 지정문자열 삭제 - Remove public static void stringMethod() { //문자열 비교 string str1="ABC"; string str2="ABC"; if(str1.Equals(str2)) Console.WriteLine("동일"); else Console.WriteLine("다름"); //문자열삭제 string str3 = "나는 문자열입니다."; Console.WriteLine(str3.Remove(3,4)); //3위체에서부터 4개 삭제 //양식문자열 str = String.Format("{0,10}","ABC"); //콘솔이 아닌 웹등에서 사용용이, 사용법은 WriteLine과 같음. Console.WriteLine(str); //콘솔에서는 WriteLine 사용 Console.WriteLine(String.Format("{0:f2}",1520)); //문자열 일정문자단위로 분리 string csv = "강남길, 최지우, 김희선,하늘이"; string[] result; result = csv.Split(','); for(int i=0; i<result.Length;i++) Console.WriteLine(result[i].Trim()); //문자열길이, 복제. 비교 str = "가나다라마바사"; Console.WriteLine("문자열 : {0}", str); Console.WriteLine("문자열 길이 : {0}", str.Length); Console.WriteLine("문자열 복제 : {0}", str.Clone()); Console.WriteLine("문자열 비교 : {0}", str.Equals("ABCDE")); //Indexer char firstChar = str[0]; Console.WriteLine("첫문자 : {0}", firstChar); // 결과 : 가 //문자열 추가 str2="추가문자열"; str = str.Insert(0, str2); //0번째 위치에 str2문자열 추가 Console.WriteLine(str); //문자열 합침 str2 = String.Concat("가","마","사"); Console.WriteLine(str2); str2 = String.Concat(str,"마","사"); Console.WriteLine(str2); str2 = str2 + str; Console.WriteLine(str2); //대소문자 변환 str = "Hi~ Hong~"; Console.WriteLine(str.ToUpper()); Console.WriteLine(str.ToLower()); Console.WriteLine(str); //문자열 좌/우 공백제거 str = " 잘 살아 보세 "; Console.WriteLine(">" + str.TrimStart() + "<") ; Console.WriteLine(">" + str.TrimEnd() + "<"); Console.WriteLine(">" + str.Trim() + "<"); Console.WriteLine(">" + str.TrimStart().TrimEnd() + "<"); //문자열 치환 str = "Hello~"; Console.WriteLine(str); Console.WriteLine(str.Replace("~", "...")); //문자열 검색, 0부터 시작. 해당하는 문자열의 첫번째 위치값 리턴 Console.WriteLine(str.IndexOf("녕하")); str = "I Love You~"; //문자열 추출 Console.WriteLine(str.Substring(2)); //2번째위치부터 끝까지 Console.WriteLine(str.Substring(2,4)); } ToCharArray - 문자열을 Char형의 배열 형식으로 반환합니다 public static void ToCharArray_Test() { string str = "012wxyz789"; char[] arr; arr = str.ToCharArray(3, 6); //3번째 위치에서 6개의 글자를 추출해 배열방에 각각 넣는다. Console.Write("The letters in '{0}' are: '", str); Console.Write(arr); //배열방 출력시 해당내용 출력 for(int i=0;i<arr.Length;i++) //각각의 배열방에도 들어가 있음. Console.WriteLine(arr[i]); Console.WriteLine("'"); char[] array; array = str.ToCharArray(); //인자를 써주지 않으면 모든 문자 배열에 집어넣음 Console.WriteLine("Each letter in '{0}' is:", str); Console.WriteLine(array); foreach (char c in arr) Console.WriteLine(c); } System.Text.StringBulider - 닷넷에서 String클래스를 이용한 문자열 처리는 비효율적 - 대형 문자열이나 잦은 문자열 변경시 - 대부분의 문자열 관련 함수들이 String 인스턴스를 새로 생성시켜 반환 - 버퍼 크기 증가(필요한 경우)와 길이 추적을 자동으로 처리 StringBulider sb = new StringBulider("ABC"); - StringBuilder.Capacity : 객체내에 문자열 버퍼 크기 - StringBuilder.Length : 문자열 길이 public static void StringBuilderTest() { StringBuilder sb = new StringBuilder("I am a Boy", 18); //가용량을 적어주지 않으면 기본 용량은 16이고, 기본 최대 용량은 Int32.MaxValue Console.WriteLine(sb.ToString()); Console.WriteLine(sb.Length); Console.WriteLine(sb.Capacity); Console.WriteLine(sb.MaxCapacity); Console.WriteLine(sb.Insert(0,"삽입")); Console.WriteLine(sb.Remove(0,2)); Console.WriteLine(sb.Append("추가문자열")); Console.WriteLine(sb.Append(5000)); Console.WriteLine(sb.AppendFormat("{0,10}","end")); Console.WriteLine(sb[0]); sb[0] = 'i'; Console.WriteLine(sb[0]); Console.WriteLine(sb.ToString().Replace(" ","")); Console.WriteLine(sb.ToString().IndexOf("Boy")); } ASPX Web Form과 같이 데이터 스트리밍을 지원하는 환경에 있거나 응용 프로그램에서 데이터를 디스크에 기록할 경우에는 연결의 버퍼 오버헤드나 StringBuilder 클래스를 사용하지 말고 Response.Write 메서드나 해당 스트림에 적합한 메서드를 통해 스트림에 직접 데이터를 기록하십시오. StringBuilder 클래스를 필요할 때마다 다시 할당하지 말고 기존의 StringBuilder 클래스를 다시 사용해 보십시오. 그러면 불필요한 힙 증가를 억제하고 가비지 수집을 줄일 수 있습니다. 두 경우 모두 StringBuilder 클래스를 사용하면 + 연산자를 사용하는 것보다 효율적으로 힙을 사용할 수 있습니다. 객체지향 - 절차 지향 프로그래밍 : 기능이나 동작 절차를 나열한 형태 - 객체 지향 프로그래밍 : 기능 위주가 아닌 객체 위주의 프로그래밍, 이벤트 위주 객체(Encapsulation) - 데이터 + 프로시저 - 독자성(Indentity) : 객체는 다른 객체와 구분 - 상태(State) : 객체의 상태(객체만의 데이터) - 행동(Behavior) : 객채의 행동(메소드, 프로시저) - 실세계 객체를 모델링해서 소프트웨어 객체 생성 캡슐화(Encapsulation) - 내부 정보 은닉화 - 외부에서 객체 내부의 데이터를 함부로 접근 불가 - 객체 내부를 몰라도 객체 사용가능 - 간결한 코드 작성 : 내부 아키텍처를 몰라도 공개된 인터페이스만 알면 코딩 가능 - 모듈화 : 모든 내부 코드가 객체 내에 기술 - 정보은닉 : 객체내 데이터는 공개된 메소드를 통해서만 제어 가능 메시지(Message) - 객체끼리 주고 받는 명령 혹은 정보(통신) - 파라미터를 통해 출력결과를 다양하게 반환 - 객체의 메소드 - 모든 기능을 하나의 객체에 집중할 필요 없음 -> 특정 기능 필요시 그 객체와만 대화 객체 & 클래스 - 클래스는 객체에 대한 설계도 클래스 & 인스턴스 - 인스턴스는 클래스를 실제 구현한 객체 - 인스턴스로 객체 생성시 다양한 객체를 생성(Indentity, State...) 클래스 상속(Inheritance) - 슈퍼클래스(Super Class) : 자신을 상속하는 클래스(부모클래스, 기본클래스) - 서브클래스(Sub Class) : 상속을 받는 클래스(자식클래스, 파생클래스) - 서브클래스는 슈퍼클래스의 변수 및 메소드를 상속받는다 - 상속 전의(Transition) : 부모의 메소드를 자식, 손자, 증손자에게 계속 전달 다형성(Polymorphism) - 클래스는 다양한 형태를 가질 수 있다. - 오버라이딩(Overridion), 오버로딩(Overloadiong) - 중복정의 or 재정의를 통해서 구현 클래스(Class) 클래스멤버(Class Member) - 클래스를 구성하는 요소 - 필드(Field) : 필드 or 멤버변수 - 메소드(Method) : 객체행동 - 프로퍼티(Property) : 특성, 속성,.. 밖에서 보기엔 멤버 변수지만, 내부적으로 메소드 - 상수(Constant) : 읽기전용 - 인덱서(Indexer) : 스마트 배열 - 이벤트(Event) - 연산자(Operator) : 연산자 오버로딩 접근제한자(Access modifier) - 클래스 멤버의 보안제어 - 캡슐화, 내부은닉화 - public, private, protected, internal public - 클래스 멤버를 공개하고자 할때..(인터페이스) - 보통 데이터는 은닉화, 메소드는 공개 - 누구나 사용가능, 클래스 내부, 파생 클래스, 클래스 외부 private - 멤버를 포함한 클래스 내부에서만 접근가능 - 가장 엄격한 수준의 접근 제한자 - 보통 데이터의 접근 제한자. protected - 클래스 내부와 파생클래스에서만 접근가능 - 클래스 자신과 파생 클래스(상속받은 클래스)에서만... - 반드시 동일어셈블리는 아니다. internal - 동일 어셈블리내에서 접근가능 - 외부에서 참조할 일이 없을 경우(참조해선 안되는 경우) - 내부에서만 사용해야 하는 경우 protected internal - 동일 어셈블리안에 있는 파생 클래스에서만 가능 기본 접근 제한자 - class : private - 멤버 : private - struct : private - enum : public - interface : public 정적(클래스) 변수 & 메소드 public class Test { public int i; //객체변수 public static int j =0; public void IncreaseI() { i++; } public void IncreaseJ() { j++; } public static int num = 0; public Test() //기본생성자 { num++; } public static int mtTest() { return num; } } class MainClass { [STAThread] static void Main(string[] args) { Test n1 = new Test(); Test n2 = new Test(); Test n3 = new Test(); Test n4 = new Test(); Test n5 = new Test(); Console.WriteLine(Test.num); //num은 정적변수이기 때문에 객체를 생성될때마다 기본생성자가 실행되어 변경된 값을 그대로 적용받는다. Console.WriteLine("객체생성전 : "+Test.j); //static으로 선언하지 않았을경우에는 객체를 생성해서 사용한다. //똑같은 이름의 객체를 생성한다 하더라도 새로 생성한 두 객체는 기본틀만 같을 뿐 각각 다른 객체이다. Test t = new Test(); t.i = 100; t.IncreaseI(); t.IncreaseI(); Test t2 = new Test(); t2.i = 200; t2.IncreaseI(); t2.IncreaseJ(); Console.WriteLine("t.i = " + t.i); Console.WriteLine("t2.i = " + t2.i); Console.WriteLine("Test.j = " + Test.j); // static으로 선언한 객체는 클래스명.객체명으로만 접근가능하다. // 각 객체간의 공통된 데이터로 사용하고 싶을때 사용.. } } 객체생성 - 클래스를 기반으로 객체를 생성 - 인스턴스화 or 객체생성 - new연산자 + 객체 생성자(Constructor) this 연산자 - 객체 자신을 의미(메소드가 호출되는 객체자신) - 정적 메소드에선 불가능(객체에서만 사용가능) - this로 객체반환도 가능 public class Goods { private int price, quantity; //private static int a; public Goods SetPrice(int price) { this.price = price; //this.a = price //정적변수는 this로 접근할수 없다. return this; //SetPrice메소드의 리턴형태는 Goods //위는 아래형태로 리턴하는것과 같다. //Goods goods = new Goods(); //return Goods; } public Goods SetQuantity(int quantity) { this.quantity = quantity; return this; } public int PutPirce() { return this.price; } public int PutQuantity() { return this.quantity; } } public class callClass { public static void ReturnThis() { Goods product = new Goods(); product.SetPrice(100).SetQuantity(30); //product.SetPrice(100); //product.SetQuantity(30); //위와 같은 형태 //product.SetPrice(100)의 리턴값이 Goods 이기때문에 //그다음에 실행해야 하는 문장은 product.SetQuantity(30);과 같다. Console.WriteLine("가격은 : {0,3}원", product.PutPirce()); Console.WriteLine("갯수은 : {0,3}개", product.PutQuantity()); } } 위임과 이벤트(Delegate & Event) - 메소드의 실행을 위임 변수가 대행 - 메소드 포인터 - 위임형식은 동일한 파라미터와 반환형을 가지는 여러개의 메소드를 수행 가능하다. - 객체 메소드 or 정적메소드 둘다 가능 - 위임은 메소드 포인터만 저장, 코드 기술은 불가 - 인터페이스를 지원하는 객체들 내에서 동일한 메소드 명으로 객체 내의 메소드 수행이 가능하듯이 위임도 동일한 위임명으로 메소드 형식이 동일한 다른 메소드 실행이 가능(다형성) 위임선언 - public delegate 반환형 위임명(인자리스트); - delegate 키워드(본문X) - 메소드 파라미터 형식과 메소드 반환형식이 같으면 위임 형식에 위임 가능 publid delegate void Sample (int x, int y); - public static void M1(int x, int y); //가능 - public void M2(int x, int y) //가능 - public int M3(int x, int y); //X, 리턴타입이 다름 - public void M4(int x); //X, 인자갯수가 다름 - public void M5(string x, int y); //X, 인자의 타입이 다름 - public void M6(int x, int y, int z); //X, 인자수가 다름 위임생성 - System.Delegate와 System.MulticastDelegate로 부터 상속 - 따라서 new 연산자로 위임 객체 생성 - 생성자의 인자는 반드시 정적메소드면 "클래스명.메소드명", 객체메소드면 "객체명.메소드명" Sample d = new Sample(Class.M1); //인자에 메소드명만 들어간다. Sample d = new Sample(obj.M2); using System; namespace CSharpStudy { class MyClass { public int num = 0; public void Plus(int value) { this.num +=value; } public void Minus(int value) { this.num -=value; } public static void PrintHello(int value) { for(int i=0; i<value; i++) Console.WriteLine("Hello~"); } } //Delagete선언 public delegate void Sample(int value); class MainClass { [STAThread] static void Main(string[] args) { MyClass c = new MyClass(); Sample d = new Sample(c.Plus); //위임 d(10); Console.WriteLine(c.num); c.Plus(10); Console.WriteLine(c.num); d = new Sample(c.Minus); d(10); Console.WriteLine(c.num); c.Minus(10); Console.WriteLine(c.num); //정적메소드 위임 d = new Sample(MyClass.PrintHello); d(5); } } } 위임사용 - 위임 객체 사용은 일반메소드와 동일 - 위임 호출시 파라미터를 전달하면 실제 메소드에 파라미터 전달, 호출 - 동일한 위임객체로 어떤 메소드를 참조하느냐에 따라 호출변경(메소드 다형성) - 위임자는 변경할 수 없으며 일단 만들어지면 위임자의 호출 목록은 바뀌지 않는다. - 여러 개의 호출목록을 지정해 주려면 그 Delegate의 형식은 리턴 타입이 반드시 void 이어야 함. -> 매개변수중에 어느것도 out 이 지정되어선 안된다. 위임연산 - Combine(+), Remove(-) - 위임 객체에 메소드 추가, 제거 - 위임 객체가 가지는 메소드 리스트(Invocation List) Combine & Remove - Combine과 Remove를 명시적으로 호출해서 리스트 관리 기능 위임간 비교연산 - Equals, ==, != 재정의 - Invocation List를 비교한다. using System; namespace CSharpStudy { // Mult Delegate 사용에 관한 예제입니다. class MyClass { public int num = 0; public void Plus(int value) { this.num +=value; } public void Minus(int value) { this.num -=value; } public static void PrintHello(int value) { for(int i=0; i<value; i++) Console.WriteLine("Hello~"); } } //delegate 선언 public delegate void Sample(int value); // 다중 메소드 연산이 가능 // 멀티 Delegate를 사용할 때 메서드는 반드시 void를 반환해야 함 -> 호출을 목적으로 하기때문 // void를 반환하지 않으면 +=과 같은 연산자를 사용할수 없다. // 중복 메서드를 포함 가능 //호출된 메서드가 예외를 throw하면 메서드는 실행을 멈추고 예외는 대리자의 호출자에게 전달. //호출 목록에 남아있는 메서드는 호출되지 않음. 호출자 안에서 예외를 catch해도 이 동작은 변하지 않습니다. class MainClass { [STAThread] static void Main(string[] args) { //위임 메소드 리스트 관리 MyClass c = new MyClass(); Sample d; //Delegate Combine // d = (Sample)Delegate.Combine(new Sample(c.Plus), new Sample(c.Minus)); d = new Sample(c.Plus) + new Sample(c.Minus); // +연산자 오버로딩됨 d(10); //c.Plus와 c.Minus 메소드가 순서대로 실행됨. 결과값 : 0 Console.WriteLine(c.num); //Delegate Remove // d = d - new Sample(c.Minus); //c.Minus메소를 제거 d -= (Sample) new Sample(c.Minus); // -=연산자 오버로딩됨 d(10); //c.Plus메소드만 실행. 결과값: 10 Console.WriteLine(c.num); //Delegate Combine d += new Sample(MyClass.PrintHello); //MyClass.PrintHello 메소드가 추가, +=연산자 오버로딩됨 d(5); //c.Plus와 MyClass.PrintHello 메소드 실행, 오래등록된 메소드부터 실행 Console.WriteLine(c.num); //Deleate 비교연산 -> 가지고 있는 메소드 목록(목록 순서, 목록갯수 포함)을 비교한다. Sample s1 = new Sample(c.Plus) + new Sample(c.Minus); Sample s2 = new Sample(c.Plus); if(s1 == s2) Console.WriteLine("s1과 s2가 같습니다"); else Console.WriteLine("s1과 s2가 다릅니다"); // 가지고 있는 목록이 다르므로 다르다는 내용 출력 s2 += new Sample(c.Minus); if(s1 == s2) Console.WriteLine("s1과 s2가 같습니다"); else Console.WriteLine("s1과 s2가 다릅니다"); // 가지고 있는 목록이 같으므로 같다는 내용 출력 } } } 이벤트(Event) - 동작을 수행하는 방식 - 출판자(Publisher) : 이벤트를 발생하며 특정 구독자에게 이벤트 발생을 알려준다. - 구독자(Subscriber) : 특정 이벤트 발생 통보를 받고 출판자로부터 호출되어질 메소드를 등록한 객체 - 이벤트 핸들러(Event Handler) : 호출되어지는 메소드 - 구독자들이 출판자에게 자신의 이벤트 핸들러를 출판자의 이벤트 핸들러 목록에 등록한다. 이벤트 정의 - event 키워드 - 접근지정자 event Delegate명 이벤트명; - 반드시 위임과 같이 정의한다. 이벤트 핸들러 추가 및 해제 - +=, -+로 이벤트 핸들러를 출판자 객체에게 등록 및 제거한다. - 위임 등록과 동일 - 객체명.이벤트명 += new Delegate명(객체명.메소드명); 구독자들에게 이벤트 발생 알리기 - 위임에서 위임 객체를 실행하며 Invocation List안에 모든 메소드를 실행하듯이 이벤트 요청이 발생하면 이벤트안에 이벤트 핸들러가 있는지 조사하고 이벤트 핸들러를 호출한다. 이벤트 핸들러 생성 - 모든 형태가능 -> 단 위임 형식과 동일한 메소드 형식 - 보통 포준적인 이벤트 핸들러 형식 public delegate void EventHandler(object sender, EventArgs args) - object sender : 동일한 이벤트 핸들러가 다중의 출판자에게 등록이 가능하므로 sender를 가지고 호출자(출판자)를 구별 - EventArgs args : 이벤트 발생시 추가 정보 전달 - 모든 이벤트 핸들러는 이 위임형과 반드시 동일 using System; namespace CSharpStudy { class Button { public event Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClick Click; //이벤트생성, 접근지정자 event Delegate명 이벤트명; public string Text; public void Trigger() { Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClickEventArgs e = new Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClickEventArgs(); e.i = 100; Console.WriteLine("Button이 클릭되었습니다"); Click(this, e); //실제로 이벤트를 발생시키는 부분 } } //delegate public delegate void Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClick(object sender, Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClickEventArgs e); //사용자 정의 EventArgs public class Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClickEventArgs : EventArgs { public int i; } class MainClass { //이벤트 핸들러 선언 public static void button1_Click(object sender, Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClickEventArgs e) { //object sender는 메시지가 어디서 발생하는지 발생된 곳의 참조값 // Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClickEventArgs e는 이벤트의 데이터를 담고 있는 매개변수. //이 두가지의 매개변수는 바꿀 수 없으며 항상 위와 같은 규칙으로 사용해야 함. Button button = (Button) sender; Console.WriteLine("Button Text : " + button.Text); Console.WriteLine("EventArgs : " + e.i); Console.WriteLine("Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClick 이벤트가 발생해서 이벤트 핸들러가 호출되었습니다."); } public static void button1_Click2(object sender, Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClickEventArgs e) { Console.WriteLine("Click2~"); } [STAThread] static void Main(string[] args) { Button btn1 = new Button(); btn1.Text = "테스트 버튼"; btn1.Click += new Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClick(button1_Click); //Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClick(위임자)에 호출메서드 등록 btn1.Click += new Butt[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonClick(button1_Click2); btn1.Trigger(); //이벤트 발생 에뮬레이터 Console.Read(); //실행화면 일시중지 } } } 프로퍼티(Property) - 클래스가 가지는 속성, 특성 - 멤버 필드(내부데이터)를 보호하되 외부에서 제어를 해야 하는 경우... - 내부적으로는 메소드의 형태를 가지고, 외부적으로는 멤버 변수의 형태를 가진다. - Smart Field or Logical Field 프로퍼티의 정의 - 파라미터가 없는 메소드 형식 - get, set 접근자 사용(일종의 내부메소드) - 한 클래스내에서 프로퍼티명과 멤버변수의 명이 같으면 X (프로퍼티는 첫글자 대문자) - get : 데이터를 읽어올때 (외부에서 클래스내의 데이터를...) 내부에 retrun문 필요(getter) - set : 데이터를 설정할때, 내부에 value 키워드 사용 (setter) private string text; public string Text //text는 필드이지만 마치 메소드인것처럼 body를 가진다. { get {return text;} set{text = value;} } 프로퍼티 형식 - 읽기 및 쓰기 지원 프로퍼티 : get, set 모두 정의한 프로퍼티 - 읽기 전용 프로퍼티 : get만 정의 - 쓰기 전용 프로퍼티 : set만 정의 - 정적 프로퍼티 : 정적메소드처럼 클래스 단위로 접근 - 계산된 프로퍼티 : 연산등 임의의 계산된 값을 다루는 프로퍼티 생성 가능 프로퍼티 & 필드 - void 형식을 제외한 데이터 형식 정의 가능 - 접근 제한자 선언가능 - 정적(static) 프로퍼티 선언 가능 - 필드 사용과 유사 - 프로퍼티는 값에 의한 전달만 가능 - 프로퍼티는 필드와는 달리 실제 메모리상에서 값을 가지고 있지 않기 때문에 주소와 관련된 ref,out같은 메소드 매게변수를 쓸 수 없다. using System; namespace CSharpStudy { class Pen { private string color; public Pen() : this("검정"){} //기본생성자 public Pen(string color) //기본생성자 오버로딩 { this.color = color; } public void TextWrite(string text) //출력메소드 { Console.WriteLine("{0} color : {1}", color, text); } //메소드를 이용해서 지역변수 필드에 특성등을 변경후 사용할때 public void ChangeColor(string color) { this.color = color; } public string GetColor() { return this.color; } //프로퍼티를 이용할때 public string Color //파라미터(인자값)이 생략된 메소드형태 { //멤버변수와 프로퍼티명은 같으면 안되므로 프로퍼티명은 멤버변수명의 첫글자를 대문자로 바꾸어 사용한다. get { return this.color;} set { this.color = value;} } } class MainClass { [STAThread] static void Main(string[] args) { Pen bPen = new Pen(); Pen rPen = new Pen("빨강"); Pen yPen = new Pen("노랑"); bPen.TextWrite("테스트"); rPen.TextWrite("테스트"); yPen.TextWrite("테스트"); //메소드 이용 Console.WriteLine("------------ Method 이용---------------"); bPen.ChangeColor("보라"); bPen.TextWrite("테스트"); //프로퍼티를 이용 Console.WriteLine("------------ Property이용---------------"); bPen.Color = "보라"; //프로퍼티명에 값 입력 bPen.TextWrite("테스트"); } } } 프로퍼티 & 메소드 - 반환 형식 설정 - virtual, abstract, override 사용가능 - 객체 내의 상태에 대한 접근 분리 - 프로퍼티는 void형식 불가 - 프로퍼티는 value 인자 하나외에는 파라미터 추가 불가 abstract class A { int y; public virtual int X { //가상 읽기전용프로퍼티 get { return 0; } } public virtual int Y { //가상 읽기,쓰기프로퍼티 get { return y; } set { y = value; } } public abstract int Z { //추상 읽기,쓰기프로퍼티 get; set; } } class B: A { int z; public override int X { //오버라이드(가상) 프로퍼티 get { return base.X + 1; } } public override int Y { //오버라이드(가상) 프로퍼티 set { base.Y = value < 0? 0: value; } } public override int Z { //오버라이드(추상) 프로퍼티 get { return z; } set { z = value; } } 프로퍼티 가이드 라인 - 객체에서 겉으로 드러나는 속성일 경우... - 읽기전용 속성, 쓰기 전용 속성 생성자 ->* readonly를 이용한 읽기전용 필드보다는 get을 이용해서 많이 사용 - 값을 받아 들일때 값의 검증이 필요한 경우... using System; namespace CSharpStudy { class Person { private string lastName =""; private string firstName=""; private int birthYear = 0; private static int generation = 0; //읽기, 쓰기 프로퍼티 public string LastName { get {return lastName;} set {this.lastName = value;} } //읽기전용 프로퍼티 public string FirstName { get {return "김";} } //쓰기전용프로퍼티 public int BirthYear { set { //입력값 검증 if(1950<=value && value <=2050) this.birthYear = value; else birthYear = 0; } } //계산된 프로퍼티 public int Age { get{return 2004-birthYear;} } //정적프로퍼티 : 정적멤버를 사용하기 위해서... 정적메소드와 동일한 형식 public static int Generation { get{return Person.generation;} set{Person.generation = value;} } } class MainClass { [STAThread] static void Main(string[] args) { Person hong = new Person(); hong.LastName = "길동"; //hong.FirstName = "홍"; //읽기전용이기 때문에 에러 hong.BirthYear = 1970; Console.WriteLine(hong.FirstName + " " + hong.LastName); Console.WriteLine(hong.Age); Console.WriteLine("계산전 : "+Person.Generation); Person.Generation++; //메소드인데 일반변수처럼 사용됨. Console.WriteLine("계산전 : "+Person.Generation); } } } 인덱서(Indexer) - 객체가 배열을 사용할때 객체 자체가 배열인 것 처럼 접근 가능 - Smart Array - System.String 인덱서 선언 - 프로퍼티 선언과 유사 - this 키워드, 배열 첨자 추가 - get, set, value 사용 - 프로퍼티는 static일수도 있지만 인덱서는 반드시 인스턴스 멤버로만 존재 (static은 인덱서 선언에 사용불가) - 인덱서는 프로퍼티와 마친가지로 실제값을 가지고 있지 않기 때문에 ref, out과 같은 접근자를 사용할수없다. public string this [int index] { get{return array[index]; set {array[index]=value;} } - 반드시 첨자가 정수일 필요는 없다 using System; namespace CSharpStudy { class MyString { private string [] data; //인덱서를 이용해서 접근할 멤버 변수(배열) //배열 크기 초기화 public MyString() : this(10) {} //기본생성자 public MyString(int size) //기본생성자 오버로딩 { this.data = new string[size]; } //인덱서 public string this[int index] //하나만 사용가능, 시그너처(차원)가 다를경우 오버로딩 가능 { //다른필드처럼 인스턴스 뒤에 점연산자를 사용하지 않고 //그 클래스 자체가 배열로 사용하기 때문에 this키워드가 인덱서의 이름으로 사용된다. get { //첨자 범위 체크 if (index > -1 && index < data.Length) return data[index]; else { return null; //예외처리부 } } set { //첨자 범위 체크 if(index >-1 && index<data.Length) data[index] = value; else throw new IndexOutOfRangeException(); //일반적으로 try~catch의 예외처리는 해당메소드를 호출한곳에서 처리하도록 한다. } } public int Length //배열의 크기는 한번정해지면 수정할수 없기 때문에 읽기전용만 가능 { get {return data.Length;} } } class MainClass { [STAThread] static void Main(string[] args) { MyString s = new MyString(5); //인덱서 호출 -> 객체명[인덱서]를 사용하기만 하면 인덱서가 호출된다. //인덱서 값 할당 s[0]= "A"; s[1]= "BC"; s[2]= "DEF"; s[3]= "GHIJ"; s[4]= "KLMNO"; //인덱서 값 읽음 for(int i=0; i<s.Length;i++) Console.WriteLine("s[{0}]={1}", i, s[i]); } } } 인덱서 & 배열 - 인덱서는 모든 데이터 형식을 첨자로 사용가능 - 인덱서는 값에 의한 전달만 가능 - 인덱서는 오버로딩 가능 - 인덱서는 값의 추가 처리 가능 * 첨자를 문자열로 사용한 예제 using System; namespace CSharpStudy { class MyString { private string data1 = "ABCDE"; private string data2 = "가나다라마"; private int [] nums = new int[5]; //Indexer public int this[int index] { get { return nums[index]; } set { this.nums[index] = value; } } //indexer 오버로딩 가능 public string this[string index] { get { //첨자 확인 if (index == "ENGLISH") return data1; else if (index == "KOREAN") return data2; else return null; } set { if (index == "ENGLISH") this.data1 = value; else if (index == "KOREAN") this.data2 = value; else throw new IndexOutOfRangeException(); } } } class MainClass { public static void Main() { MyString s = new MyString(); s["ENGLISH"] = "I'm American"; s["KOREAN"] = "나는 한국인입니다"; Console.WriteLine("ByEnglish : {0}", s["ENGLISH"]); Console.WriteLine("ByKorean : {0}", s["KOREAN"]); s[0] = 100; Console.WriteLine(s[0]); } } } 인덱서 & 프로퍼티 - 둘다 get, set사용 - void불가 - 인덱서만 오버로딩 가능(프로퍼티는 인자리스트X) - 프로퍼티는 정적 구현 가능 파일 & 디렉토리 - System.IO - FileInfo - DirectoryInfo - FileSystemInfo - 파일 및 디렉토리 조작 관련 클래스 인코딩 - 문자 코드를 컴퓨터가 이해가능한 0과 1의 바이너리 값을 가지는 연속적인 비트형태로 매핑시켜주는 작업 - ASCII : 7비트사용, 총 128문자 표현 - ISO-8859-1 : 8비트 사용, 서유럽 문자 집합, 기존 ASCII코드에 추가 문자 포함, 총 256문자 표현 - KSC 5601 : 한국 공업표준, 2바이트 완성형 한글 표현, ASCII 문자제외 - EUC-KR : ASCII문자 코드는 1바이트, 한글은 2바이트로 표현 - 유니코드 : 인간이 사용하는 모든 언어표현, 2바이트 사용, 총 65365개 문자표현 - UTF-8 : ASCII문자 코드는 1바이트, 다른 문자는 2바이트나 그 이상으로 표현(한글은 3바이트로 인코딩), 기본 사용 추세 - UTF-16 : 2바이트로 모든 문자 코드 표현 스트림 - C#에서의 모든 입출력 - 스트림을 통해 입출력되는 단위는 byte -> 스트림 내부에는 데이터 타입X -> 어떤 종류의 입출력장치나 파일도 쉽게 처리 - 프로그램상의 객체(데이터)는 데이터 타입이 있기 때문에 이런 바이트 단위와 변한하는 과정이 필요 -> 닷넷 스트림 관련 클래스 - System.IO : 스트림 관련 클래스 Stream 추상클래스 - 모든 스트림 - FileStream, MemoryStream, NetworkStream - 입출력 장치에 관계없는 일관된 프로그래밍 지원 FileStream - 파일에 들어있는 데이터를 바이트 배열로 읽고 쓰기 위한 기능 제공 Stream 관련 클래스 - 의미없이 연속된 바이트 데이터를 의미있는 타입 데이터로 바꾸는 기능 제공 - Reader / Writer - StreamReader : 파일등의 입출력 장치에서 얻은 바이트들을 여러 인코딩을 통해서 의미있는 문자나 문자열로 해석(TextReader 구현) - StreamWriter : 프로그램에서의 의미있는 문자나 문자열을 입출력 장치로 쓸수 있게 한다(TextWriter 구현) - 개발자는 더이상 바이트 스트림에 대한 신경 안써도 됨 -> 스트림을 직접 다루지 않아도 된다. FileStream.Flush - 스트림에 대한 모든 버퍼를 지우고 버퍼링된 모든 데이터가 내부 장치에 저장되도록 한다. - Close를 하기전에 적절히 사용 파일 메소드 - 파일에 텍스트 추가 : File.AppendText, FileInfo.AppendText - 파일이름 변경, 이동 : File.Move,FileInfo.MoveTo!! - 파일삭제 : File.Delete, FileInfo.Delete - 파일복사 : File.Copy, FileInfo.CopyTo - 파일 크기를 정보 : FileInfo.Length - 파일특성 가져옴 : File.GetAttributes - 파일의 특성 설정 : File.SetAttributes - 파일이 존재여부 체크 : File.Exists - 파일의 정규화된 경로를 검색 : Path.GetFullPath - 파일 확장명을 검색 : Path.GetExtension - 경로에서 파일 이름 및 확장명을 검색 : Path.GetFileName - 파일 확장명을 변경 : Path.ChangeExtension * 파일 속성 이용 예제 using System; using System.IO; namespace CSharpStudy { class MainClass { [STAThread] static void Main(string[] args) { string path = @"C:\boot.ini"; Console.WriteLine("------------- -FileInfo ------------------"); FileInfo file = new FileInfo(path); if(file.Exists) //파일이 해당경로에 존재하는지 여부 체크 { Console.WriteLine("Attributes : {0}", file.Attributes); Console.WriteLine("File Name : {0}", file.Name); Console.WriteLine("File Ext : {0}", file.Extension); Console.WriteLine("File Size : {0}", file.Length); Console.WriteLine("Create time : {0}", file.CreationTime); Console.WriteLine("DirectoryName : {0}", file.DirectoryName); Console.WriteLine("Full Name: {0}", file.FullName); Console.WriteLine("Last AccessTime : {0}", file.LastAccessTime.ToString()); Console.WriteLine("Last WriteTime : {0}", file.LastWriteTime.ToString()); } else { Console.WriteLine("파일이 존재하지 않습니다."); } Console.WriteLine("\n"); Console.WriteLine("-------------- DirectoryInfo ------------------"); string dirPath = @"D:\Inetpub\wwwroot"; DirectoryInfo dir = new DirectoryInfo(dirPath); Console.WriteLine("Attributes : {0}", dir.Attributes); Console.WriteLine("Directory Name : {0}", dir.Name); Console.WriteLine("Parent : {0}", dir.Parent.Name); Console.WriteLine("Root : {0}", dir.Root.Name); Console.WriteLine("Create time : {0}", dir.CreationTime); Console.WriteLine("Full Name: {0}", dir.FullName); Console.WriteLine("Last AccessTime : {0}", dir.LastAccessTime.ToString()); Console.WriteLine("Last WriteTime : {0}", dir.LastWriteTime.ToString()); } } } *파일 메소드 이용예제 using System; using System.IO; namespace CSharpStudy { class MainClass { [STAThread] static void Main(string[] args) { string path = @"text.txt"; FileInfo file = new FileInfo(path); bool flag = true; while(flag) { Console.WriteLine("====================="); Console.WriteLine(" 파일 처리"); Console.WriteLine("====================="); Console.WriteLine("1. 파일생성"); Console.WriteLine("2. 텍스트추가"); Console.WriteLine("3. 파일 읽기"); Console.WriteLine("4. 파일삭제"); Console.WriteLine("5. 파일 복사"); Console.WriteLine("6. 파일이동"); Console.WriteLine("7. 종료"); Console.Write("\n원하시는 작업 : "); string sel = Console.ReadLine(); switch(sel) { case "1": CreateText(file); break; case "2": AppendText(file); break; case "3": ReadText(file); break; case "4": DeleteFile(file); break; case "5": CopyFile(file); break; case "6": MoveFile(file); break; case "7": default: Console.WriteLine("프로그램을 종료합니다."); flag = false; break; } } } //파일생성 public static void CreateText(FileInfo file) { StreamWriter writer = file.CreateText(); //UTF-8로 인코딩된 텍스트를 쓰기 위해 파일을 만들거나 엽니다 //file.CreateText(쓰기용으로 사용할 파일의 경로); -> 경로가 없으면 자기자신에게 실행 writer.Close(); Console.WriteLine("파일이 생성되었습니다\n\n"); } //텍스트추가 public static void AppendText(FileInfo file) { if(file.Exists) { Console.WriteLine("\n텍스트를 입력하세요(/p : 입력종료)"); StreamWriter writer = file.AppendText(); //기존 파일에 UTF-8로 인코딩된 텍스트를 추가하는 StreamWriter를 만듬 //file.AppendText(추가하고자하는 파일의 경로); ->경로가 없으면 자기자신에게 실행 string inputString = Console.ReadLine(); while(inputString != "/q") { writer.WriteLine(inputString); inputString = Console.ReadLine(); } writer.Close(); Console.WriteLine("텍스트 추가가 완료 되었습니다.\n\n"); } else { Console.WriteLine("파일이 존재하지 않습니다."); } } //파일읽기 public static void ReadText(FileInfo file) { if(file.Exists) { StreamReader reader = file.OpenText(); //UTF-8로 인코딩된 기존 텍스트 파일을 읽기 용으로 엽니다 Console.WriteLine(reader.ReadToEnd()); Console.WriteLine("\n\n"); reader.Close(); } else { Console.WriteLine("파일이 존재하지 않습니다\n\n"); } } //파일삭제 public static void DeleteFile(FileInfo file) { if(file.Exists) { file.Delete(); Console.WriteLine("파일을 삭제하였습니다."); } else { Console.WriteLine("파일이 존재하지 않습니다\n\n"); } } //파일복사 public static void CopyFile(FileInfo file) { if(file.Exists) { file.CopyTo("copy.txt", true); Console.WriteLine("파일을 복사하였습니다."); } else { Console.WriteLine("파일이 존재하지 않습니다\n\n"); } } //파일이동 public static void MoveFile(FileInfo file) { if(file.Exists) { Console.Write("이동 경로 입력 : "); string dirPath = Console.ReadLine(); file.MoveTo!!(dirPath + "\\move.txt"); //해당경로로 이름을 바꿔서 이동한다. Console.WriteLine("파일을 복사하였습니다."); } else { Console.WriteLine("파일이 존재하지 않습니다\n\n"); } } } } using System; namespace cSharpStudy { class MainClass { [STAThread] static void Main(string[] args) { DateTime myDate = DateTime.Now; Console.WriteLine(myDate.ToString()); Console.WriteLine("DateTime.Now : "+DateTime.Now); // 현재 날짜및 시간 Console.WriteLine("DateTime.Today : "+DateTime.Today); //0시 0분 0초로 셋팅된 현재 날짜와 시간 Console.WriteLine("myDate.Year : "+ myDate.Year); //현재날짜의 년도, int Console.WriteLine("myDate.Month : "+ myDate.Month); //현재날짜의 월, int Console.WriteLine("myDate.Day : "+ myDate.Day); //현재날짜의 일, int Console.WriteLine("myDate.Hour : "+ myDate.Hour); Console.WriteLine("myDate.Minute : "+ myDate.Minute); Console.WriteLine("myDate.Second : "+ myDate.Second); Console.WriteLine("myDate.Millisecond : "+ myDate.Millisecond); Console.WriteLine("myDate.DayOfWeek : "+ myDate.DayOfWeek ); Console.WriteLine("myDate.DayOfYear : "+ myDate.DayOfYear ); Console.WriteLine("myDate.Date : "+ myDate.Date); Console.WriteLine("myDate.Ticks : "+ myDate.Ticks); Console.WriteLine("DateTime.UtcNow : "+ DateTime.UtcNow); //UTC Universal Time Coordinated 협정 세계시(時) //협정 세계시는 국제 사회가 사용하는 과학적 시간의 표준 DateTime dt = DateTime.Today; Console.WriteLine("오늘날짜 : " + dt); //지정한 년도가 윤년인지 아닌지를 체크 Console.WriteLine(DateTime.IsLeapYear(dt.Year)); //결과값 : true or false // TimeSpan duration = new System.TimeSpan(1, 2, 3, 4); // Console.WriteLine(dt.Add(duration)); Console.WriteLine("오늘날짜 + 1일 2시간 3분 4초 : " + dt.Add(new TimeSpan(1,2,3,4))); //new TimeSpan(day,hour,minute,second) Console.WriteLine(dt.AddDays(36)); //지정된 일수를 더한다. Console.WriteLine(dt.AddHours(20)); //지정된 시간값을 더한다. // AddMilliseconds : 지정된 밀리초수를 더한다. // AddMinutes : 지정된 분수를 더한다. // AddMonths : 지정된 월수를 더한다. // AddSeconds : 지정된 초수를 더한다. // AddYears : 지정된 연도수를 더한다. Console.WriteLine("\n\n"); DateTime t1 = new DateTime(2004, 5, 10); DateTime t2 = new DateTime(2002, 10, 5); Console.WriteLine("{0}과 {1}를 비교합니다.: ", t1, t2); Console.WriteLine("Compare를 이용한 결과값 : " + DateTime.Compare(t1, t2)); Console.WriteLine("CompareTo를 이용한 결과값 : " + t1.CompareTo(t2)); // 0보다 작으면 : t1 < t2 // 0과 같으면 : t1 = t2 // 0보다 크면 : t1 > t2 or null Console.WriteLine(DateTime.DaysInMonth(2004, 5)); //지정된 연도, 지정된 월의 일 수 반환 DateTime july28 = new DateTime(1979, 7, 28, 5, 23, 15, 16); string[] july28Formats = july28.GetDateTimeFormats(); //foreach (string format in july28Formats) { // System.Console.WriteLine(format); //} Console.WriteLine(july28.ToString("d")); // 1979-07-28 Console.WriteLine(july28.ToString("D")); // 1979년 7월 28일 토요일 Console.WriteLine(july28.ToString("f")); // 1979년 7월 28일 토요일 오전 5:23 Console.WriteLine(july28.ToString("F")); // 1979년 7월 28일 토요일 오전 5:23:15 Console.WriteLine(july28.ToString("g")); // 1979-07-28 오전 5:23 Console.WriteLine(july28.ToString("G")); // 1979-07-28 오전 5:23:15 Console.WriteLine(july28.ToString("m")); // 7월 28일 Console.WriteLine(july28.ToString("r")); // Sat, 28 Jul 1979 05:23:15 GMT Console.WriteLine(july28.ToString("s")); // 1979-07-28T05:23:15 Console.WriteLine(july28.ToString("t")); // 오전 5:23 Console.WriteLine(july28.ToString("T")); // 오전 5:23:15 Console.WriteLine(july28.ToString("u")); // 1979-07-28 05:23:15Z //세계 표준시 Console.WriteLine(july28.ToString("U")); // 1979년 7월 27일 금요일 오후 8:23:15 Console.WriteLine(july28.ToString("y")); // 1979년 7월 } } } |
출처 : http://blog.daum.net/sadest/15853400