WordPress问题解决: 要执行请求的操作, WordPress需要访问您网页服务器的权限 - 简书

mikel阅读(1501)

来源: WordPress问题解决: 要执行请求的操作, WordPress需要访问您网页服务器的权限 – 简书

WordPress安装插件的时候, 可能会遇到错误:

要执行请求的操作,WordPress需要访问您网页服务器的权限。 请输入您的FTP登录凭据以继续。 如果您忘记了您的登录凭据(如用户名、密码),请联系您的网站托管商。

要执行请求的操作WordPress需要访问您网页服务器的权限

原因: 网站目录权限不够

解决方案: 修改网站目录权限为755, 并且将所有者改为www用户

Xshell运行以下命令:
chmod -R 755 /home/wwwroot/wmsoho.com
chown -R www: /home/wwwroot/wmsoho.com

wmsoho.com域名以及网站目录替换成你自己的.

作者:外贸SOHO笔记
链接:https://www.jianshu.com/p/70a98eb679fe
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

CodeSmith模板代码生成实战详解 - 张龙豪 - 博客园

mikel阅读(1522)

来源: CodeSmith模板代码生成实战详解 – 张龙豪 – 博客园

前言

公司项目是基于soa面向服务的架构思想开发的,项目分解众多子项目是必然的。然而子项目的架子结构种类也过多的话,就会对后期的开发维护产生一锅粥的感觉。为了尽可能的在结构层避免出现这种混乱的现象,我们就做了一个决定,使用一个统一的架子结构,让项目管理变的简单起来。

这样一来,结构中各层就会有很多重复的代码或者重复的逻辑出现,为啦提高开发效率,节约开发时间,我们采用了codesmith根据自定义模板,生成代码功能。让单表的增删改查功能从数据访问层到ui展示层一键批量生成。下面就开始我的codeSmith模板编写历程回顾。

CodeSmith安装下载

官网地址:http://www.codesmithtools.com

下载地址:http://www.codesmithtools.com/downloads

我使用的,带破解注册工具的codesmith链接:http://pan.baidu.com/s/1dDdndsd

傻瓜式安装,不做介绍。只不过你安装完需要很多码。那么烦啦,就用我百度云里面的。带注册软件,安装完之后,不要急于打开codesmith,先去用注册软件注册下。

安装完成,破解成功。

打开codesmith主界面如下。

Note:打开新建Csharp template,然后后缀名为cst的就是模板文件,自己写的模板代码,就在这种后缀格式的文件中。然后光标放在模板文件中,F5即可生成你要代码的文件。

写自己的codesmith模板代码。

1、自定义参数模板

Note:从这里我们能看到参数的声明,与基本语法的使用规则,需带<%%>。熟悉之后,在右下角给参数赋值,然后光标放入模板中,点击f5生成代码,看下,推敲下。

2、遍历数据库中表的模板

 

Note:图片展示的是怎么设置数据库配置

模板代码如下

复制代码
<%--引入c#模板--%>
<%@ CodeTemplate Language="C#" TargetLanguage="C#" Debug="False" Description="Create an enum of tables." %>
<%--声明数据库的参数,在左下角的Database属性中,选择要操作的数据库名称--%>
<%@ Property Category="Database" Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" Optional="False" Description="Database the table enums will come from." %>
<%--引入下面的类库,操作数据库必备的。不要纠结加入就行啦。--%>
<%@ Assembly Name="SchemaExplorer" %>
<%@ Import Namespace="SchemaExplorer" %>
<%--SourceDatabase, 是你选择数据库的属性类,涵盖数据库的名称,创建时间,字符串链接,描述等等,自己可以点点看 --%>
public enum <%=SourceDatabase.Name %>Tables
{
<%-- 遍历数据库中的表集合 --%>
<% for(int x = 0; x < SourceDatabase.Tables.Count; x++) 
{ 
    TableSchema table = SourceDatabase.Tables[x];
    if (x < SourceDatabase.Tables.Count -1)
        //输出表名,这里是c#的注释,不会被写进生成的代码中。\t为换行符。
        Response.WriteLine("\t{0},", table.Name);
    else
        Response.WriteLine("\t{0}", table.Name);
}
%>    
}
复制代码

3、遍历数据库表中的字段,声明并使用自定义函数

复制代码
<%@ CodeTemplate Language="C#" TargetLanguage="C#" Debug="False" Description="Create a list of properties from database table." %>
<%--声明数据库表的参数,在左下角的表属性中,选择要操作的数据库表--%>
<%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Category="Context" Description="Table that the object is based on." %>
<%--引入system类型转为c#的数据类型的映射字典 --%>
<%@ Map Name="CSharpAlias" Src="System-CSharpAlias" Description="System to C# Type Map" %>
<%--引入下面的类库,操作数据库必备的。--%>
<%@ Assembly Name="SchemaExplorer" %>
<%@ Import Namespace="SchemaExplorer" %>
<%--遍历数据库表的字段属性--%>
<% foreach (ColumnSchema column in this.SourceTable.Columns) {  %>
<%--拼接字符串,输出c#中实体的属性--%>
public <%= ControlType(CSharpAlias[column.SystemType.FullName]) %> <%= StringUtil.ToPascalCase(column.Name) %>{ get; set; }

<% } %>
<script runat="template">
 //如果类型为int,或datetime类型输出可空类型
 public string ControlType(object val)
 {
     var ty=val.ToString();
     if(ty=="int")
     {
         return "int?";
     }
     if(ty=="System.DateTime")
     {
         return "System.DateTime?";
     }
     return ty;
 }
</script>
复制代码

4、批量生成文件,并指定生成文件位置

代码如下

复制代码
<%@ Template Language="C#" TargetLanguage="Text" %>
<%-- 注册要生成的模板 --%>
<%@ Register Name="TableEnumTemplate" Template="TableEnum.cst" MergeProperties="Flase" ExcludeProperties=""%>
<%@ Register Name="TableClumTemplate" Template="TableProperties.cst" MergeProperties="Flase" ExcludeProperties=""%>

<%--声明数据库的参数,在左下角的Database属性中,选择要操作的数据库名称--%>
<%@ Property Category="Database" Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" Optional="False" Description="Database the table enums will come from." %>
<%--Type数据类型为TableSchema,表明参数Table是一个表对象。--%>
<%@ Property Name="SourceTable" Type="TableSchema" DeepLoad="True" Optional="False" Category="Table" Description="Table Name"%>
<%-- 执行输出文件的函数 --%>
<% this.OutPutFile(); %>
<script runat="template">
    //输出文件
    private void OutPutFile()
    {
        //生成列举表名的模板
        CodeTemplate table =new TableEnumTemplate();
        //指定输出路径
        string tableFilePath = OutputDirectory +"\\"+ this.SourceDatabase.Name +".cs";
        //给子模板参数赋值
        table.SetProperty("SourceDatabase",this.SourceDatabase);
        table.RenderToFile(tableFilePath,true);
        
        //生成列表表字段的模板
        CodeTemplate cloumn =new TableClumTemplate();
        //指定输出路径
        string cloumnFilePath = OutputDirectory +"\\"+ this.SourceTable.Name +".cs";
         //给子模板参数赋值
        cloumn.SetProperty("SourceTable",this.SourceTable);
        cloumn.RenderToFile(cloumnFilePath,true);
    }
    //解决方案输出路径
    private string Directory = String.Empty;
    [Editor(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))] 
    [Optional, NotChecked]
    [DefaultValue("")]
    public string OutputDirectory 
    { 
        get
        {
            return Directory;
        }
        set
        {
            if (value.EndsWith("\\")) value = value.Substring(0, value.Length -1);
            Directory = value;
        } 
    }
</script>
复制代码

数据库表生成md文档模板

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%--目标语言C#--%>
<%@ CodeTemplate Inherits="CodeTemplate" Language="C#" TargetLanguage="Text" Description="" Debug="True" ResponseEncoding="UTF-8"%>
<%--Type数据类型为TableSchema,表明参数Table是一个表对象。--%>
<%@ Property Name="Table" Type="TableSchema" DeepLoad="True" Optional="False" Category="Table" Description="Table Name"%>
<%--引入数据库操作组件--%>
<%@ Assembly Name="SchemaExplorer"%>
<%@ Import Namespace="SchemaExplorer"%>
### <%=Table.FullName %>表描述
|字段名|数据类型|是否可空|数据库类型|长度|描述|
|--|--|--|--|--|--|
<%for(int i=0;i<Table.Columns.Count;i++){%>
|<%=Table.Columns[i].Name.ToString()%>|<%=Table.Columns[i].SystemType.ToString()%>|<%=Table.Columns[i].AllowDBNull?"Yes":"No" %> |<%=Table.Columns[i].NativeType.ToString() %>|<%=Table.Columns[i].Size %>|<%=Table.Columns[i].Description.ToString()%>|
<%}%>       

 

 

 

好啦,就这么多啦,能满足我的需求啦。

小结

如果你在看到本文后有什么疑问,请加入博客左上角群,一起交流学习。

(1条消息)CodeSmith激活教程【适用任意版本】 - 【大BUG】的博客

mikel阅读(1023)

来源: (1条消息)CodeSmith激活教程【适用任意版本】 – 【大BUG】的博客

非原创,我在百度贴吧看到的破解教程  原文地址http://tieba.baidu.com/p/3373160396?traceid=

仅供学习使用,请支持正版

第一步:下载好安装包,记住版本号

 

第二步:安装好codesmith

第三步:下载好注册机(也就是破解工具)点击下载破解工具  解压密码 502

第四步:启动注册机(注意修改对应版本,codesmith是7.0改为CS70P-       8.0则是CS80P-  )

第五步:修改好版本号后点击“Generate”按钮生成假注册码

第六步:复制假的注册码

第七步:启动你的codesmith,并且点击注册按钮

第八步:粘贴之前注册机复制的假注册码

第九步:点注册按钮

第十步:开始注册

第十一步:这里不要关闭(这个验证码一会儿有用)

第十二步:开始真正的注册(点击按钮)

第十三步:同样的该版本号,要选时间(大于当前时间即可),然后输入第十一步的验证码(手动输入,要确认正确),填写好后即可点击“Generate”按钮,生成注册码

第十四步:输入注册码,完成

 

 

 

————————————————
版权声明:本文为CSDN博主「聚繁大BUG」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_31384551/article/details/80238656

解决 EF where(func) 查询的一个性能问题 - 未煮熟的虾 - 博客园

mikel阅读(816)

来源: 解决 EF where(func) 查询的一个性能问题 – 未煮熟的虾 – 博客园

前两年帮朋友 做了个网吧管理软件,采用动软的三层架构 SQL语句生成的。最近因功能变更 要改动,而我这段正在做ASP.NET mvc +ef+autofac的一个电商网站。索性 就把原来的底层全重新了套用了我现在的架构 EF6.0+autofac+三层架构,上层的ASP.NET没有变。改完后发现交班页面打开巨慢。

跟踪EF生成的SQL语句   发现生成的sql 有问题,查找的全表,而全表有近10万条的数据。

继续跟踪数据库的耗时查询 发现确实是这条语句占时间

为什么会这样呢,我在查询里做条件搜索了,为啥 结果不对呢?

贴出 BaseRepository.cs 的代码

 View Code

调用代码

return jiaobanitem.LoadEntities(t => t.JiaoBanID == jiaobanID && t.GoodsID == GoodsID).FirstOrDefault();

参考 nopCommerce  修改baserepository

 View Code

同时修改调用代码 为

return jiaobanitem.Table.Where(t=>t.JiaoBanID ==jiaobanID && t.GoodsID ==GoodsID).FirstOrDefault();

问题解决 页面响应不到100ms   同时调试中 生成的sql语句已经有 查询条件了

问题出在

//查询
public IQueryable<T> LoadEntities(Func<T, bool> wherelambda)
{
return db.Set<T>().Where<T>(wherelambda).AsQueryable();
}

为了验证,我在前台直接调用

return this.context.Set<tb_e_jiaoBanItem>().Where(t => t.JiaoBanID == jiaobanID && t.GoodsID == GoodsID).AsQueryable().FirstOrDefault();

页面响应也是 100ms左右,性能没问题。直接调用 dbcontext的set<>方法 没问题。但跨了几层传递后 就有问题。并没有生成我想要的查询语句。

 

这个问题原来别人也碰到过  http://www.cnblogs.com/yjmyzz/archive/2008/09/06/1285564.html

如果传入Where的参数为Expression,则L2S会自动帮忙处理Expression的拼接;而如果传入的是Func,而L2S无法拼接Expression与Func,所以只好先把数据全部取出来,然后再应用Func来进行数据过滤。

代码应该修改为:

public virtual IEnumerable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T,bool>> wherelambda)
{
return this.Table.Where<T>(wherelambda);
}

linq to sql中慎用Where(Func predicate),小心被Linq给"骗"了! - 菩提树下的杨过 - 博客园

mikel阅读(1024)

来源: linq to sql中慎用Where(Func predicate),小心被Linq给”骗”了! – 菩提树下的杨过 – 博客园

近日在一个大型Web项目中,采用Linq to SQL替换原来的SQLcommand/SQLdatareader方式来获取数据,上线后刚开始一切正常,但是随着访问量的增加,网站明显慢了很多,监测服务器CPU占用率/内存使用情况等性能指标却发现均在正常范围内,无意中在SQLServer Profier中跟踪数据库执行的sql语句时,发现有大量语句直接将整个表的数据全部提取出来了,而非仅返回分页中的当前页数据!

而这些SQL都是Linq自动翻译并最终提交到数据库的,查看了相关的代码,明明写着Skip(n).Take(m)类似的语句,为何还会生成这么“傻”的sql呢?

于是写了以下测试代码[测试环境:vs.net2008 + sqlsever2005 + win2003],最终发现是Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);使用后,导致这个问题的产生

1.测试表T_Test:

复制代码

CREATE TABLE [dbo].[T_Test](
    [F_ID] [int] IDENTITY(1,1) NOT NULL,
    [F_Name] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
    [F_Age] [int] NULL,
 CONSTRAINT [PK_T_Test] PRIMARY KEY CLUSTERED
(
    [F_ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

复制代码

 

录入了几条测试数据:
F_ID F_Name F_Age
15 Jimmy 20
16 Mary 14
17 Jack 30
18 张三 35
19 李四 24

2.新建一个”控制台应用程序”,把T_Test拖到dbml中,Program.cs文件中输入如下代码:

复制代码

1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Linq.Expressions;
5using CNTVS.LINQ;
6
7namespace TestLinq
8{
9    class Program
10    {
11        static void Main(string[] args)
12        {
13
14            //Expression<Func<T_Test, bool>> _Expression = PredicateBuilder.True<T_Test>();
15            //_Expression = _Expression.And(t => t.F_Age >= 20).And(t => t.F_Name.Contains(“J”));
16            //var Data = GetData(_Expression, 1, 1);
17
18            var Data = GetData(1, 1);
19
20            ShowData(Data);
21
22
23        }

24
25        /// <summary>
26        /// 用Where<T>(Expression)方式获取数据
27        /// </summary>
28        /// <param name=”ExpWhere”></param>
29        /// <param name=”PageSize”></param>
30        /// <param name=”CurrentPageIndex”></param>
31        /// <returns></returns>

32        static List<T_Test> GetData(Expression<Func<T_Test,bool>> ExpWhere,int PageSize,int CurrentPageIndex)
33        {
34            List<T_Test> _Result = null;
35            using (DBDataContext db = new DBDataContext())
36            {
37                try
38                {
39                    var query = db.T_Test.Where<T_Test>(ExpWhere.Compile()).Skip((CurrentPageIndex – 1) * PageSize).Take(PageSize);
40                    _Result = query.ToList();
41                }

42                finally { db.Connection.Close(); }
43            }

44            return _Result;
45        }

46
47
48        /// <summary>
49        /// 用Where(Lambda)方式获取数据
50        /// </summary>
51        /// <param name=”PageSize”></param>
52        /// <param name=”CurrentPageIndex”></param>
53        /// <returns></returns>

54        static List<T_Test> GetData(int PageSize, int CurrentPageIndex)
55        {
56            List<T_Test> _Result = null;
57            using (DBDataContext db = new DBDataContext())
58            {
59                try
60                {
61                    var query = db.T_Test.Where(t => t.F_Age >= 20 && t.F_Name.Contains(“J”)).Skip((CurrentPageIndex – 1) * PageSize).Take(PageSize);
62                    _Result = query.ToList();
63                }

64                finally { db.Connection.Close(); }
65            }

66            return _Result;
67        }

68
69
70        /// <summary>
71        /// 显示数据
72        /// </summary>
73        /// <param name=”Data”></param>

74        static void ShowData(List<T_Test> Data)
75        {
76            foreach (var item in Data)
77            {
78                Console.WriteLine(“Name:{0}\t,Age:{1}”, item.F_Name, item.F_Age.ToString());
79            }

80            Console.ReadKey();
81        }

82    }

83}

复制代码

 

代码很简单,找出F_Name中包含字母”J”,F_Age大于20的记录,并且跳过第一个后,仅获取一条记录

注:PredicateBuilder是一个老外写的用于动态构造Expression表达式的工具类,在查询条件不确定,需要动态创建时,非常有用,完整代码如下:

 


1using System;
2using System.Linq;
3using System.Linq.Expressions;
4
5namespace CNTVS.LINQ
6{
7
8    public static class PredicateBuilder
9    {
10      public static Expression<Func<T, bool>> True<T> ()
11      {
12          return f => true;
13      }

14
15      public static Expression<Func<T, bool>> False<T> ()
16      {
17          return f => false;
18      }

19
20      public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
21                                                          Expression<Func<T, bool>> expr2)
22      {
23        var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
24        return Expression.Lambda<Func<T, bool>>
25              (Expression.Or (expr1.Body, invokedExpr), expr1.Parameters);
26      }

27
28      public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
29                                                           Expression<Func<T, bool>> expr2)
30      {
31        var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
32        return Expression.Lambda<Func<T, bool>>
33              (Expression.And (expr1.Body, invokedExpr), expr1.Parameters);
34      }

35    }

36}

 

以下是输出结果:

Name:Jimmy      ,Age:20

用Sql Server Profiler跟踪提交到数据库的语句为:

复制代码

exec sp_executesql N’SELECT [t1].[F_ID], [t1].[F_Name], [t1].[F_Age]
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY [t0].[F_ID], [t0].[F_Name], [t0].[F_Age]) AS [ROW_NUMBER], [t0].[F_ID], [t0].[F_Name], [t0].[F_Age]
    FROM [dbo].[T_Test] AS [t0]
    WHERE ([t0].[F_Age] >= @p0) AND ([t0].[F_Name] LIKE @p1)
    ) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p2 + 1 AND @p2 + @p3
ORDER BY [t1].[ROW_NUMBER]’,N’@p0 int,@p1 nvarchar(3),@p2 int,@p3 int’,@p0=20,@p1=N’%J%’,@p2=1,@p3=1

复制代码

 

一切都很完美,跟我们想象的一样仅取了一条记录

3.但是,我们稍微把代码改一下:

把Main方法中的前三行注释去掉,同时把var Data = GetData(1, 1);注释掉,即

 

复制代码

1static void Main(string[] args)
2        {
3            Expression<Func<T_Test, bool>> _Expression = PredicateBuilder.True<T_Test>();
4            _Expression = _Expression.And(t => t.F_Age >= 20).And(t => t.F_Name.Contains(“J”));
5            var Data = GetData(_Expression, 1, 1);
6
7            //var Data = GetData(1, 2);
8
9            ShowData(Data);
10        }

复制代码

修改的用意在换一种方法(即Where<T>(Expression))取数据,运行后输出结果跟上一种方式完全相同,而且这种方式可以在调用方法前动态创建需要的查询条件表达式,用法更灵活,但是我跟踪到的sql语句却是:

SELECT [t0].[F_ID], [t0].[F_Name], [t0].[F_Age]
FROM [dbo].[T_Test] AS [t0]

 

即采用Where<T>(Expression)方式取数据时,居然先把所有数据取回来,再利用Expression来进行结果筛选以及Skip/Take操作,真是令人大跌眼镜!(或许仅仅是我水平有限,理解不了而已),这样的方式,在单表数据量很大时,性能当然极低。

恳请园子里的哪位linq达人,能解释一二?

知道了最终结果,处理方法自然也就明朗了,当时为了快速解决问题,只能把这类操作回归到最原始的SqlCommand/SqlDataReader方式读取,也许有更好的办法,欢迎大家指点。

SQL Server附加数据库出现错误5123的正确解决方法 - 岁月已走远 - 博客园

mikel阅读(1388)

来源: SQL Server附加数据库出现错误5123的正确解决方法 – 岁月已走远 – 博客园

因为自己有一本基于SQL Server 2005的数据库教程,里边使用的示例数据库是AdventureWorks for SQL Server 2005,而我的机子上装的是SQL Server 2008,示例数据库是AdventureWorks for SQL Server 2008。起初我以为示例数据库AdventureWorks for SQL Server 2005 与AdventureWorks for SQL Server 2008 数据库结构应该差不多,可是在练习的过程中,我发现两个数据库中很多表的结构还是有很多不一样的地方。于是决定到微软下载中心将示例数据库AdventureWorks for SQL Server 2005下过来,附加到SQL Server 2008上,以便顺利进行练习。我以SQL Server 2008的超级管理员账户“sa”连接登录到实例SQLServer2008:

在附加示例数据库AdventureWorks for SQL Server 2005时,弹出了下图这个错误:

    仔细看了一下主要信息“尝试打开或创建物理文件……时,CREATE FILE遇到操作系统错误 5(拒绝访问。)”  ,一看就知道应当是对要附加的数据文件的操作权限不够。     按一般的思维习惯,我们会对操作权限不够的文件授予足够的操作权限。比如,有网友说“给要附加的数据文件和相应的日志文件授予Everyone的权限”,授权过程如下三张截图所示(注意数据文件和日志文件都必须授权):

(图1:授权数据文件)
(图2:数据文件授权后)
(图3:日志文件授权后)
    对要附加的数据文件和日志文件分别授予Everyone【读取和执行】、【读取】的权限后,在SQL Server 2008中重新尝试附加数据库,发现可以附加成功了! 是不是问题就这样解决了呢?这样子做对吗?     如果在真实的数据库管理过程中,我们把数据文件、日志文件的权限放大到Everyone,那肯定是不对的做法。因为这样数据库的安全性将大打折扣,虽然对Everyone只授予了【读取和执行】、【读取】的权限,但这仍然有泄漏数据的危险。
     我们应当保证能正常访问的情况下,使数据文件具有最小的访问权。我们之前授权给Everyone,那所有用户或账户都能操作相应的文件了,这肯定不安全的。那么如何才能授予最小的访问权限呢?思考一下,我们用SQL Server 2008去附加相应的数据文件,报出“拒绝访问”即权限不够的错误,换句话说,当前SQL Server 2008没有权限访问这些文件。我们右键文件,到文件属性中查看一下文件的权限情况,如下图所示:

(相应数据文件原本的权限情况)
     我们发现只有SYSTEM和xrm这两个组或用户才有权操作此数据文件。SYSTEM是一个用户组,即【本地系统】组,而xrm是一个管理员用户,如图示:

 
(xrm用户的信息)
    SYSTEM用户组和xrm这个管理员用户都有权限操作此数据文件和日志文件,而以SQL Server 2008的超级管理员SA连接登录实例后,SQL Server却没有权限访问此数据文件。换句话说,以SQL Server 2008的超级管理员SA连接登录实例后,登录的身份不在SYSTEM用户组,也不是xrm这个管理员。那会是什么呢?
         我们查看一下当前SQL Server 2008的实例服务的相关信息就知道了,打开Sql Server Configuration Manager (即SQL Server 配置管理器)查看一下当前连接到的实例服务的相关信息,如下图所示:

(当前实例服务的相关信息)
    发现当前实例SQLServer2008的登录身份为“NT AUTHORITY\LocalService”,即操作系统授权的【本地服务】,本地服务也是了个用户组。换句话说,如果我们仅授予【本地服务】这个用户组的权限(而不是Everyone),应该也可以在SQL Server 2008中用sa的账户附加数据库了。为此,将刚刚授予相应数据文件和日志文件Everyone的权限都删除,再授予LocalService用户组相应数据文件和日志文件的权限,重新尝试附加相应的数据库,发现的确可以附加成功!不必说,授予操作系统授权的【本地服务】用户组比起授予Everyone来说肯定要安全的多。
    上面提到的方法中,我们都是改变了数据文件原来的权限范围(原来的权限范围只有SYSTEM即【本地系统】用户组和xrm这个系统管理员) 。而更好的办法是不要改变数据文件的权限范围,仍然以SA身份连接登录SQL Server 2008的实例也能访问相应的数据文件。而要达到这个目的,我们只需要将相应实例的登录身份改为SYSTEM【本地系统】用户组,SYSTEM也是在相应数据文件的权限范围之内的用户组,而且SQL Server实例以本地系统身份运行,安全性将更高。我们可以在SQL Server 配置管理器中将相应的SQL Server实例的登录身份修改为【本地系统】即Local System,如下列图所示:

(修改实例的登录身份)
   
(实例的登录身份变为LocalSystem)
    然后重启相应实例服务,重新以SA身份连接登录SQL Server 2008的相应实例并尝试附加数据库, 同样可以成功的将数据库附加上!!!

其实,如果不是要特别地以SA身份连接登录SQL Server 2008的相应实例来附加相应数据库,那么在连接登录SQL Server 2008的相应实例时,身份验证选择【Windows 身份验证】,不做前文中所述的其他修改就可以把数据库附加上去了,原因就在于:【Windows 身份验证】用的是当前操作系统的用户的权限,权限一般都足够大的。另外,在【SQL Server 配置管理器】中针对实例服务可以做的操作,在Windows的【服务】上也可以做到。

table 编辑时更新合计项 - Fly社区

mikel阅读(1512)

来源: table 编辑时更新合计项 – Fly社区

layui.use(['table'], function () {
    var table = layui.table;
    partsTable = table.render({
        elem: '#parts',
        toolbar: '#partsToolbar',
        page: true,
        limit: 10,
        height: 'full-250',
        totalRow: true,
        cols: cols,
        done: function (res, curr, count) {

        }
    });
    table.on('edit(parts)', function (obj) {
        obj.update({
            peij_sl: response.data.peij_sl + obj.data.peij_dw,
        });
        tabTotal(partsTable);
    });
})
/*
* 更新表格合计
* @param {obj} obj  table 对象
*/ 
var tabTotal = function (obj) {
    var layui_table = obj.config.elem.next('.layui-table-view');
    var table_data = {};
    var table_total_field = [];
    layui.use(['table'], function () {
        var table = layui.table;
        table_data = table.cache[obj.config.id];
        var table_cols = obj.config.cols[0];
        // 获取合计项
        $.each(table_cols, function (i, v) {
            if (v.totalRow) {
                table_total_field.push(v.field);
            }
        });
    })
    var layui_table_total = layui_table.find('.layui-table-total');
    $.each(table_total_field, function (i, v) {
        // 合计
        var sum = table_data.reduce(function (num1, num2) {
            // 精度处理
            const num1Digits = (num1.toString().split('.')[1] || '').length;
            const new_num2 = num2[v] ? num2[v] : 0;
            const num2Digits = (new_num2.toString().split('.')[1] || '').length;
            const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits));
            return (num1 * baseNum + new_num2 * baseNum) / baseNum;

        }, 0);
        layui_table_total.find('td[data-field=' + v + '] div').text(sum);
    });
}

哈哈 业务需求简单的实现一下下[嘻嘻]

CRL快速开发框架系列教程一(Code First数据表不需再关心) - hubro - 博客园

mikel阅读(846)

来源: CRL快速开发框架系列教程一(Code First数据表不需再关心) – hubro – 博客园

本系列目录

  1. CRL快速开发框架系列教程一(Code First数据表不需再关心)
  2. CRL快速开发框架系列教程二(基于Lambda表达式查询)
  3. CRL快速开发框架系列教程三(更新数据)
  4. CRL快速开发框架系列教程四(删除数据)
  5. CRL快速开发框架系列教程五(使用缓存)
  6. CRL快速开发框架系列教程六(分布式缓存解决方案)
  7. CRL快速开发框架系列教程七(使用事务)
  8. CRL快速开发框架系列教程八(使用CRL.Package)
  9. CRL快速开发框架系列教程九(导入/导出数据)
  10. CRL快速开发框架系列教程十(导出对象结构)
  11. CRL快速开发框架系列教程十一(大数据分库分表解决方案)
  12. CRL快速开发框架系列教程十二(MongoDB支持)
  13. CRL快速开发框架系列教程十三(嵌套查询)

 正文

在面向对象的概念越来越深入的今天,Code First开发模式想必也不再陌生,开发关注点由数据库为主变为以对象结构为主

在开发程序时,以编程的思想去考虑,如何用对象结构表示这一数据结构,至于数据结构的载体是什么数据库,无所谓了

在面得对象的框架中,EF是做得比较好了,特别是Code First模式下,数据表能自动生成,相比一般的形式,建立对象,再按对象生成数据库脚本,好多重复工作

CRL同样采用Code First开发模式,更值得一提的是,数据结构是自动创建的,无论是增加对象,或增加对象的属性(当然没能自动删除)

对象定义

CRL对象需要继承IModel或IModelBase,它们之间的区别:

  • IModel是一个抽象类,不包含任何属性,继承它可以定义自定义类型的主建字段,如GUID类型的主键
  • IModelBase包含int类型主键ID和AddTime字段,继承后满足一般自增主键要求

来看一个简单对象定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[CRL.Attribute.Table(TableName = "TestModel_1")]//定义映射名
public class TestModel : CRL.IModel
{
    [CRL.Attribute.Field(IsPrimaryKey = true)]//定义为主键
    public int Id
    {
        get;
        set;
    }
    [CRL.Attribute.Field(Length = 50)]//定义列长度
    public string Name
    {
        get;
        set;
    }
}

在上面定义中使用了CRL.Attribute.Table和CRL.Attribute.Field属性标注,当要指定对应的数据结限定,使用此标注即可

创建对象管理类

1
2
3
4
5
6
7
8
9
10
public class TestModelManage : CRL.BaseProvider<TestModel>
{
    public static TestModelManage Instance
    {
        get
        {
            return new TestModelManage();
        }
    }
}

调用试试看(重点来了,一般框架肯定会报错,找不到数据表,CRL不会,因为它自动创建了)

1
var data = TestModelManage.Instance.QueryList(b => b.Id > 0);

看数据库里结构

再增加一个属性 Name2,重编译运行上面代码

可以看到增加的属性自动创建了对应的字段

CRL如何做到这点

  • CRL在对象被调用时,会检查一次数据结构,看和对象定义是不是一致,如果有少了就创建表或字段(当然不是直接从数据库里查,那样效率太低了,也耗资源)
  • 对象检查会耗费一些资源,只建议在开发阶段使用,上线后可以通过CRL.SettingConfig.CheckModelTableMaping设置开关

对象数据检查

除数据表结构检查,CRL还可以对数据作检查

上面对象定义了Name长度为50,在插入此数据时,如果数据长度超过了50,会怎么样呢

1
2
3
var data2 = new TestModel();
            data2.Name = "这是一个超过50的字符串这是一个超过50的字符串这是一个超过50的字符串这是一个超过50的字符串这是一个超过50的字符串这是一个超过50的字符串这是一个超过50的字符串这是一个超过50的字符串这是一个超过50的字符串";
            TestModelManage.Instance.Add(data2);

正常会报数据库错误,如SQL会报将截断字符串,也不会告诉你是哪个字段,而CRL会抛出异常

也可以对数据自定义检查

重写TestModel的CheckData方法,这里就可以自由发挥了,如按业务规则,从根本上封堵了错误数据的产生

1
2
3
4
5
6
7
8
public override string CheckData()
        {
            if (Name!="hubro")
            {
                return "输入的值?";
            }
            return base.CheckData();
        }<br>

data2.Name = “ggy”;
TestModelManage.Instance.Add(data2);

运行结果

重复数据提交判断

当在短时间内, 插入相同的数据,CRL默认为重复提交了,重复依据为数据内容MD5值

同时插入两条相同的数据

1
2
3
4
5
6
var data2 = new TestModel();
            data2.Name = "hubro";
            TestModelManage.Instance.Add(data2);
            var data3 = new TestModel();
            data3.Name = "hubro";
            TestModelManage.Instance.Add(data3);

运行如下

若要关闭,重写TestModel方法

1
2
3
4
5
6
7
protected override bool CheckRepeatedInsert
        {
            get
            {
                return false;
            }
        }

CRL Code First开发方式介绍到这里

更详细的例子见CRL开发文档

SQL Server 中WITH (NOLOCK)浅析 - nuptsv_ice的专栏 - CSDN博客

mikel阅读(689)

来源: SQL Server 中WITH (NOLOCK)浅析 – nuptsv_ice的专栏 – CSDN博客

概念介绍

 

开发人员喜欢在SQL脚本中使用WITH(NOLOCK), WITH(NOLOCK)其实是表提示(table_hint)中的一种。它等同于 READUNCOMMITTED 。 具体的功能作用如下所示(摘自MSDN):

1: 指定允许脏读。不发布共享锁来阻止其他事务修改当前事务读取的数据,其他事务设置的排他锁不会阻碍当前事务读取锁定数据。允许脏读可能产生较多的并发操作,但其代价是读取以后会被其他事务回滚的数据修改。这可能会使您的事务出错,向用户显示从未提交过的数据,或者导致用户两次看到记录(或根本看不到记录)。有关脏读、不可重复读和幻读的详细信息,请参阅并发影响

2: READUNCOMMITTED 和 NOLOCK 提示仅适用于数据锁。所有查询(包括那些带有 READUNCOMMITTED 和 NOLOCK 提示的查询)都会在编译和执行过程中获取 Sch-S(架构稳定性)锁。因此,当并发事务持有表的 Sch-M(架构修改)锁时,将阻塞查询。例如,数据定义语言 (DDL) 操作在修改表的架构信息之前获取 Sch-M 锁。所有并发查询(包括那些使用 READUNCOMMITTED 或 NOLOCK 提示运行的查询)都会在尝试获取 Sch-S 锁时被阻塞。相反,持有 Sch-S 锁的查询将阻塞尝试获取 Sch-M 锁的并发事务。有关锁行为的详细信息,请参阅锁兼容性(数据库引擎)

3:  不能为通过插入、更新或删除操作修改过的表指定 READUNCOMMITTED 和 NOLOCK。SQL Server 查询优化器忽略 FROM 子句中应用于 UPDATE 或 DELETE 语句的目标表的 READUNCOMMITTED 和 NOLOCK 提示。

 

功能与缺陷

 

使用WIHT(NOLOCK)有利也有弊,所以在决定使用之前,你一定需要了解清楚WITH(NOLOCK)的功能和缺陷,看其是否适合你的业务需求,不要觉得它能提升性能,稀里糊涂的就使用它。

 

1:使用WITH(NOLOCK)时查询不受其它排他锁阻塞

打开会话窗口1,执行下面脚本,不提交也不回滚事务,模拟事务真在执行过程当中

BEGIN TRAN

       UPDATE TEST SET NAME='Timmy' WHERE OBJECT_ID =1;

       --ROLLBACK

 

打开会话窗口2,执行下面脚本,你会发现执行结果一直查询不出来(其实才两条记录)。当前会话被阻塞了

SELECT * FROM TEST;

打开会话窗口3,执行下面脚本,查看阻塞情况,你会发现在会话2被会话1给阻塞了,会话2的等待类型为LCK_M_S:“当某任务正在等待获取共享锁时出现”



  SELECT wt.blocking_session_id                    AS BlockingSessesionId
        ,sp.program_name                           AS ProgramName
        ,COALESCE(sp.LOGINAME, sp.nt_username)     AS HostName
        ,ec1.client_net_address                    AS ClientIpAddress
        ,db.name                                   AS DatabaseName
        ,wt.wait_type                              AS WaitType
        ,ec1.connect_time                          AS BlockingStartTime
        ,wt.WAIT_DURATION_MS/1000                  AS WaitDuration
        ,ec1.session_id                            AS BlockedSessionId
        ,h1.TEXT                                   AS BlockedSQLText
        ,h2.TEXT                                   AS BlockingSQLText
  FROM sys.dm_tran_locks AS tl
  INNER JOIN sys.databases db
    ON db.database_id = tl.resource_database_id
  INNER JOIN sys.dm_os_waiting_tasks AS wt
    ON tl.lock_owner_address = wt.resource_address
  INNER JOIN sys.dm_exec_connections ec1
    ON ec1.session_id = tl.request_session_id
  INNER JOIN sys.dm_exec_connections ec2
    ON ec2.session_id = wt.blocking_session_id
  LEFT OUTER JOIN master.dbo.sysprocesses sp
    ON SP.spid = wt.blocking_session_id
  CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
  CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2

 

 

clipboard

 

此时查看会话1(会话1的会话ID为53,执行脚本1前,可以用SELECT  @@spid查看会话ID)的锁信息情况,你会发现表TEST(ObjId=1893581784)持有的锁信息如下所示

 

clipboard[1]

 

打开会话窗口4,执行下面脚本.你会发现查询结果很快就出来,会话4并不会被会话1阻塞。

SELECT * FROM TEST WITH(NOLOCK)

从上面模拟的这个小例子可以看出,正是由于加上WITH(NOLOCK)提示后,会话1中事务设置的排他锁不会阻碍当前事务读取锁定数据,所以会话4不会被阻塞,从而提升并发时查询性能。

 

2:WITH(NOLOCK) 不发布共享锁来阻止其他事务修改当前事务读取的数据,这个就不举例子了。

本质上WITH(NOLOCK)是通过减少锁和不受排它锁影响来减少阻塞,从而提高并发时的性能。所谓凡事有利也有弊,WITH(NOLOCK)在提升性能的同时,也会产生脏读现象。

如下所示,表TEST有两条记录,我准备更新OBJECT_ID=1的记录,此时事务既没有提交也没有回滚

clipboard[2]

BEGIN TRAN

UPDATE TEST SET NAME='Timmy' WHERE OBJECT_ID =1;

--ROLLBACK

此时另外一个会话使用WITH(NOLOCK)查到的记录为未提交的记录值

clipboard[3]

假如由于某种原因,该事务回滚了,那么我们读取到的OBJECT_ID=1的记录就是一条脏数据。

脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。

 

WITH(NOLOCK)使用场景

 

什么时候可以使用WITH(NOLOCK)? 什么时候不能使用WITH(NOLOCK),这个要视你系统业务情况,综合考虑性能情况与业务要求来决定是否使用WITH(NOLOCK), 例如涉及到金融或会计成本之类的系统,出现脏读那是要产生严重问题的。关键业务系统也要慎重考虑。大体来说一般有下面一些场景可以使用WITH(NOLOCK)

1: 基础数据表,这些表的数据很少变更。

2:历史数据表,这些表的数据很少变更。

3:业务允许脏读情况出现涉及的表。

4:数据量超大的表,出于性能考虑,而允许脏读。

另外一点就是不要滥用WITH(NOLOCK),我发现有个奇怪现象,很多开发知道WITH(NOLOCK),但是有不了解脏读,习惯性的使用WITH(NOLOCK)。

 

WITH(NOLOCK)与 NOLOCK区别

 

为了搞清楚WITH(NOLOCK)与NOLOCK的区别,我查了大量的资料,我们先看看下面三个SQL语句有啥区别

SELECT * FROM TEST NOLOCK

SELECT * FROM TEST (NOLOCK);

SELECT * FROM TEST WITH(NOLOCK);

上面的问题概括起来也就是说NOLOCK、(NOLOCK)、 WITH(NOLOCK)的区别:

1: NOLOCK这样的写法,其实NOLOCK其实只是别名的作用,而没有任何实质作用。所以不要粗心将(NOLOCK)写成NOLOCK

2:(NOLOCK)与WITH(NOLOCK)其实功能上是一样的。(NOLOCK)只是WITH(NOLOCK)的别名,但是在SQL Server 2008及以后版本中,(NOLOCK)不推荐使用了,”不借助 WITH 关键字指定表提示”的写法已经过时了。 具体参见MSDN http://msdn.microsoft.com/zh-cn/library/ms143729%28SQL.100%29.aspx

2.1  至于网上说WITH(NOLOCK)在SQL SERVER 2000不生效,我验证后发现完全是个谬论。

2.2  在使用链接服务器的SQL当中,(NOLOCK)不会生效,WITH(NOLOCK)才会生效。如下所示

clipboard[4]

消息 4122,级别 16,状态 1,第 1 行

Remote table-valued function calls are not allowed.

 

3.语法上有些许出入,如下所示

这种语法会报错
SELECT  * FROM   sys.indexes  WITH(NOLOCK) AS i
-Msg 156, Level 15, State 1, Line 1
-Incorrect syntax near the keyword 'AS'.

这种语法正常
SELECT  * FROM   sys.indexes  (NOLOCK) AS i

可以全部改写为下面语法

SELECT  * FROM   sys.indexes   i WITH(NOLOCK)


SELECT  * FROM   sys.indexes   i (NOLOCK)

 

WITH(NOLOCK)会不会产生锁

很多人误以为使用了WITH(NOLOCK)后,数据库库不会产生任何锁。实质上,使用了WITH(NOLOCK)后,数据库依然对该表对象生成Sch-S(架构稳定性)锁以及DB类型的共享锁, 如下所示,可以在一个会话中查询一个大表,然后在另外一个会话中查看锁信息(也可以使用SQL Profile查看会话锁信息)

不使用WTIH(NOLOCK)

clipboard[5]

使用WITH(NOLOCK)

clipboard[6]

从上可以看出使用WITH(NOLOCK)后,数据库并不是不生成相关锁。  对比可以发现使用WITH(NOLOCK)后,数据库只会生成DB类型的共享锁、以及TAB类型的架构稳定性锁.

另外,使用WITH(NOLOCK)并不是说就不会被其它会话阻塞,依然可能会产生Schema Change Blocking

会话1:执行下面SQL语句,暂时不提交,模拟事务正在执行

BEGIN TRAN

  ALTER TABLE TEST ADD Grade VARCHAR(10) ;

会话2:执行下面语句,你会发现会话被阻塞,截图如下所示。

SELECT * FROM TEST WITH(NOLOCK)

image

在sqlserver 中with(nolock)详解 - ~雨落忧伤~ - 博客园

mikel阅读(739)

来源: 在sqlserver 中with(nolock)详解 – ~雨落忧伤~ – 博客园

所有Select加 With (NoLock)解决阻塞死锁
在查询语句中使用 NOLOCK 和 READPAST

处理一个数据库死锁的异常时候,其中一个建议就是使用 NOLOCK 或者 READPAST 。有关 NOLOCK 和 READPAST的一些技术知识点:

对于非银行等严格要求事务的行业,搜索记录中出现或者不出现某条记录,都是在可容忍范围内,所以碰到死锁,应该首先考虑,我们业务逻辑是否能容忍出现或者不出现某些记录,而不是寻求对双方都加锁条件下如何解锁的问题。

NOLOCK 和 READPAST 都是处理查询、插入、删除等操作时候,如何应对锁住的数据记录。但是这时候一定要注意NOLOCK 和 READPAST的局限性,确认你的业务逻辑可以容忍这些记录的出现或者不出现:

简单来说:

NOLOCK 可能把没有提交事务的数据也显示出来.

READPAST 会把被锁住的行不显示出来

不使用 NOLOCK 和 READPAST ,在 Select 操作时候则有可能报错误:事务(进程 ID **)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。

下面就来演示这个情况。

为了演示两个事务死锁的情况,我们下面的测试都需要在SQL Server Management Studio中打开两个查询窗口。保证事务不被干扰。

演示一 没有提交的事务,NOLOCK 和 READPAST处理的策略:

查询窗口一请执行如下脚本:

CREATE TABLE t1 (c1 int IDENTITY(1,1), c2 int)
go

BEGIN TRANSACTION
insert t1(c2) values(1)

在查询窗口一执行后,查询窗口二执行如下脚本:

select count(*) from t1 WITH(NOLOCK)
select count(*) from t1 WITH(READPAST)

结果与分析:

查询窗口二依次显示统计结果为: 1、0

查询窗口一的命令没有提交事务,所以 READPAST 不会计算没有提交事务的这一条记录,这一条被锁住了,READPAST 看不到;而NOLOCK则可以看到被锁住的这一条记录。

如果这时候我们在查询窗口二中执行:

select count(*) from t1 就会看到这个执行很久不能执行完毕,因为这个查询遇到了一个死锁。

清除掉这个测试环境,需要在查询窗口一中再执行如下语句:

ROLLBACK TRANSACTION
drop table t1

演示二:对被锁住的记录,NOLOCK 和 READPAST处理的策略

这个演示同样需要两个查询窗口。

请在查询窗口一中执行如下语句:

CREATE TABLE t2 (UserID int , NickName nvarchar(50))
go
insert t2(UserID,NickName) values(1,’郭红俊’)
insert t2(UserID,NickName) values(2,’蝈蝈俊’)
go

BEGIN TRANSACTION
update t2 set NickName = ‘蝈蝈俊.net’ where UserID = 2

请在查询窗口二中执行如下脚本:

select * from t2 WITH(NOLOCK) where UserID = 2
select * from t2 WITH(READPAST) where UserID = 2

结果与分析:

查询窗口二中, NOLOCK 对应的查询结果中我们看到了修改后的记录,READPAST对应的查询结果中我们没有看到任何一条记录。 这种情况下就可能发生脏读