在使用EF的情况下,怎么进行事务的处理,来减少数据操作时的失误,比如重复插入数据等等这些问题,这都是经常会遇到的一些问题
但是如果是我有多个站点,然后存在同类型的角色去操作同一条数据的同一个字段的话,那就需要对数据库进行操作,这是数据库里面的事务了
这个另外再说。
这里有这么一个很好的解决方式,EF6里面提供了这么一个方式来处理事物
Database.BeginTransaction() : 为用户提供一种简单易用的方案,在dbEntitys
中启动并完成一个事务 -- 合并一系列操作到该事务中。同时使用户更方便的指定事务隔离级别。
Database.UseTransaction() : 允许DbContext使用一个EF框架外的事务。
using System; using System.Collections.Generic; using System.Data.Entity; using System.Data.SqlClient; using System.Linq; using System.Transactions; namespace TransactionsExamples { class TransactionsExample { static void StartOwnTransactionWithinContext() { using (var db= new dbEntitys()) { using (var dbContextTransaction = db.Database.BeginTransaction()) { try { var query = context.Posts.Where(p => p.Blog.Rating >= 5); foreach (var post in query) { post.Title += "[Cool Blog]"; } context.SaveChanges(); dbContextTransaction.Commit(); } catch (Exception) { dbContextTransaction.Rollback(); } } } } } }
环境:win7 64位, VS2010
1、首先用VS2010创建命令行工程NLogDemo
2、在程序包管理器控制台中输入:Install-Package NLog -Version 4.4.12
这句是怎么来的,要是你用过nuget包管理工具,那就可以跳过这里的说明了。
要使用nuget添加NLog包到项目中。请看下图。
然后在程序包管理工具控制台下输入:Install-Package NLog -Version 4.4.12
再看看Install-Package NLog -Version 4.4.12这个怎么找。
打开百度搜索:Nuget
然后在Nuget官网上搜索栏输入:Nlog 回车
选择第一项Nlog
然后在 Version History 下选择 4.4.12 这个版本
至于为什么选择这个版本,因为这个版本下载的次数多。嘿嘿,没办法,随大流。当然还要看这个版本包的依赖项
这个包的没有什么特殊依赖项,所以可以使用。然后拷贝
这里这句话就是要我们要找的。是不是挺简单的。
当我们在包程序包管理器控制台中输入:Install-Package NLog -Version 4.4.12 然后按下回车键,VS IDE 会自动到 nuget.org 这里下载依赖包。
NLog 包添加完之后,还要添加 NLog.config(4.4.12)(Install-Package NLog.Config -Version 4.4.12) 这个包,按道理 NLog 和 NLog.config 应该一起的,
突然从某个版本开始分开了,要单独添加。具体情况可以去官网看介绍:
添加 NLog.config 的方法跟上面添加 NLog 的方法一样。
3、简单封装 Log
添加类Log.cs到工程中,修改代码如下:
public sealed class Log{ private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger(); private Log() { } public static void Trace(string strMsg) { _logger.Trace(strMsg); } public static void Debug(string strMsg) { _logger.Debug(strMsg); } public static void Info(string strMsg) { _logger.Info(strMsg); } public static void Warn(string strMsg) { _logger.Warn(strMsg); } public static void Error(string strMsg) { _logger.Error(strMsg); } public static void Fatal(string strMsg) { _logger.Fatal(strMsg); }}
4、修改NLog.config文件,具体内容如下:
简单解释:
variable log文件的内容输出格式
targets 目标文件(要生成的Log文件)的配置(文件名、格式变量、文件个数、文件大小等等)
rules 规则,也就是俗话说的Log输出级别 以上内容不进行过多解释了,再多解释也不如官网的说明。详细介绍请看官网:
5、使用Log输出日志到文件,简单示例代码如下
class Program{ static void Main(string[] args) { RunTest(); Console.WriteLine("Press a key end ..."); Console.ReadKey(true); } static void RunTest() { for (int i = 0; i < 1000; i++) { Log.Info(string.Format("{0}", i + 1)); System.Threading.Thread.Sleep(10); } }}
输出路径结构
输出文件内容:
以上内容输出格式可以在NLog.config中根据需求进行裁剪。
本文转自: https://blog.csdn.net/Cooldiok/article/details/7831351
2017年10月22日 21:31:22
微软作为ASP.NET的创造者,它对于官网的结构设计肯定有值得我们借鉴和参考的地方
本项目是基于VS2017 pro开发的,将从你已经创建了一个MVC项目开始介绍:
流程图1.创建语言文件
创建App_GlobalResources文件夹创建Language文件夹
创建资源文件
这些操作做完后,目录结构应该是以下这样的
我们打开每个资源文件,在里面添加一条TiTle数据
我推荐使用ResX Manager来管理语言文件
比如我已经创建了中文、英语、日语这三个语言文件,我如果要做修改的话就需要每个文件轮流修改,使用ResX Manager就能直接同时修改这三个语言文件,它还提供语言翻译功能。具体使用方法与此文无关,就不再赘述了。2.创建一个过滤器
1 namespace MvcEdu.Filters 2 { 3 public class LocalizationAttribute : ActionFilterAttribute 4 { 5 public override void OnActionExecuting(ActionExecutingContext filterContext) 6 { 7 8 bool isSkipLocalization = filterContext.ActionDescriptor.IsDefined(typeof(WithoutLocalizationAttribute), inherit: true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(WithoutLocalizationAttribute), inherit: true); 9 10 if (!isSkipLocalization)11 {12 if (filterContext.RouteData.Values["lang"] != null && !string.IsNullOrWhiteSpace(filterContext.RouteData.Values["lang"].ToString()))13 {14 ///从路由数据(url)里设置语言15 var lang = filterContext.RouteData.Values["lang"].ToString();16 Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(lang);17 }18 else19 {20 ///从cookie里读取语言设置21 var cookie = filterContext.HttpContext.Request.Cookies["Localization.CurrentUICulture"];22 var langHeader = string.Empty;23 if (cookie != null && cookie.Value != "")24 {25 ///根据cookie设置语言26 langHeader = cookie.Value;27 Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader);28 }29 else30 {31 ///如果读取cookie失败则设置默认语言32 langHeader = filterContext.HttpContext.Request.UserLanguages[0];33 Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader);34 }35 ///把语言值设置到路由值里36 filterContext.RouteData.Values["lang"] = langHeader;37 //如果url中不包含语言设置则重定向到包含语言值设置的url里38 string ReturnUrl = $"/{filterContext.RouteData.Values["lang"]}/{filterContext.RouteData.Values["controller"]}/{filterContext.RouteData.Values["action"]}";39 filterContext.Result = new RedirectResult(ReturnUrl);40 }41 42 /// 把设置保存进cookie43 HttpCookie _cookie = new HttpCookie("Localization.CurrentUICulture", Thread.CurrentThread.CurrentUICulture.Name);44 _cookie.Expires = DateTime.Now.AddYears(1);45 filterContext.HttpContext.Response.SetCookie(_cookie);46 47 base.OnActionExecuting(filterContext);48 }49 50 }51 }52 53 public class WithoutLocalizationAttribute : Attribute54 {55 }56 }
3.配置路由文件
我这边因为只有三个语言文件,所以我对于语言项的输入做了限制。1 namespace MvcEdu 2 { 3 public class RouteConfig 4 { 5 public static void RegisterRoutes(RouteCollection routes) 6 { 7 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 8 9 routes.MapRoute(10 name: "Localization", // 路由名称11 url: "{lang}/{controller}/{action}/{id}", // 带有参数的 URL\12 constraints: new { lang = "zh-CN|en-US|ja-JP" }, //限制可输入的语言项13 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }//参数默认值14 );15 16 routes.MapRoute(17 name: "Default",18 url: "{controller}/{action}/{id}",19 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }20 );21 }22 }23 }
4.修改HomeController.cs文件,添加修改语言函数
1 namespace MvcEdu.Controllers 2 { 3 [Localization] //HomeController里的函数都要走Localization过滤器 4 public class HomeController : Controller 5 { 6 public ActionResult Index() 7 { 8 ViewBag.Title = Resources.Language.Title;//页面中的Title值取语言文件里的Title值 9 return View();10 }11 12 public ActionResult About()13 {14 ViewBag.Title = Resources.Language.Title;//页面中的Title值取语言文件里的Title值15 ViewBag.Message = "Your application description page.";16 17 return View();18 }19 20 public ActionResult Contact()21 {22 ViewBag.Title = Resources.Language.Title;//页面中的Title值取语言文件里的Title值23 ViewBag.Message = "Your contact page.";24 25 return View();26 }27 [WithoutLocalization]//这个函数不走Localization过滤器28 public ActionResult ChangeLanguage(String NewLang, String ReturnUrl)29 {30 if (!ReturnUrl.EndsWith("/"))31 {32 ReturnUrl += "/";33 }34 //use NewLang replace old lang,include input judgment35 if (!string.IsNullOrEmpty(ReturnUrl) && ReturnUrl.Length > 3 && ReturnUrl.StartsWith("/") && ReturnUrl.IndexOf("/", 1) > 0 && new string[] { "zh-CN", "en-US","ja-JP" }.Contains(ReturnUrl.Substring(1, ReturnUrl.IndexOf("/", 1) - 1)))36 {37 ReturnUrl = $"/{NewLang}{ReturnUrl.Substring(ReturnUrl.IndexOf("/", 1))}";38 }39 else40 {41 ReturnUrl = $"/{NewLang}{ReturnUrl}";42 }43 return Redirect(ReturnUrl);//redirect to new url44 }45 }46 }
注意:我在使用vs2015 express for web时,出现了使用Resources.Language时智能提示没出现Title的情况,此时去找一下Language.designer.cs里有无以下代码,如果没有的话则以后添加键值对的时候你们都要在此手动添加,或者把Language文件夹建在Controllers的同级目录下然后再新建资源文件等操作也能解决该问题。
1 ///2 /// 查找类似 标题 的本地化字符串。3 /// 4 internal static string Title {5 get {6 return ResourceManager.GetString("Title", resourceCulture);7 }8 }
5.修改母版页,添加了修改语言的link
1
6.Views/Home的三个页面我都加了显示ViewBag.Title值的代码
1@ViewBag.Title.
7.现在我们来运行,看一下效果
首次登录的时候因为url是localhost:50062/,没有语言项,所以读取浏览器默认语言“zh-CN”,然后重定向。以下是点击导航栏的en-US和ja-JP时的情况
8.如果用户直接输入
程序会重定向到里保存的语言项OR浏览器默认语言/Home/Index/基本做到了和MSDN效果一样。
本文Demo下载:
本文参考了:
使用特性(Attribute)可以将描述程序集的信息和描述程序集中任何类型和成员的信息添加到程序集的元数据和IL代码中,程序可以在运行时通过反射获取到这些信息;
一、通过直接或间接的继承自抽象类System.Attribute可以创建自定义的特性类,自定义的特性类必须声明为公共类,命名一般使用Attribute结尾以保证可读性,自定义特性可以附加到大多数元素声明中,也可以使用特性System.AttributeUsage(该特性只能用于特性类声明)指定该特性所能生效的范围及其它特性特征参数:
[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = true)] //其中,枚举组合AttributeTargets指定该特性生效的范围,默认为All即所有范围; //布尔值Inherited指定应用该特性的成员在派生类中是否会继承该特性,默认为true; //布尔值AllowMultiple指定能否为同一个元素指定多个此特性,默认为falsepublic class MyselfAttribute : Attribute{ public string ClassName { get; private set; } public string Author; public MyselfAttribute(string className) { this.className = className; }}
其中特性类的构造函数中的参数称为位置参数(Positional Parameters),类中的其他公共字段和属性称为命名参数(Named Parameter), 通常情况下,将所有必选的参数定义为位置参数,将所有可选的参数定义为命名参数;特性类和普通类一样可以进行构造函数的重载以适应各种情况下初始化参数的组合使用;
二、使用特性时,通过方括号[]将特性名称括起来,并置于使用该特性的元素声明的上方或前方以指定特性,使用时可以省略Attribute后缀,根据想要初始化时调用特性类构造函数的不同,需要将该构造函数所需的参数(即位置参数)的值按照顺序传入,还可以选择是否指定命名参数的值,命名参数的值通过赋值运算符=显式指定:
[Myself("MyClass", Author = "Me")] //这个声明在概念上等效于://MyselfAttribute myselfObj = new MyselfAttribute("MyClass");//myselfObj.Author = "Me";//[Myself("MyClass", Author = "You")] //特性Myself可以对同一元素指定多次//也可以将多个特性合并在一个方括号里://[Myself("MyClass", Author = "Me"), Myself("MyClass", Author = "You")]public class MyClass{ public void MyFunc([Myself("MyParameter")]int myNum) //在方法参数列表中给参数指定特性 { //do… }}
经过编译后,在元数据中查看到的类型定义中的特性信息:
TypeDef #1 (02000002)------------------------------------------------------- TypDefName: MyClass (02000002) Flags : [Public] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit] (00100001) Extends : 01000013 [TypeRef] System.Object Method #1 (06000001) ------------------------------------------------------- MethodName: MyFunc (06000001) Flags : [Public] [Virtual] [HideBySig] [NewSlot] (000001c6) RVA : 0x00002050 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: I4 1 Parameters (1) ParamToken : (08000001) Name : myNum flags: [none] (00000000) CustomAttribute #1 (0c000003) ------------------------------------------------------- CustomAttribute Type: 06000009 CustomAttributeName: MyselfAttribute :: instance void .ctor(class System.String) Length: 16 Value : 01 00 0b 4d 79 50 61 72 61 6d 65 74 65 72 00 00 > MyParameter < ctor args: ("MyParameter") Method #2 (06000002) ------------------------------------------------------- MethodName: .ctor (06000002) Flags : [Public] [HideBySig] [ReuseSlot] [SpecialName] [RTSpecialName] [.ctor] (00001886) RVA : 0x0000205a ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] hasThis ReturnType: Void No arguments. CustomAttribute #1 (0c000015) ------------------------------------------------------- CustomAttribute Type: 06000009 CustomAttributeName: MyselfAttribute :: instance void .ctor(class System.String) Length: 24 Value : 01 00 07 4d 79 43 6c 61 73 73 01 00 54 0e 06 41 > MyClass T A< : 75 74 68 6f 72 02 4d 65 >uthor Me < ctor args: ("MyClass")
在IL代码中查看到的类型定义中的特性信息:
三、系统预定义的一些常用特性:
四、特性通常配合反射起作用,在指定的时机通过反射获得自定义特性并对其进行操作,具体内容在下一章中介绍;
/// base64上传图片 /// ///成功上传返回上传后的文件名 [HttpPost] public async TaskUpLoadImageBase64() { HttpContextBase context = (HttpContextBase)Request.Properties["MS_HttpContext"]; string text = context.Request.Form["file"]; Stream stream = new MemoryStream(Convert.FromBase64String(text.Split(',')[1])); using (HttpClient client = new HttpClient()) { var request = new HttpRequestMessage(HttpMethod.Post, ConfigurationManager.AppSettings["Imgaes"].ToString() + "/Upload"); var content = new MultipartFormDataContent(); //client.DefaultRequestHeaders.Add("fileext", HttpContext.Request.Headers["fileext"]); content.Add(new StreamContent(stream), "file", "file.jpg"); request.Content = content; var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var filenamestr = await response.Content.ReadAsStringAsync();//返回结果 } return Ok(); }
需要引用的命名空间:
读取的具体应用:
this代表本实体(对象),通过PopulateObject,直接将读取到的json数据与对象进行绑定
Json保存的具体应用:
将对象保存为Json
JObject来源如下图: