心雨纷扬的博客

一个简单的博客


  • Home

  • Archives

(787) 735-2700

Posted on 2018-11-05

(602) 275-4142hexo搭建

  • hexo搭建

    • 安装环境
    • 特定文件夹初始化hexo
    • 6264268523
    • (705) 498-1341
    • 修改配置文件
    • 发布部署
    • (650) 594-4385
    • 参考文档

      安装环境

  • nodejs,git安装
    此处不举例,自行百度

  • hexo-cli安装

npm install -g hexo-cli

特定文件夹初始化hexo

$ hexo init 或者npm install hexo --save

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 安装插件
npm install hexo-generator-index --save
npm install hexo-generator-archive --save
npm install hexo-generator-category --save
npm install hexo-generator-tag --save
npm install hexo-server --save
npm install hexo-deployer-git --save
npm install hexo-deployer-heroku --save
npm install hexo-deployer-rsync --save
npm install hexo-deployer-openshift --save
npm install hexo-renderer-marked --save
npm install hexo-renderer-stylus --save
npm install hexo-generator-feed --save
npm install hexo-generator-sitemap --save

301-567-2373Git配置多个SSH-Key

  • 当有多个git账号时,比如:

    a. 一个gitee,用于公司内部的工作开发;

    b. 一个github,用于自己进行一些开发活动;

  • 解决方法

    1. 生成一个公司用的SSH-Key

      $ ssh-keygen -t rsa -C '174499700@qq.com' -f ~/.ssh/gitee_id_rsa

    2. 生成一个github用的SSH-Key

      ssh-keygen -t rsa -C 'benguahao@foxmail.com' -f ~/.ssh/github_id_rsa

    3. 在 ~/.ssh 目录下新建一个config文件,添加如下内容(其中Host和HostName填写git服务器的域名,IdentityFile指定私钥的路径)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      # gitee
      Host gitee.com
      HostName gitee.com
      PreferredAuthentications publickey
      IdentityFile ~/.ssh/gitee_id_rsa
      # github
      Host github.com
      HostName github.com
      PreferredAuthentications publickey
      IdentityFile ~/.ssh/github_id_rsa

sterculiaceous如果源的网速不好,

可以更换淘宝源:npm install -g cnpm --registry=/registry.npm.taobao.org

把npm命令替换使用cnpm命令

修改配置文件

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
# Hexo Configuration  
## Docs: /hexo.io/docs/configuration.html
## Source: /github.com/xyfy/xyfy.github.io

# Site 站点信息设置
title: 心雨纷扬的博客 #站名
subtitle: 一个简单的博客 #副标题
description: #站描述
author: Xyfy #作者
language: zh-CN #语言
timezone:

# URL 链接设置
## If your site is put in a subdirectory, set url as '/yoursite.com/child' and root as '/child/'
url: /www.52dzd.com
root: /
permalink: :year/:month/:day/:title/
permalink_defaults:

# Directory 文件目录
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: :lang
skip_render:

# Writing 文章
new_post_name: :title.md # File name of new posts
default_layout: post
titlecase: false # Transform title into titlecase
external_link: true # Open external links in new tab
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
future: true
highlight:
enable: true
line_number: true
auto_detect: true
tab_replace:

# Category & Tag
default_category: uncategorized
category_map:
tag_map:

# Date / Time format 日期
## Hexo uses Moment.js to parse and display date
## You can customize the date format as defined in
## /momentjs.com/docs/#/displaying/format/
date_format: YYYY-MM-DD
time_format: HH:mm:ss

# Pagination 分页
## Set per_page to 0 to disable pagination
per_page: 20
pagination_dir: page

# Extensions 扩展
## Plugins: /hexo.io/plugins/
## Themes: /hexo.io/themes/
theme: landscape

# Deployment 这里设置了Git获
#这里一定要注意不要写错了,否则部署到Github上会出问题
## Docs: /hexo.io/docs/deployment.html
deploy:
type: git
repo: git@github.com:xyfy/xyfy.github.io.git
branch: master
message: '站点更新:{{now("YYYY-MM-DD HH/mm/ss")}}'

发布部署

1
2
3
4
# 编译
hexo generate
# 在主机的hexo目录下 执行以下命令将自动更新到Github
hexo d

修改主题和配置配置文件

  • 安装主题NexT

    ps: 我们现在在目录hexo下

    git clone /github.com/iissnan/hexo-theme-next themes/next

    并在目录hexo下的_config.yml中找到 theme: 修改后面的参数,默认是 landscape

    theme: next

  • 克隆慢问题解决

    修改/etc/hosts文件 ,加入两行

    1
    2
    151.101.72.249 /global-ssl.fastly.Net
    192.30.253.112 /github.com

参考文档

  • (916) 785-7335
  • /gitee.com/help/articles/4229

334-782-0185

Posted on 2018-10-05

518-664-8280elastic安装过程-Win7

  • elastic安装过程-Win7
    • 8602564696
    • pachycephal
      • 844-338-4250
      • (404) 550-3152
    • 启动elasticsearch
    • 安装错误
    • (810) 760-7344
    • 608-885-9551
    • 参考文档

941-248-5074下载最新版openjdk安装

  • 由于oracle对jdk进行了收费,不能用于相关的商业用途,可以下载基于GPL的(505) 793-5813代替

    下载windows的压缩包后,进行解压到指定目录,例如D:\java\jdk-11.0.1

  • 打开系统设置,设置环境变量

    1. 第一步:右键“我的电脑”,选择“属性”,弹出的对话框中选择“高级系统设置”
    2. 选择“高级”,点击“环境变量”按钮,进入环境变量配置界面
    3. 添加JAVA_HOME变量,点击新建按钮,输入相应数据

      变量名:JAVA_HOME,变量值:D:\java\jdk-11.0.1(jdk安装的路径)

    4. 添加CLASSPATH变量,点击新建按钮,输入相应数据

      变量名:CLASSPATH,变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;

      切记:最前面.;必须要有,不能删除

    5. 设置path属性,找到变量path,点击编辑在其变量值后面加上:

      %java_home%\bin;%java_home%\jre\bin;

      新添加变量值与已有变量值必须分好;隔开

    6. 测试是否成功,在powershell中执行:java –version

      1
      2
      3
      openjdk 11.0.1 2018-10-16
      OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
      OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)

下载elasticsearch

4076921915zip压缩包安装

  • 下载最新版本的elasticsearch

    • [官方下载页面]

    • [844-348-3109]

  • 下载完成后进行解压到指定目录,例如D:\elasticsearch-6.2.2

  • 打开powershell 进入到目录,

    d:

    cd elasticsearch-6.2.2

2504961914msi安装

  • 下载地址

    716-245-3360


启动elasticsearch

1
2
# - 打开powershell 进入到目录后运行bat文件
.\bin\elasticsearch

安装错误

  • 默认情况下,Elastic 只允许本机访问,如果需要远程访问,可以修改 Elastic 安装目录的config/elasticsearch.yml文件,去掉network.host的注释,将它的值改成0.0.0.0,然后重新启动 Elastic。

下载安装kibana

  • 下载
    • (575) 267-2742
    • 3142507290

安装中文分词器

  1. 执行命令

    ./bin/elasticsearch-plugin install /github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.2.2/elasticsearch-analysis-ik-6.2.2.zip

  2. 测试IK

    1. 创建Index

      curl -XPUT /localhost:9200/index

    2. 创建 mapping

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      curl -XPOST /localhost:9200/index/fulltext/_mapping -H 'Content-Type:application/json' -d'
      {
      "properties": {
      "content": {
      "type": "text",
      "analyzer": "ik_max_word",
      "search_analyzer": "ik_max_word"
      }
      }

      }'
    3. 生成若干索引文档

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      curl -XPOST /localhost:9200/index/fulltext/1 -H 'Content-Type:application/json' -d'
      {"content":"美国留给伊拉克的是个烂摊子吗"}
      '
      curl -XPOST /localhost:9200/index/fulltext/2 -H 'Content-Type:application/json' -d'
      {"content":"公安部:各地校车将享最高路权"}
      '
      curl -XPOST /localhost:9200/index/fulltext/3 -H 'Content-Type:application/json' -d'
      {"content":"中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"}
      '
      curl -XPOST /localhost:9200/index/fulltext/4 -H 'Content-Type:application/json' -d'
      {"content":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"}
      '
    4. 高亮查询

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      curl -XPOST /localhost:9200/index/fulltext/_search  -H 'Content-Type:application/json' -d'
      {
      "query" : { "match" : { "content" : "中国" }},
      "highlight" : {
      "pre_tags" : ["<tag1>", "<tag2>"],
      "post_tags" : ["</tag1>", "</tag2>"],
      "fields" : {
      "content" : {}
      }
      }
      }
      '
  3. 字典配置

    IKAnalyzer.cfg.xml 文件一般位于 {conf}/analysis-ik/config/IKAnalyzer.cfg.xml 或者 {plugins}/elasticsearch-analysis-ik-*/config/IKAnalyzer.cfg.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE properties SYSTEM "/java.sun.com/dtd/properties.dtd">
    <properties>
    <comment>IK Analyzer 扩展配置</comment>
    <!--用户可以在这里配置自己的扩展字典 -->
    <entry key="ext_dict">custom/mydict.dic;custom/single_word_low_freq.dic</entry>
    <!--用户可以在这里配置自己的扩展停止词字典-->
    <entry key="ext_stopwords">custom/ext_stopword.dic</entry>
    <!--用户可以在这里配置远程扩展字典 -->
    <entry key="remote_ext_dict">location</entry>
    <!--用户可以在这里配置远程扩展停止词字典-->
    <entry key="remote_ext_stopwords">/xxx.com/xxx.dic</entry>
    </properties>
  4. 热更新 IK 分词使用方法

    目前该插件支持热更新 IK 分词,通过上文在 IK 配置文件中提到的如下配置

    1
    2
    3
    4
    <!--用户可以在这里配置远程扩展字典 -->
    <entry key="remote_ext_dict">location</entry>
    <!--用户可以在这里配置远程扩展停止词字典-->
    <entry key="remote_ext_stopwords">location</entry>

    其中 location 是指一个 url,比如 /yoursite.com/getCustomDict,该请求只需满足以下两点即可完成分词热更新。

    该 http 请求需要返回两个头部(header),一个是 Last-Modified,一个是 ETag,这两者都是字符串类型,只要有一个发生变化,该插件就会去抓取新的分词进而更新词库。

    该 http 请求返回的内容格式是一行一个分词,换行符用 \n 即可。

    满足上面两点要求就可以实现热更新分词了,不需要重启 ES 实例。

    可以将需自动更新的热词放在一个 UTF-8 编码的 .txt 文件里,放在 nginx 或其他简易 http server 下,当 .txt 文件修改时,http server 会在客户端请求该文件时自动返回相应的 Last-Modified 和 ETag。可以另外做一个工具来从业务系统提取相关词汇,并更新这个 .txt 文件。

(843) 400-5721参考文档

  • elastican安装手册
  • 909-342-8954

elastic安装过程-Ubuntu

Posted on 2018-10-05

elastic安装过程-Ubuntu

  • elastic安装过程-Ubuntu
    • 2568826763
      • 官网下载JDK
      • 解压缩,放到指定目录(以jdk-7u60-linux-x64.gz为例)
      • 248-712-6994
      • 设置系统默认jdk 版本
    • 测试jdk
    • 5627569367
    • 启动elasticsearch
    • 安装错误
    • 510-861-4040

直接下载jdk压缩包方式安装(这里只介绍jdk7的,jdk8 的原理完全一致)

分为下面5个步骤

官网下载JDK

地址: 5143560346 , 选择相应的 .gz包下载

abstinence theory解压缩,放到指定目录(以jdk-7u60-linux-x64.gz为例)

  1. 创建目录:

    sudo mkdir /usr/lib/jvm

  2. 解压缩到该目录:

    sudo tar -zxvf jdk-7u60-linux-x64.gz -C /usr/lib/jvm

修改环境变量

sudo vim ~/.bashrc

  1. 文件的末尾追加下面内容:

    1
    2
    3
    4
    5
    #set oracle jdk environment
    export JAVA_HOME=/usr/lib/jvm/jdk1.7.0_60 ## 这里要注意目录要换成自己解压的jdk 目录
    export JRE_HOME=${JAVA_HOME}/jre
    export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
    export PATH=${JAVA_HOME}/bin:$PATH
  2. 使环境变量马上生效
    source ~/.bashrc

910-650-9685设置系统默认jdk 版本

1
2
3
4
5
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.7.0_60/bin/java 300  
sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.7.0_60/bin/javac 300
sudo update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/jdk1.7.0_60/bin/jar 300
sudo update-alternatives --install /usr/bin/javah javah /usr/lib/jvm/jdk1.7.0_60/bin/javah 300
sudo update-alternatives --install /usr/bin/javap javap /usr/lib/jvm/jdk1.7.0_60/bin/javap 300

 然后执行:sudo update-alternatives --config java

若是初次安装jdk,会有下面的提示
1
2
There is only one alternative in link group java (providing /usr/bin/java): 
/usr/lib/jvm/jdk1.7.0_60/bin/java
否则,选择合适的jdk

测试jdk

1
2
3
4
5
java -version
#显示如下
java version "1.7.0_60"
Java(TM) SE Runtime Environment (build 1.7.0_60-b19)
Java HotSpot(TM) 64-Bit Server VM (build 24.60-b09, mixed mode)
jdk 安装成功

6417935813下载elasticsearch

1
2
3
4
5
wget /artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.4.tar.gz
wget /artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.4.tar.gz.sha512
shasum -a 512 -c elasticsearch-6.2.4.tar.gz.sha512
tar -xzf elasticsearch-6.2.4.tar.gz
cd elasticsearch-6.2.4/

启动elasticsearch

1
2
3
4
5
6
# Running Elasticsearch from the command line
./bin/elasticsearch
# Running as a daemon
./bin/elasticsearch -d -p pid
#To shut down Elasticsearch, kill the process ID recorded in the pid file:
kill `cat pid`

安装错误

  • max file descriptors [4096] for elasticsearch process is too low

    解决办法:

    1
    2
    3
    4
    5
    sudo vim /etc/security/limits.conf

    # 在最后面追加下面内容
    *** - nofile 65536
    *** 是启动ES的用户

    Ubuntu ignores the limits.conf file for processes started by init.d. To enable the limits.conf file, edit /etc/pam.d/su and uncomment the following line:

    #session required pam_limits.so

  • max virtual memory areas vm.max_count [65530] likely too low,increase to at least [26244]

    解决办法

    sudo sysctl -w vm.max_map_count=262144

  • 默认情况下,Elastic 只允许本机访问,如果需要远程访问,可以修改 Elastic 安装目录的config/elasticsearch.yml文件,去掉network.host的注释,将它的值改成0.0.0.0,然后重新启动 Elastic。

(949) 809-3244安装中文分词器

  1. 执行命令

    ./bin/elasticsearch-plugin install /github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.2.4/elasticsearch-analysis-ik-6.2.4.zip

  2. 配置IK[仅供v5.0以下版本使用]

    执行以下CURL

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    curl -XPOST '/localhost:9200/_all/_close' 
    curl -XPUT '/localhost:9200/_all/_settings?preserve_existing=true' -d '{
    "index.analysis.analyzer.default.type" : "ik_max_word",
    "index.analysis.analyzer.ik.alias" : [
    "ik_analyzer"
    ],
    "index.analysis.analyzer.ik.type" : "org.elasticsearch.index.analysis.IkAnalyzerProvider",
    "index.analysis.analyzer.ik_max_word.type" : "ik_max_word",
    "index.analysis.analyzer.ik_max_word.use_smart" : "false",
    "index.analysis.analyzer.ik_smart.type" : "ik_max_word",
    "index.analysis.analyzer.ik_smart.use_smart" : "true"
    }'

(443) 581-3610

Posted on 2011-03-01 | In 未分类

原文: /www.almnetworks.net/zh-CN/post/2010/08/20/TFS-Backup-and-Restore-become-much-easier-than-ever.aspx 今天早上收到了发自LinkedIn讨论组里面的一封邮件,有关新版的TFS PowerTools对TFS 2010的备份和恢复的全面支持,是Brian Harry昨天和前天分别在博客上发布的两篇文章 new Power Tools which support TFS Backup and Restore, 仅仅看这个名称我就已经很激动了,因为TFS的备份和恢复一直都没有很完整的解决方案,要完成一个很好的备份需要有很多的手动步骤才行。关于这点,可以参考 /msdn.microsoft.com/en-us/library/bb552295.aspx 我还没有具体测试这个新版的Tfs PowerTools,光看一下截图,可以说确实不错。 安装了Power Tools以后,在Administrative Console里面会有新的Team Foundation Backup选项出现 image 备份计划向导 - 选择备份数据的位置 image 运行一个建好的备份计划 image 如果你的TFS里面同时部署了门户和报表,这个工具同时也支持对于SharePoint和Reporting Service数据的备份和恢复 image 以上仅仅是快速浏览了一下这个工具的功能,这个周末假具体测试一下在给大家提供更多的信息吧。

(204) 202-0981

Posted on 2011-03-01 | In 未分类

最近这段时间,开始使用TFS2010进行项目的源码管理,在使用过程中,发现了不些问题,由于开发人员的操作失误,经常导致了源码中的文件被锁定,而在开发人员的PC机上又不能把锁定的文件签入到TFS中,刚开始遇到这个问题时,想通过管理员帐号来“取消锁定”,但在“源代码管理器”中,管理员帐号也没有权限操作“取消锁定”。遇到这种文件被锁定的事,是相当的郁闷。 郁闷归郁闷,问题还是得要解决,所以baidu、google了不少资料,原来“取消锁定”是不能通过界面来操作的,而是要使用TFS的命令来实现解锁操作,在不断的摸索和参考其它文章,总算把这个头痛的问题解决了,为了方便以后解决同样的问题、也为了其他同志在遇到这相相似的问题时有一个解决方案,故把我解决的过程记录一下。 1、CMD到TFS的命令 A:32位操作系统:c:/program files/microsoft visual studio 10.0/common7/ide。 B:64位操作系统:c:/program files(x86)/microsoft visual studio 10.0/common7/ide。 2、执行tf undo解锁命令 如:c:\program files (x86)\microsoft visual studio 10.0\common7\ide\tf undo /workspace:testing-pc;test_user $/works/ias.works/ias.mvcimp/controllers/homecontroller.cs。 注:testing_pc:表示锁定文件的工作区;test_user:表示的是锁定文件的用户。譬如我自己的PC机上的工作区是:BEA-PC,我的TFS登录帐号是:tfs001。则:tf undo /workspace:BEA-PC;tfs001

MVC中输出Html标签的方法

Posted on 2011-02-28 | In 未分类

@: item.content 用过ASP.NET MVC的人都知道,这是MVC的基本输出的方式,但是最近我在写一个页面的时候,却碰上了一个问题,我需要在一个div中输出一个
标签,然而他却直接把
给输了出来,这确实让人很郁闷。 我看了一下代码,原来在输出的时候,这种方式直接把<和>给变换成了<和>,所以我想尽任何编码解码的方式想要把这个给还原出来,然而什么都没有效果。 在不断摸索之后我发现了简单的不能再简单的方法, @(“

asdfasd

“) @(new HtmlString( “

asdfasd

“)) @(Html.Encode(“

asdfasd

“))

281-270-9163

Posted on 2011-02-28 | In 未分类

Following New Is from 212-782-4272 Localization is a common issue when we develop a world wide web application. The key point of making your application localizable is to separate the page content from your logic implementation. That means, when you want to display something on the page, never put them directly on the page file (or the backend logic). You should give the content a key which can be linked to the real content for the proper language setting. Last week I was implementing the localization on my ASP.NET MVC application. This is my first time to do it so I spent about 3 days for investigation, trying and come up with a final solution which only needs 1 day’s job. So let’s take a look on what I have done.

Localization supported by ASP.NET MVC

ASP.NET MVC was built on top of the ASP.NET runtime so all feature provided by ASP.NET can be used in MVC without any wheaks such as caching, session state and localization. In the traditional ASP.NET web form ages we were using the resource files to store the content of the application with different cultures and using the ResourceManager class to retrieve them which can be generated by Visual Studio automatically. In ASP.NET MVC they works well. Let’s create a standard ASP.NET MVC application for an example. The website was in English and we can see all content are hard-written in the view pages and the controller classes. diffraction spectrum Now what I need to do is to put all contents out of from the pages and the controllers. ASP.NET gives us a special folder named App_GlobalResources which contains the resource files for the content of all cultures. Just right-click the project in the solution explorer window and create the folder under the Add > Add ASP.NET Folders menu. I created 2 resource files for 2 langauges: English and Chinese. The English would be the default language of this application so I will create Global.resx file firstly, then Global.zh.resx. The middle name ‘zh’ was the culture name of this language. If we need a French version in the future we can simply create Global.fr.resx. The Visual Studio will help us to generate the accessing class for them. image Then let’s move some content into the resource files. In the home page there are 3 places need to be changed: the title, message and the description. So we add 3 items in our 2 resource files. image The title and the description are defined in the view page so we will change the view page. It will load the content through the access class generated by Visual Studio.

1: <%@ Page Language=”C#” MasterPageFile=”~/Views/Shared/Site.Master” Inherits=”System.Web.Mvc.ViewPage” %>

2:

3: <asp:Content ID=”Content1” ContentPlaceHolderID=”TitleContent” runat=”server”>

4: <%

1: : Resources.Global.HomeIndex_Title

%>

5: </asp:Content>

6:

7: <asp:Content ID=”Content2” ContentPlaceHolderID=”MainContent” runat=”server”>

8:

<%

1: : ViewData[“Message”]

%>

9:

10: <%

1: : Resources.Global.Home_Index_Desc

%> 6056895888Specify the language through the URL

We had moved the content into the resource files but our application does not support localization since there’s no place we can specify the language setting. In order to make it as simple as possible we will make the URL indicate the current selected language, which means if my URL was (229) 448-7075 it will in English while /localhost/zh-CN/Home/Index will in Chinese. The user can change the language at any pages he’s staying, and also when he want to share the URL it will pass his language setting as well. In order to do so I changed the application routes, add a new route with a new partten named lang in front of the controller.

1: public static void RegisterRoutes(RouteCollection routes)

2: {

3: routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);

4:

5: routes.MapRoute(

6: “Localization”, / Route name

7: “{lang}/{controller}/{action}/{id}”, / URL with parameters

8: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional } / Parameter defaults

9: );

10:

11: routes.MapRoute(

12: “Default”, / Route name

13: “{controller}/{action}/{id}”, / URL with parameters

14: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional } / Parameter defaults

15: );

16:

17: }

You may noticed that I added a new route rather than modifed the default route, and didn’t specify the default value of the {lang} pattern. It’s because we need the default route render the default request which without the language setting such as 623-742-4644 and 4055858903. If I modied the default route, 336-300-5118 cannot be routed; and the 6152357567 would be routed to lang = Home, controller = Index which is incorrect.

Since we need the URL control the language setting we should perform some logic before each action was executed. The ActionFilter would be a good solution in this scenario.

1: using System;

2: using System.Collections.Generic;

3: using System.Linq;

4: using System.Web;

5: using System.Web.Mvc;

6: using System.Threading;

7: using System.Globalization;

8:

9: namespace ShaunXu.MvcLocalization

10: {

11: public class LocalizationAttribute : ActionFilterAttribute

12: {

13: public override void OnActionExecuting(ActionExecutingContext filterContext)

14: {

15: if (filterContext.RouteData.Values[“lang”] != null &&

16: !string.IsNullOrWhiteSpace(filterContext.RouteData.Values[“lang”].ToString()))

17: {

18: / set the culture from the route data (url)

19: var lang = filterContext.RouteData.Values[“lang”].ToString();

20: Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(lang);

21: }

22: else

23: {

24: / load the culture info from the cookie

25: var cookie = filterContext.HttpContext.Request.Cookies[“ShaunXu.MvcLocalization.CurrentUICulture”];

26: var langHeader = string.Empty;

27: if (cookie != null)

28: {

29: / set the culture by the cookie content

30: langHeader = cookie.Value;

31: Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader);

32: }

33: else

34: {

35: / set the culture by the location if not speicified

36: langHeader = filterContext.HttpContext.Request.UserLanguages[0];

37: Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader);

38: }

39: / set the lang value into route data

40: filterContext.RouteData.Values[“lang”] = langHeader;

41: }

42:

43: / save the location into cookie

44: HttpCookie _cookie = new HttpCookie(“ShaunXu.MvcLocalization.CurrentUICulture”, Thread.CurrentThread.CurrentUICulture.Name);

45: _cookie.Expires = DateTime.Now.AddYears(1);

46: filterContext.HttpContext.Response.SetCookie(_cookie);

47:

48: base.OnActionExecuting(filterContext);

49: }

50: }

51: }

I created an attribute named LocalizationAttribute which inherited from the ActionFilterAttribute and overrided its OnActionExecuting method. I firstly checked the RouteData. If it contains the language setting I will set it to the CurrentUICulture of the CurrentThread, which will indicate the resource manager (generated by Visual Studio based on the resource files) retrieve the related value. If no language setting in the RouteData I checked the cookie and set it if available. Otherwise I used the user language of the HttpRequest and set into the current thread. Finally I set the language setting back to the route data so all coming actions would retrieve it and also saved it into the cookie so that next time the user opened the browser he will see his last language setting. Then I applied the attribute on the home controller so that all actions will perform my localization logic.

1: namespace ShaunXu.MvcLocalization.Controllers

2: {

3: [HandleError]

4: [Localization]

5: public class HomeController : Controller

6: {

7: public ActionResult Index()

8: {

9: ViewData[“Message”] = Resources.Global.HomeIndex_Message;

10:

11: return View();

12: }

13:

14: public ActionResult About()

15: {

16: return View();

17: }

18: }

19: }

Now if we start the application and add the language setting on the URL we can see the result. 214-347-2619 6042191794

Links for the language selection

Let the user change the language through the URL would not be a good solution. We need to give them some links on top of the pages so that they can change it at any time. In ASP.NET MVC the simplest way is to create a HtmlHelper to render the links for each language.

1: using System;

2: using System.Collections.Generic;

3: using System.Linq;

4: using System.Web;

5: using System.Web.Routing;

6: using System.Web.Mvc;

7: using System.Web.Mvc.Html;

8: using System.Threading;

9:

10: namespace ShaunXu.MvcLocalization

11: {

12: public static class SwitchLanguageHelper

13: {

14: public class Language

15: {

16: public string Url { get; set; }

17: public string ActionName { get; set; }

18: public string ControllerName { get; set; }

19: public RouteValueDictionary RouteValues { get; set; }

20: public bool IsSelected { get; set; }

21:

22: public MvcHtmlString HtmlSafeUrl

23: {

24: get

25: {

26: return MvcHtmlString.Create(Url);

27: }

28: }

29: }

30:

31: public static Language LanguageUrl(this HtmlHelper helper, string cultureName,

32: string languageRouteName = “lang”, bool strictSelected = false)

33: {

34: / set the input language to lower

35: cultureName = cultureName.ToLower();

36: / retrieve the route values from the view context

37: var routeValues = new RouteValueDictionary(helper.ViewContext.RouteData.Values);

38: / copy the query strings into the route values to generate the link

39: var queryString = helper.ViewContext.HttpContext.Request.QueryString;

40: foreach (string key in queryString)

41: {

42: if (queryString[key] != null && !string.IsNullOrWhiteSpace(key))

43: {

44: if (routeValues.ContainsKey(key))

45: {

46: routeValues[key] = queryString[key];

47: }

48: else

49: {

50: routeValues.Add(key, queryString[key]);

51: }

52: }

53: }

54: var actionName = routeValues[“action”].ToString();

55: var controllerName = routeValues[“controller”].ToString();

56: / set the language into route values

57: routeValues[languageRouteName] = cultureName;

58: / generate the language specify url

59: var urlHelper = new UrlHelper(helper.ViewContext.RequestContext, helper.RouteCollection);

60: var url = urlHelper.RouteUrl(“Localization”, routeValues);

61: / check whether the current thread ui culture is this language

62: var current_lang_name = Thread.CurrentThread.CurrentUICulture.Name.ToLower();

63: var isSelected = strictSelected ?

64: current_lang_name == cultureName :

65: current_lang_name.StartsWith(cultureName);

66: return new Language()

67: {

68: Url = url,

69: ActionName = actionName,

70: ControllerName = controllerName,

71: RouteValues = routeValues,

72: IsSelected = isSelected

73: };

74: }

75:

76: public static MvcHtmlString LanguageSelectorLink(this HtmlHelper helper,

77: string cultureName, string selectedText, string unselectedText,

78: IDictionary<string, object> htmlAttributes, string languageRouteName = “lang”, bool strictSelected = false)

79: {

80: var language = helper.LanguageUrl(cultureName, languageRouteName, strictSelected);

81: var link = helper.RouteLink(language.IsSelected ? selectedText : unselectedText,

82: “Localization”, language.RouteValues, htmlAttributes);

83: return link;

84: }

85:

86: }

87: }

I created a class to store the information of the language links. This can be used to render a linkage for a language, and it also can be used if we need the selector it be an image linkage, dropdown list or anything we want as well. The LanguageUrl method takes the main responsible for generating the information that can be used in the selector such as the URL, RouteValues, etc. It loads the RouteData and query string from the incoming request and swich the language part, then generate the URL of current page with that language so that it will render the same page with that language when the user clicked. The LanguageSelectorLink method takes the responsible for rendering a full Html linkage for this language which we will use it for our simple exmaple. We need the language select available in all pages so we should put the links in the master page.

1:

2: <%

1: Html.RenderPartial(“LogOnUserControl”);

%>

3:

4: <%

1: : Html.LanguageSelectorLink(“en-US”, “[English]“, “English”, null)

%>

5: <%

1: : Html.LanguageSelectorLink(“zh-CN”, “[中文]“, “中文”, null)

%>

6:

Don’t forget to import the namespace of the SwitchLanguageHelper class on top of the master page otherwise the extension method will not work.

image

Oops! Log On page crashed

Some web application only can be viewed once logged on, such as some CRM system used inside the company. It means before any action was performed the application should be redirected to the log on page if the user was not identitied. Let’s have a look on what will be in our sample application. Just add the Authorize attribute on the home controller. 781-528-3289 Oops! It gave me a 404 error which means the application cannot find the resource for /Account/LogOn. This is because our routes. We have 2 routes registered in the system, the Localization route has 4 parttens: lang, controller, action and id; the Default route has 3 parttens: controller, action and id. The incoming request will be checked through all routes based on their rules and once it’s matched the value would be identified by that route. For example if the URL was /localhost/en-US/Home/Index it matches the Localization route (lang = en-US, controller = Home, action = Index, id is optional). If the URL was 4405645514 it was not match the Localization route (lang cannot be null or empty) so it matches the Default route since it allows all parttens to be null. Now let’s have a look on this URL /localhost/Account/LogOn, the Account could be the lang partten and LogOn could be the controller, since the action and id partten are all optional it matchs the Localization route so it means: language = Account, controller = LogOn, action = Index (by default). But there is no controller named LogOn and action named Index so it’s the reason why it returned 404 error. Since the logon URL was redirected by the ASP.NET authorizing model which means we cannot add the language data into the URL we have to add a new route individually for it.

1: routes.MapRoute(

2: “LogOn”, / Route name

3: “Account/{action}”, / URL with parameters

4: new { controller = “Account”, action = “LogOn” } / Parameter defaults

5: );

6:

7: routes.MapRoute(

8: “Localization”, / Route name

9: “{lang}/{controller}/{action}/{id}”, / URL with parameters

10: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional } / Parameter defaults

11: );

12:

13: routes.MapRoute(

14: “Default”, / Route name

15: “{controller}/{action}/{id}”, / URL with parameters

16: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional } / Parameter defaults

17: );

In front of the Localization and Default route I added a new one named LogOn, it only accept the Account controller so for this URL podaxonial the controller would be Account and action would be LogOn which is correct. Let’s have a look on the result. image

Refactoring the codes

This application is a fairly simple example, like all example the microsoft provided, it only contains one project which is my website. In the real projects we might not want to organize our application in one project. We would like to separate the webiste, the controllers, the models, and maybe we need the data access and business layers in the different projects. So let’s refactor my example a little bit and see what we should do then to make it localizable. Here I just want to separte the controllers and view models out of my website project but would not create the data access and business logic layer since normally they would not be related with the localization.

Localization is the matter we should solve at the persentation layer. We should never pass any localized information from the business layer. For example, if the password was incorrect when authorizing an user at the business layer we should always return a flag (int or enum) to indicate the error instead of any error message strings.

image I moved the controllers and models out of the my main website project and let them referenced by the webiste project. I added the necessary assemblies and built it. All worked well except my localization code under the home controller class. I set the message string into the ViewData from the resource class which defined in my website project, now it cannot be accessed through my controller project. image So what I should do here is to move the resource files out of the website project since it’s at the bottom of the references hierarchy. image After moved the resource files to the new project and added the refereneces, I built it again but I got more error. This is because the accessing classes generated for the resource files are defined as “internal” by default which cannot be invoked out of the project. So what I can do is to create the new resource files for localization and update their access model to “Public”. imageAnd this time our application works well. image

Localizing messages in ViewModels

In the ASP.NET MVC application the message can be defined directly on the view pages, controllers and the view models. One of the scenario is to define the error messages on the view model classes through the attributes provided by System.ComponentModel.DataAnnotations. With the DataAnnotations attributes we can add the validation method and the error messages on the propties of the model classes through the AOP approch. For example when loggin on the user name field should be displayed as “User name” and should be mandatory. So the model would be defined like this, whichi doesn’t support localization.

1: [Required]

2: [DisplayName(“User name”)]

3: public string UserName { get; set; }

We can defined the error messages for the Requeired attribute. And the pre-defined DataAnnotations attributes supports localization which means we can define the resource key and resource type then it will find the relevant resources and returned the content back. Assuming that I had defined 2 resources one for the display name the other for error message, then the attribute would be changed like this.

1: [Required(ErrorMessageResourceName = “LogOnModel_UserName_Required”,

2: ErrorMessageResourceType = typeof(Resources.Global))]

3: [Display(Name = “LogOnModel_UserName_Required”,

4: ResourceType = typeof(Resources.Global))]

5: public string UserName { get; set; }

You might noticed that I changed the DisplayName attribute to Display attribute. This is because the DisplayName attribute does not support localization. Let’s execute and see what’s happen. image Oops! I think we are running into a lot of problems.

  • The localization doesn’t work. You can see on the URL it’s in Chinese version but the user name displayed in English.
  • The display name doesn’t work. In my model attributes I specified its resource name but now it shown the property’s name.
  • The error message was not localized.

Let’s explain one by one. For the first one, the localization didn’t work at all. That is because we implemented the localization by the action filter attribute we created before. But the validation logic was performed by the default model binder which was invoked before the action filter attribute was performed. So when the model binder failed the validation and attempted to retrieve the error message from the resource files the culture of the current thread has not been changed by the action filter. image In order to make the localization (culture setting) being invokde before the model binder was executed we should move the localization logic to the Controller.ExecuteCode method, which is earlier than the model binder and validation. So I created a new class named BaseController and let it inherited from the abstract Controller class and then overrided the ExecuteCode method with the localization logic. Then I updated all controllers in the application to inherit from this BaseController.

1: using System;

2: using System.Collections.Generic;

3: using System.Linq;

4: using System.Text;

5: using System.Web.Mvc;

6: using System.Threading;

7: using System.Globalization;

8: using System.Web;

9:

10: namespace ShaunXu.MvcLocalization.Controllers

11: {

12: public abstract class BaseController : Controller

13: {

14: protected override void ExecuteCore()

15: {

16: if (RouteData.Values[“lang”] != null &&

17: !string.IsNullOrWhiteSpace(RouteData.Values[“lang”].ToString()))

18: {

19: / set the culture from the route data (url)

20: var lang = RouteData.Values[“lang”].ToString();

21: Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(lang);

22: }

23: else

24: {

25: / load the culture info from the cookie

26: var cookie = HttpContext.Request.Cookies[“ShaunXu.MvcLocalization.CurrentUICulture”];

27: var langHeader = string.Empty;

28: if (cookie != null)

29: {

30: / set the culture by the cookie content

31: langHeader = cookie.Value;

32: Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader);

33: }

34: else

35: {

36: / set the culture by the location if not speicified

37: langHeader = HttpContext.Request.UserLanguages[0];

38: Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader);

39: }

40: / set the lang value into route data

41: RouteData.Values[“lang”] = langHeader;

42: }

43:

44: / save the location into cookie

45: HttpCookie _cookie = new HttpCookie(“ShaunXu.MvcLocalization.CurrentUICulture”, Thread.CurrentThread.CurrentUICulture.Name);

46: _cookie.Expires = DateTime.Now.AddYears(1);

47: HttpContext.Response.SetCookie(_cookie);

48:

49: base.ExecuteCore();

50: }

51: }

52: }

For the second and third problem that is because the DisplayName attributes was defined on .NET 4.0 platform but currently the ASP.NET MVC runtime was built on .NET 3.5 which cannot invoke the assemblies under .NET 4.0. If you downloaded the source code of the ASP.NET MVC 2 there is a solution named MvcFuturesAspNet4 which will create some assemblies built on .NET 4.0 and support the DisplayName attribute. Here I would like to use another approch to work around it.

1: using System;

2: using System.Collections.Generic;

3: using System.Linq;

4: using System.Text;

5: using System.ComponentModel;

6: using System.ComponentModel.DataAnnotations;

7:

8: namespace ShaunXu.MvcLocalization.Models

9: {

10: public class LocalizationDisplayNameAttribute : DisplayNameAttribute

11: {

12: private DisplayAttribute display;

13:

14: public LocalizationDisplayNameAttribute(string resourceName, Type resourceType)

15: {

16: this.display = new DisplayAttribute()

17: {

18: ResourceType = resourceType,

19: Name = resourceName

20: };

21: }

22:

23: public override string DisplayName

24: {

25: get

26: {

27: return display.GetName();

28: }

29: }

30: }

31: }

I created another attribute which wapped the DisplayName one. It will create an inner instance of the DisplayAttribute and set the resource key and type accordingly. Then when the DisplayName was invoked it will perform the DisplayAttribute.GetName method which supports localization. So the view model part should be changed like this below.

1: [Required(ErrorMessageResourceName = “LogOnModel_UserName_Required”,

2: ErrorMessageResourceType = typeof(Resources.Global))]

3: [LocalizationDisplayName(“LogOnModel_UserName_Required”,

4: typeof(Resources.Global))]

5: public string UserName { get; set; }

And the let’s take a look. image

Summary

In this post I explained about how to implement the localization on an ASP.NET MVC web application. I utilized the resource files as the container of the localization information which provided by the ASP.NET runtime. And I also explain on how to update our solution while the project was being grown and separated which more usefule when we need to implement in the real projects. The localization information can be stored in any places. In this post I just use the resource files which I can use the ASP.NET localization support classes. But we can store them into some external XML files, database and web services. The key point is to separate the content from the usage. We can isolate the resource provider and create the relevant interface to make it changable and testable. PS: You can download the source code of the example 4386184956. Hope this helps, Shaun

Tfs 2010使用小技巧

Posted on 2011-02-26 | In 未分类

一、如何删除工作项 1、使用Tfs管理员账户登录 2、使用Cmd打开命令行窗口 如果是32位系统,cd “C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE” 64位系统则 cd “C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE” 3、使用 witadmin.exe destroywi命令,按下面的方式 witadmin.exe destroywi /Collection:\\[ServerName]:8080\tfs\[CollectionName] /id:[WI ID] 可以一次删除多个工作项,使用逗号分隔工作项Id,比如10,22,30。可以使用 /noprompt屏蔽提示消息 4、假设服务器名称为ServerDemo,团队项目集合名称为TeamDemo,要删除Id为17、18的工作项,则使用如下命令: witadmin.exe destroywi /Collection:\\ServerDemo:8080\tfs\TeamDemo /id:17,18 5、上述方法为微软工作人员答疑,经测试,在Tfs2010 简体中文正式版,能够正常的删除工作项。请注意,在做这个操作之前,先关闭Vs2010。 二、使用Ghost或者Windows 镜像备份的情形下,如何备份项目集? 当我们安装了操作系统、开发环境之后,我们常常为此时干净的系统,做一个镜像备份,有时候是使用Ghost,有时候是使用Windows 7或者Sql Server 2008 R2的Server Backup功能做镜像备份。当然,因为安装了Sql server 2008 R2和Tfs2010、Vs2010之后,C:盘往往有17G左右,因为速度的关系我们推荐使用Ghost,能在20分钟之内恢复C:\盘,使用Windows Server Backup功能,常常需要数个小时。 我们一般做两个Ghost镜像,第一个是操作系统安装好、驱动安装好、操作系统各项更新完成、常用软件如Live Writer、QQ、网银、迅雷、Winrar之类安装好、操作系统配置好(比如关机不要输入关机原因、登录不需要按Ctrl+Alt+Del、或者自动使用某个账户登录而无需输入密码等等),这些完成之后做一个镜像,叫做工作镜像。在这个镜像做好之后,安装开发环境,然后做第二个镜像:开发环境镜像。请注意做镜像前关闭休眠功能并删除休眠文件、禁用虚拟内存或将虚拟内存文件放在D:盘,这样会大大的减少镜像文件的大小。 那么,每次恢复镜像,会造成Tfs的项目管理信息丢失。所以,这之前需要备份Tfs的数据库,这是件很麻烦的事情,下面列出我目前采用的一个取巧的方法,请注意我在自己个人的开发机器上安装的是Tfs的Basic版本: 1、安装Sql 2008 R2和Tfs 2010之后,默认的项目集保存在C:盘,此时我们在C盘将三个Tfs数据库,备份在C:盘默认的Sql Server备份位置。这是为了防止Tfs系统完全不匹配,造成不能正常工作的最后挽救方法。 2、在Sql server中设置默认的数据库位置在D:\Database或D:盘的其他目录 3、重新启动系统,注意,不要忽略这一步,我们在上一步的设置或许仅仅是修改了一个配置项,目前Sql的默认数据库文件存放路径,还是在C:盘,没有改变。 4、使用Tfs 2010的管理控制台,创建新的团队项目集合,假设我们为其命名为TeamWork。 5、此时,你会发现在D:\Database下,有了一个新的数据库Tfs_TeamWork 6、将Sql server的三个Tfs_开头的数据库,同样备份到C:盘,这个时候再开始为系统做Ghost镜像,今后每次使用Ghost恢复干净的开发环境,就不用考虑Tfs数据库的问题,直接用Ghost恢复就行了。当然,前提是你不要删除掉D:\Database目录下的相关数据库。以后,只需要随时备份Tfs_TeamWork以策万全。 7、如果D:\盘的数据库出现意外,最坏的情况,我们使用C:盘的初始备份能让系统正常运行起来,然后再用平常做的Tfs_TeamWork的备份,按照标准的恢复模式进行。 注意,如果我们仅备份某个团队项目集合的数据库,而没有备份Tfs_Configuration数据库,则在上次创建镜像到此次恢复镜像期间创建的团队项目会丢失。 三、安装好Scrum模版后,创建新的团队项目集合时,如何使用? 选择该团队项目集合,右键,运行过程模版管理器。选上载,找到安装目录:默认是C:\Program Files (x86)\Microsoft\Microsoft Visual Studio Scrum 1.0\Process Template 此后创建团队项目时,就多了Scrum项目这一项。 四、如何清除Vs2010的工作区影射关系的缓存信息? 在原有的团队项目集合移除,或者更换Tfs服务器后,一些工作区的影射关系仍然存在,这会导致“将解决方案添加到源代码管理”之类的功能不可使用。 这些信息缓存于文件C:\Users\Administrator\AppData\Local\Microsoft\TeamFoundation\3.0\Cache\VersionControl.config中,只要把跟旧服务器相关的 ServerInfo 节点删掉,问题即可解决。 五、如何还原已经备份的团队项目集合数据库? 1、关闭Tfs服务: 运行: “C:\Program Files\Microsoft Team Foundation Server 2010”\Tools\TFSServiceControl quiesce 2、还原数据库,请注意两个选项:选择从设备恢复、选择覆盖原数据库 3、启动Tfs服务: 运行: “C:\Program Files\Microsoft Team Foundation Server 2010”\Tools\TFSServiceControl unquiesce 六、删除团队项目 “C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\TFSDeleteProject” /force /collection:(401) 227-8169 Faster 其中/x200:8080是服务器名称和端口,Stock是团队项目集合的名称,Faster是Stock团队项目集合中要删除的项目

pine bark aphid

Posted on 2011-02-25 | In 未分类

有时候我们手头上的数据库可能只剩下了mdf文件,而日志文件丢失了或者损坏了, 那么你可以尝试使用以下方法重建事务日志,注意sql 2Q不是这个语句 USE master; GOCREATE DATABASE nuke ON (FILENAME = ‘H:\Mdf-BackUp\Nuke.mdf’), –数据库文件所在 (FILENAME = ‘H:\Mdf-BackUp\Nuke_Log.ldf’)—指定重建的日志文件路径 FOR ATTACH_REBUILD_LOGGO

修复数据库帐号Aspuser

Posted on 2011-02-25 | In 未分类

大家以前应该碰到过这样的情况: 在作业或者项目数据库中,创建和映射了数据库帐号aspuser,当你重装了数据库,或者备份了到另外的服务器上去还原的时候,你的aspuser帐号不能对数据库正常访问了,即使在数据库的登录帐号中创建了相同的aspuser帐号,也不行。 今天在嘉为培训的时候,主将老师谈到这个问题,提供了很好的方案:

–报告孤立用户 Exec sp_change_users_login ‘Report’

执行这个存储过程可以查出数据库中,存在相同问题的帐号的列表

–修复用户与已经存在的登录账号间的映射 Exec sp_change_users_login ‘Auto_Fix’,’aspuser’ –通过更新用户,共修复了 1 个孤立用户。这个就是修复帐号的存储过程(前提是数据库登录帐号中有aspuser)

–创建登录并修复用户与登录账号间的映射 Exec sp_change_users_login ‘Auto_Fix’,’aspuser’,null,’000000’

创建aspuser帐号的同时,对帐号进行修复,一举两得

337-328-7479

Posted on 2011-02-25 | In 未分类

在程序中使用DataTable对象(非原创,来自伯乐园) DataTable表示一个与内存有关的数据表,可以使用工具栏里面的控件拖放来创建和使用,也可以在编写程序过程中根据需要独立创建和使用,最常见的情况是作为DataSet的成员使用,在这种情况下就需要用在编程过程中根据需要动态创建数据表。那么在8.4节中主要讲用编码的方式来建立DataTable数据表以及对它的操作。 1 代码创建DataTable数据表 如上8.3节里面所讲,通过添加对象的方式直接在DataSet中创建数据表,可以通过使用Add方法将DataTable添加到DataSet中,这种是使用控件的可视化添加DataTable的操作,那么在代码中怎么来创建DataTable数据表呢? 在程序中创建DataTable对象可以使用相应的DataTable构造函数。创建一个表名为TableName的数据表,实现代码如下所示: DataTable NewTable = new DataTable(TableName); 另外也可以通过以下方法创建DataTable对象:使用DataAdapter对象的Fill方法或FillSchema方法在DataSet中创建,这种方式都用于与数据库相连接操作的情况下。实现代码如下所示: /数据库联接字符串 string connectionString = “Data Source=local;Initial Catalog=Northwind;Integrated Security=True;UserID=sa;Password=”; /sql语句查询 string commandString = “Select from Customers”; / 创建SqlDataAdapter对象,并执行sql命令 SqlDataAdapter dataAdapter = new SqlDataAdapter(commandString, connectionString); /创建数据集dataSet DataSet dataSet = new DataSet(); /把数据表添加到数据集中 DataTable dataTable = dataSet.Tables(“Customers”); /将数据填充到数据集中 dataAdapter.Fill(dataSet,”Customers”); 注意:将一个DataTable作为成员添加到一个DataSet的Tables集合中后,不能再将其添加到任何其他DataSet的表集合中。 使用DataTable构造函数初次创建DataTable时,是没有架构(即结构,没有列)的。没有架构的DataTable数据表示没有办法使用的,因此要在使用这种DataTable数据表之前要定义表的架构,必须创建DataColumn对象并将其添加到表的Columns集合中。如何使用代码创建Columns列,将在本章后面几节中讲到。 创建DataTable时,不需要为TableName属性提供值,可以在其他时间指定该属性,或者将其保留为空,这些都不影响DataTable的使用。应该注意的是在将一个没有TableName值的表添加到DataSet中时,该表会得到一个从“Table”(表示Table0)开始递增的默认名称TableN。 以下示例创建DataTable对象的实例,并为其指定名称“Customers”。 实现代码如下所示: DataTable workTable = new DataTable(“Customers”); 以下代码是将创建的DataTable实例Customers表添加到DataSet的Tables集合中。实现代码如下所示: DataSet customers = new DataSet(); DataTable customersTable = customers.Tables.Add(“CustomersTable”); 或者 DataSet customers = new DataSet(); DataTable customersTable = new DataTable(“Customers”) customers.Tables.Add(Customers); 2 用编程方式添加DataTable列 前面已经学过使用代码创建DataTable,但是使用DataTable构造函数初次创建 DataTable时,是没有架构(即结构,没有列)的。要定义表的架构,必须创建DataColumn 对象并将其添加到表的Columns集合中。也可以为表定义主键列,并且可以创建Constraint约束对象并将其添加到表的Constraints约束集合中。 DataColumn类型表示了DataTable上的一列。总的来说,绑定到某个DataTable的所有DataColumn类型的集合就表示一个表。 DataTable包含了由表的Columns属性引用的DataColumn对象的集合。这个列的集合与任何约束一起定义表的架构(即结构)。 通过使用DataColumn构造函数,或者通过调用表的Columns属性的Add方法,可在表内创建DataColumn对象。Add方法将接受可选的ColumnName、DataType参数,并将创建新的DataColumn作为集合的成员。它还会接受现有的DataColumn对象并会将其添加到集合中,并会根据请求返回对所添加的DataColumn的引用。 以下示例向DataTable中添加了四列。实现代码如下所示: DataTable workTable = new DataTable(“Customers”); DataColumn workCol = workTable.Columns.Add(“CustID”); workTable.Columns.Add(“CustLName”); workTable.Columns.Add(“CustFName”); workTable.Columns.Add(“Purchases”); 代码说明: q CustID,CustLName,CustFName,Purchases:数据表Customers中的列名。 3 设置DataTable数据表的主键 数据库开发的一个通常规则就是表至少得有一个列作为主键。主键约束用于惟一标识给定表中的一条记录(行)。假设现在需要新建一个DataColumn列来表示EmpID字段并且要将这个列将作为表的主键,它必须有AllowDBNull和Unique属性,实现代码如下所示: DataTable workTable = new DataTable(“Customers”); DataColumn workCol = workTable.Columns.Add(“CustID”, typeof(Int32)); workCol.AllowDBNull = false; workCol.Unique = true; workTable.Columns.Add(“CustLName”, typeof(String)); workTable.Columns.Add(“CustFName”, typeof(String))); workTable.Columns.Add(“Purchases”, typeof(String))); 代码说明: 示例中用于CustID列的属性设置为不允许DBNull值并将值约束为唯一。但是,如果将CustID列定义为表的主键列,AllowDBNull属性就会自动设置为false,并且Unique属性会自动设置为true。 4 设置列的数据类型 通过上面8.4.2节的学习已经知道怎么向新建的数据表中添加列了,那么下面来看一看,怎么为添加的列设置列的数据类型。数据类型是标明一列数据的数据类型属性,根据不同的需要可以在DataTable数据表中建立不同的列,并可以为不同的列设置不同的数据类型,来满足需要。继续上面Customers表的例子,为创建的列添加数据类型: 实现代码如下所示: /创建一个数据表Customers DataTable CustomersTable = new DataTable(“Customers”); /创建一个Int32类型名称是CustID列,把这个列设置成主键,并且不允许为空, DataColumn CustomersCol = CustomersTable.Columns.Add(“CustID”, typeof(Int32)); CustomersCol.AllowDBNull = false; CustomersCol.Unique = true; /创建三个String类型的列CustLName,CustFName,Purchases CustomersTable.Columns.Add(“CustLName”, typeof(String)); CustomersTable.Columns.Add(“CustFName”, typeof(String))); CustomersTable.Columns.Add(“Purchases”, typeof(String))); 代码说明: 示例中用于CustID列定义为表的主键列。CustID列指定的数据类型是Int32,CustLName列、CustFName列、Purchases列指定的数据类型都是String的列,当然也可以不设置列的数据类型,在这个时候DataColumn的DataType属性默认为字符串类型,当然可以根据需要在创建列名时进行列数据类型的设置。 5 启用Autoincrementing字段 在8.4.4节中学会了如何设置DataColumn列的数据类型,在设置完DataColumn列的数据类型以后,也可以像SQL-Server数据库表一样把某一列设置成自动递增的。简单地说,自动增加列可以确保当一个新行被添加到给定表时,可以基于当前的递增步长值自动指定这个列的值。特别是某一列作为没有重复值得主键的时候,这个功能就特别有用。在DataTable中这个功能可以用AutoIncrement(列是否将列的值自动递增)、AutoIncrementSeed(起始值,种子值)和AutoIncrementStep(步长)属性来控制。 下面是创建一个支持自动递增的DataColumn列的例子。种子值用于标记列的起始值,步长值表示递增时增加种子值的数值,代码如下所示: / 创建一个新列 DataColumn myColumn = new DataColumn(); myColumn.ColumnName = “ CustID “; myColumn.DataType = System.Type.GetType(“System.Int32”); / 设置自动递增 myColumn.AutoIncrement = true; myColumn.AutoIncrementSeed = 0; myColumn.AutoIncrementStep = 1; 代码说明: q AutoIncrement:列是否将列的值自动递增,true表示自动递增,false表示不能自动递增。 q AutoIncrementSeed:起始值种子值,AutoIncrement属性设置为true的列的起始值。 q AutoIncrementStep:步长,递增量,AutoIncrement属性设置为true的列的步长。 创建一个数据类型为Int32的CustID列,为了能使这个字段的值实现自动增加的效果,把列AutoIncrement属性设置为true;把列得种子值AutoIncrementSeed定为0,也就是从0开始计数;同时设置自动增加的步长AutoIncrementStep为1,每次增加一个。由于种子值被定为0,前面5个值应该是0、1、2、3和4。 可以往一个DataTable中添加这个DataColumn来测试一下。然后往这个表中添加一些新行,当然会自动转储CustID列中的值,代码如下所示: /实现列自动增加功能 protected void Button1_Click(object sender, EventArgs e) { /创建一个新的数据列,名称:CustID ,数据类型:Int32. DataColumn myColumn = new DataColumn(); myColumn.ColumnName = “ CustID “; myColumn.DataType = System.Type.GetType(“System.Int32”); /把新创建的列设置自动增加,种子为0,增加步长为1. myColumn.AutoIncrement = true; myColumn.AutoIncrementSeed = 0; myColumn.AutoIncrementStep = 1; /把这个列添加到Customers表中. DataTable CustomersTable = new DataTable(“Customers”); myTable. CustomersTable.Add(myColumn); /添加20个新行. DataRow r; for (int i = 0; i < 20; i++) { r = CustomersTable.NewRow(); CustomersTable.Rows.Add(r); } /显示每一行的数据值. string temp = “”; DataRowCollection rows = CustomersTable.Rows; for (int i = 0; i < CustomersTable.Rows.Count; i++) { DataRow currRow = rows[i]; temp += currRow[“CustID “] + “ “; } /在Label1面显示所有值 Label1.Text = Label1.Text+temp; } 如果把上面代码写在建立的Web程序中,运行后点击“Button”按钮,就会得出初始值为0的步长为1的一系列数。 6 用编程方式添加DataTable行 在为DataTable定义了架构之后,也就是设置好了需要的列名以后,就可以可通过将DataRow对象添加到表的Rows集合中来将数据行添加到表中。与添加DataColumn类似,同样可以通过使用DataRow构造函数,或者通过调用表的Rows属性的Add方法,可在表内创建DataRow对象。 DataColumn对象集合表示了表的模式(Schema)。DataTable通过内部的DataColumnCollection类型保存表中所有列。相反,DataRow类型集合就表示表中的实际数据。这样,如果Customers表中有10个记录,就可以使用10个DataRow类型来表示它们。使用DataRow类的成员可以对表中的值进行插入、删除、求值和操作操作。 创建一个DataRow数据行的对象,实现代码如下所示: /创建一个Customers数据表 DataTable CustomersTable = new DataTable(“Customers “); /创建一个新的数据行 DataRow arow = CustomersTable.NewRow(); /设置行的值 arow[ColumnName] = DataValue; /把数据行添加创建的Customers数据表中 CustomersTable.Rows.Add(arow); 功能说明: 新建一行arow, 并给这行某一个列名付值为DataValue,最后把这一行添加到Customers表中。使用DataRow与使用DataColumn有些不同,因为不可以直接创建这个类型的实例,而是获得一个来自给定DataTable的引用。例如,假设想往Customers表中添加新行,DataTable.NewRow()方法可以获得下一空位,然后在上面填充每列的数据。 实现代码如下所示: /创建一个数据表 DataTable CustomersTable = new DataTable(“Customers”); /声明数据表的行和列变量 DataColumn column; DataRow row; /创建一个新列,设置列的数据列性和列名,并把这个新列添加到Customers表中 column=new DataColumn(); column.DataType = System.Type.GetType(“System.Int32”); column.ColumnName = “ CustID “; CustomersTable.Columns.Add(column); /再创建一个新列 column = new DataColumn(); column.DataType = Type.GetType(“System.String”); column.ColumnName = “ CustLName “; CustomersTable.Columns.Add(column); /创建新的一行并把这个行添加到Customers表中 for(int i = 0; i < 10; i++) { row = CustomersTable.NewRow(); row[“CustID “] = i; row[“CustLName “] = “item “ + i.ToString(); CustomersTable.Rows.Add(row); } 功能说明: 向CustomersTable表创建两个列分别是CustID, CustLName,然后用循环的方式产生10行并附值,添加到CustomersTable表中。 7 操作DataTable:更新行 在前面一节里面讲了,怎么样添加一个DataRow行,那么下面需要了解的关于DataTable的另一个方面就是怎样用新值更新已有的DataRow行。下面开始介绍关于DataTable更新行的问题。 最常使用的一个方法就是先用Select()方法获得符合给定过滤条件的行。一旦获得这些DataRow,就对它们作相应的修改。例如,假定有一个新按钮在被单击后,搜索DataTable中所有EmployeeID列值为5的行。一旦标识这些项后,就可以把EmployeeID列对应值5改为6。实例代码如下: /数据库联接字符串 string connectionString = “Data Source=local;Initial Catalog=Northwind;Integrated Security=True;UserID=sa;Password=”; /sql语句把Orders表中的数据信息都取出来 string commandString = “Select from Orders”; SqlDataAdapter dataAdapter = new SqlDataAdapter(commandString, connectionString); DataSet dataSet = new DataSet( ); /填充数据集 dataAdapter.Fill(dataSet,” Orders”); /填充数据表 DataTable dataTable = dataSet.Tables(“Orders”); / 建立一个用于过滤出EmployeeID列值为5的行的行的变量 string filterStr = “EmployeeID=5”; string strEmployeeID = null; / 查询出来所有EmployeeID列值为5的行. DataRow[] EmployeeID= dataTable.Select(filterStr); / EmployeeID列对应值5改为6 for(int i = 0; i < EmployeeID.Length; i++) { DataRow temp = EmployeeID [i]; strEmployeeID += temp[“EmployeeID “] = 6; EmployeeID [i] = temp; } 8 用编程方式删除DataTable行 用于从DataTable对象中删除DataRow对象的方法有两种:DataRowCollection对象的 Remove方法和DataRow对象的Delete方法。 Remove方法和Delete方法都可以将DataTable的行DataRow删除,但是前者是从DataRowCollection中删除DataRow,而后者只将行标记为删除。当应用程序调用AcceptChanges方法时,才会发生实际的删除。通过使用Delete,可以在实际删除之前先以编程方式检查哪些行标记为删除。如果将行标记为删除,其RowState属性会设置为Deleted。 在将DataSet或DataTable与DataAdapter和关系型数据源一起使用时,用DataRow的 Delete方法移除行。Delete方法只是在DataSet或DataTable中将行标记为Deleted,而不会移除它。而DataAdapter在遇到标记为Deleted的行时,会执行其DeleteCommand方法以在数据源中删除该行。然后,就可以用AcceptChanges方法永久移除该行。如果使用Remove 删除该行,则该行将从表中完全移除,但DataAdapter不会在数据源中删除该行。 DataRowCollection的Remove方法采用DataRow作为参数,并将其从集合中移除,实现代码如下所示: DataTable CustomersTable = new DataTable(“Customers “); DataRow workRow = empTable.NewRow(); CustomersTable.Rows.Remove(workRow); 作为对比,以下示例演示了如何调用DataRow上的Delete方法来将其RowState改为Deleted。实现代码如下所示: DataTable CustomersTable = new DataTable(“Customers “); DataRow workRow = empTable.NewRow(); workRow.Delete(); 如果将行标记为删除,并且调用DataTable对象的AcceptChanges方法,该行就会从DataTable中移除。相比之下,如果调用RejectChanges,行的RowState就会恢复到被标记为Deleted之前的状态。 9 向DataTable填充数据 ADO.NET中的DataSet是数据的内存驻留表示形式,它提供了独立于数据源的一致关系编程模型。DataSet表示整个数据集,其中包含表、约束和表之间的关系。由于DataSet独立于数据源,DataSet可以包含应用程序本地的数据,也可以包含来自多个数据源的数据。与现有数据源的交互通过DataAdapter来控制。 DataAdapter的SelectCommand属性是一个Command对象,用于从数据源中检索数据。DataAdapter的InsertCommand、UpdateCommand和DeleteCommand属性也是Command对象,用于按照对DataSet中数据的修改来管理对数据源中数据的更新。 DataAdapter的Fill方法用于使用DataAdapter的SelectCommand的结果来填充DataSet。Fill将要填充的DataSet和DataTable对象(或要使用从SelectCommand中返回的行来填充的DataTable的名称)作为它的参数。 Fill方法使用DataReader对象来隐式地返回用于在DataSet中创建表的列名称和类型以及用于填充DataSet中的表行的数据。表和列仅在不存在时才创建;否则,Fill将使用现有的DataSet架构。 以下代码示例使用SqlDataAdapter对象获取Microsoft SQL Server Northwind数据库的数据填充到Customers数据集中的Customers表。 实现代码如下所示: /使用DataAdapter的Fill方法向Customers表中填充数据 string connectionString = “Data Source= local;Initial Catalog=Northwind;Integrated Security=True; UserID=sa;Password=”; string commandString = “Select from Customers”; SqlDataAdapter dataAdapter = new SqlDataAdapter(commandString, connectionString); DataSet customers = new DataSet(); dataAdapter.Fill(customers, “Customers”); 10 在DataTable实现类似sql语句的查询功能 在脱离数据库的DataSet实现类似sql语句的查询。 也就是(select … from tablename where …)这样的功能。 将从DataSet中查询出来的数据以行的形式保存到arow中。 实现代码如下所示: DataSet ds= new DataSet(); DataRow[] arow = ds.Tables[TableName].Select(“” + ColumnsName+ “=’” + DataValue + “‘“); 代码说明: qTableName:数据集ds中的表名。 qColumnsName:TableName表中的某一列名。 qDataValue:和列名对应参数的值。 功能说明: 上面语句功能相当于sql语句中的查询语句 Select From TableName where ColumnsName= DataValue 11 DataTable中数据记录的统计 在使用数据库时例如SQL-Server、Oracle这些数据库,可以轻松的通过统计和计算函数例如Sum、Aver、Count等统计或计算出相关结果,那么,在已经把数据检索出来的DataTable数据集中能否同样使用呢?在程序中根据需要动态创建的DataTable是没有办法使用sql语句进行查询统计的,例如没有办法使用Select语句来获取查询统计结果。那么在DataTable中怎么来进行统计呢? 本节将介绍一个简单的方法,可以轻松的获得DataTable中的记录统计结果。这个简单的方法就是调用功能强大的DataTable的函数Compute。 函数如下: public object Compute(string expression,string filter) 参数说明: qexpression 参数需要聚合函数,要计算的表达式字符串,基本上类似于Sql Server中的统计表达式。例如,以下是合法表达式:Count(ID)。 qfilter:统计的过滤字符串,只有满足这个过滤条件的记录才会被统计,也就是确定在表达式中使用哪些行。 以下示例,以SQL-Server数据库中的Northwind数据库中的Orders数据表,描述订单信息,包含字段为:订单号(OrderID)、客户编号(CustomerID)、职工编号(EmployeeID)、订货时间(OrderDate)、船号(ShipVia)、运费(Freight)。 1.统计所有职工编号EmployeeID为5的数量: table.Compute(“Count()”,”EmployeeID=5”); 2.统计所有运费Freight中运费大于100的个数 table.Compute(“Count()”,”Freight>100’”); 3.统计运费Freight的平均值 table.Compute(“Aver(Freight)”,”true”); 4.统计职工编号EmployeeID为5的运费总额: table.Compute(“Sum(Freight)”,” EmployeeID=5”); 以上都是计算每一列的合计,那么要添加一行求合计可以使用下面的方法: /创建一个数据集 DataSet customers = new DataSet(); /在数据集中添加一个名称为CustomersTable的数据表 DataTable customersTable = customers.Tables.Add(“CustomersTable”); /创建一个新行并添加到CustomersTable数据表中 DataRow dataRow = new DataRow(); dataRow= customersTable.NewRow(); /然后就是统计了,声明连个int 变量i:循环变量, colCnt: customersTable表中的列数 int i ; int colCnt ; colCnt = customersTable.Cols.Count; for( i=0 ;i< colCnt -1;i++) /求第i列的和并且结果赋值给新的dataRow数据行 dataRow(i)= customersTable.Compute(“Sum(“+i.ToString()+”)”,”true”); /把数据行添加到customersTable数据表中 customersTable.Rows.Add(dataRow); 12 DataTable和xml的一些应用总结 在ASP.NET2.0中ADO.NET和XML结合的很紧密,第7章中已经详细介绍了在ADO.NET中的数据通过DataSet很容易存取在XML中的,那么在DataTable能像在DataSet中那样操作XML数据文件吗?答案是可以的,下面就是一个将DataTable中的数据写入到XML文件中去的操作,实例代码如下所示: /创建一个Customers数据表 DataTable dt = new DataTable(“Customers”); /添加两列CustID,CustLName数据类型分别为Int32,String,并添加到数据表中 DataColumn dc1 = new DataColumn(“CustID”, Type.GetType(“System.Int32”)); DataColumn dc2 = new DataColumn(“CustLName”, Type.GetType(“System.String”)); dt.Columns.Add(dc1); dt.Columns.Add(dc2); /利用循环创建数据行并赋值,添加到数据表中 for (int i = 0; i < al.Count; i++) { DataRow dr = dt.NewRow(); DS_Option dso = (DS_Option)al[i]; dr[“CustID”] = dso.ID; dr[“CustLName”] = dso.Name; dt.Rows.Add(dr); } /将数据表中的数据写入到XML文件中 string xmlstr; System.IO.StringWriter writer = new System.IO.StringWriter(); dt.WriteXml(writer); xmlstr = writer.ToString(); return xmlstr; 有了向XML文件写数据的操作,当然也可以从XML文件中读取数据信息到DataTable数据表中,方法累也类似,但要先建立好打DataTable的结构,不然会出错。 实例代码如下所示: string tbxml = xmlinfo; DataTable dt = new DataTable(“Customers “); DataColumn dc1 = new DataColumn(“CustID”, Type.GetType(“System.Int32”)); DataColumn dc2 = new DataColumn(“CustLName”, Type.GetType(“System.String”)); dt.Columns.Add(dc1); dt.Columns.Add(dc2); System.IO.StringReader reader = new System.IO.StringReader(tbxml); dt.ReadXml(reader);

IIS服务启动发生意外错误0x8ffe2740的解决方法

Posted on 2011-02-25 | In 未分类

如果系统中存在端口冲突就有可能发生本情况. IIS默认使用80端口进行HTTP通信. 如果除IIS外的应用程序正在运行并且正在相同的IP地址上使用80端口,在您试图使用IIS管理器启动网站时您也可能收到该错误讯息. 解决办法

  1. 直接修改网站的端口,不再绑定80,而切换其他端口,如果这样就不会有问题了,但是如果访问网站的时候就得加上端口号,很麻烦
  2. 使用工具查看谁在占用TCP80端口:一般占用该端口的是网站服务器,比如我装了两个Web服务器,IIS 5.1和Apache+php+Mysql,如果你先启用了默认配置的Apache(你的IIS网站没有启动)那么,你的TCP80端口就会被占用,导致IIS启动时发生0x8ffe2740错误。停止了PHP服务器你的IIS又可以启动了。当然,不光光是网站会占用这个端口的,今天早上我就发现了一个奇怪的事情,我没有启动我的PHP服务器,但是还是发生了这个错误,很奇怪啊,我使用了360安全卫士的常用–>高级工具–>网络连接查看器,看到skype个破东西居然占着我宝贵的80端口,是可忍孰不可忍,马上把它退出了,然后启动我的IIS,OK,成功启动。唉,一无是处的Skype尽给我找麻烦,为了防止下次还被skype占用,可以在skype设置里的高级里的连接选项里,去掉将80端口与443端口作为备用端口的选项。我使用的skype是5.0国际版

9783631469

Posted on 2011-02-25 | In 未分类

有时候我们需要获得连接字符串里的各个参数,比如说服务器,数据库,用户名,密码等等信息 刚开始的时候我没有发现现成的办法去取得这些信息,就是使用的对连接字符串直接分析 方法如下: //conn是连接字符串的Name string cc = ConfigurationManager.ConnectionStrings[“conn”].ToString(); int firstindex = 0; int lastIndex = 0; Sname = SubStr(cc, ref firstindex, ref lastIndex);/服务器名称 SubStr(cc, ref firstindex, ref lastIndex);/数据库名 Uname = SubStr(cc, ref firstindex, ref lastIndex);/用户名 Passwd = SubStr(cc, ref firstindex, ref lastIndex);/密码 //

// 获取”=”和”;”之间的字符串 // // 连接字符串 // “=”的位置 // “;”的位置 private string SubStr(string cc, ref int firstindex, ref int lastIndex) { firstindex = cc.IndexOf(“=”, lastIndex); lastIndex = cc.IndexOf(“;”, firstindex); return cc.Substring(firstindex + 1, lastIndex - firstindex - 1); } 这个方法有个明显的缺陷就是连接字符串的格式被限制死了,如果更换顺序或者中间增加参数就无效了

今天在学习C#3.0的时候发现了微软在.net2.0就增加了的实例成员,可以直接读取,设置字符串的各种参数

需要引用System.Data.SqlClient命名空间,它底下有个类SqlConnectionStringBuilder,通过这个类的实例我们可以创建或者管理连接字符串.

string cc = ConfigurationManager.ConnectionStrings[“conn”].ToString(); SqlConnectionStringBuilder sb=new SqlConnectionStringBuilder(cc); sb.DataSource;/服务器名称 sb.InitialCatalog;/数据库名 sb.UserID;/用户名 sb.Password;/密码

很明显微软自带的方法是很好使的,这个类还有其他成员,请自行查看

js调用C#后台方法

Posted on 2011-02-25 | In 未分类

前台 值得注意的是这个调用的方法不能是private或者internal的. 如果PrintStr()该方法是有返回值的时候需要在page_load里加入Page.DataBind()方法,不然不会成功返回值的 方法需要传参数的话,不知道咋搞了.

二次查询(对结果查询)

Posted on 2011-02-25 | In 未分类

第一次绑定的时候 ViewState[“result”] = dv.ToTable(); 对结果进行查询 DataTable dt = (DataTable)ViewState[“result”]; DataView dv = dt.DefaultView; dv.AllowDelete = true; dv.AllowEdit = true; dv.AllowNew = true; string filter = string.Format(“表名 like ‘%{0}%’”, txtSearch.Text); dv.RowFilter = filter; AspNetPager1.CurrentPageIndex = 0; BindCtrl(dv, gvList, AspNetPager1); ViewState[“result”] = dv.ToTable(); 这个不完善,只是个简单示例

subsonic的group by的使用

Posted on 2011-02-25 | In 未分类

表ChooseAuthorize和membership的User表,联合查询 //

// 取得当前登陆用户收藏授权记录的用户集合 // // public static DataTable GetAuthorizeUserList() { string uid = new ChooseAuthorizeInfo().GetCurrentUserId(); Aggregate AuthorizerId = new Aggregate(ChooseAuthorize.AuthorizerIdColumn, “AuthorizerId”, AggregateFunction.GroupBy); Aggregate RealName = new Aggregate(UserInfo.RealNameColumn, “RealName”, AggregateFunction.GroupBy); Aggregate ReceiverId = new Aggregate(ChooseAuthorize.ReceiverIdColumn, “ReceiverId”, AggregateFunction.GroupBy); DataTable dt = new Select(ChooseAuthorize.Columns.ReceiverId, UserInfo.Columns.RealName).From() .InnerJoin(UserInfo.UserIdColumn, ChooseAuthorize.ReceiverIdColumn) .Where(ChooseAuthorize.Columns.AuthorizerId).IsEqualTo(uid) .ExecuteDataSet().Tables[0]; return dt; }

多表查询取前几列

Posted on 2011-02-25 | In 未分类

环境:有一张Global_CollectInfo_tb来存放有关收藏的记录包括收藏者ID,收藏的记录的主表ID,收藏的记录在具体副表里的ID,收藏记录在主表里的ID,具体的数据记录放在各个副表里. Global_TableDetail_tb里存放有关表的具体信息,包括列名,列类型, USE [cys] GO /** 对象: StoredProcedure [dbo].[getMyCollectList_sp] 脚本日期: 07/15/2010 08:46:24 **/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO – ============================================= – Author: dzd – Create date: 2010-7-14 – Description: 收藏库多表查询 – ============================================= ALTER PROCEDURE [dbo].[getMyCollectList_sp] – Add the parameters for the stored procedure here @UserId nvarchar(50) AS –定义sql语句变量 declare @nsql nvarchar(2000) DECLARE @strOrder varchar(400); – 排序类型 DECLARE @StrGetFields varchar(1000); – 需要返回的列 –定义临时表 create TABLE #t([id] nvarchar(50),[字段1] nvarchar(500),[字段2] nvarchar(500),[字段3] nvarchar(500),[字段4] nvarchar(500),[字段5] nvarchar(500),[来源表] nvarchar(500)) –定义游标 DECLARE tnames_cursor CURSOR FOR SELECT Global_TableDetail_tb.TableName,Global_TableDetail_tb.TableDetailId FROM Global_TableDetail_tb INNER JOIN Global_CollectInfo_tb ON Global_TableDetail_tb.TableDetailId = Global_CollectInfo_tb.CollectTableId WHERE (Global_CollectInfo_tb.CollectorId = @UserId) and Global_TableDetail_tb.IsShow=’true’ group by Global_TableDetail_tb.TableName,Global_TableDetail_tb.TableDetailId –打开游标 OPEN tnames_cursor declare @TableName nvarchar(100),@TableDetailId nvarchar(100) FETCH next from tnames_cursor into @TableName,@TableDetailId while @@fetch_status=0 begin select top 5 @StrGetFields=isnull(@StrGetFields+’,’,’’)+case when ColumnType =’date’ then ‘convert(nvarchar(100), ‘ else ‘’ end + ColumnName+ case when ColumnType =’date’ then ‘,120)’ else ‘’ end from Global_ColumnConfiger_tb where (903) 261-0806 order by ColumnIndex asc SET @nsql = ‘SELECT id,’ +@StrGetFields +’,TableName FROM Global_TableDetail_tb INNER JOIN Global_CollectInfo_tb ON Global_TableDetail_tb.TableDetailId = Global_CollectInfo_tb.CollectTableId INNER JOIN ‘ + @TableName + ‘_副表 ON Global_CollectInfo_tb.CollectRecordId = ‘+ @TableName+’_副表.id WHERE (Global_CollectInfo_tb.CollectorId = ‘‘‘+@UserId+’’’) AND (Global_TableDetail_tb.IsShow = ‘’true’’)’ print(@nsql) insert into #t execute(@nsql) set @StrGetFields = null FETCH next from tnames_cursor into @TableName,@TableDetailId end CLOSE tnames_cursor DEALLOCATE tnames_cursor select * from #t

动态创建gridview的列

Posted on 2011-02-25 | In 未分类

我在开发过程中发现有需要根据数据库传来的表的不同,产生不同的gridview的列,但是,其中根据数据表生成的列是要放到几个模板列之间的.前台代码如下

<asp:GridView ID=”gvList” runat=”server” AutoGenerateColumns=”False” OnRowCommand=”gvList_RowCommand” OnRowCreated=”gvList_RowCreated” OnRowDataBound=”gvList_RowDataBound” DataKeyNames=”id”> asp:TemplateField </asp:TemplateField> <asp:TemplateField HeaderText=”序号”> </asp:TemplateField> <asp:TemplateField HeaderText=”管理”> </asp:TemplateField> </asp:GridView> <webdiyer:AspNetPager ID=”AspNetPager1” runat=”server” ShowBoxThreshold=”10” NumericButtonCount=”8” OnPageChanging=”AspNetPager1_PageChanging” SubmitButtonClass=”saveBtn”> </webdiyer:AspNetPager>
后台代码相当多,可能有人说为什么前台里的模板列里没有控件呢?这个是因为我现在要做的是插入列,使用的是insert,如果是使用了add,那么这个是可以直接在前台完全写好模板列的,也没有下面的这么麻烦了,贴出后台代码,希望有人可以给出更简单的办法. /创建及设置字段 public void setfields() { int recordCount = 0; string tabname = getTabName(); /取得一次分页数据,以用来确定列 string where=”where 1=1”; DataTable dt = ColumnConfigerInfo.GetValueByTableName(AspNetPager1.PageSize,AspNetPager1.CurrentPageIndex,tabname,where,out recordCount); /设置总记录数 AspNetPager1.RecordCount = recordCount; int num = dt.Columns.Count; /循环插入列,并绑定字段 for (int i = 3; i < num; i++) { BoundField cc = new BoundField(); cc.DataField = dt.Columns[i].ColumnName; cc.HeaderText = dt.Columns[i].ColumnName; cc.ItemStyle.Wrap = false; /if(dt.Columns[i].ColumnName.Equals(“外键”)) /{ / /隐藏掉该列 / cc.Visible = false; /} /判断是否是时间类型的列 if (dt.Columns[i].DataType.Name == “DateTime”) { /设置时间格式 cc.DataFormatString = “{0:yyyy-MM-dd}”; cc.HtmlEncode = false; } cc.ReadOnly = true; gvList.Columns.Insert(i-1, cc); } /绑定分页控件,数据源,Gridview,aspnetpager UI.BindCtrl(recordCount, dt.DefaultView, gvList, AspNetPager1); } // // 取得表名 // // private string getTabName() { int tabid = int.Parse(lbltabId.Text); TableDetailInfo tab = new TableDetailInfo(tabid); string tabname = tab.TableName; return tabname; } 看到这里,是不是觉得很简单呢?错了.麻烦的在后面呢.这个使用了列的insert方法后,进行翻页的时候模板列如果本来在前台写了控件的就会消失,这个还不知道原因,网上找了找,据说是微软的bug.所以我追加下面的代码来解决这个问题 /行创建时候添加模板列的控件 protected void gvList_RowCreated(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.Header) { int cc = gvList.Columns.Count; CheckBox cb = new CheckBox(); cb.ID = “ckbAll”; e.Row.Cells[0].Controls.Add(cb); cb.AutoPostBack = true; cb.CheckedChanged += new EventHandler(cb_CheckedChanged); } if (e.Row.RowType == DataControlRowType.DataRow) { int cc=gvList.Columns.Count; CheckBox ckb = new CheckBox(); ckb.ID = “ckbDetail”; e.Row.Cells[0].Controls.Add(ckb); LinkButton lbtn1 = new LinkButton(); lbtn1.Text = “ [收藏] “; lbtn1.CommandName = “collect”; e.Row.Cells[cc - 1].Controls.Add(lbtn1); lbtn1.CommandArgument = e.Row.RowIndex.ToString(); LinkButton lbtn2 = new LinkButton(); lbtn2.CommandName = “attention”; e.Row.Cells[cc - 1].Controls.Add(lbtn2); lbtn2.Text = “ [中标] “; lbtn2.CommandArgument = e.Row.RowIndex.ToString(); LinkButton lbtn3 = new LinkButton(); lbtn3.CommandName = “compare”; e.Row.Cells[cc - 1].Controls.Add(lbtn3); lbtn3.Text = “ [比对] “; lbtn3.CommandArgument = e.Row.RowIndex.ToString(); LinkButton lbtn4 = new LinkButton(); lbtn4.CommandName = “detail”; e.Row.Cells[cc - 1].Controls.Add(lbtn4); lbtn4.Text = “ [查看详细] “; lbtn4.CommandArgument = e.Row.RowIndex.ToString(); } } 其中类似lbtn4.CommandArgument = e.Row.RowIndex.ToString();的代码是绑定行值,以方便后面进行操作 而 if (e.Row.RowType == DataControlRowType.Header) { int cc = gvList.Columns.Count; CheckBox cb = new CheckBox(); cb.ID = “ckbAll”; e.Row.Cells[0].Controls.Add(cb); cb.AutoPostBack = true; cb.CheckedChanged += new EventHandler(cb_CheckedChanged); } 则是为了生成全选按钮,并订阅CheckedChanged事件.以用来激发下面的事件,来全选上所有复选框 protected void cb_CheckedChanged(object sender, EventArgs e) { for (int i = 0; i < gvList.Rows.Count; i++) { CheckBox ckb = (CheckBox)gvList.Rows[i].Cells[0].Controls[0] as CheckBox; CheckBox ckbAll = sender as CheckBox; if (ckbAll.Checked) { ckb.Checked = true; } else { ckb.Checked = false; } } }

2484846928

Posted on 2011-02-25 | In 未分类

USE [cys]/使用的数据库/ GO /** 对象: StoredProcedure [dbo].[CysTablePager_sp] 脚本日期: 07/07/2010 00:42:20 **/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO – ============================================= – Author: peter-pan – Create date: 2009-9-3 – Description: 分页 在sql2005下适用 – Alter: dzd – Alter Date: 2010-7-6 – ============================================= CREATE PROCEDURE [dbo].[CysTablePager_sp] /创建的存储过程名称/ – Add the parameters for the stored procedure here —下面是传进来的分页参数—– @PageSize int = 10, – 页尺寸 @PageIndex int = 1, – 页码 @tbname nvarchar(50),–表名 @TotalCount int output–总记录数 AS BEGIN – SET NOCOUNT ON added to prevent extra result sets from – interfering with SELECT statements. SET NOCOUNT ON; DECLARE @StrGetFields varchar(1000); – 需要返回的列 DECLARE @strSql nvarchar(4000); –主语句 DECLARE @FieldOrder varchar(255); – 排序的字段名 DECLARE @where nvarchar(2000); –where条件 DECLARE @strTmp varchar(110); – 临时变量 DECLARE @strOrder varchar(400); – 排序类型 select @StrGetFields=isnull(@StrGetFields+’,’,’’)+name from syscolumns where id=object_id(@tbname) and colid between 1 and 8 –获取数据表里的前八列 –如果@PageCount为NULL值,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,把总页数传回给存储过程,避免再次计算总页数,对于不想计算总页数的处理而言,可以给@PageCount赋值) IF @TotalCount is null BEGIN IF(@where != ‘ where 1=1’) SET @strSql=N’SELECT @TotalCount=COUNT()’ +N’ FROM ‘+@tbname ELSE SET @strSql=N’SELECT @TotalCount=COUNT()’ +N’ FROM ‘+@tbname EXEC sp_executesql @strSql,N‘@TotalCount int OUTPUT’,@TotalCount output END ————————————————————————–排序规则 SET @strOrder = ‘ ORDER BY id asc’ —————————————————————————-第一页 IF @PageIndex < 1 BEGIN SET @PageIndex = 1 END IF @PageIndex = 1 BEGIN SET @strSql = ‘SELECT TOP ‘+ str(@PageSize)+’ ‘ +@StrGetFields + ‘ FROM ‘ + @tbname + @strOrder END —————————————————————————-其他页 ELSE BEGIN DECLARE @STARTID nvarchar(50) DECLARE @ENDID nvarchar(50) SET @STARTID = convert(nvarchar(50),(@PageIndex - 1) @PageSize + 1) SET @ENDID = convert(nvarchar(50),@PageIndex @PageSize) SET @strSql = ‘WITH MYTABLE AS (SELECT ROW_NUMBER() OVER (‘ + @strOrder + ‘) AS RowNumber,’+ @StrGetFields + ‘ FROM ‘+ @tbname +’) SELECT * FROM MYTABLE WHERE RowNumber BETWEEN ‘ + @STARTID + ‘ AND ‘ + @ENDID –上面的@strSql先创建了一个临时表MYTABLE,这个表包含了@StrGetFields所标识的列,以及RowNumber个数据.最后一个select表示选择上面的结果的从@STARTID 到@ENDID 之间的数据.. END PRINT(@strSql) EXEC(@strSql) END

267-516-1443

Posted on 2011-02-25 | In 未分类

从数据文件向 Microsoft SQL Server 实例大容量导入数据时,请遵循下列原则:

  • 您的用户帐户 使用 bcp、BULK INSERT 或 INSERT…SELECT * FROM OPENROWSET(BULK…) 的用户帐户必须拥有访问表所需的权限(由表所有者分配)。有关每一个用户帐户所需权限的详细信息,请参阅 bcp 实用工具、OPENROWSET (Transact-SQL) 和 BULK INSERT (Transact-SQL)。
  • 对于使用完全恢复模式的数据库:向无索引表中大容量导入数据之前,Microsoft 建议将数据库更改为使用大容量日志恢复模式。系统管理员或数据库所有者可以设置恢复模式。大容量操作以后,请将数据库重置为完全恢复模式。 使用大容量日志恢复有助于防止事务日志耗尽空间(大容量日志恢复不会记录行插入)。
  • 大容量导入数据后进行备份 对于使用简单恢复模式的数据库,建议在大容量导入操作后进行完全或差异备份。对于大容量日志恢复或完全恢复,进行日志备份即可。
  • 表索引 如果要加载的数据与表中已存在的数据相比数量较大,则执行大容量导入操作之前从表中删除索引将显著提高性能。但是,如果要加载的数据与表中已存在的数据相比数量较小,则删除索引将不会提高性能。因为重建索引所需的时间可能要比大容量导入操作期间所节省的时间更长。
  • 数据文件中的隐藏字符 许多实用工具和文本编辑器都可以显示隐藏字符,它们通常位于数据文件的底部。在大容量导入操作过程中,ASCII 数据文件中的隐藏字符可能会产生问题,导致“发现意外的空值”错误。找到并删除所有的隐藏字符可以解决此问题。
1(864) 366-4716

Xyfy

21 posts
1 categories
2 tags
RSS
© 2018 Xyfy  3472640426
Powered by Hexo
|
Theme — 4143865054 v5.1.4