[WPF 문법] WPF MVVM 패턴 이용하여 오라클 DB 연동하기

소개

  • 안녕하세요. 오늘은 WPF MVVM 패턴을 토대로 오라클 DB 연동하는 방법에 대해서 알려 드리려고 합니다.
  • 크게 어려운 부분은 없기 때문에 각각의 Class들과 소스코드를 올려서 필요하신 부분들은 해당 내용들 참고해서 가져다가 쓰시면 되겠습니다!
  • 그럼 바로 예제 코드를 작성해 보도록 하겠습니다.

예제코드

프로젝트 구성

  • 다음은 WPF MVVM 패턴으로 오라클 DB 연동 프로젝트 구성도 입니다.
  • 크게 Database, Model, ViewModel 폴더가 있습니다.
  • 이제 각각 폴더 안에 있는 클래스들의 내용을 보여 드리겠습니다.

DataBase

OracleDBManager.cs

  • 오라클 연동 관련 소스코드 입니다.
using System;
using System.Data;
using System.Data.OracleClient;

namespace Oracel_Connect_Program.Class
{
    public sealed class OracleDBManager : Singleton<OracleDBManager>
    {
        public event ExceptionEventHandler ExceptionEvent;
        public string LastExceptionString = string.Empty;
        public string ConnectionString = string.Empty;
        public string Address = string.Empty;
        public string Port = string.Empty;

        private OracleCommand LastExecutedCommand = null;
        private int RetryCnt = 0;

        public bool IsRunning
        {
            get
            {
                return CheckDBConnected();
            }
        }

        public OracleConnection Connection { get; private set; }

        public OracleDBManager()
        {

        }

        public static OracleDBManager GetNewInstanceConnection()
        {
            if (Instance == null) return null;

            OracleDBManager dbManager = new OracleDBManager
            {
                ConnectionString = Instance.ConnectionString
            };
            dbManager.GetConnection();
            dbManager.ExceptionEvent = Instance.ExceptionEvent;

            return dbManager;
        }

        public bool GetConnection()
        {
            try
            {
                if (this.Connection != null)
                {
                    this.Connection.Close();
                    this.Connection.Dispose();
                    this.Connection = null;
                }

                if (ConnectionString == string.Empty)
                    SetConnectionString();

                Connection = new OracleConnection(ConnectionString);

                if (this.Address != string.Empty) //주소가 없을 경우 그냥 리턴
                    Connection.Open();
            }
            catch (Exception ex)
            {
                System.Reflection.MemberInfo info = System.Reflection.MethodInfo.GetCurrentMethod();
                string id = string.Format("{0}.{1}", info.ReflectedType.Name, info.Name);

                if (this.ExceptionEvent != null)
                    this.ExceptionEvent(id, ex);

                return false;
            }

            if (Connection.State == ConnectionState.Open)
                return true;
            else
                return false;
        }

        public int ExecuteNonQuery(string query)
        {
            lock (this)
            {
                RetryCnt = 0;

                int result = Execute_NonQuery(query);

                return result;
            }
        }

        public int ExecuteNonQuery(string query, params object[] oParams)
        {
            lock (this)
            {
                RetryCnt = 0;

                int result = Execute_NonQuery(query, oParams);

                return result;
            }
        }

        public bool HasRows(string query)
        {
            lock (this)
            {
                RetryCnt = 0;

                OracleDataReader result = ExecuteReader(query);

                return result.HasRows;
            }
        }

        public OracleDataReader ExecuteReaderQuery(string query)
        {
            lock (this)
            {
                RetryCnt = 0;

                OracleDataReader result = ExecuteReader(query);

                return result;
            }
        }

        public DataSet ExecuteDsQuery(DataSet ds, string query)
        {
            ds.Reset();

            lock (this)
            {
                RetryCnt = 0;

                return ExecuteDataAdt(ds, query);
            }
        }

        public int ExecuteProcedure(string procName, params string[] pValues)
        {
            lock (this)
            {
                RetryCnt = 0;

                return ExecuteProcedureAdt(procName, pValues);
            }
        }

        public void Close()
        {
            Connection.Close();
        }

        public void QueryCancel()
        {
            if (this.LastExecutedCommand != null)
            {
                this.LastExecutedCommand.Cancel();
            }
        }

        #region private..........................................................

        private void SetConnectionString()
        {
            string user = XmlManager.GetValue("DATABASE", "USER");
            string pwd = XmlManager.GetValue("DATABASE", "PWD");
            string port = XmlManager.GetValue("DATABASE", "PORT");
            string svr = XmlManager.GetValue("DATABASE", "SERVICE_NAME");
            string addr01 = XmlManager.GetValue("DATABASE", "D_ADDR01");
            string addr02 = XmlManager.GetValue("DATABASE", "D_ADDR02");

            string address01 = string.Format("(ADDRESS = (PROTOCOL = TCP)(HOST = {0})(PORT = {1}))", addr01, port);
            string address02 = string.Format("(ADDRESS = (PROTOCOL = TCP)(HOST = {0})(PORT = {1}))", addr02, port);

            string dataSource = string.Format(@"(DESCRIPTION =(ADDRESS_LIST ={0}{1})(CONNECT_DATA =(", address01, address02);

            dataSource += svr == string.Empty ? string.Format("SID = {0})))", svr) : string.Format("SERVICE_NAME = {0})))", svr);

            this.Address = addr01;
            this.Port = port;
            this.ConnectionString = "User Id=" + user + ";Password=" + pwd + ";Data Source=" + dataSource;
        }

        private int Execute_NonQuery(string query)
        {
            int result = 0;

            try
            {
                OracleCommand cmd = new OracleCommand
                {
                    Connection = this.Connection,
                    CommandText = query
                };

                LastExecutedCommand = cmd;
                result = cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                //연결 해제 여부 확인 후 해제 시 재연결 후 다시 시도...
                if (RetryCnt < 1 && CheckDBConnected() == false)
                {
                    RetryCnt++;

                    GetConnection();

                    Exception ex02 = new Exception("Reconnect to database");

                    if (this.ExceptionEvent != null)
                        this.ExceptionEvent(string.Empty, ex02);

                    result = Execute_NonQuery(query);
                    return result;
                }

                //사용자 Cancel
                if (ex.Message.Contains("ORA-01013"))
                {
                    return -1;
                }

                System.Reflection.MemberInfo info = System.Reflection.MethodInfo.GetCurrentMethod();
                string id = string.Format("{0}.{1}\n[{2}]", info.ReflectedType.Name, info.Name, query);

                if (this.ExceptionEvent != null)
                    this.ExceptionEvent(id, ex);

                this.LastExceptionString = ex.Message;

                result = -1;
            }

            return result;
        }
        private int Execute_NonQuery(string query, params object[] oParams)
        {
            int result = 0;

            try
            {
                OracleCommand cmd = new OracleCommand
                {
                    Connection = this.Connection,
                    CommandText = query
                };

                for (int i = 0; i < oParams.Length; i += 2)
                {
                    cmd.Parameters.Add(oParams[i].ToString(), oParams[i + 1]);
                }

                LastExecutedCommand = cmd;
                result = cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                //연결 해제 여부 확인 후 해제 시 재연결 후 다시 시도...
                if (RetryCnt < 1 && CheckDBConnected() == false)
                {
                    RetryCnt++;

                    GetConnection();

                    Exception ex02 = new Exception("Reconnect to database");

                    if (this.ExceptionEvent != null)
                        this.ExceptionEvent(string.Empty, ex02);

                    result = Execute_NonQuery(query, oParams);
                    return result;
                }

                //사용자 Cancel
                if (ex.Message.Contains("ORA-01013"))
                {
                    return -1;
                }

                System.Reflection.MemberInfo info = System.Reflection.MethodInfo.GetCurrentMethod();
                string id = string.Format("{0}.{1}\n[{2}]", info.ReflectedType.Name, info.Name, query);

                if (this.ExceptionEvent != null)
                    this.ExceptionEvent(id, ex);

                this.LastExceptionString = ex.Message;

                result = -1;
            }

            return result;
        }

        private OracleDataReader ExecuteReader(string query)
        {
            OracleDataReader result = null;

            try
            {
                OracleCommand cmd = new OracleCommand
                {
                    Connection = this.Connection,
                    CommandText = query
                };

                LastExecutedCommand = cmd;
                result = cmd.ExecuteReader();
            }
            catch (Exception ex)
            {
                //연결 해제 여부 확인 후 해제 시 재연결 후 다시 시도...
                if (RetryCnt < 1 && CheckDBConnected() == false)
                {
                    RetryCnt++;

                    GetConnection();

                    Exception ex02 = new Exception("Reconnect to database");

                    if (this.ExceptionEvent != null)
                        this.ExceptionEvent(string.Empty, ex02);

                    result = ExecuteReader(query);
                    return result;
                }

                //사용자 Cancel
                if (ex.Message.Contains("ORA-01013"))
                {
                    return null;
                }

                System.Reflection.MemberInfo info = System.Reflection.MethodInfo.GetCurrentMethod();
                string id = string.Format("{0}.{1}\n[{2}]", info.ReflectedType.Name, info.Name, query);

                if (this.ExceptionEvent != null)
                    this.ExceptionEvent(id, ex);

                this.LastExceptionString = ex.Message;

                return null;
            }

            return result;
        }

        private DataSet ExecuteDataAdt(DataSet ds, string query)
        {
            try
            {
                OracleDataAdapter cmd = new OracleDataAdapter
                {
                    SelectCommand = new OracleCommand()
                };
                cmd.SelectCommand.Connection = this.Connection;
                cmd.SelectCommand.CommandText = query;

                LastExecutedCommand = cmd.SelectCommand;
                cmd.Fill(ds);
            }
            catch (Exception ex)
            {
                //연결 해제 여부 확인 후 해제 시 재연결 후 다시 시도...
                if (RetryCnt < 1 && CheckDBConnected() == false)
                {
                    RetryCnt++;

                    GetConnection();

                    Exception ex02 = new Exception("Reconnect to database");

                    if (this.ExceptionEvent != null)
                        this.ExceptionEvent(string.Empty, ex02);

                    ds = ExecuteDataAdt(ds, query);
                    return ds;
                }

                //사용자 Cancel
                if (ex.Message.Contains("ORA-01013"))
                {
                    return null;
                }

                System.Reflection.MemberInfo info = System.Reflection.MethodInfo.GetCurrentMethod();
                string id = string.Format("{0}.{1}\n[{2}]", info.ReflectedType.Name, info.Name, query);

                if (this.ExceptionEvent != null)
                    this.ExceptionEvent(id, ex);

                this.LastExceptionString = ex.Message;

                return null;
            }

            return ds;
        }

        private int ExecuteProcedureAdt(string procName, params string[] pValues)
        {
            int result = -1;

            try
            {
                OracleCommand cmd = new OracleCommand(procName, this.Connection)
                {
                    CommandType = CommandType.StoredProcedure
                };

                for (int i = 0; i < pValues.Length; ++i)
                {
                    string par = string.Format("PARAM{0}", i + 1);

                    cmd.Parameters.Add(par, OracleType.VarChar).Value = pValues[i];
                }

                cmd.Parameters.Add("execResult", OracleType.Int32);
                cmd.Parameters["execResult"].Direction = ParameterDirection.Output;

                LastExecutedCommand = cmd;
                cmd.ExecuteNonQuery();

                result = int.Parse(cmd.Parameters["execResult"].Value.ToString());
            }
            catch (Exception ex)
            {
                //연결 해제 여부 확인 후 해제 시 재연결 후 다시 시도...
                if (RetryCnt < 1 && CheckDBConnected() == false)
                {
                    RetryCnt++;

                    GetConnection();

                    Exception ex02 = new Exception("Reconnect to database");

                    if (this.ExceptionEvent != null)
                        this.ExceptionEvent(string.Empty, ex02);

                    result = ExecuteProcedureAdt(procName, pValues);
                    return result;
                }

                //사용자 Cancel
                if (ex.Message.Contains("ORA-01013"))
                {
                    return result;
                }

                System.Reflection.MemberInfo info = System.Reflection.MethodInfo.GetCurrentMethod();
                string id = string.Format("{0}.{1}\n[{2}]", info.ReflectedType.Name, info.Name, procName);

                if (this.ExceptionEvent != null)
                    this.ExceptionEvent(id, ex);

                this.LastExceptionString = ex.Message;
            }

            return result;
        }

        private bool CheckDBConnected()
        {
            string query = "SELECT 1 FROM DUAL";
            OracleDataReader result = null;

            try
            {
                OracleCommand cmd = new OracleCommand
                {
                    Connection = this.Connection,
                    CommandText = query
                };
                result = cmd.ExecuteReader();
            }
            catch { }

            if (result != null && result.HasRows)
                return true;

            return false;
        }

        #endregion private..................................................................
    }
}

Singleton.cs

  • 싱글톤 클래스 입니다.
using System;

namespace Oracel_Connect_Program.Class
{
    public class Singleton<T> where T : class, new()
    {
        private static object _syncobj = new object();
        private static volatile T _instance = null;
        public static T Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_syncobj)
                    {
                        if (_instance == null)
                        {
                            _instance = new T();
                        }
                    }
                }
                return _instance;
            }
        }

        public delegate void ExceptionEventHandler(string LocationID, Exception ex);
    }
}

XmlManager.cs

  • Config.xml 파일을 읽기 위한 XmlManager.cs 입니다.
  • 오라클 DB 정보를 Config.xml에 입력하여 해당 내용을 읽어서 파싱후, 가져다 쓰도록 하였습니다.
using System;
using System.Xml.Linq;

namespace Oracel_Connect_Program.Class
{
    public class XmlManager : Singleton<XmlManager>
    {
        #region " Properties & Variables "

        private static string configFile = @"Config.xml";
        public static string ConfigFile { get { return configFile; } set { configFile = value; } }

        #endregion " Properties & Variables End"

        #region "  Public methode "

        public static string GetValue(params string[] args)
        {
            string result = string.Empty;

            try
            {
                XDocument xDoc = XDocument.Load(configFile);
                result = GetNodeValue(xDoc.FirstNode as XElement, 0, args);
            }
            catch (Exception ex)
            {
                result = ex.Message;
                result = string.Empty;
            }

            return result;
        }

        public static bool SetValue(params string[] args)
        {
            bool result = false;

            try
            {
                XDocument xDoc = XDocument.Load(configFile);

                result = SetNodeValue(xDoc.FirstNode as XElement, 0, args);

                xDoc.Save(configFile);
            }
            catch
            {
                result = false;
            }

            return result;
        }

        #endregion "  Public methode End"

        #region "  Private methode "

        private static string GetNodeValue(XElement node, int idx, params string[] args)
        {
            string result = string.Empty;

            if (args.Length > idx + 1)
                result = GetNodeValue(node.Element(args[idx]), ++idx, args);
            else
                result = node.Element(args[idx]).Value.ToString();

            return result;
        }

        private static bool SetNodeValue(XElement node, int idx, params string[] args)
        {
            if (args.Length > idx + 1)
            {
                SetNodeValue(node.Element(args[idx]), ++idx, args);
            }
            else
            {
                node.SetValue(args[idx]);
            }

            return true;
        }

        #endregion "  Private methode End"
    }
}

Config.xml

  • 오라클 접속 정보 내용입니다.
<Configuration>

  <DATABASE>
    <D_ADDR01>127.0.0.1</D_ADDR01>
    <D_ADDR02>127.0.0.1</D_ADDR02>
    <PORT>1525</PORT>
    <USER>system</USER>
    <PWD>oracle</PWD>
    <SERVICE_NAME>xe</SERVICE_NAME>
  </DATABASE>

</Configuration>

Model

Sutdent.cs

  • Model 클래스 입니다.
  • 오라클 DB에 테스트로 Student 테이블을 하나 만들었고, 해당 내용을 WPF 바인딩 하기 위한 모델 클래스 입니다.
namespace WPFDBTest.Model
{
    public class Student
    {
        public string NAME
        {
            get;
            set;
        }

        public string AGE
        {
            get;
            set;
        }

        public string Class
        {
            get;
            set;
        }
    }
}

ViewModel

DelegateCommand.cs

  • WPF Command 바인딩을 하기 위한 Command 클래스입니다.
using System;
using System.Windows.Input;

namespace WPFDBTest.ViewModel
{
    public class DelegateCommand : ICommand
    {
        private readonly Func<bool> canExecute;
        private readonly Action execute;

        public DelegateCommand(Action exectue) : this(exectue, null)
        {

        }

        public DelegateCommand(Action execute, Func<bool> canExecute)
        {
            this.execute = execute;
            this.canExecute = canExecute;
        }

        /// <summary>
        /// can executes event handler
        /// </summary>
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// implement of icommand can execute method
        /// </summary>
        /// <param name="o">parameter by default of icomand interface</param>
        /// <returns>can execute or not</returns>
        public bool CanExecute(object o)
        {
            if (this.canExecute == null)
            {
                return true;
            }
            return this.canExecute();
        }

        /// <summary>
        /// implement of icommand interface execute method
        /// </summary>
        /// <param name="o">parameter by default of icomand interface</param>
        public void Execute(object o)
        {
            this.execute();
        }

        /// <summary>
        /// raise ca excute changed when property changed
        /// </summary>
        public void RaiseCanExecuteChanged()
        {
            if (this.CanExecuteChanged != null)
            {
                this.CanExecuteChanged(this, EventArgs.Empty);
            }
        }
    }
}

MainViewModel.cs

  • 실제 DB연동 관련 비지니스 로직을 수행하는 ViewModel 클래스입니다.
using Oracel_Connect_Program.Class;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Windows;
using System.Windows.Input;
using WPFDBTest.Model;

namespace WPFDBTest.ViewModel
{
    public class MainViewModel : INotifyPropertyChanged
    {
        readonly MainWindow ownerWindow = null; // MainWindow 객체 선언
        Student _stu = new Student();

        public MainViewModel(MainWindow win)
        {
            ownerWindow = win;
        }

        public string NAME
        {
            get
            {
                return _stu.NAME;
            }
            set
            {
                _stu.NAME = value;
                OnPropertyChanged("NAME");
            }
        }

        public string AGE
        {
            get
            {
                return _stu.AGE;
            }
            set
            {
                _stu.AGE = value;
                OnPropertyChanged("AGE");
            }
        }

        ObservableCollection<Student> _sampleDatas = null;
        public ObservableCollection<Student> SampleDatas
        {
            get
            {
                if (_sampleDatas == null)
                {
                    _sampleDatas = new ObservableCollection<Student>();
                }
                return _sampleDatas;
            }
            set
            {
                _sampleDatas = value;
            }
        }

        //PropertyChaneged 이벤트 선언 및 이벤트 핸들러
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// Connect Command 선언
        /// </summary>
        private ICommand connectCommand;
        public ICommand ConnectCommand
        {
            get
            {
                return (this.connectCommand) ?? (this.connectCommand = new DelegateCommand(Connect));
            }
        }

        private ICommand selectCommand;
        public ICommand SelectCommand
        {
            get
            {
                return (this.selectCommand) ?? (this.selectCommand = new DelegateCommand(DataSearch));
            }
        }

        private ICommand _insertCommand;
        public ICommand InsertCommand
        {
            get
            {
                return (this._insertCommand) ?? (this._insertCommand = new DelegateCommand(DataInsert));
            }
        }

        private ICommand loadedCommand;
        public ICommand LoadedCommand
        {
            get
            {
                return (this.loadedCommand) ?? (this.loadedCommand = new DelegateCommand(LoadEvent));
            }
        }

        private void LoadEvent()
        {
            //Connect to DB
            if (OracleDBManager.Instance.GetConnection() == false)
            {
                string msg = $"Failed to Connect to Database";
                MessageBox.Show(msg, "Error");
                return;
            }
            else
            {
                string msg = $"Success to Connect to Database";
                MessageBox.Show(msg, "Inform");
            }
        }

        private void DataSearch()
        {  
            DataSet ds = new DataSet();

            string query = @"
SELECT NAME, AGE
FROM STUDENT
";

            OracleDBManager.Instance.ExecuteDsQuery(ds, query);

            for(int idx = 0; idx < ds.Tables[0].Rows.Count; idx++)
            {
                Student obj = new Student
                {
                    NAME = ds.Tables[0].Rows[idx]["NAME"].ToString(),
                    AGE = ds.Tables[0].Rows[idx]["AGE"].ToString()
                };

                SampleDatas.Add(obj);
            }
        }

        private void DataInsert()
        {
            var studentList = SampleDatas;

            foreach (var stu in studentList)
            {
                string query = @"
MERGE 
 INTO STUDENT
USING dual
   ON (NAME = '#NAME' AND AGE = '#AGE')
 WHEN MATCHED THEN
      UPDATE
         SET NAME = '#NAME',
             AGE  = '#AGE'
 WHEN NOT MATCHED THEN
      INSERT (NAME, AGE)
      VALUES ('#NAME', '#AGE');
";

                query = query.Replace("#NAME", stu.NAME);
                query = query.Replace("#AGE", stu.AGE);

                OracleDBManager.Instance.ExecuteNonQuery(query);
            }
        }

        /// <summary>
        /// DB Connect
        /// </summary>
        private void Connect()
        {
            //Connect to DB
            if (OracleDBManager.Instance.GetConnection() == false)
            {
                string msg = $"Failed to Connect to Database";
                MessageBox.Show(msg, "Error");
                return;
            }
            else
            {
                string msg = $"Success to Connect to Database";
                MessageBox.Show(msg, "Inform");
            }
        }
    }
}

UI

MainWindow.xaml

<Window x:Class="WPFDBTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFDBTest"
        xmlns:ViewModel="clr-namespace:WPFDBTest.ViewModel"
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding LoadedCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="150"/>
            <ColumnDefinition Width="200"/>
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="70"/>
        </Grid.RowDefinitions>

        <DataGrid x:Name="uiGrid_Main" Grid.ColumnSpan="3" Margin="5"
                  AutoGenerateColumns="False"
                  ItemsSource="{Binding Path= SampleDatas, Mode=TwoWay, 
            NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True}">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="grid_Name" MinWidth="10" Width="Auto" Header="NAME" Binding="{Binding NAME}"/>
                <DataGridTextColumn x:Name="grid_AGE" MinWidth ="100" Width="Auto" Header="AGE" Binding="{Binding AGE}"/>
                <!--<DataGridTextColumn MinWidth="100" Width="Auto" Header="GRADE" Binding="{Binding GRADE}"/>
                <DataGridTextColumn MinWidth="200" Width="*" Header="SCORE" Binding="{Binding SCORE}"/>-->
            </DataGrid.Columns>
        </DataGrid>

        <Button Grid.Row="1" Grid.Column="0" Margin="5"
                Content="Connect"
                Command="{Binding ConnectCommand}"/>
        <Button Grid.Row="1" Grid.Column="1" Margin="5"
                Content="조회"
                Command="{Binding SelectCommand}"/>
        <Button Grid.Row="1" Grid.Column="2" Margin="5"
                Content="Insert"
                Command="{Binding InsertCommand}"/>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Windows;
using WPFDBTest.ViewModel;

namespace WPFDBTest
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = new MainViewModel(this);
        }
    }
}

실행 결과

  • 위의 내용을 실제로 실행 시키면 아래와 같이 WPF 실행이 되면서, Oracle 에 Student 테이블에 저장된 내용을 제대로 가져와 사용자에게 보여지는 것을 확인할 수 있습니다.

WPF 화면

실제 Oracle Student 테이블

728x90

이 글을 공유하기

댓글

Designed by JB FACTORY