[转载]网站性能指南(二)网站性能测量神器

mikel阅读(1433)

[转载]【网站性能指南】(二)网站性能测量神器 – 技术弟弟 – 博客园.

上一章我讲了很多关于Fiddler的东西。其实有很多检测工具可以使用,如 Fiddler 、chrome、firebug、Network Monitor、IIS 和一些第三方的service。

首先我们还是先继续回顾一下fiddler的功能

【Fiddler】

  •  追踪工具,尤其针对Http
  •  展示完成的request和response
  •  可以保存session存档
    • 在提高我网站性能之前,我先把网站相关信息保存起来。等我优化之后,我可以拿出来做对比。哦,原来我的站点性能提高了这么多!

  •  网页加载耗时时间轴
  •  统计。还是以微软的网站为例:
  • 我们可以很清楚的看到加载了哪些类型的文件,已经文件的大小。

 

 

【Chrome 浏览器】


Chrome 是google 开发的一个非常适合开发人员使用的浏览器。它同样可以测量一个网站的性能,

 现在一个chrome浏览器,并且按F12。你可以看到很多开发人员选项。我们可以看到以下工具:

让我们试试他们都能干吗,功能可能一带而过,因为我们这节只关注性能相关的功能。

element :可以让我们观察当前页面包含哪些html元素。

Resources:引用哪些资源。

network 和timeline:功能类似fiddler。是关于http request 、response和timeline情况

 

profiles:可以收集三种profile。比如JavaScript 占用多少cpu。大家不防自己试试。

 

 

Audits 就更酷了。它可以为你的站点提出优化建议。就像下图。他提供了一些建议。开启gzip压缩,使用浏览器缓存移除没有使用到的css引用等。这个页面就是我写博客时候用的。所以,咱们的院子还可以提高性能:)

【Firebug】

 由于篇幅有限,我这里就不详细介绍了,功能上和chrome差不多。下载一个firefox浏览器之后,安装firebug插件就可以使用了。呼出也是F12(让我想起了小时候的传奇外挂。。)

 配上个图:

 

【Microsoft Network Monitor】

  •  通用的网络追踪工具,适用于多种协议。http、tcp/IP等等。
  •  网络适配器的钩子。
  • 在多个等级去看网络的结构。
  •  对于特定的协议、ip地址等应用不同过滤器。

以下是获得这个免费工具的地址:http://www.microsoft.com/en-us/download/details.aspx?id=4865

看到这的朋友们就下载下来试试吧。

首先创建一个新的Capture-》工具栏里的”New Capture“。然后点击上边绿色三角 start。切换到IE浏览器。访问www.microsoft.com。然后切换回来点击stop。

我们可以发现有很多信息。包含了很多协议。现在我们添加一个过滤器:http。

第一条信息居然是搜狐mail。不要紧,一定是它定期去发送http request获取mail信息了。

我们可以看到location实际访问的***/mail/check。是的,我们想对了。它就是去检查邮件啦。

我在这里只是想抛砖引玉。如果你对Microsoft Network Monitor感兴趣。请参见:http://en.wikipedia.org/wiki/Microsoft_Network_Monitor

 

【IIS 日志文件】

IIS对于性能测量方面能为我们提供2个feature:

  •  所用时间
  •  日志剖析
    • 通用方法查询IIS日志文件、事件日志等
    • 查询语法特别接近SQL语句
    • 记录站点健康信息

所用时间

我们可以通过IIS的日志文件进行我们的性能分析。首先打开IIS->选定站点->logging(日志)

 

点击选择字段。并且勾选上所用时间以及你感兴趣的字段。

点击确定之后,每当有request来到你的IIS服务器。IIS都会为你记录一份详尽的日志。

日志剖析

LogParser 是一个命令行工具,可以通过SQL 语句对日志进行分析统计。可以分析IIS日志,还可以分析系统事件日志,CSV,XML等格式日志

基本的用法如下:

LogParser –i:输入文件的格式 –o:输出格式 “SQL语句”
例如下面的例子是用Log Parser统计访问整个IIS站点次数最多的IP:
logparser.exe -i:IISW3C SELECT TOP 25   cs-uri-stem as Url,   COUNT(*) As Hits  FROM c:\inetpub\logs\LogFiles\W3SVC1\*  GROUP BY cs-uri-stem  ORDER By Hits DESC

如果你对logparser 感兴趣。可以再去读读 这篇文章:http://blogs.msdn.com/b/carlosag/archive/2010/03/25/analyze-your-iis-log-files-favorite-log-parser-queries.aspx

【第三方服务】

Keynote http://www.keynote.com/ ,Gomez(收费的)

  • 提供性能分析服务。
  • 允许我们比较自己和其他站点性能上的差异
  • 提供代理服务
  • 响应时间和每X分钟的有效性。

 

好,感谢大家的阅读。下一章我们会介绍【基础设施性能】。

[转载]ASP.NET开发工具整理第一季

mikel阅读(1145)

[转载]ASP.NET开发工具整理第一季 – rickc2k – 博客园.

1.Microsoft SQL Server Compact:
http://www.microsoft.com/en-us/download/details.aspx?id=17876
简化的本地数据库,标准连接字符串为”Data Source=MyData.sdf;Persist Security Info=False;”。

2.JQuery.template()函数
在新版本JQuery中的模板函数,快速提高重复代码或DOM的生成。

复制代码
// Convert the markup string into a named template
$.template( "summaryTemplate", "<li>${Name}</li>" ); function renderList() { // Render the movies data using the named template: "summaryTemplate"
    $.tmpl( "summaryTemplate", movies ).appendTo( "#moviesList" ); }
复制代码

3.jqPlot客户端图表脚本库
http://www.jqplot.com/images/leftcharts.jpg

4.jQuery.simulate
模拟键盘鼠标事件的测试脚本库
https://github.com/eduardolundgren/jquery-simulate

5.QUnit
客户端JavaScript脚本测试框架
http://docs.jquery.com/Qunit

6.modernizr
浏览器版本及支持功能测试
http://modernizr.com/

7.Backbone.js
提供客户端脚本的model键值绑定及自定义事件功能
http://backbonejs.org/

8.Knockout.js
实现客户端脚本的MVVM模式
http://knockoutjs.com/

9.SproutCore
一个高效的Web框架
http://sproutcore.com/

10.BBQ plugin
在HTML5中实现浏览历史及导航功能
http://benalman.com/projects/jquery-bbq-plugin/

[转载]Download jQuery EasyUI 1.3 - jQuery EasyUI

mikel阅读(1339)

[转载]Download jQuery EasyUI 1.3 – jQuery EasyUI.

Download JQuery EasyUI 1.3

Current Version: 1.3

ChangeLog

Bug
  • combogrid: When set to ‘remote’ query mode, the ‘queryParams’ parameters can’t be sent to server. fixed.
  • combotree: The tree nodes on drop-down panel can not be unchecked while calling ‘clear’ method. fixed.
  • datetimebox: Setting ‘showSeconds’ property to false cannot hide seconds info. fixed.
  • datagrid: Calling ‘mergeCells’ method can’t auto resize the merged cell while header is hidden. fixed.
  • dialog: Set cache to false and load data via ajax, the content cannot be refreshed. fixed.
Improvement
  • The HTML5 ‘data-options’ attribute is available for components to declare all custom options, including properties and events.
  • More detailed documentation is available.
  • panel: Prevent script on panel body from running twice.
  • accordion: Add ‘getPanelIndex’ method.
  • accordion: The tools can be added on panel header.
  • datetimebox: Add ‘timeSeparator’ option that allows users to define the time separator.
  • pagination: Add ‘refresh’ and ‘select’ methods.
  • datagrid: Auto resize the column width to fit the contents when the column width is not defined.
  • datagrid: Double click on the right border of columns to auto resize the columns to the contents in the columns.
  • datagrid: Add ‘autoSizeColumn’ method that allows users to adjust the column width to fit the contents.
  • datagrid: Add ‘getChecked’ method to get all rows where the checkbox has been checked.
  • datagrid: Add ‘selectOnCheck’ and ‘checkOnSelect’ properties and some checking methods to enhance the row selections.
  • datagrid: Add ‘pagePosition’ property to allow users to display pager bar at either top,bottom or both places of the grid.
  • datagrid: The buffer view and virtual scroll view are supported to display large amounts of records without pagination.
  • tabs: Add ‘disableTab’ and ‘enableTab’ methods to allow users to disable or enable a tab panel.

License: GPL License Commercial License

Plugins

draggable
droppable
resizable
panel
tabs
accordion
layout
linkbutton
menubutton
splitbutton
menu
form
combo
combobox
combotree
combogrid
numberbox
validatebox
searchbox
messager
progressbar
spinner
numberspinner
timespinner
window
dialog
datagrid
propertygrid
pagination
tree
treegrid
calendar
datebox
datetimebox
slider
parser

Download this EasyUI package:

[转载]关于SQL删除语句TRUNCATE和DELETE

mikel阅读(881)

[转载]关于SQL删除语句TRUNCATE和DELETE – dessay – 博客园.

truncate操作同没有where条件的delete操作十分相似。
1、无论truncate大表还是小表速度都非常快。delete要产生回滚信息来满足回滚需求,而truncate是不产生的。
2、truncate是DDL语句进行隐式提交,不能进行回滚操作。
3、truncate重新设定表和索引的HWM(高水标记),由于全表扫描和索引快速扫描都要读取所有的数据块知道HWM为止。所以全表扫描的性能不会因为delete而提高,但是经过truncate操作后速度会很快。
4、truncate不触发任何delete触发器
5、不能赋给某个用户truncate其它用户表的权限。如果需要trucate其它用户表的权限必须对该用户赋DROP ANY TABLE权限。
6、当表被truncate后,这个表和索引所占用的空间会恢复到初始大小,而delete操作不会减少表或索引所占用的空间。
7、不能truncate一个带有外键的表,如果要删除首先要取消外键,然后再删除。

TRUNCATE和DELETE有以下几点区别

1、TRUNCATE在各种表上无论是大的还是小的都非常快。如果有ROLLBACK命令DELETE将被撤销,而TRUNCATE则不会被撤销。

2、TRUNCATE是一个DDL语言,向其他所有的DDL语言一样,他将被隐式提交,不能对TRUNCATE使用ROLLBACK命令。

3、TRUNCATE将重新设置高水平线和所有的索引。在对整个表和索引进行完全浏览时,经过TRUNCATE操作后的表比DELETE操作后的表要快得多。

4、TRUNCATE不能触发任何DELETE触发器。

5、不能授予任何人清空他人的表的权限。

6、当表被清空后表和表的索引讲重新设置成初始大小,而delete则不能。

7、不能清空父表。 TRUNCATE TABLE (schema)table_name DROP(REUSE) STORAGE 在默认是 DROP STORAGE 当使用DROP STORAGE时将缩短表和表索引,将表收缩到最小范围,并重新设置NEXT参数。REUSE STORAGE不会缩短表或者调整NEXT参数在特殊情况下使用 REUSE ST

DELETE语句执行删除的过程是每次从表中删除一行,并且同时将该行的的删除操作作为事务记录在日志中保存以便进行进行回滚操作。
TRUNCATE TABLE 则一次性地从表中删除所有的数据页并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。

TRUNCATE 是将你的表初始化。假如现在你的表中有10条数据,现在TRUNCATE TABLE 的话,就会将表还原为你最初刚创建好时的状态。表刚创建好时肯定是没有任何数据。因此数据就都没有了。

DELETE TABLE虽然也将你表中的数据清除,但是在你的事务日志文件(LDF)里,还会有相应的记录。没有彻底删除。并且DELETE TABLE 还可以删除指定列,比如我想删除ID为1的列。就可以写: delete 表名 where id=1

 

简单说:

TRUNCATE 删除数据表的结构

DELETE 删除数据表的数据 结构还在

 

如为字段设置了标识列 identity(1,1)

TRUNCATE 删除数据后 再添加数据 就从1开始自增

DELETE 删除数据后 再添加数据 原来的使用的就不能再用了 也就是不是从1开始了 因为原来的占用了

[转载]jQuery EasyUI MC3的应用实例

mikel阅读(1299)

[转载]jQuery EasyUI MC3的应用实例 – wikstone – 博客园.

之前写过一个WebForm和JQuery EasyUI结合的实例,一个用户管理,主要是帮助大家怎样把WebForm及MVC和EasyUI结合起来做项目。这里只有简单实例及入门方法,下面就主要贴图及附源码供大家下载!

这里依然套用疯狂秀才的界面。代码有借鉴博客园一哥们,并进行了修改。

此部分代码可以参考之前WebForm

列表页面:

添加页面:

主要一个了自带控件没有直接使用客户端控件,随后整理全部使用EasyUI控件,表达你提交此处使用了JQuery form提交

下面附上通用js代码:

View Code

<script type="text/javascript">

    $(function () {
        InitGird();
        InitSearch();
    });

    //初始化表格
    function InitGird() {
        $('#tab_list').datagrid({
            title: '用户列表', //表格标题
            url: '@Url.Action("List","User")', //请求数据的页面
            sortName: 'ID', //排序字段
            idField: 'ID', //标识字段,主键
            iconCls: '', //标题左边的图标
            nowrap: false, //是否换行,True 就会把数据显示在一行里
            striped: true, //True 奇偶行使用不同背景色
            collapsible: false, //可折叠
            sortOrder: 'desc', //排序类型
            remoteSort: true, //定义是否从服务器给数据排序
            fit: true,
            fitColumns: true, //自适应
            frozenColumns: [[//冻结的列,不会随横向滚动轴移动
                    {field: 'cbx', checkbox: true },
                    { title: '账号', field: 'UserName', width: 150, sortable: true },
                    { title: '真实姓名', field: 'RealName', width: 150 }
                ]],
            columns: [[
                    { title: '所属角色', field: 'Role', formatter: function (value, rec, index) { return value == 0 ? '管理员' : '普通用户' }, width: 120 },
                    { title: '是否超级管理员', field: 'IsAdmin', formatter: function (value, rec, index) { return value == 0 ? '否' : '是' }, width: 100 },
                    { title: '邮箱地址', field: 'Email', width: 150 },
                    { title: '操作', field: 'ID', width: 80, formatter: function (value, rec) {
                        return '<a style="color:red" href="javascript:;" onclick="EditData(' + value + ');$(this).parent().click();return false;">修改</a>';
                    }

                    }
                ]],
            toolbar: "#toolbar",
            pagination: true, //是否开启分页
            pageNumber: 1,
            pageSize: 10,
            pageList: [10, 20, 30, 40, 50],
            rownumbers: true //行号
        });

    }

    //初始化搜索框
    function InitSearch() {
        $("#ipt_search").searchbox({
            width: 200,
            iconCls: 'icon-save',
            searcher: function (val, name) {
                $('#tab_list').datagrid('options').queryParams.search_type = name;
                $('#tab_list').datagrid('options').queryParams.search_value = val;
                $('#tab_list').datagrid('reload');
            },
            prompt: '请输入要查询的账号'
        });
    }

    //打开添加窗口
    function AddData() {
        var url_str = '@Url.Action("Create","User")';

        $('#Creat_Dialog').load(url_str, function () {
            $(this).dialog({
                title: '添加用户',
                modal: true,
                loadingMessage: '正在加载...',
                buttons: [{
                    text: '提交',
                    iconCls: 'icon-ok',
                    handler: function () {
                        $('#add_form').submit();
                    }
                }, {
                    text: '取消',
                    iconCls: 'icon-cancel',
                    handler: function () {
                        $('#Creat_Dialog').dialog('close');
                    }
                }

                ]
            });
        }).show();
    }

    //打开编辑窗口
    function EditData(id) {
        if (id != undefined) {
            var url = '@Url.Action("Edit","User")/' + id;

            $('#Edit_Dialog').load(url, function () {
                $(this).dialog({
                    title: '编辑用户',
                    modal: true,
                    loadingMessage: '正在加载...',
                    buttons: [{
                        text: '提交',
                        iconCls: 'icon-ok',
                        handler: function () {
                            $('#edit_form').submit();
                        }
                    }, {
                        text: '取消',
                        iconCls: 'icon-cancel',
                        handler: function () {
                            $('#Edit_Dialog').dialog('close');
                        }
                    }]
                });
            }).show();
        }
    }

    //添加AJAX提交
    function ajaxAdd() {
        $('#add_form').ajaxSubmit({
            url: '@Url.Action("Create","User")',
            beforeSubmit: function () {
              //  console.info($('#add_form').form('validate'));
                if ($('#add_form').form('validate') != true) {
                    return false;
                }
                if ($("#add_form").valid() != true) {
                    return false;
                }
                return true;
            },
            success: function (data) {
                if (data == true) {
                    $('#Creat_Dialog').dialog('close');
                    $('#tab_list').datagrid('reload');
                    $.messager.show({
                        title: '提示',
                        msg: '保存成功',
                        timeout: 2000,
                        showType: 'slide'
                    });
                } else {
                    $.messager.show({
                        title: '提示',
                        msg: '保存失败:' + data,
                        timeout: 0,
                        showType: 'slide'
                    });
                }
            }
        });

        return false;
    }
    //编辑AJAX提交
    function ajaxEdit() {
        $('#edit_form').ajaxSubmit({
            url: '@Url.Action("Edit","User")',
            beforeSubmit: function () {
                if ($('#edit_form').form('validate') != true) {
                    return false;
                }
                if ($("#edit_form").valid() != true) {
                    return false;
                }
                return true;
            },
            success: function (data) {
                if (data == true) {
                    $('#Edit_Dialog').dialog('close');
                    $('#tab_list').datagrid('reload');
                    $.messager.show({
                        title: '提示',
                        msg: '保存成功',
                        timeout: 2000,
                        showType: 'slide'
                    });
                } else {
                    $.messager.show({
                        title: '提示',
                        msg: '保存失败:' + data,
                        timeout: 0,
                        showType: 'slide'
                    });
                }
            }
        });

        return false;
    }

    //删除
    function DelData(id) {
        var selected = "";
        if (id <= 0) {
            $($('#tab_list').datagrid('getSelections')).each(function () {
                selected += this.ID + ",";
            });
            selected = selected.substr(0, selected.length - 1);
            if (selected == "") {
                $.messager.alert('提示', '请选择要删除的数据!', 'info');
                return;
            }
        }
        else {
            selected = id;
        }

        if (id != undefined) {
            $.messager.confirm('确认', '确定删除?', function (r) {
                if (r) {
                    var url = '@Url.Action("Delete","User")/' + selected;
                    $.post(url, function () {

                    }).success(function (data) {
                        var msgstr = "删除成功";
                        if (data != true) {
                            msgstr = "删除失败" + data;
                            $.messager.show({
                                title: '提示',
                                msg: msgstr,
                                timeout: 0,
                                showType: 'slide'
                            });
                        } else {
                            $('#tab_list').datagrid('reload');
                            selected = '';
                            $.messager.show({
                                title: '提示',
                                msg: msgstr,
                                timeout: 3000,
                                showType: 'slide'
                            });
                        }

                        $('#tab_list').datagrid('reload');
                    }).error(function () {
                        $.messager.alert('错误', '删除发生错误');
                    });

                }
            });
        }
    }

</script>

今天简单就到这里吧!QQ群:92257772 希望大家能够共同学习。

下载链接

[转载]jQuery实现表格按列字母或数字排序

mikel阅读(1729)

[转载]jQuery实现表格按列字母或数字排序 – 海之澜 – 博客园.

最近做的一个项目中需要自己写个表格排序的功能,于是就上网收集了一下,主要原理就是JQuery操作表格

JQuery代码如下:

$(function () {
$('#tblGrid').each(function () {
var $table = $(this); //将table存储为一个jquery对象

$('thead td', $table).each(function (column) {
var findSortKey;
if ($(this).is('.sort-alpha')) { //按字母排序
findSortKey = function ($cell) {
return $cell.find('sort-key').text().toUpperCase() + '' + $cell.text().toUpperCase();
};
} else if ($(this).is('.sort-numeric')) { //按数字排序
findSortKey = function ($cell) {
var key = parseFloat($cell.text().replace(/^[^\d.]*/, ''));
return isNaN(key) ? 0 : key;
};
}

if (findSortKey) {
$(this).addClass('clickable').hover(function () { $(this).addClass('hover'); }, function () { $(this).removeClass('hover'); }).click(function () {
//反向排序状态声明
var newDirection = 1;
if ($(this).is('.sorted-asc')) {
newDirection = -1;
}
var rows = $table.find('tbody&gt;tr').get(); //将数据行转换为数组
$.each(rows, function (index, row) {
row.sortKey = findSortKey($(row).children('td').eq(column));
});
rows.sort(function (a, b) {
if (a.sortKey &lt; b.sortKey) return -newDirection; if (a.sortKey &gt; b.sortKey) return newDirection;
return 0;
});
$.each(rows, function (index, row) {
$table.children('tbody').append(row);
row.sortKey = null;
});

$table.find('thead td').removeClass('sorted-asc').removeClass('sorted-desc');
var $sortHead = $table.find('thead td').filter(':nth-child(' + (column + 1) + ')');
//实现反向排序
if (newDirection == 1) {
$sortHead.addClass('sorted-asc');
} else {
$sortHead.addClass('sorted-desc');
}

//移除已排序的列的样式,添加样式到当前列
$table.find('td').removeClass('sorted').filter(':nth-child(' + (column + 1) + ')').addClass('sorted');
$table.trigger('repaginate');
});
}
});
});
});

Html代码如下:


&nbsp;
<table id="tblGrid">
<thead>
<tr>
<td style="width: 10%;">员工工号</td>
<td style="width: 10%;">员工姓名</td>
<td style="width: 15%;">职务名称</td>
<td class="sort-numeric" style="width: 10%;">得分</td>
<td class="sort-alpha" style="width: 10%;">绩效考核等级

(直接主管)</td>
<td style="width: 25%;">事例说明</td>
<td class="sort-alpha" style="width: 10%;">绩效考核等级

(上级主管)</td>
<td style="width: 10%;">绩效考核等级

(部门主管)</td>
</tr>
</thead>
<tbody><!--#RowBegin#-->
<tr>
<td height="28px"></td>
<td>张三</td>
<td>客服支持</td>
<td></td>
<td class="director_1">优秀</td>
<td>李四 直接主管考评信息</td>
<td>待改进</td>
<td><select name="Table:model:RANK:0"> <option value="">-请选择-</option></select>
<select name="Table:model:RANK:0"> <option value="优秀">优秀</option></select>
<select name="Table:model:RANK:0"> <option value="优良">优良</option></select>
<select name="Table:model:RANK:0"> <option value="良好">良好</option></select>
<select name="Table:model:RANK:0"> <option selected="selected" value="待改进">待改进</option></select>
<select name="Table:model:RANK:0"> <option value="不胜任">不胜任</option></select></td>
</tr>
<tr>
<td height="28px"></td>
<td>王五</td>
<td>客服支持</td>
<td></td>
<td class="director_2">优良</td>
<td>事例说明</td>
<td>优良</td>
<td><select name="Table:model:RANK:1"> <option value="">-请选择-</option></select>
<select name="Table:model:RANK:1"> <option value="优秀">优秀</option></select>
<select name="Table:model:RANK:1"> <option selected="selected" value="优良">优良</option></select>
<select name="Table:model:RANK:1"> <option value="良好">良好</option></select>
<select name="Table:model:RANK:1"> <option value="待改进">待改进</option></select>
<select name="Table:model:RANK:1"> <option value="不胜任">不胜任</option></select></td>
</tr>
<tr>
<td height="28px"></td>
<td>周氏</td>
<td>客服支持</td>
<td></td>
<td class="director_3">优秀</td>
<td>直接主管考评信息</td>
<td>优秀</td>
<td><select name="Table:model:RANK:2"> <option value="">-请选择-</option></select>
<select name="Table:model:RANK:2"> <option selected="selected" value="优秀">优秀</option></select>
<select name="Table:model:RANK:2"> <option value="优良">优良</option></select>
<select name="Table:model:RANK:2"> <option value="良好">良好</option></select>
<select name="Table:model:RANK:2"> <option value="待改进">待改进</option></select>
<select name="Table:model:RANK:2"> <option value="不胜任">不胜任</option></select></td>
</tr>
<!--#RowEnd#--></tbody>
</table>

css:


 

利用JQuery的ready事件即可实现排序功能,

页面效果如图:

点击查看源代码SortTable.rar

[转载]LINQ to SQL实战(3) N层架构中使用LINQ联合查询多表结果集的返回

mikel阅读(1014)

[转载]LINQ to SQL实战(3) N层架构中使用LINQ联合查询多表结果集的返回 – C#|DOTNET – yaosansi’s Blog.

转载请标明出处: http://www.yaosansi.com

原文:http://www.yaosansi.com/post/1388.html

首先,我们先来了解一些知识点。

1.匿名类型的传递

       static void Main(string[] args)
        {
            var User = GetAnonymous().Cast(new { UserName = "", LastLoginIp = "" });
            Console.Write(User.UserName);
        }

        static object GetAnonymous()
        {
            var User = new { UserName = "yaosansi", LastLoginIp = "127.0.0.1" };
            return User;
        }

当我们定义一个匿名类型,只能通过object类型传递,传递后编译器将无法获悉匿名类型的实际类型。

这行可以通过Cast扩展方法来进行强制转换。以下是Cast方法的原型。

        public static T Cast<T>(this object o, T t)
        {
            return (T)o;
        }

2.如何生成匿名类型的List?

           var User = GetAnonymous().Cast(new { UserName = "", LastLoginIp = "" });
           var list = new List<???>();
原理和上面一致。
            var User = new { UserName = "yaosansi", LastLoginIp = "127.0.0.1" };
            var list = User.MakeList();
            list.Add(User);
            Console.Write(list[0].UserName);

我们再来看看MakeList()方法:

        public static List<T> MakeList<T>(this T t)
        {
            return new List<T>();
        }

当然,你可能想到上面的方法还不够完美,需要在List中Add一个User,于是有了下面的方法:
        public static List<T> MakeList<T>(this T t,params T[] items)
        {
            return new List<T>(items);
        }
这时调用的时候可以写成:
            var User = new { UserName = "yaosansi", LastLoginIp = "127.0.0.1" };
            var list = User.MakeList(User);
            Console.Write(list[0].UserName);

这回我们切入正题,来了解一下LINQ中是怎样多表查询的。

    var q =
    from p in db.Products
    where p.Supplier.Country == "USA" && p.UnitsInStock == 0
    select p;


以上的查询是两个有关系的表,并且返回的只是一个表的内容,
这种情况下可以在数据层中返回强类型的List。如:

 public List<Products> SelectProducts()
 {
      var q =
      from p in db.Products
      where p.Supplier.Country == "USA" && p.UnitsInStock == 0
      select p;
      return q.ToList<Products>;
 }

如果返回的结果集是两个以上表的时候,那该如何传递呢?

聪明的你一定想到了,如果返回的是单行数据的结果集就可以我们前面提到的
使用 匿名类型的传递 得到我们需要的结果.
 public object SelectProducts()
 {
      var q =
      from p in db.Products
      where p.Supplier.Country == "USA" && p.UnitsInStock == 0
      select new {p.UnitsInStock,p.Supplier.Sid};
      var result = q.Single();
      return result;
 }
但这个前提是业务逻辑层需要知道数据层的匿名类型中的具体类型。
这样分层的意义也就不大了。这并不是我们想要的。
而且返回多行数据的结果集时用 匿名的List类型 的方法经实验也失败了。
这就意味着本文开篇的两种传递匿名类型的方法都行不通。

方法一:
自定义与返回类型相同结构的类,
        public class CustomQuery
        {
            public uint UnitsInStock { get; set; }
            public int Sid { get; set; }
        }
这样在查询结果为多个表的结果集时,就可以解决了。
由于需要知道返回的匿名类型,除了不符合多层以外,还需要额外定义一个类。
但这样确时可以使用强类型返回我们所需要的结果。

方法二:
使用System.Func委托 (参考:Returning var from a method in C# 3.0

数据层:
public IEnumerable<TProjection> GetCustomersWithOrders<TProjection>(Func<Customer, IEnumerable<Order>, TProjection> projection) {
    return from customer in _customers
           let customerOrders = from order in _orders
                                where order.CustomerID = customer.ID
           select projection(customer, customerOrders);
}

业务逻辑层:
var results = GetCustomersWithOrders((customer, orders) =>
 new {
                 Name = customer.Name,
                 OrderCount = orders.Count()
      });

这样返回的结果在业务逻辑层里仍然是真正的匿名类型,可以直接使用了。

方法三:

使用存储过程或视图。

[转载]LINQ to Entities 实现sql 关键字"In"方式总结

mikel阅读(1016)

[转载]LINQ to Entities 实现sql 关键字”In”方式总结 – ejiyuan – 博客园.

在LINQ to Entities中没有办法再像 LINQ to SQL 中一样使用 Contains 的方法来实现SQL “in” 关键字

下面代码在 LINQ to SQL 中可行 在LINQ to Entities却无法运行:

var s = db.Account.Select(c => c.ID);
var ret 
=(from t in db.Profile
where s.Contains(t.ID)
select t).ToList();

 

替代方法1:使用方法Any

var ids=db.Account.Select(c => c.ID);
var ret 
= (from t in db.Profile where ids.Any(c=>c==t.UserID) select t).ToList();

使用方法Any替换法搞了好久都没法实现直接对数组Any,下列代码仍无法执行:

int[] ids = new int[]{10101,10005,10007};
var ret 
= (from t in db.Profile where ids.Any(c=>c==t.UserID) select t).ToList();

于是继续Goolge寻找第二种方法,在MSDN论坛上找一个构造Lambda语句的方法
替代方法2:构造Lambda语句

复制代码

        private static Expression<Func<TElement, bool>> BuildWhereInExpression<TElement, TValue>(Expression<Func<TElement, TValue>> propertySelector, IEnumerable<TValue> values)
{
ParameterExpression p 
= propertySelector.Parameters.Single();
if (!values.Any())
return e => false;

var equals = values.Select(value => (Expression)Expression.Equal(propertySelector.Body, Expression.Constant(value, typeof(TValue))));
var body 
= equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal));

return Expression.Lambda<Func<TElement, bool>>(body, p);
}

复制代码

调用方法:

int[] ids = new int[]{10101,10005,10007};
db.Profile.Where(BuildWhereInExpression
<Profile,int>(v=>v.Id,ids);

该方法可也扩展为:

        public static IQueryable<TElement> WhereIn<TElement, TValue>(this IQueryable<TElement> source, Expression<Func<TElement, TValue>> propertySelector, params TValue[] values)
{
return source.Where(BuildWhereInExpression(propertySelector, values));
}

这样就可以直接使用下列方法调用

string[] ids = new string[]{10101,10005,10007};
db.Profile.WhereNotIn(c 
=> c.Id,ids);

后来又看到网上有这样的解决办法
替代方法3:字符串构造
这个方法比较简单

string[] ids = new string[]{10101,10005,10007};
string csvIds = string.Join(,, ids.Cast<string>().ToArray());
db.Profile.Where(
it.Id in {+csvIds+});

it是什么这里就不用说了吧!

[转载]ASP.NET MVC 3的分部视图

mikel阅读(1785)

[转载]ASP.NET MVC 3的分部视图 – R-King – 博客园.

1、什么是分部视图,我们应该什么时候应该用?

作为一个对ASP.NET MVC 模型很熟悉的开发者,他们自然想创建一个内容和代码都可以重用的组件,在web 窗体,我们可以创建一个web用户控件或web服务器控件。但是在MVC,我们应该用分部视图,在这个概念的角度看,对任何情景的应用情景都应该有用。
在应用程序中,每一页上都显示这个股票行情
在应用程序中,一个日历控件显示在多个页面中
一个登录框
用于在多个页面上的社交网络组件,如Facebook的Like按钮。
虽然ASP.NET MVC 的分部视图,在语法和功能这两个不同的角度,理论上可以理解为用户控件。WEB用户控件在WEB窗体中使用ViewState、PostBacks, and Events 。而在MVC的分部视图,不使用任何上述技术管理状态。正如ASP.NET Web用户控件做的,分部视图,可以挖掘到你的应用程序以及其他应用程序组件之间的数据共享中的模型。
2、分部视图的渲染
ASP.NET MVC3的分部视图周昂,允许开发人员用精确和简洁的Razor syntax语法(或ASPX)创建可重复使用的内容模块。呈现分部视图的语法被作为一个HTML辅助实现。
 Html.Partial辅助呈现分部视图名为“_FeaturedProduct”内联。所有重载方法的第一个参数为@Html.Partial 你期望的视图名称或者分部视图的名字,没有文件扩展名。
例如,一个@Html.Partial辅助假定视图放在 \Views\Shared\ 的文件夹下。其他的 @Html.Partial方法重载允许你在各个视图之间传递ViewData或者 ViewBag对象.
下面的代码演示调用呈现分部视图的特点。
<div> @Html.Partial("_FeaturedProduct") </div>

 

分部视图可以在Layout Page布局页面呈现。
也有一些情况下,你可能要另外一种方式实现,比如直接写入HTTP响应流,而不是局部视图渲染结果。
<div> @Html.RenderPartial("_FeaturedProduct") </div>

使用Html.RenderPartial流图像或其他元素,媒体中心或更快的下载时间是非常重要的。

 

3、创建一个局部视图

不管是主视图还是分部视图都是.cshtml 的文件,其中分部视图的不同之处是在于文件放在:\Views\Shared\ 文件下。通过在解决方案资源管理器上下文菜单中使用“添加新视图”对话框来访问\Views\Shared 文件节点。添加新的视图模板“对话框提供了用于创建您的部分视图,特别注意,包括选项的选择。不要忘记检查“作为一个局部视图”创建或你会结束大量的代码删除。

 

一旦你创建的视图,你可以开始通过简单的编辑文件定制。删除或修改视图的代码捆绑在一起。下面所示的代码(_FeaturedProduct.cshtml)是默认视图模板创建相同的代码,我们可以修改,以显示不同的特色产品:

<div>
<div>
<h2>Our Featured product:

@ViewBag.FeaturedProduct.Name</h2>
</div>
<div>
<h3>Now discounted to $@String.Format("{0:F}", ((decimal)ViewBag.FeaturedProduct.Price)-100)</h3>
</div>
<div>@Html.ActionLink("Featured Product Details", "Details", new { id = ViewBag.FeaturedProduct.ProductId })</div>
<div><img class="featuredProduct" src="@Href(" alt="Featured Product" /></div>
</div>

和强类型一样,强类型分部视图也支持点标记语法和访问模型,ViewBag,ViewData的其他类,并专门设计数据共享。

我们阅读上面的代码,我们应该很明确,分部视图和常规视图的语法没有区别。

重要的是没有相关语法关于如何使用分部视图。然而,考虑分部视图和常规视图之间的一致性,特别是当我们需要在它们之间共享数据。

4、主视图与分部视图的数据共享

应用程序组件之间的数据传递,这是一个普遍的现象,MVC,视图和控制器这些组件也一样。 如前所述,你可以使用ViewBag或ViewData的类进行数据的共享。首先,介绍ViewBag的ViewData几个关键字:

ViewData的是以前发布的版本的;,ViewBag与MVC3一起发布的。

ViewData的可以包含任何类型的数据在一个键—值对格式。即,ViewData[“Message”] = “Welcome”;

ViewBag对象的ViewData对象的包装,并允许开发人员编写他们使用强类型的语法。

ViewBag对象可以通过简单地设置在一个更流畅的语法属性扩展。即· ViewBag.Customer = new Customer(1,”Smith”);

 

如果在一个控制器的代码使用ViewBag,或ViewData的类,这些类将可视图的整个生命周期,而且包括其分部视图。

可取的对象是的ViewBag。由于其更加流畅和动感的语法,还有复杂的对象可以很容易地在组件之间共享。下面的示例演示设置在控制器的ViewBag对象,它会提供所有必要的组件:

ProductModel productModel = new ProductModel(); public ActionResult Index() { ViewBag.FeaturedProduct = new FeaturedProduct(105, "The Most Awesome Bike Ever!", 1000.00M, "bike4.png"); return View(productModel.Products); }

访问视图里面的ViewBag或部分使用语法如下:

@ViewBag.FeaturedProduct.Name

5、总结

部分视图重用HTML和Razor 语法,具有很好的数据共享。

 

6、资料来源

Introducing Razor

Introducing MVC Development w/the Razor View Engine

Razor View Syntax

[转载]对于ajax传递中文乱码问题研究js encodeURI 与request.HtmlEncode的区别

mikel阅读(895)

[转载]对于ajax传递中文乱码问题,研究js encodeURI 与request.HtmlEncode的区别 – akak123 – 博客园.

引入:

今天在研究ajax调用服务器一般处理程序的时候,发现中文乱码的问题。于是着手研究一下js端 和服务器端对html的编码和解码方式。

对于ajax中碰到的问题是: 在url传值中参数包含中文。 传到服务器时无法解析中文导致乱码。后来找了些资料发现js会自动编码。

于是 我这样做:

<script type="text/JavaScript">
        //var data=<%=data %>
    JQuery(document).ready(function ($) {
        $("ul.menu").dropmenu();
        var title = encodeURI('联系我们');
        $.ajax({
            type: "GET",
            url: "http://www.cnblogs.com/Controls/Handler1.ashx?title=" + title + "&value=TopicContent",
            //我们用text格式接收
            dataType: "application/x-www-form-urlencoded; charset=utf-8",
            data: "meth=load",
            success: function (msg) {
                alert(msg);
                //显示后台数据
                $(".contact").html(msg);
            }
        });
 
</script>

然后在服务器端:

其实request.querystring 除了接受不被强制编码的数据外,反之也是可以解析得到中文的。

 

再次基础上我查了些资料希望对同样处于困惑的你又帮助:

 

js对文字进行编码涉及3个函数:escape,encodeURI,encodeURIComponent,相应3个解码函 数:unescape,decodeURI,decodeURIComponent

1、   传递参数时需要使用encodeURIComponent,这样组合的url才不会被#等特殊字符截 断。

例如:<script language=”JavaScript”>document.write(‘<a href=”http://passport.baidu.com/?logout&aid=7& u=’+encodeURIComponent(“http://cang.baidu.com/bruce42″)+'”>退出</a& amp; gt;’);</script>

2、   进行url跳转时可以整体使用encodeURI

例如:Location.href=encodeURI(“http://cang.baidu.com/do/s?word=百度& ct=21”);

3、   js使用数据时可以使用escape

[Huoho.Com编辑]

例如:搜藏中history纪录。

4、   escape对0-255以外的unicode值进行编码时输出%u****格式,其它情况下 escape,encodeURI,encodeURIComponent编码结果相同。
最多使用的应为encodeURIComponent,它是将中文、韩文等特殊字符转换成utf-8格式的url编码,所以如果给后台传递 参数需要使用encodeURIComponent时需要后台解码对utf-8支持(form中的编码方式和当前页面编码方式相同)

escape不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z

encodeURI不编码字符有82个:!,#,$,&,’,(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a- z,A-Z

encodeURIComponent不编码字符有71个:!, ‘,(,),*,-,.,_,~,0-9,a-z,A-Z

JavaScript中URL编码转换,escape() encodeURI() encodeURIComponent
2007年05月12日 星期六 下午 04:48

 

在使用url进行参数传递时,经常会传递一些中文名的参数或URL地址,在后台处理时会发生转换错误。在有些传递页 面使用GB2312,而在接收页面使用UTF8,这样接收到的参数就可能会与原来发生不一致。使用服务器端的urlEncode函数编码的URL,与使用 客户端javascript的encodeURI函数编码的URL,结果就不一样。

escape() 方法:
采用ISO Latin字符集对指定的字符串进行编码。所有的空格符、标点符号、特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符 在字符集表里面的编码的16进制数字)。比如,空格符对应的编码是%20。unescape方法与此相反。不会被此方法编码的字符: @ * / +

encodeURI() 方法:把URI字符串采用UTF-8编码格式转化成escape格式的字符串。不会被此方法编码的字符:! @ # $& * ( ) = : / ; ? + ‘

encodeURIComponent() 方法:把URI字符串采用UTF-8编码格式转化成escape格式的字符串。与encodeURI()相比,这个方法将对更多的字符进行编码,比如 / 等字符。所以如果字符串里面包含了URI的几个部分的话,不能用这个方法来进行编码,否则 / 字符被编码之后URL将显示错误。不会被此方法编码的字符:! * ( )

因此,对于中文字符串来说,如果不希望把字符串编码格式转化成UTF-8格式的(比如原页面和目标页面 的charset是一致的时候),只需要使用escape。如果你的页面是GB2312或者其他的编码,而接受参数的页面是UTF-8编码的,就要采用 encodeURI或者encodeURIComponent。

另外,encodeURI/encodeURIComponent是在javascript1.5之后引进的,escape则在 javascript1.0版本就有。

 

 

escape() 方法

MSDN JScript Reference中如是说:

The escape method returns a string value (in Unicode format) that contains the contents of [the argument]. All spaces, punctuation, accented characters, and any other non-ASCII characters are replaced with %xx encoding, where xx is equivalent to the hexadecimal number representing the character. For example, a space is returned as “%20.”

译:escape方法以Unicode格式返回一个包含传入参数内容的string类型的值。 Escape方法会将传入参数中所有的空格、标点符号、重音字符以及其它任何非ASCII字符替换为%xx的编码形式,其中xx与其所表示的字符的16进 制数表示形式相同。如空格字符的16进制表示形式为0x20,则此时xx应为20,即escape(‘ ’) 返回“%20”。

Mozilla Developer Core Javascript Guide中如是说:

The escape and unescape functions let you encode and decode strings. The escape function returns the hexadecimal encoding of an argument in the ISO Latin character set. The unescape function returns the ASCII string for the specified hexadecimal encoding value.

译:escape和unescape方法能够帮助你编码和解码字符串。escape方法对于ISO Latin字符集中的字符组成的参数,返回其16进制编码。相对应的,unescape方法则能将16进制编码形式的参数转化成为其ASCII码形式。

encodeURI()方法

MSDN JScript Reference中如是说:

The encodeURI method returns an encoded URI. If you pass the result to decodeURI, the original string is returned. The encodeURI method does not encode the following characters: “:”, “/”, “;”, and “?”. Use encodeURIComponent to encode these characters.

译:encodeURI方法返回一个经过编码的URI。如果将encodeURI方法的编码结果传递给decodeURI方法作参数,则能得到原始 的未编码的字符串。需要注意到是encodeURI方法不编码如下字符”:”, “/”, “;”, and “?”。如果想要编码这些字符,请使用encodeURIComponent方法。

Mozilla Developer Core Javascript Guide中如是说:

Encodes a Uniform Resource Identifier (URI) by replacing each instance of certain characters by one, two, or three escape sequences representing the UTF-8 encoding of the character.

译:通过将每个属于特定的字符集合的字符替换为一个、两个或者三个(为什么是“一个、两个或者三个”本人也没有搞懂,望高人赐教)使用UTF-8编 码来表示这个字符的escape序列来编码一个URI。如 ~!@#$%^&*(){}[]=:/,;?+\””\\ 将被替换为 ~!@#$%25%5E&*()%7B%7D%5B%5D=:/,;?+”%22%5C

encodeURIComponent()方法

MSDN JScript Reference中如是说:

The encodeURIComponent method returns an encoded URI. If you pass the result to decodeURIComponent, the original string is returned. Because the encodeURIComponent method encodes all characters, be careful if the string represents a path such as /folder1/folder2/default.html. The slash characters will be encoded and will not be valid if sent as a request to a web server. Use the encodeURI method if the string contains more than a single URI component.

译:encodeURIComponent方法返回一个编码过的URI。如果将encodeURIComponent方法的编码结果传递给 encodeURIComponent方法作参数,则能得到原始的未编码的字符串。因为encodeURIComponent方法会编码所有的字符,所以 如果待编码的字符串是用来表示一个路径(如/dir1/dir2/index.htm)时,就一定要小心使用了。‘/’符号会被其编码之后,将不再是一个 有效的路径标识符,所以不能被web服务器正确地识别。当字符串包含一个单独的URI component(指?后面的请求参数)的时候,请使用此方法。

Mozilla Developer Core Javascript Guide中如是说:

Encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, or three escape sequences representing the UTF-8 encoding of the character.

译:通过将每个属于特定的字符集合的字符替换为一个、两个或者三个(为什么是“一个、两个或者三个”本人也没有搞懂,望高人赐教)使用UTF-8编 码来表示这个字符的escape序列来编码一个URIComponent。

有什么区别?何时使用?
通过上面的介绍可以看出,MS的文档明显要比Mozilla详细、易懂一些,但是它们表达的都是一个意思。但是escape(), encodeURI()和 encodeURIComponent()有什么异同,它们分别适用于那种特定的情况呢?

escape 方 法并不编码字符+。而我们知道,在用户提交的表单字段中,如果有空格,则会被转化为+字符,而服务器解析的时候则会认为+号代表空格。由于这个缺 陷,escape方法并不能正确地处理所有的非ASCII字符,你应当尽量避免使用escape方法,取而代之,你最好选择 encodeURIComponent()方法。
escape()不编码的字符:@*/+

相对于使用escape方法,使用encodeURI方法会显得更专业一些。当你需要编码一整个URI的时候,你可以使用此方法,因为URI中的合 法字符都不会被编码转换。需要注意到是字符’也是URI中的合法字符,所以也不会被编码转换。
encodeURI() 不编码的字符: ~!@#$&*()=:/,;?+”

encodeURIComponent方法在编码单个URIComponent(指请求参数)应当是最常用的。需要注意到是字符’也是URI中的合 法字符,所以也不会被编码转换。
encodeURIComponent()不编码的字符: ~!*()”

 

 

然而对于serve.htmlencode: msdn是这样说的:

HTML 编码确保文本能在浏览器中正确显示,而不是被浏览器解释为 HTML。 例如,如果文本字符串包含小于号 (<) 或大于号 (>),则浏览器会把这些字符解释为 HTML 标记的起始或结束括号。 当字符为 HTML 编码时,它们将转换为字符串 &lt; 和 &gt;,以便浏览器能够正确显示小于号和大于号。

HtmlEncode 方法是一种简便方式,用于在运行时从 ASP.NET 应用程序访问 HttpUtility.HtmlEncode 方法。 HtmlEncode 在内部使用 HttpUtility.HtmlEncode 对字符串进行编码。