Edi Wang

.NET and Azure Developer

SQL

Merge Data for N-N Relationship Tables in T-SQL

最近在整理博客的数据,需要做一个操作就是合并文章的分类。我的博客中文章和分类是多对多的关系。即一篇文章可以属于多个分类,一个分类可以包含多篇文章。这是一个很典型的多对多关系,我用的是一个多对多的表,做联合主键关联这些数据。 就像这样: 我需要做的是把“DotNetBeginner”这个分类的文章移到“CSharpAndDotNet”分类里去。但是因为原先在“DotNetBeginner”里的文章有些也是属于“CSharpAndDotNet”的,所以直接Update关联表的话,会产生重复的联合主键,就会爆。 直观一点看,写个SQL语句查询出原分类(DotNetBeginner)和目标分类(CSharpAndDotNet)中的数据: DECLARE @SourceCatId AS UNIQUEIDENTIFIER, @TargetCatId AS …
SQL SQL Server

Azure SQL数据库如何做定期自动备份

Azure上的数据库可以通过手工export来备份,方法我在博客里写过。但是如果要求定期做的话,需要人工参与。偷懒的做法是用Azure自带的定期备份功能。 1. 在Azure Portal点开你的数据库,切换到CONFIGURE页面。 Automated Export的意思就是自动导出数据库(bacpac格式),默认是NONE,也就是不自动备份。选择AUTOMATIC。 2. 选完之后,下面会出来详细设置。 STORAGE ACCOUNT选你要保存备份文件的存储账户。FREQUENCY是频率,这个例子里我选择每28天备份一次,从2015年4月2日12:00A.M.开始。保留90天内的备份(这个选项的意思就是备份文件多久以后会被自动删除) 另外,还需要填写SQL数据库服务器的登录账户和密码。然后保存设置就完成了! 3. 一旦到了指定时间,触发了备份。你就能在你刚才设置的存储账户里找到一个 …
SQL Azure

Azure SQL数据库Web Tier爆了,如何迁移数据库

今天做了次数据库迁移,目的是开个最新版的Azure SQL Database(V12 Update),然后把博客的数据库迁移到新的server上去。按以往的做法(也就是我曾经写过的《图解:如何将SQL Server数据库迁移到SQL Azure 》),把bacpac文件下载下来,然后import到新的数据里,结果爆了: 爆炸是因为Web Tier和Business Tier在最新版的Azure上面已经被微软撸掉了,SSMS 2014却没有升级,不认识这两个Tier,还在用老的Web Tier。 TITLE: Microsoft SQL Server Management Studio ------------------------------ An exception occurred while executing a Transact-SQL statement or batch. …
SQL SSMS Azure

EntityFramework 6 SqlQuery传递可空类型参数的写法

有时候我们需要在EF里直接执行参数化的SQL语句,如果有返回,就要把结果映射成C#对象集合。貌似是从EF4.2开始(4.0写法不一样)提供了DbContext.Database.SqlQuery()的API可以直接执行SQL。但是如果碰到可控类型的参数,比如Guid?,就会爆。 看一个例子,定义的SQL语句如下: string sql = @"SELECT p2.Id AS PeriodId, p2.Title AS PeriodTitle, u.UserId AS UserId, u.DisplayName AS …
Entity Framework SQL

EntityFramework中使用.Include()做饥饿加载可能产生的性能问题

这几天在码新版博客程序,因为文章表字段太多,手贱把几个相关列拆分到了1-1的表中。比如Post 1-1 PostPublish,Post 1-1 PostExtension。但是性能突然比以前差了一点。 和这两张相关表直接交互的是这么一段代码: var query = Repository.Select().Include(p => p.PostExtension).Include(p => p.PostPublish) .Where(p => p.PostPublish.IsPublished && (authorName == null || String.Compare(p.Author, …
Entity Framework SQL Performance

SQL游标的使用

SQL里要做循环比较麻烦,有时候需要用游标(CURSOR)。我是SQL大菜鸟,昨天刚开荒成功了一个游标。发出来备用。 基本语法形式是这样的: DECLARE @临时变量 UNIQUEIDENTIFIER DECLARE 游标名称 CURSOR FOR -- SELECT的结果 OPEN 游标名称 FETCH NEXT FROM 游标名称 INTO @临时变量 WHILE @@FETCH_STATUS = 0 BEGIN -- 对每一条记录的操作 FETCH NEXT FROM 游标名称 INTO @临时变量 END CLOSE 游标名称 DEALLOCATE 游标名称 举个例子,遍历我博客的分类表,输出每一项的Route名称: DECLARE @tempId UNIQUEIDENTIFIER DECLARE @tempName NVARCHAR(150) …
SQL

在Entity Framework中使用LINQ语句分页

我们知道,内存分页效率很低。并且,如果是WebForm的项目,页面上会有巨型ViewState,这必然不好。我自己博客用的是一个存储过程做的分页,用到现在都挺好,没有任何效率问题。后来想到,既然项目里有Entity Framework,那为什么不利用EF完成分页呢~ 稍做研究之后发现,EF分页其实很简单。不过一样写文章了,光贴代码是不负责的,还是得稍微介绍一下相关的知识。 一、页数计算 关于分页的基本原理,网上有很多文章,我就不多叙述了。但我发现很多介绍分页的文章里,计算页码公式都掐掉了,广为流传的版本是: totalPage = totalRecord / pageSize + 1 稍微推敲一下就会发现,这个公式在totalRecord和pageSize正好整除时,会多一页。比如10条记录,每页5条,应该是2页的,但结果是3。然而,不写+1又不行,因为要考虑到记录总数小于页尺寸的情况。现 …
C# Entity Framework SQL

博客数据库升级手记(四):XML数据的导入

在上一篇文章中,我已经完成了旧数据库的导入。然而,我的博客原先除了用Access数据库保存数据,也大量使用了XML存储,这借鉴自BlogEngine.NET,但后来发现XML存储弊大于利,最适合我的还是传统关系型数据库。因此,我有必要把所有非系统数据迁移到SQL Server上。这里要提一句,系统数据和用户数据是不一样的。系统数据是维持系统程序的运行所需要的数据,用户数据是用户使用系统产生的数据。系统数据包括系统设置(XML保存)、系统菜单等等,而用户数据除了博客文章,还有其创建的页面、友情链接,这些东西原先都是XML存储的,这次要统一迁移到SQL Server上。 首先,要对应XML的数据结构,在SQL Server中建立对应的表,列名和数据类型可以不一样,但要记得方便导入,不然就得用前几篇文章的技巧处理了。本文以友情链接表为例,建立的表如下: CREATE TABLE [dbo].[ …
SQL XML

博客数据库升级手记(三):标签库的导入

上篇文章留下了一个话题,关于标签库的导入。因为设计的变化,标签库无法从Keywords字段中直接导了。 首先,分析一下新表的结构。Tag表是用来保存所有标签的。Tag.Id是uniqueidentifier类型的主键,它将被PostTag表关联,来描述多对多的结构。Tag.Name是标签名称。这是可以从老数据的Blog.Keywords字段中获得的。 所以,第一步,是要从Keywords字段提取信息,插入到Tag表中。随后再处理关联问题。 老数据库里的Keywords字段中保存的,是以英文逗号分隔的文章标签。比如“ASP.NET,CSS,HTML”就表示这篇文章拥有3个标签,分别是ASP.NET、CSS和HTML。首先,我需要解析原先的Keywords字符串,将以逗号分隔的内容解析出来。但SQL Server没有提供Split函数,所以需要自己写一个: CREATE …
SQL

博客数据库升级手记(二):新数据库的建立及简单数据的导入

前面一片文章讲了如何将Access数据库直接导入SQL Server。但导入完成后,是强烈建议不要使用的。因为里面的object命名都与sql默认的不符,许多T-SQL行为也很诡异,所以我需要重新建立一个数据库,并且把旧的数据导入到新的数据库中。 新数据库的设计 对于新的数据库,这恰好是一次重构和升级的机会,我可以将4年前不合理的表结构设计重构一下(4年前也就是我第一次做这个博客的时候,菜鸟一只)。新的数据库中,博客子系统的设计如下(其实还有很多别的表,但不是给博客主业务用的,以后再讨论): 而旧数据库仅仅只有3张表:Blog、Category、Comment。 对于Category,没有太大的改动,仅仅是增加一个”Name”字段,用来做MVC的路由,而”DisplayName”的功能则和原先数据库是一样的,表示这个分类在页面上显示的名称。 Comment表增加了Email字段,是可选的 …
SQL SQL Server