目录 MVC5 网站开发实践 概述 MVC5 网站开发实践 1、建立项目 从这一部分开始做后台管理,首先是基本框架的 一、Data项目 1、项目添加EntityFramework引用 在Data项目的引用上右键-> 管理NuGet程序包。 在弹出的窗口中选择 EntityFramework 安装 2、添加排序枚举 在Data项目上点右键新建文件夹Type。在文件夹内添加类【OrderType】,代码如下
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
//创建2014.12.8 namespace Data.Types { /// <summary> /// 排序类型 /// </summary> public enum OrderType { /// <summary> /// 不排序 /// </summary> No, /// <summary> /// 正序 /// </summary> Asc, /// <summary> /// 倒序 /// </summary> Desc } } |
3、添加数据访问类 在Data项目上点右键新建类输入类名【BaseRepository】,这个类主要负责数数据的存取。 类内添加私有成员DbContext _baseDbContext用来在数据库进行增、删、改和查询。 BaseRepository的构造函数public BaseRepository(DbContext dbContext)中dbContext为数据上下文。在该类中写了一些数据的增删改和查询方法。整个代码如下。
|
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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
using Ninesky.Data.Types; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Linq.Expressions; namespace Ninesky.Data { /// <summary> /// 数据仓储基类 /// <remarks> /// 创建:2014.12.13 /// </remarks> /// </summary> /// <typeparam name="T"></typeparam> public class BaseRepository<T> where T : class { private DbContext _baseDbContext; /// <summary> /// 构造函数 /// </summary> /// <param name="dbContext">数据上下文</param> public BaseRepository(DbContext dbContext) { _baseDbContext = dbContext; } /// <summary> /// 添加 /// </summary> /// <param name="entity">数据实体</param> /// <param name="isSave">是否立即保存</param> /// <returns></returns> public T Add(T entity, bool isSave = true) { _baseDbContext.Set<T>().Add(entity); if (isSave) _baseDbContext.SaveChanges(); return entity; } /// <summary> /// 批量添加【立即执行】 /// </summary> /// <param name="entities">数据列表</param> /// <returns>添加的记录数</returns> public int AddRange(IEnumerable<T> entities, bool isSave = true) { _baseDbContext.Set<T>().AddRange(entities); return isSave ? _baseDbContext.SaveChanges() : 0; } /// <summary> /// 修改 /// </summary> /// <param name="entity">数据实体</param> /// <param name="isSave">是否立即保存</param> /// <returns></returns> public bool Update(T entity, bool isSave = true) { _baseDbContext.Set<T>().Attach(entity); _baseDbContext.Entry<T>(entity).State = EntityState.Modified; return isSave ? _baseDbContext.SaveChanges() > 0 : true; } /// <summary> /// 删除 /// </summary> /// <param name="entity">数据实体</param> /// <param name="isSave">是否立即保存</param> /// <returns></returns> public bool Delete(T entity, bool isSave = true) { _baseDbContext.Set<T>().Attach(entity); _baseDbContext.Entry<T>(entity).State = EntityState.Deleted; return isSave ? _baseDbContext.SaveChanges() > 0 : true; } /// <summary> /// 批量删除 /// </summary> /// <param name="entities">数据列表</param> /// <param name="isSave">是否立即保存</param> /// <returns>删除的记录数</returns> public int DeleteRange(IEnumerable<T> entities, bool isSave = true) { _baseDbContext.Set<T>().RemoveRange(entities); return isSave ? _baseDbContext.SaveChanges() : 0; } /// <summary> /// 保存 /// </summary> /// <returns>受影响的记录数</returns> public int Save() { return _baseDbContext.SaveChanges(); } /// <summary> /// 是否有满足条件的记录 /// </summary> /// <param name="anyLamdba">条件表达式</param> /// <returns></returns> public bool Any(Expression<Func<T, bool>> anyLamdba) { return _baseDbContext.Set<T>().Any(anyLamdba); } /// <summary> /// 查询记录数 /// </summary> /// <param name="countLamdba">查询表达式</param> /// <returns>记录数</returns> public int Count(Expression<Func<T, bool>> countLamdba) { return _baseDbContext.Set<T>().Count(countLamdba); } /// <summary> /// 查找实体 /// </summary> /// <param name="ID">实体ID</param> /// <returns></returns> public T Find(int ID) { return _baseDbContext.Set<T>().Find(ID); } /// <summary> /// 查找实体 /// </summary> /// <param name="findLambda">Lambda表达式</param> /// <returns></returns> public T Find(Expression<Func<T, bool>> findLambda) { return _baseDbContext.Set<T>().SingleOrDefault(findLambda); } /// <summary> /// 查找所有列表 /// </summary> /// <returns></returns> public IQueryable<T> FindAll() { return FindList<int>(0, T => true, OrderType.No, null); } /// <summary> /// 查找数据列表 /// </summary> /// <param name="number">返回的记录数【0-返回所有】</param> /// <param name="whereLandba">查询条件</param> /// <param name="orderType">排序方式</param> /// <param name="orderLandba">排序条件</param> /// <returns></returns> public IQueryable<T> FindList<TKey>(int number, Expression<Func<T, bool>> whereLandba, OrderType orderType, Expression<Func<T, TKey>> orderLandba) { IQueryable<T> _tIQueryable = _baseDbContext.Set<T>().Where(whereLandba); switch (orderType) { case OrderType.Asc: _tIQueryable = _tIQueryable.OrderBy(orderLandba); break; case OrderType.Desc: _tIQueryable = _tIQueryable.OrderByDescending(whereLandba); break; } if (number > 0) _tIQueryable = _tIQueryable.Take(number); return _tIQueryable; } /// <summary> /// /// </summary> /// <typeparam name="TKey">排序字段类型</typeparam> /// <param name="pageIndex">页码【从1开始】</param> /// <param name="pageNumber">每页记录数</param> /// <param name="totalNumber">总记录数</param> /// <param name="whereLandba">查询表达式</param> /// <param name="orderType">排序类型</param> /// <param name="orderLandba">排序表达式</param> /// <returns></returns> public IQueryable<T> FindPageList<TKey>(int pageIndex, int pageNumber, out int totalNumber, Expression<Func<T, bool>> whereLandba, OrderType orderType, Expression<Func<T, TKey>> orderLandba) { IQueryable<T> _tIQueryable = _baseDbContext.Set<T>().Where(whereLandba); totalNumber = _tIQueryable.Count(); switch (orderType) { case OrderType.Asc: _tIQueryable = _tIQueryable.OrderBy(orderLandba); break; case OrderType.Desc: _tIQueryable = _tIQueryable.OrderByDescending(whereLandba); break; } _tIQueryable = _tIQueryable.Skip((pageIndex - 1) * pageNumber).Take(pageNumber); return _tIQueryable; } } } |
4、添加业务逻辑基类 在data项目右键添加【BaseService】,此类通过调用BaseRepository进行数据处理,作为业务逻辑的基类,其他业务类继承自此类。这个类的方法与BaseRepository比较相似,建立此类的主要体现分层的思路,一些数据访问的异常处理应该放在此类中。代码如下:
|
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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
using Ninesky.Data.Types; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Linq.Expressions; namespace Ninesky.Data { /// <summary> /// 业务逻辑基类 /// <remarks> /// 创建:2014.12.13 /// </remarks> /// </summary> public class BaseService<T> where T : class { private BaseRepository<T> _baseRepository; /// <summary> /// 创建业务逻辑类 /// </summary> /// <param name="dbContext">数据上下文</param> public BaseService(DbContext dbContext) { _baseRepository = new BaseRepository<T>(dbContext); } /// <summary> /// 添加 /// </summary> /// <param name="entity">数据实体</param> /// <returns>添加后的数据实体</returns> public T Add(T entity, bool isSave = true) { return _baseRepository.Add(entity, isSave); } ///// <summary> ///// 添加【必须先实例化才能使用】 ///// </summary> ///// <param name="entity">数据实体</param> ///// <returns>添加后的记录ID</returns> //public virtual int Add(T entity) { return 0; } /// <summary> /// 批量添加 /// </summary> /// <param name="entities">数据列表</param> /// <param name="isSave">是否立即保存</param> /// <returns></returns> public int AddRange(IEnumerable<T> entities, bool isSave = true) { return _baseRepository.AddRange(entities, isSave); } /// <summary> /// 修改 /// </summary> /// <param name="entity">数据实体</param> /// <param name="isSave">是否立即保存</param> /// <returns></returns> public bool Update(T entity, bool isSave = true) { return _baseRepository.Update(entity, isSave); } /// <summary> /// 删除 /// </summary> /// <param name="entity">数据实体</param> /// <param name="isSave">是否立即保存</param> /// <returns></returns> public bool Delete(T entity, bool isSave = true) { return _baseRepository.Delete(entity, isSave); } /// <summary> /// 批量删除 /// </summary> /// <param name="entities">数据列表</param> /// <param name="isSave">是否立即保存</param> /// <returns>删除的记录数</returns> public int DeleteRange(IEnumerable<T> entities, bool isSave = true) { return _baseRepository.DeleteRange(entities, isSave); } /// <summary> /// 保存 /// </summary> /// <returns>受影响的记录数</returns> public int Save() { return _baseRepository.Save(); } /// <summary> /// 查询记录数 /// </summary> /// <param name="countLamdba">查询表达式</param> /// <returns>记录数</returns> public int Count(Expression<Func<T, bool>> countLamdba) { return _baseRepository.Count(countLamdba); } /// <summary> /// 查找实体 /// </summary> /// <param name="ID">实体ID</param> /// <returns></returns> public T Find(int ID) { return _baseRepository.Find(ID); } /// <summary> /// 查找实体 /// </summary> /// <param name="findLambda">Lambda表达式</param> /// <returns></returns> public T Find(Expression<Func<T, bool>> findLambda) { return _baseRepository.Find(findLambda); } /// <summary> /// 查找所有列表 /// </summary> /// <returns></returns> public IQueryable<T> FindAll() { return _baseRepository.FindAll(); } /// <summary> /// 查找数据列表 /// </summary> /// <param name="number">返回的记录数【0-返回所有】</param> /// <param name="whereLandba">查询条件</param> /// <param name="orderType">排序方式</param> /// <param name="orderLandba">排序条件</param> /// <returns></returns> public IQueryable<T> FindList<TKey>(int number, Expression<Func<T, bool>> whereLandba, OrderType orderType, Expression<Func<T, TKey>> orderLandba) { return _baseRepository.FindList<TKey>(number, whereLandba, orderType, orderLandba); } /// <summary> /// /// </summary> /// <typeparam name="TKey">排序字段类型</typeparam> /// <param name="pageIndex">页码【从1开始】</param> /// <param name="pageNumber">每页记录数</param> /// <param name="totalNumber">总记录数</param> /// <param name="whereLandba">查询表达式</param> /// <param name="orderType">排序类型</param> /// <param name="orderLandba">排序表达式</param> /// <returns></returns> public IQueryable<T> FindPageList<TKey>(int pageIndex, int pageNumber, out int totalNumber, Expression<Func<T, bool>> whereLandba, OrderType orderType, Expression<Func<T, TKey>> orderLandba) { return FindPageList<TKey>(pageIndex, pageNumber, out totalNumber, whereLandba, orderType, orderLandba); } } } |
二、User项目 1、建立管理员模型 在User项目的引用上点右键添加System.ComponentModel.DataAnnotations的引用和Ninesky.Data项目、E的引用。 在User项目上点右键新建文件夹Models,在文件夹中添加类Administrator。代码如下:
|
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 |
using System; using System.ComponentModel.DataAnnotations; namespace Ninesky.User.Models { /// <summary> /// 管理员模型 /// <remarks> /// 创建:2014.12.13 /// </remarks> /// </summary> public class Administrator { [Key] public int AdministratorID { get; set; } /// <summary> /// 管理员账号 /// </summary> [Required(ErrorMessage = "必须输入{0}")] [Display(Name = "管理员账号")] public string Account { get; set; } /// <summary> /// 管理员名称 /// </summary> [Required(ErrorMessage = "必须输入{0}")] [Display(Name = "管理员名称")] public string Name { get; set; } /// <summary> /// 密码 /// </summary> [Required(ErrorMessage = "必须输入{0}")] [Display(Name = "密码")] [DataType(DataType.Password)] public string Password { get; set; } /// <summary> /// 创建时间 /// </summary> public DateTime CreateDate { get; set; } /// <summary> /// 上次登陆Ip /// </summary> public string LoginIp { get; set; } /// <summary> /// 上次登陆日期 /// </summary> public Nullable<DateTime> LoginTime { get; set; } } } |
2、建立管理员业务逻辑类 在User项目上点右键添加AdministratorService类,该类继承自BaseService。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Ninesky.Data; using Ninesky.User.Models; namespace Ninesky.User { /// <summary> /// 管理员业务逻辑类 /// <remarks> /// 创建:2014.12.13 /// </remarks> /// </summary> public class AdministratorService:BaseService<Administrator> { public AdministratorService(DbContext dbContext) : base(dbContext) { } } } |
三、Website项目 1、添加User项目的引用上右键添加对User项目的引用。 2、建立数据上下文 在Site项目上点右键添加类【NineskyDbContext】,继承自DbContext
|
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 |
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Entity; using Ninesky.User.Models; namespace Ninesky.Website { /// <summary> /// 网站数据上下文 /// <remarks> /// 创建:2014.12.13 /// </remarks> /// </summary> public class NineskyDbContext : DbContext { public DbSet<Administrator> Administrators { get; set; } public NineskyDbContext() : base("name=NineskyConnection") { Database.SetInitializer<NineskyDbContext>(new CreateDatabaseIfNotExists<NineskyDbContext>()); } } } |
3、建立数据库连接 打开Web.config文件,在</configSections><appSettings>之间添加数据库的连接
|
1 2 3 |
<connectionStrings> <add name="NineskyConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\Ninesky.mdf;Initial Catalog=Ninesky;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" /> </connectionStrings> |
4、建立简单工厂 在Website项目上点右键添加类【ContextFactory】,代码如下:
|
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 |
using System.Runtime.Remoting.Messaging; namespace Ninesky.Website { /// <summary> /// 上下文简单工厂 /// <remarks> /// 创建:2014.12.13 /// </remarks> /// </summary> public class ContextFactory { /// <summary> /// 获取当前数据上下文 /// </summary> /// <returns>数据上下文</returns> public static NineskyDbContext GetCurrentContext() { NineskyDbContext _nineskyDbContext = CallContext.GetData("NineskyDbContext") as NineskyDbContext; if (_nineskyDbContext == null) { _nineskyDbContext = new NineskyDbContext(); CallContext.SetData("NineskyDbContext", _nineskyDbContext); } return _nineskyDbContext; } } } |
5、Config区域主界面 在Site项目的Config区域的Controller文件夹上点右键添加Home控制器,类型选择【MVC5控制器-空】。在添加的控制器中添加【Index】 action
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Ninesky.Website.Areas.Config.Controllers { /// <summary> /// 主界面 /// <remarks> /// 创建:2014.12.13 /// </remarks> /// </summary> public class HomeController : Controller { // GET: Config/Home public ActionResult Index() { return View(); } } } |
在Config区域Views/Share文件夹添加布局页【_Layout.cshtml】 在Index action上右键添加一个空视图 =========================== 代码下载:http://pan.baidu.com/s/1sj6Ya2D from:http://www.cnblogs.com/mzwhj/p/4155896.html
View Details单条: WeiXinOpenId weiXinOpenId = _db.WeiXinOpenId.Find(1); _db.WeiXinOpenId.Remove(weiXinOpenId); _db.SaveChanges(); 另一种方法: WeiXinOpenId weiXinOpenId = _db.WeiXinOpenId.Find(1); _db.Entry(weiXinOpenId).State = EntityState.Deleted; _db.SaveChanges(); ================================================ 批量: var openids = _db.WeiXinOpenId.Where(item => item.Uid == uid).ToList(); _db.WeiXinOpenId.RemoveRange(openids); return _db.SaveChanges();
View DetailsC#中的webbrowser控件比较好用. 下面本人搜索整理的几个小技巧. 1. 从C#中取得javascript的变量值. using mshtml; using System.Reflection; IHTMLDocument2 vDocument = webBrowser1.Document.DomDocument as IHTMLDocument2; IHTMLWindow2 vWindow = vDocument.parentWindow; Type vWindowType = vWindow.GetType(); object xpt = vWindowType.InvokeMember("_xpt", BindingFlags.GetProperty, null, vWindow, new object[] { }); xpt 就是取得的javascript中的变量"_xpt"的值. 2. 禁止显示脚本错误窗口. webBrowser1.ScriptErrorsSuppressed = true; 3. 如何取弹出网页的网址 string newUrl = webBrowser_temp.Document.ActiveElement.GetAttribute("href"); 4. 禁止打开新窗口, 在本窗口打开. 4.1 设置属性. void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { //将所有的链接的目标,指向本窗体 foreach (HtmlElement archor in this.webBrowser1.Document.Links) { archor.SetAttribute("target", "_self"); } //将所有的FORM的提交目标,指向本窗体 foreach (HtmlElement form in this.webBrowser1.Document.Forms) { form.SetAttribute("target", "_self"); } } 将 WebBrowser 的 AllowWebBrowserDrop 设为 false 将 WebBrowser 的 WebBrowserShortcutsEnabled […]
View Details今天一位同事想写一个全屏幕截图的代码。当然要实现的第一步是能够获取整个屏幕的位图,记得Win32 API的CreateDC, BitBlt等函数可以使用。于是上网查了下,果然屏幕截图用这些函数。但winform已经可以把API都忘记了,所以得寻找一个无Win32 API的实现方式。综合了网上的实现,以及自己的一些设计,实现思路如下: 1. 开始截图时,创建一个与屏幕大小一样的位图,然后用Graphics.CopyFromScreen()把屏幕位图拷贝到该位图上。这是很关键的一步,这样所有的操作就都可以在该位图上进行了,而无实际屏幕无关了。 复制代码代码如下: Code int width = Screen.PrimaryScreen.Bounds.Width; int height = Screen.PrimaryScreen.Bounds.Height; Bitmap bmp = new Bitmap(width, height); using (Graphics g = Graphics.FromImage(bmp)) { g.CopyFromScreen(0, 0, 0, 0, new Size(width, height)); } 2. 接下来为了方便在这之上进行截图,有一个很重要的设计实现方式:用全屏幕窗体代替现有真实屏幕,这样就可以把截图过程的所有操作都在那个窗体上实现(该窗体设置成无边框,高宽等于屏幕大小即可),另外为了显示掩蔽效果(只能正常显示选择的部分屏幕内容,而其实部分用一个如半透明层覆盖),就添加一层半透明位置位图。具体代码如下: 复制代码代码如下: Code public partial class FullScreenForm : Form { private Rectangle rectSelected = Rectangle.Empty; private bool isClipping = false; private Bitmap screen; private Bitmap coverLayer = null; private Color coverColor; private Brush rectBrush = null; private Bitmap resultBmp = null; public FullScreenForm(Bitmap screen) { InitializeComponent(); int width = Screen.PrimaryScreen.Bounds.Width; int […]
View Details有时需要用WebBrowser加载URL,来实现某些功能。而这时,我们就不希望所打开的页面中的链接,在新窗口中打开,因为这样的话,实际上是用系统默认的浏览器打开了,从而脱离了你的WebBrowser,也就不能被你所控制了。 要解决这个问题,可以使用下面的方法: 第一种解决该当推荐使用 [code=csharp] private void webBrowser1_NewWindow(object sender, CancelEventArgs e) { string url = ((WebBrowser)sender).StatusText; webBrowser1.Navigate(url); e.Cancel = true; }[/code] StatusText就是要跳转到的Url e.Cancel = true;是取消新窗口打开, 第二种方法 假设WebBrowser的Name是 webBrowser1 简单方法-利用加载完成事件将所有的链接和form的target值改为"_seft": [code=csharp]private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { //将所有的链接的目标,指向本窗体 foreach (HtmlElement archor in this.webBrowser1.Document.Links) { archor.SetAttribute("target", "_self"); } //将所有的FORM的提交目标,指向本窗体 foreach (HtmlElement form in this.webBrowser1.Document.Forms) { form.SetAttribute("target", "_self"); } } 取消新窗口事件 ? private void webBrowser1_NewWindow(object sender, CancelEventArgs e) { e.Cancel = true; }[/code] 将 WebBrowser 的 AllowWebBrowserDrop 设为 false(禁止拖放) 将 WebBrowser 的 WebBrowserShortcutsEnabled 设为 false(禁止使用快捷键)将 WebBrowser 的 IsWebBrowserContextMenuEnabled 设为 false(禁止右键上下文菜单) from:http://www.sufeinet.com/thread-2970-1-1.html
View Details分屏显示即可把一台主机内运行的多个程序分别显示在不同的两个(或多个)屏幕上。目前市面上主流的显卡都支持分屏显示(显示双屏幕),如果需要显示2个以上的屏幕,则应使用“拖机卡”类的硬件。 设置分屏显示的两种方法如下: 1、用两个显卡连接两台显示器,进入系统后,分清楚哪一个是主显卡,在桌面空白处右键单击,点属性,然后在窗口中点“设置”选项卡,会看到有两个显示,分别是1(主显卡)和2(副显卡),点击那个2,在下面的“将windows桌面扩展到该监视器”打上对号,确定后,你试着把鼠标往主显示器右边界移动,再移动,鼠标会跑到第二台显示器上去了,这样,同样运行几个程序,分别将它们的窗口拖拽到两个显示器的区域中就可以了,这实际上是将桌面扩展了一下。 2、使用专门的硬件。可以使用“一拖多”的拖机卡,只要将设备插入usb口中,将设备上引出的两个ps/2口分别接鼠标和键盘,主机中还是有两块显卡,然后再装上这个设备的专用软件,重启后,经过简单的配置,即可实现“完全”独立的两个系统。 所谓的分屏或多屏软件,就是把软件中的多个窗体,在主屏幕运行,但是把各个窗体(坐标)移动到各个扩展屏幕位置上如下图所示: 主屏幕 (MainForm) index=0 扩展屏幕1 (Form1) index=1 扩展屏幕2 (Form2) index=… 扩展屏幕3 (Form3) index=… 以下介绍最常用的双屏幕显示,也就是左右模式的屏幕显示的方法。 WinForm 的实现办法: 利用WinForm中的Screen类,即可比较方便地实现多窗体分别在多个屏幕上显示。 获取当前系统连接的屏幕数量: Screen.AllScreens.Count(); 获取当前屏幕的名称:string CurrentScreenName = Screen.FromControl(this).DeviceName; 获取当前屏幕对象:Screen CurrentScreen = Screen.FromControl(this); 获取当前鼠标所在的屏幕:Screen CurrentScreen = Screen.FromPoint(new Point(Cursor.Position.X, Cursor.Position.Y)); 让窗体在第2个屏幕上显示: this.Left = ((Screen.AllScreens[1].Bounds.Width – this.Width) / 2); this.Top = ((Screen.AllScreens[1].Bounds.Height – this.Height) / 2); 把任何窗体显示在任何屏幕的方法: [csharp] view plaincopy //在窗体的OnLoad事件中调用该方法 protected void Form1_OnLoad(…) { showOnMonitor(1);//index=1 } private void showOnMonitor(int showOnMonitor) { Screen[] sc; sc = Screen.AllScreens; if (showOnMonitor >= sc.Length) { showOnMonitor = 0; } this.StartPosition = FormStartPosition.Manual; this.Location = new Point(sc[showOnMonitor].Bounds.Left, sc[showOnMonitor].Bounds.Top); // If you intend the form to be maximized, change it to normal then maximized. this.WindowState = FormWindowState.Normal; this.WindowState = FormWindowState.Maximized; } 对WPF窗体来说,只要简单的更改即可: 首先要添加对 System.Windows.Forms 和 System.Drawing 的引用 简单的参考代码如下: [csharp] view plaincopy protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); […]
View Details安全研究人员称,攻击者没有浪费一点时间,开始利用刚刚曝出的ImageMagick高危漏洞去执行恶意代码以控制网站的Web服务器。ImageMagick是一个广泛使用的图像处理库,它的一个高危漏洞允许远程代码执行,攻击者上传植入恶意代码的图像,Web服务器在处理时能被利用执行攻击者选择的代码。开发者尚未释出修正漏洞的补丁。CloudFlare的研究员 John Graham-Cumming在官方博客上称,攻击者正在利用该漏洞攻击网站。 from:http://www.oschina.net/news/73296/inside-imagetragick-the-real-payloads-used-to-hack-websites
View Details我们继续讲解LINQ to SQL语句,这篇我们来讨论Union All/Union/Intersect操作和Top/Bottom操作和Paging操作和SqlMethods操作 。 Union All/Union/Intersect操作 适用场景:对两个集合的处理,例如追加、合并、取相同项、相交项等等。 Concat(连接) 说明:连接不同的集合,不会自动过滤相同项;延迟。 1.简单形式:
|
1 2 3 4 5 6 7 8 9 10 |
var q = ( from c in db.Customers select c.Phone ).Concat( from c in db.Customers select c.Fax ).Concat( from e in db.Employees select e.HomePhone ); |
语句描述:返回所有消费者和雇员的电话和传真。 2.复合形式:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var q = ( from c in db.Customers select new { Name = c.CompanyName, c.Phone } ).Concat( from e in db.Employees select new { Name = e.FirstName + " " + e.LastName, Phone = e.HomePhone } ); |
语句描述:返回所有消费者和雇员的姓名和电话。 Union(合并) 说明:连接不同的集合,自动过滤相同项;延迟。即是将两个集合进行合并操作,过滤相同的项。
|
1 2 3 4 5 6 7 |
var q = ( from c in db.Customers select c.Country ).Union( from e in db.Employees select e.Country ); |
语句描述:查询顾客和职员所在的国家。 Intersect(相交) 说明:取相交项;延迟。即是获取不同集合的相同项(交集)。即先遍历第一个集合,找出所有唯一的元素,然后遍历第二个集合,并将每个元素与前面找出的元素作对比,返回所有在两个集合内都出现的元素。
|
1 2 3 4 5 6 7 |
var q = ( from c in db.Customers select c.Country ).Intersect( from e in db.Employees select e.Country ); |
语句描述:查询顾客和职员同在的国家。 Except(与非) 说明:排除相交项;延迟。即是从某集合中删除与另一个集合中相同的项。先遍历第一个集合,找出所有唯一的元素,然后再遍历第二个集合,返回第二个集合中所有未出现在前面所得元素集合中的元素。
|
1 2 3 4 5 6 7 |
var q = ( from c in db.Customers select c.Country ).Except( from e in db.Employees select e.Country ); |
语句描述:查询顾客和职员不同的国家。 Top/Bottom操作 适用场景:适量的取出自己想要的数据,不是全部取出,这样性能有所加强。 Take 说明:获取集合的前n个元素;延迟。即只返回限定数量的结果集。
|
1 2 3 4 5 |
var q = ( from e in db.Employees orderby e.HireDate select e) .Take(5); |
语句描述:选择所雇用的前5个雇员。 Skip 说明:跳过集合的前n个元素;延迟。即我们跳过给定的数目返回后面的结果集。
|
1 2 3 4 5 |
var q = ( from p in db.Products orderby p.UnitPrice descending select p) .Skip(10); |
语句描述:选择10种最贵产品之外的所有产品。 TakeWhile 说明:直到某一条件成立就停止获取;延迟。即用其条件去依次判断源序列中的元素,返回符合判断条件的元素,该判断操作将在返回false或源序列的末尾结束 。 SkipWhile 说明:直到某一条件成立就停止跳过;延迟。即用其条件去判断源序列中的元素并且跳过第一个符合判断条件的元素,一旦判断返回false,接下来将不再进行判断并返回剩下的所有元素。 Paging(分页)操作 适用场景:结合Skip和Take就可实现对数据分页操作。 1.索引
|
1 2 3 4 5 6 |
var q = ( from c in db.Customers orderby c.ContactName select c) .Skip(50) .Take(10); |
语句描述:使用Skip和Take运算符进行分页,跳过前50条记录,然后返回接下来10条记录,因此提供显示Products表第6页的数据。 2.按唯一键排序
|
1 2 3 4 5 6 |
var q = ( from p in db.Products where p.ProductID > 50 orderby p.ProductID select p) .Take(10); |
语句描述:使用Where子句和Take运算符进行分页,首先筛选得到仅50 (第5页最后一个ProductID)以上的ProductID,然后按ProductID排序,最后取前10个结果,因此提供Products表第6页的数据。请注意,此方法仅适用于按唯一键排序的情况。 SqlMethods操作 在LINQ to SQL语句中,为我们提供了SqlMethods操作,进一步为我们提供了方便,例如Like方法用于自定义通配表达式,Equals用于相比较是否相等。 Like 自定义的通配表达式。%表示零长度或任意长度的字符串;_表示一个字符;[]表示在某范围区间的一个字符;[^]表示不在某范围区间的一个字符。比如查询消费者ID以“C”开头的消费者。
|
1 2 3 |
var q = from c in db.Customers where SqlMethods.Like(c.CustomerID, "C%") select c; |
比如查询消费者ID没有“AXOXT”形式的消费者:
|
1 2 3 |
var q = from c in db.Customers where !SqlMethods.Like(c.CustomerID, "A_O_T") select c; |
DateDiffDay 说明:在两个变量之间比较。分别有:DateDiffDay、DateDiffHour、DateDiffMillisecond、DateDiffMinute、DateDiffMonth、DateDiffSecond、DateDiffYear
|
1 2 3 4 |
var q = from o in db.Orders where SqlMethods .DateDiffDay(o.OrderDate, o.ShippedDate) < 10 select o; |
语句描述:查询在创建订单后的 10 天内已发货的所有订单。 已编译查询操作(Compiled Query) 说明:在之前我们没有好的方法对写出的SQL语句进行编辑重新查询,现在我们可以这样做,看下面一个例子:
|
1 2 3 4 5 6 7 8 9 10 11 |
//1.创建compiled query NorthwindDataContext db = new NorthwindDataContext(); var fn = CompiledQuery.Compile( (NorthwindDataContext db2, string city) => from c in db2.Customers where c.City == city select c); //2.查询城市为London的消费者,用LonCusts集合表示,这时可以用数据控件绑定 var LonCusts = fn(db, "London"); //3.查询城市为Seattle的消费者 var SeaCusts = fn(db, "Seattle"); |
语句描述:这个例子创建一个已编译查询,然后使用它检索输入城市的客户。 本系列链接:LINQ体验系列文章导航 LINQ推荐资源 LINQ专题:http://kb.cnblogs.com/zt/linq/ 关于LINQ方方面面的入门、进阶、深入的文章。 LINQ小组:http://space.cnblogs.com/group/linq/ 学习中遇到什么问题或者疑问提问的好地方。 from:http://www.cnblogs.com/lyj/archive/2008/01/27/1054995.html
View Details我们继续讲解LINQ to SQL语句,这篇我们来讨论Group By/Having操作符和Exists/In/Any/All/Contains操作符。 Group By/Having操作符 适用场景:分组数据,为我们查找数据缩小范围。 说明:分配并返回对传入参数进行分组操作后的可枚举对象。分组;延迟 1.简单形式:
|
1 2 3 4 |
var q = from p in db.Products group p by p.CategoryID into g select g; |
语句描述:使用Group By按CategoryID划分产品。 说明:from p in db.Products 表示从表中将产品对象取出来。group p by p.CategoryID into g表示对p按CategoryID字段归类。其结果命名为g,一旦重新命名,p的作用域就结束了,所以,最后select时,只能select g。当然,也不必重新命名可以这样写:
|
1 2 3 |
var q = from p in db.Products group p by p.CategoryID; |
我们用示意图表示: 如果想遍历某类别中所有记录,这样:
|
1 2 3 4 5 6 7 8 9 10 |
foreach (var gp in q) { if (gp.Key == 2) { foreach (var item in gp) { //do something } } } |
2.Select匿名类:
|
1 2 3 4 |
var q = from p in db.Products group p by p.CategoryID into g select new { CategoryID = g.Key, g }; |
说明:在这句LINQ语句中,有2个property:CategoryID和g。这个匿名类,其实质是对返回结果集重新进行了包装。把g的property封装成一个完整的分组。如下图所示: 如果想遍历某匿名类中所有记录,要这么做:
|
1 2 3 4 5 6 7 8 9 10 |
foreach (var gp in q) { if (gp.CategoryID == 2) { foreach (var item in gp.g) { //do something } } } |
3.最大值
|
1 2 3 4 5 6 7 |
var q = from p in db.Products group p by p.CategoryID into g select new { g.Key, MaxPrice = g.Max(p => p.UnitPrice) }; |
语句描述:使用Group By和Max查找每个CategoryID的最高单价。 说明:先按CategoryID归类,判断各个分类产品中单价最大的Products。取出CategoryID值,并把UnitPrice值赋给MaxPrice。 4.最小值
|
1 2 3 4 5 6 7 |
var q = from p in db.Products group p by p.CategoryID into g select new { g.Key, MinPrice = g.Min(p => p.UnitPrice) }; |
语句描述:使用Group By和Min查找每个CategoryID的最低单价。 说明:先按CategoryID归类,判断各个分类产品中单价最小的Products。取出CategoryID值,并把UnitPrice值赋给MinPrice。 5.平均值
|
1 2 3 4 5 6 7 |
var q = from p in db.Products group p by p.CategoryID into g select new { g.Key, AveragePrice = g.Average(p => p.UnitPrice) }; |
语句描述:使用Group By和Average得到每个CategoryID的平均单价。 说明:先按CategoryID归类,取出CategoryID值和各个分类产品中单价的平均值。 6.求和
|
1 2 3 4 5 6 7 |
var q = from p in db.Products group p by p.CategoryID into g select new { g.Key, TotalPrice = g.Sum(p => p.UnitPrice) }; |
语句描述:使用Group By和Sum得到每个CategoryID 的单价总计。 说明:先按CategoryID归类,取出CategoryID值和各个分类产品中单价的总和。 7.计数
|
1 2 3 4 5 6 7 |
var q = from p in db.Products group p by p.CategoryID into g select new { g.Key, NumProducts = g.Count() }; |
语句描述:使用Group By和Count得到每个CategoryID中产品的数量。 说明:先按CategoryID归类,取出CategoryID值和各个分类产品的数量。 8.带条件计数
|
1 2 3 4 5 6 7 |
var q = from p in db.Products group p by p.CategoryID into g select new { g.Key, NumProducts = g.Count(p => p.Discontinued) }; |
语句描述:使用Group By和Count得到每个CategoryID中断货产品的数量。 说明:先按CategoryID归类,取出CategoryID值和各个分类产品的断货数量。 Count函数里,使用了Lambda表达式,Lambda表达式中的p,代表这个组里的一个元素或对象,即某一个产品。 9.Where限制
|
1 2 3 4 5 6 7 8 |
var q = from p in db.Products group p by p.CategoryID into g where g.Count() >= 10 select new { g.Key, ProductCount = g.Count() }; |
语句描述:根据产品的―ID分组,查询产品数量大于10的ID和产品数量。这个示例在Group By子句后使用Where子句查找所有至少有10种产品的类别。 说明:在翻译成SQL语句时,在最外层嵌套了Where条件。 10.多列(Multiple Columns)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var categories = from p in db.Products group p by new { p.CategoryID, p.SupplierID } into g select new { g.Key, g }; |
语句描述:使用Group By按CategoryID和SupplierID将产品分组。 说明: 既按产品的分类,又按供应商分类。在by后面,new出来一个匿名类。这里,Key其实质是一个类的对象,Key包含两个Property:CategoryID、SupplierID。用g.Key.CategoryID可以遍历CategoryID的值。 11.表达式(Expression)
|
1 2 3 4 |
var categories = from p in db.Products group p by new { Criterion = p.UnitPrice > 10 } into g select g; |
语句描述:使用Group By返回两个产品序列。第一个序列包含单价大于10的产品。第二个序列包含单价小于或等于10的产品。 说明:按产品单价是否大于10分类。其结果分为两类,大于的是一类,小于及等于为另一类。 Exists/In/Any/All/Contains操作符 适用场景:用于判断集合中元素,进一步缩小范围。 Any 说明:用于判断集合中是否有元素满足某一条件;不延迟。(若条件为空,则集合只要不为空就返回True,否则为False)。有2种形式,分别为简单形式和带条件形式。 1.简单形式: 仅返回没有订单的客户:
|
1 2 3 4 |
var q = from c in db.Customers where !c.Orders.Any() select c; |
[…]
View Details在这篇文章中,我们将讨论成为一个成功的软件工程师需要注意哪些要点,以便于鞭策自己也成为一个成功的软件工程师。 背景 上周,我参加了印度德里最值得期待的会议——C# Corner annual conference。如果你需要了解更多,那么请点这里。当我知道我有机会聆听大师级谈话的时候,真的非常惊喜。我学到了很多。下面我会把我听到的来自于Mr. Glenn Block的关于“如何成为一个成功的软件工程师”的要点分享给大家。这些内容激励了所有的与会者。Mr. Glenn Block是一位前微软员工,他曾在微软工作了近10年,并且他一直是Azure、WCF、.NET等的一部分,目前,他正担任着Splunk的首席产品经理。 我在写这篇文章前得到了Mr. Glenn Block的允许。 如何成为一个成功的软件工程师? 我发现Mr. Glenn Block提出的所有建议都非常有意义,并且我们每个人都应该好好学习。 不要害怕失败 我们是开发人员和程序员。我们也是人,我们也会犯错。你是不是没有任何错误就创建好了软件无关紧要。反倒是如果你这么说了,那么你可能需要确定你的软件是否能够正常工作。记住爱因斯坦有一句名言:“不要害怕失败。” 不要害怕失败,失败是你最好的老师。我们都曾犯过一些导致我们失败的错误,但更重要的是要从错误中学习。如果你这样做了,那么也许你的下一次尝试就成功了。 如果你从来没有失败过,那么说明你畏头畏尾,从来没有尝试过任何新的东西。 不要害怕寻求帮助 我们都工作在一个会犯错会失败的环境中。所以,你不应该害怕寻求别人的帮助。这样可以减少你的工作压力,并让你能够按时交付产品!而这正是你的经理对你的要求。有时候,你的后辈也能指引你走向正确的道路。所以,不要害怕寻求帮助。让你的自负随风而去吧。 做一个持续的学习者 这个时代每时每刻都有新事物被发明被创造。这在IT行业也是如此。每一天都有新的东西需要学习。在一天结束时,你学到了什么才是最重要的。你应该尝试所有与开发相关的技术。同时,重要的要掌握其中一些技术。 你不能掌握所有内容 在看完以上几点之后,你的脑海中可能会出现这样一个念头:“我怎么才能学习所有的内容呢?”当我说要成为一个持续的学习者时,其实这受你真正能学到什么的限制。你只需要去尝试你认为对你的编程生涯有帮助的技术。当然,正如我在上面所说,你必须掌握其中的一些技术。 重视你的代码 在你写代码的时候,只要确保代码确实能用一种清晰和易于阅读的方式如愿实现目标即可。我的朋友,Mr. Dhananjay Kumar说Mr. Glenn Block写代码就像是诗人在写诗歌一样,非常值得我们借鉴。此外,代码的可维护性也非常重要,否则维护这些代码的人搞不好在几天/月/年之后就得经历一场求生不得求死不能的痛苦。 找导师,成为导师 老师能够传业授道解惑,能帮助我们理解学习的内容。因此,找到一个能指点正确方向的导师尤为重要。向你的导师学习,因为导师可以教你许多他/她从他/她的生活中总结出来的内容。正如大家都知道的,“经验让人完美”!一旦你学会了,那不妨也成为别人的导师,分享你从你的导师那里学到的知识。当然,在做导师的时候,请确保不要误人子弟。 不要拖后腿 不可否认我们周围有不少拖后腿的人。虽然没有强制要求说所有人都必须优秀。但是有时你可能会不得不和一个消极被动的人一起工作。但是重要的是,你得保持住自己的乐观和主动性。 不要过度承诺 我们的项目都有时间期限,这是我们都知道的。你在时间框架中能做什么是有限制的。要去理解那些。当你接受需求列表时,你应该清楚你需要付出什么样的努力以及多少时间才能完成工作。如果不能满足你的经理/客户给出的时间框架,那就随时告知报告人。发布如他们期望那样而非满是bug的产品很重要。所以,千万不要过度承诺。如果你这样做了的话,那就准备好再找一份工作吧。因为你可能会被炒鱿鱼。 永远不要在你想说“No”的时候违心地说“Yes”。 正确的想法不必是你的想法 这一点还需要我解释吗? 我们都在工作,我们都有脑子,我们都有自己的想法。有时候你的后辈也可以教你很多,有时候他解决问题的速度快于你。承认这一点,并赞同他们给出的解决方案。集思广益将有助于按时交付项目。重要的是,这能帮助你做到不以自我为中心。 做一个良好的倾听者 做一个良好的倾听者,意味着你可以通过他人的角度来看事情。这将丰富你的阅历提高你的声誉。如果他们错了,你就向他们解释他们错了以及为什么。 测试,测试,还是测试 测试是软件开发周期中最重要的角色之一。没有经过适当测试之前永远不要发布你的产品,因为测试是捕获bug的阶段,而bug是为客户和管理者所不喜的。如果你认为你已经做完测测试了,那么再做一次。 问:开发人员说的最多的谎言是什么? 答:我已经做过单元测试了。 模式 始终追求适合你项目的最相关的模式。如果你根据自己的要求选择模式的话,它可能会在最后的周期使你功亏一篑。 问:软件开发中最重要的阶段是什么? 答:需求收集或需求理解。 成为社区的一部分 这一点也非常重要。你需要成为一些社区的一份子,因为这些都能给我们提供帮助。推荐一些很不错的社区: C# Corner MSDN ASP.NET Stack Overflow Code Project 这种方式可以让你在网络世界中被大家所关注。分享你的所有知识,并尽可能地从各种资源获取知识。 致力于OSS(Open Source) 如果你得到一个机会可以致力于开源项目,那么一定不要错过,一定要勇往直前。这将增加你的声誉,因为开源项目正在被数十亿用户使用。 结论 最后但并非最不重要的一点,如果有任何遗漏的地方,欢迎给出你的建议和反馈。 稿源:码农网
View Details