我的 WPF+EF(DBFirst) 簡單應用開發習慣及EF學習測試(備忘) -- 2

接上篇:我的 WPF+EF(DBFirst) 簡單應用開發習慣及EF學習測試(備忘) -- 1html

 

Step1 在主程序中設置鏈接數據庫

從Model類庫的 App.Config 把數據庫字符串拷貝出來,放到主程序 App.Config 中:數據庫

<connectionStrings>
  <add name="DBEntities" connectionString="metadata=res://*/EFDBFirstModel.csdl|res://*/EFDBFirstModel.ssdl|res://*/EFDBFirstModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=localhost;initial catalog=AdventureWorks2016;persist security info=True;user id=sa;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>

注:此前從數據庫中創建模型時選擇的是:在數據庫鏈接字符串裏把密碼隱藏,之後在應用中指定密碼;因此此字符串中密碼是不顯示的;express

在 主程序 App中設置這個完整的帶密碼的字符串,做爲後續鏈接時使用:(後面直接用 App.DBConnectionString 這個靜態字符串屬性便可)ide

using System;
using System.Configuration;
using System.Data.Common;
using System.Data.Entity.Core.EntityClient;
using System.Windows;

namespace WPF_EF_DBFirst
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private static string _db_ConnectionString;

        /// <summary>
        /// DB Connection String With Password
        /// </summary>
        public static string DBConnectionString
        {
            get
            {
                if (String.IsNullOrEmpty(_db_ConnectionString))
                {
                    var originalConnectionString = ConfigurationManager.ConnectionStrings["DBEntities"].ConnectionString;
                    var entityBuilder = new EntityConnectionStringBuilder(originalConnectionString);
                    var factory = DbProviderFactories.GetFactory(entityBuilder.Provider);
                    var providerBuilder = factory.CreateConnectionStringBuilder();
                    providerBuilder.ConnectionString = entityBuilder.ProviderConnectionString;
                    providerBuilder.Add("Password", "Your Password");
                    _db_ConnectionString = providerBuilder.ToString();
                }
                return _db_ConnectionString;
            }
        }
    }
}

 

Step2 作第一個Datagrid 顯示數據的測試

在 MainWindow 窗口上放第一個測試按鈕:函數

<Button x:Name="ListView" Content="列表顯示" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Click="ListView_Click"/>

在 ListView_Click 事件中,打開準備要新建的 Win_ListView 測試窗口:post

        private void ListView_Click(object sender, RoutedEventArgs e)
        {
            Win_ListView win_ListView = new Win_ListView();
            win_ListView.Owner = this;
            win_ListView.ShowDialog();
        }

新建一個 Win_ListView 測試顯示窗口: (就放一個 TabControl 、一個DataGrid 和一個退回 按鈕) (先準備測試顯示 Person表裏的人名數據)學習

<Window x:Class="WPF_EF_DBFirst.Win_ListView"
        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:WPF_EF_DBFirst"
        mc:Ignorable="d"
        Title="Win_ListView" Height="326.341" Width="455.122" Loaded="Window_Loaded" WindowState="Maximized">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="257*"/>
            <RowDefinition Height="38"/>
        </Grid.RowDefinitions>
        <TabControl Margin="6,3,3,3">
            <TabItem Header="Person">
                <Grid Background="#FFE5E5E5">
                    <DataGrid Margin="3,3,3,3" x:Name="dg_Person" AutoGenerateColumns="False" IsReadOnly="True">
                        <DataGrid.Columns>
                            <DataGridTextColumn Binding="{Binding FirstName}" Header="FirstName" ElementStyle="{StaticResource DataGridTextCenter}"/>
                            <DataGridTextColumn Binding="{Binding MiddleName}" Header="MiddleName" ElementStyle="{StaticResource DataGridTextCenter}"/>
                            <DataGridTextColumn Binding="{Binding LastName}" Header="LastName" ElementStyle="{StaticResource DataGridTextCenter}"/>
                        </DataGrid.Columns>
                    </DataGrid>
                </Grid>
            </TabItem>
            <TabItem Header="TabItem">
                <Grid Background="#FFE5E5E5"/>
            </TabItem>
        </TabControl>
        <Button x:Name="btBack" Content="Back" HorizontalAlignment="Right" Margin="0,3,3,0" Grid.Row="1" VerticalAlignment="Top" Width="75" Click="btBack_Click"/>
    </Grid>
</Window>

Win_ListView中增長實體定義(簡單測試就直接在本窗口內進行數據鏈接了)以及增長 2個事件處理:(一個是Windows Load 一個是 退出按鈕);測試

using System.Linq;
using System.Windows;
using WPF_EF_DBFirst.Model;

namespace WPF_EF_DBFirst
{
    /// <summary>
    /// Interaction logic for Win_ListView.xaml
    /// </summary>
    public partial class Win_ListView : Window
    {
        private DBEntities DB;
        public Win_ListView()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            DB = new DBEntities();
            DB.Database.Connection.ConnectionString = App.DBConnectionString;                
            dg_Person.ItemsSource = DB.Person.ToList();
        }

        private void btBack_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }
    }
}

運行結果:
ui

Step3 作一個出現異常的數據讀取測試 

 在主窗口隨便加個測試按鈕,而後爲按鈕事件加上如下代碼:this

        private void ListReadTest_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                DBEntities DB = new DBEntities();
                DB.Database.Connection.ConnectionString = App.DBConnectionString;
                MessageBox.Show(DB.Address.First().AddressLine1);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

很是簡單的代碼,就是直接讀取 Address 表的第一條記錄的 AddressLine1 列的數據;
直接運行,點擊這個按鈕後會彈出如下錯誤:

(Spatial types and functions are not available for this provider because the assmbly 'Microsoft.SqlServer.Types' version 10 or higher could not be found.)

以爲挺奇怪的,本機 是安裝了 VS2017 + SQL Server 2016 的,爲何會出現這個錯誤;

一樣,若是這個時候把 Bin目錄 拷貝到其餘PC運行,一樣也會出現這個錯誤;(若是是SQL Server 2012 就不會有這個錯誤。)

具體原理確實不是很清楚。。。

我的經過查詢參考相關帖子,而後用瞭如下解決方法:

 在Model類庫中對 數據庫上下文類的構造函數中加入強制定義:(在本機上就能夠直接執行,若是要發佈到其餘PC運行,則須要拷貝SQL Server 2016 對應的Microsoft.SqlServer.Types.dll 到應用程序根目錄)

 

      public DBEntities() : base("name=DBEntities")
        {
            SqlProviderServices.SqlServerTypesAssemblyName = "Microsoft.SqlServer.Types, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91";         }

注:這樣作也有個小問題,好像每次若是數據庫更新要刷新這個Model的時候,這行代碼可能會自動消失,還要手動再拷貝進來;

這樣就能夠正確取出數據:

 

 

 

 

 

 

 

 

 

 

Step3

相關文章
相關標籤/搜索