个人 WPF+EF(DBFirst) 简单应用开发习惯及EF学习测试(备忘) -- 2
接上篇:个人 WPF+EF(DBFirst) 简单应用开发习惯及EF学习测试(备忘) -- 1
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="data source=localhost;initial catalog=AdventureWorks2016;persist security info=True;user id=sa;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
注:此前从数据库中建立模型时选择的是:在数据库连接字符串里把密码隐藏,以后在应用中指定密码;所以此字符串中密码是不显示的;
在 主程序 App中设置这个完整的带密码的字符串,作为后续连接时使用:(后面直接用 App.DBConnectionString 这个静态字符串属性即可)
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 测试窗口:
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=""/>
</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="" VerticalAlignment="Top" Width="" 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();
}
}
}
运行结果:
Step3 做一个出现异常的数据读取测试
在主窗口随便加个测试按钮,然后为按钮事件加上以下代码:
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
个人 WPF+EF(DBFirst) 简单应用开发习惯及EF学习测试(备忘) -- 2的更多相关文章
- JavaScript日历控件开发 C# 读取 appconfig文件配置数据库连接字符串,和配置文件 List<T>.ForEach 调用异步方法的意外 ef 增加或者更新的习惯思维 asp.net core导入excel 一个二级联动
JavaScript日历控件开发 概述 在开篇之前,先附上日历的代码地址和演示地址,代码是本文要分析的代码,演示效果是本文要实现的效果代码地址:https://github.com/aspwebc ...
- 8天掌握EF的Code First开发系列之2 简单的CRUD操作
本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 创建控制台项目 根据.Net中的类来创建数据库 简单的CRUD操作 数据库模式更改介绍 本章小结 本人的实验环境 ...
- 8天掌握EF的Code First开发系列之3 管理数据库创建,填充种子数据以及LINQ操作详解
本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LI ...
- 8天掌握EF的Code First开发系列之2 Code First开发系列之领域建模和管理实体关系
本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 理解Code First及其约定和配置 创建数据表结构 管理实体关系 三种继承模式 本章小结 本人的实验环境是V ...
- 8天掌握EF的Code First开发系列之动手写第一个Code First应用
返回<8天掌握EF的Code First开发>总目录 本篇目录 创建控制台项目 根据.Net中的类来创建数据库 简单的CRUD操作 数据库模式更改介绍 本章小结 自我测试 上一篇<8 ...
- 8天掌握EF的Code First开发系列之5 视图、存储过程和异步API
本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 视图View 存储过程 异步API 本章小结 咱们接着上一篇继续深入学习,这一篇说说Entity Framewo ...
- jsp简单标签开发(一)
孤傲苍狼 @Override22 public void doTag() throws JspException, IOException {23 //得到代表jsp标签体的JspFragment24 ...
- javaweb学习总结(二十五)——jsp简单标签开发(一)
一.简单标签(SimpleTag) 由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单.便于编 ...
- WCF/WPF公司内部订餐程序开发
WCF/WPF公司内部订餐程序开发 (服务端篇) 上班的第一天,群里讨论关于订餐的问题,所以想到了要不要自己开发一个公司内部的订餐系统呢?方便公司内部员工的订餐,有了想法就简单的实践了下 . 实现还是 ...
随机推荐
- 重写COMBOXEDIT
一.需求 C#种的下拉框ComboBox不支持下拉复选框列表与下拉树形列表等,系统中需要用到的地方使用了第三方组件,现在需要将第三方组件替换掉. 二.设计 基本思路:重写ComboBox,将原生的下拉 ...
- vue响应式原理
vue的响应式,数据模型仅仅是普通的Javascript对象.当你修改它们时,视图会进行更新 那么如何追踪变化: 当把普通的js对象传给vue实例的data选项,Vue将遍历此对象的所有属性,并使用O ...
- LayUI左侧菜单无法保持选中状态
1.问题描述:一般的左侧菜单都会是动态添加的模块,利用循环把模块名和链接地址逐个显示出来如下图 但是问题来了,只要点任何二级菜单就不会保持左侧菜单当前一级菜单和二级菜单选中状态. 2.分析原因:因为模 ...
- Python 解决命令行删除、退格乱码问题
安装了python 在命令行界面无法进行删除.退格 1 安装readline模块 两种方式:yum install -y readline-devel readline 或者 下载文件https:/ ...
- systemverilog soft constraint
1.class my_item; rand bit constrainted_random; rand bit usually_one; endclass class my_generator; my ...
- oracle 按表数据新增一行
在功能实现时,能尽量用一个sql语句直接实现业务逻辑的话,就不要去写C#代码,便于维护. 以下sql的逻辑是:给明细表新增一条数据,前提是传入的债券代码存在与债券表,否则不新增.此sql返回受影响行数 ...
- go语言环境安装
Go 是一个开源的编程语言,被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言. 1. 准备环境并安装依赖包 创建centos 7.6 64bit的虚拟机. 安装 ...
- ASP.Net的工作线程与请求队列
当 ASP.NET 接收针对页的请求时,它从线程池中提取一个线程并将请求分配给该线程. 一个普通的(或同步的)页在该请求期间保留线程,从而防止该线程用于处理其他请求.如果一个同步请求成为 I/O bo ...
- odoo qweb 记录
默认的打印功能修改,比如在动作中的打印功能: 继承抽象模型 models.AbstractModel 重写 _get_report_values class PayslipDetailsReportI ...
- C++实现词法分析器
#include <iostream> #include <stdlib.h> #include <stdio.h> using namespace std; ]= ...