All posts by 龙生
MySql 里的IFNULL、NULLIF和ISNULL用法
今天用到了MySql里的isnull才发现他和MSSQL里的还是有点区别,现在简单总结一下: mysql中isnull,ifnull,nullif的用法如下: isnull(expr) 的用法: 如expr 为null,那么isnull() 的返回值为 1,否则返回值为 0。 mysql> select isnull(1+1); -> 0 mysql> select isnull(1/0); -> 1 使用= 的null 值对比通常是错误的。 isnull() 函数同 is null比较操作符具有一些相同的特性。请参见有关is null 的说明。 IFNULL(expr1,expr2)的用法: 假如expr1 不为 NULL,则 IFNULL() 的返回值为 expr1; 否则其返回值为 expr2。IFNULL()的返回值是数字或是字符串,具体情况取决于其所使用的语境。 mysql> SELECT IFNULL(1,0); -> 1 mysql> SELECT IFNULL(NULL,10); -> 10 mysql> SELECT IFNULL(1/0,10); -> 10 mysql> SELECT IFNULL(1/0,’yes'); -> 'yes' IFNULL(expr1,expr2)的默认结果值为两个表达式中更加“通用”的一个,顺序为STRING、 REAL或 INTEGER。假设一个基于表达式的表的情况, 或MySQL必须在内存储器中储存一个临时表中IFNULL()的返回值: CREATE TABLE tmp SELECT IFNULL(1,’test') AS test; 在这个例子中,测试列的类型为 CHAR(4)。 NULLIF(expr1,expr2) 的用法: 如果expr1 = expr2 成立,那么返回值为NULL,否则返回值为 expr1。这和CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END相同。 mysql> SELECT NULLIF(1,1); […]
View Detailsc# windows服务状态、启动和停止服务
首先先引用System.ServiceProcess.dll 然后在引用命名空间using System.ServiceProcess; ServiceController sc = new ServiceController("Server");建立服务对象 //服务运行则停止服务 if (sc.Status.Equals(ServiceControllerStatus.Running)) { sc.Stop(); sc.Refresh(); } //服务停止则启动服务 if ((sc.Status.Equals(ServiceControllerStatus.Stopped)) || (sc.Status.Equals(ServiceControllerStatus.StopPending))) { sc.Start(); sc.Refresh(); } from:http://www.cnblogs.com/luluping/archive/2010/08/27/1809896.html
View Details5天玩转C#并行和多线程编程 —— 第三天 认识和使用Task
对于多线程,我们经常使用的是Thread。在我们了解Task之前,如果我们要使用多核的功能可能就会自己来开线程,然而这种线程模型在.net 4.0之后被一种称为基于“任务的编程模型”所冲击,因为task会比thread具有更小的性能开销,不过大家肯定会有疑惑,任务和线程到底有什么区别呢? 任务和线程的区别: 1、任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执行。 2、任务跟线程不是一对一的关系,比如开10个任务并不是说会开10个线程,这一点任务有点类似线程池,但是任务相比线程池有很小的开销和精确的控制。 一、认识Task和Task的基本使用 1、认识Task 首先来看一下Task的继承结构。Task标识一个异步操作。 可以看到Task和Thread一样,位于System.Threading命名空间下,这也就是说他们直接有密不可分的联系。下面我们来仔细看一下吧! 2、创建Task 创建Task的方法有两种,一种是直接创建——new一个出来,一种是通过工厂创建。下面来看一下这两种创建方法:
|
1 2 3 4 5 |
//第一种创建方式,直接实例化 var task1 = new Task(() => { //TODO you code }); |
这是最简单的创建方法,可以看到其构造函数是一个Action,其构造函数有如下几种,比较常用的是前两种。
|
1 2 3 4 5 |
//第二种创建方式,工厂创建 var task2 = Task.Factory.StartNew(() => { //TODO you code }); |
这种方式通过静态工厂,创建以个Task并运行。下面我们来建一个控制台项目,演示一下,代码如下: 要添加System.Threading.Tasks命名控件引用。
|
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 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace TaskDemo { class Program { static void Main(string[] args) { var task1 = new Task(() => { Console.WriteLine("Hello,task"); }); task1.Start(); var task2 = Task.Factory.StartNew(() => { Console.WriteLine("Hello,task started by task factory"); }); Console.Read(); } } } |
这里我分别用两种方式创建两个task,并让他们运行。可以看到通过构造函数创建的task,必须手动Start,而通过工厂创建的Task直接就启动了。 下面我们来看一下Task的声明周期,编写如下代码:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var task1 = new Task(() => { Console.WriteLine("Begin"); System.Threading.Thread.Sleep(2000); Console.WriteLine("Finish"); }); Console.WriteLine("Before start:" + task1.Status); task1.Start(); Console.WriteLine("After start:" + task1.Status); task1.Wait(); Console.WriteLine("After Finish:" + task1.Status); Console.Read(); |
task1.Status就是输出task的当前状态,其输出结果如下: 可以看到调用Start前的状态是Created,然后等待分配线程去执行,到最后执行完成。 从我们可以得出Task的简略生命周期: Created:表示默认初始化任务,但是“工厂创建的”实例直接跳过。 WaitingToRun: 这种状态表示等待任务调度器分配线程给任务执行。 RanToCompletion:任务执行完毕。 成员名称 说明 Canceled 该任务已通过对其自身的 CancellationToken 引发 OperationCanceledException 对取消进行了确认,此时该标记处于已发送信号状态;或者在该任务开始执行之前,已向该任务的 CancellationToken 发出了信号。 有关详细信息,请参阅任务取消。 Created 该任务已初始化,但尚未被计划。 Faulted 由于未处理异常的原因而完成的任务。 RanToCompletion 已成功完成执行的任务。 Running 该任务正在运行,但尚未完成。 WaitingForActivation 该任务正在等待 .NET Framework 基础结构在内部将其激活并进行计划。 WaitingForChildrenToComplete 该任务已完成执行,正在隐式等待附加的子任务完成。 WaitingToRun 该任务已被计划执行,但尚未开始执行。 二、Task的任务控制 Task最吸引人的地方就是他的任务控制了,你可以很好的控制task的执行顺序,让多个task有序的工作。下面来详细说一下: 1、Task.Wait 在上个例子中,我们已经使用过了,task1.Wait();就是等待任务执行完成,我们可以看到最后task1的状态变为Completed。 2、Task.WaitAll 看字面意思就知道,就是等待所有的任务都执行完成,下面我们来写一段代码演示一下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
static void Main(string[] args) { var task1 = new Task(() => { Console.WriteLine("Task 1 Begin"); System.Threading.Thread.Sleep(2000); Console.WriteLine("Task 1 Finish"); }); var task2 = new Task(() => { Console.WriteLine("Task 2 Begin"); System.Threading.Thread.Sleep(3000); Console.WriteLine("Task 2 Finish"); }); task1.Start(); task2.Start(); Task.WaitAll(task1, task2); Console.WriteLine("All task finished!"); Console.Read(); } |
其输出结果如下: 可以看到,任务一和任务二都完成以后,才输出All task finished! 3、Task.WaitAny 这个用法同Task.WaitAll,就是等待任何一个任务完成就继续向下执行,将上面的代码WaitAll替换为WaitAny,输出结果如下: 4、Task.ContinueWith 就是在第一个Task完成后自动启动下一个Task,实现Task的延续,下面我们来看下他的用法,编写如下代码:
|
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 |
static void Main(string[] args) { var task1 = new Task(() => { Console.WriteLine("Task 1 Begin"); System.Threading.Thread.Sleep(2000); Console.WriteLine("Task 1 Finish"); }); var task2 = new Task(() => { Console.WriteLine("Task 2 Begin"); System.Threading.Thread.Sleep(3000); Console.WriteLine("Task 2 Finish"); }); task1.Start(); task2.Start(); var result = task1.ContinueWith<string>(task => { Console.WriteLine("task1 finished!"); return "This is task result!"; }); Console.WriteLine(result.Result.ToString()); Console.Read(); } |
执行结果如下: 可以看到,task1完成之后,开始执行后面的内容,并且这里我们取得task的返回值。 在每次调用ContinueWith方法时,每次会把上次Task的引用传入进来,以便检测上次Task的状态,比如我们可以使用上次Task的Result属性来获取返回值。我们还可以这么写:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var SendFeedBackTask = Task.Factory.StartNew(() => { Console.WriteLine("Get some Data!"); }) .ContinueWith<bool>(s => { return true; }) .ContinueWith<string>(r => { if (r.Result) { return "Finished"; } else { return "Error"; } }); Console.WriteLine(SendFeedBackTask.Result); |
首先输出Get some data,然后执行第二个获得返回值true,最后根据判断返回Finished或error。输出结果: Get some Data! Finished 其实上面的写法简化一下,可以这样写:
|
1 |
Task.Factory.StartNew<string>(() => {return "One";}).ContinueWith(ss => { Console.WriteLine(ss.Result);}); |
输出One,这个可以看明白了吧~ […]
View Details导出csv时,在数据项前加上等号可以防止长数字以指数表示
今天帮同事导数据(csv格式),发现大数字问题以指数形式表示,这倒没什么问题,把excel的单元格拉宽一些就行了。可是有些是以0开头的字符也被以指数化了,而且把前面的0丢掉了,这是个大问题。网上查尽资料,没找到好的办法,记得看过别人导的数据加了等号,当时不理解,试了一下,果然是解决这个问题的~
View DetailsThinkpad笔记本各系列型号的区别
T系列,旗舰系列,综合性能做好的,低中高配置都有,显卡,集成,低端入门独显,或是双显卡,内建光驱,可以非常方便的更换成硬盘或是电池。键盘7排设计,磨砂屏幕,有的是高分屏,键盘灯设计。14寸或是15.6寸的机器。也有轻薄性的带s的,比如T420s,比普通的T重量轻一些。薄一些。也有一部分低配置的带i后缀的机器。很多机器都配备指纹识别器。T系列,适合于对性能有一定要求,移动性稍微少一些的商业用户。基本价格6000以上。 X系列,移动旗舰。12寸的设计,全系列集成下那可,没有内建光驱,重量轻,电池使用时间长,其他键盘,屏幕等特点的跟T系列差不多。也有更轻薄型。X系列中,还有一部分带有t后缀的可以旋转屏幕的平板机器,一般是电磁笔控制,有的也有手触功能。比如T201t。该系列适合经常出差的商业人士。基本价格5500以上。 W系列,移动工作站系列,一般是15.6寸设计,曾有过17寸设计,但是可能是因为价格问题,不做了。性能最强的系列。使用半专业显卡,这些显卡驱动针对专用工具进行过优化,速度更快。其他的特点,跟T系列差不多。但是没有带s后缀的轻薄型了。W系列适合那些设计人员,或是对性能要求比较高的移动商业用户。价格一般都是8000以上开始。 R系列,采用了 Intel Centrino Duo 移动技术 – 包括 Intel Core™2 Duo 处理器,可以提高性能、增强可管理性并且延长电池寿命。 E系列,基本说是挂牌系列,除了指点杆,没有什么硬件上面的thinkpad的特点。也就是除了指点杆,跟其他品牌是一样的。没什么大的优势。现在的出机器,基本都是巧克力键盘。该系列部分机器还带背光的。6排键盘设计。尺寸从12到15.6都有。一般都是普通分辨率的镜面屏幕。外壳有多种颜色,比如红色。该系列,配置一般主流,很多都是中端独立显卡。适合家用用户。 sl系列,联想2008年推出的低价系列,但是因为做工问题,已经停产了。基本特点跟E系列差不多。 S系列,基本就是E系列中的带s后缀的机器,单独排列了一个系列而已。价格高,特点同E系列。 from:http://zhidao.baidu.com/link?url=h-cpOxeraqIwugNVUHPoSF-B0DrhPAeadAB-p5QsXmCHwmV_q0QCMFxviggEk6VmZb9Qz38Jnv-kxVIl2a0--q
View Details线程同步(C# 和 Visual Basic)
以下各节描述了在多线程应用程序中可以用来同步资源访问的功能和类。 在应用程序中使用多个线程的一个好处是每个线程都可以异步执行。对于 Windows 应用程序,耗时的任务可以在后台执行,而使应用程序窗口和控件保持响应。对于服务器应用程序,多线程处理提供了用不同线程处理每个传入请求的能力。否则,在完全满足前一个请求之前,将无法处理每个新请求。 然而,线程的异步特性意味着必须协调对资源(如文件句柄、网络连接和内存)的访问。否则,两个或更多的线程可能在同一时间访问相同的资源,而每个线程都不知道其他线程的操作。结果将产生不可预知的数据损坏。 对于整数数据类型的简单操作,可以用 Interlocked 类的成员来实现线程同步。对于其他所有数据类型和非线程安全的资源,只有使用本主题中的结构才能安全地执行多线程处理。 有关多线程编程的背景信息,请参见: Managed Threading Basics Using Threads and Threading Managed Threading Best Practices 锁和 SyncLock 关键字 lock (C#) 和 SyncLock (Visual Basic) 语句可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。 lock 或 SyncLock 语句有一个作为参数的对象,在该参数的后面还有一个一次只能由一个线程执行的代码块。例如: C#
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class TestThreading { private System.Object lockThis = new System.Object(); public void Process() { lock (lockThis) { // Access thread-sensitive resources. } } } |
提供给 lock 关键字的参数必须为基于引用类型的对象,该对象用来定义锁的范围。在上面的示例中,锁的范围限定为此函数,因为函数外不存在任何对对象 lockThis 的引用。如果确实存在此类引用,锁的范围将扩展到该对象。严格地说,提供的对象只是用来唯一地标识由多个线程共享的资源,所以它可以是任意类实例。然而,实际上,此对象通常表示需要进行线程同步的资源。例如,如果一个容器对象将被多个线程使用,则可以将该容器传递给 lock,而 lock 后面的同步代码块将访问该容器。只要其他线程在访问该容器前先锁定该容器,则对该对象的访问将是安全同步的。 通常,最好避免锁定 public 类型或锁定不受应用程序控制的对象实例。例如,如果该实例可以被公开访问,则 lock(this) 可能会有问题,因为不受控制的代码也可能会锁定该对象。这可能导致死锁,即两个或更多个线程等待释放同一对象。出于同样的原因,锁定公共数据类型(相比于对象)也可能导致问题。锁定字符串尤其危险,因为字符串被公共语言运行时 (CLR)“暂留”。这意味着整个程序中任何给定字符串都只有一个实例,就是这同一个对象表示了所有运行的应用程序域的所有线程中的该文本。因此,只要在应用程序进程中的任何位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中该字符串的所有实例。因此,最好锁定不会被暂留的私有或受保护成员。某些类提供专门用于锁定的成员。例如,Array 类型提供 SyncRoot。许多集合类型也提供 SyncRoot。 有关 lock 和 SyncLock 语句的更多信息,请参见以下主题: “锁定”语句(C# 参考) SyncLock 语句 监视器 监视器 与 lock 和 SyncLock 关键字类似,监视器防止多个线程同时执行代码块。 Enter 方法允许一个且仅一个线程继续执行后面的语句;其他所有线程都将被阻止,直到执行语句的线程调用 Exit。这与使用 lock 关键字一样。例如: C#
|
1 2 3 4 |
lock (x) { DoSomething(); } |
这等效于: C#
|
1 2 3 4 5 6 7 8 9 10 |
System.Object obj = (System.Object)x; System.Threading.Monitor.Enter(obj); try { DoSomething(); } finally { System.Threading.Monitor.Exit(obj); } |
使用 lock (C#) 或 SyncLock (Visual Basic) 关键字通常比直接使用 Monitor […]
View Details“锁定”语句(C# 参考)
lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。 下面的示例包含一个 lock 语句。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class Account { decimal balance; private Object thisLock = new Object(); public void Withdraw(decimal amount) { lock (thisLock) { if (amount > balance) { throw new Exception("Insufficient funds"); } balance -= amount; } } } |
有关更多信息,请参见 线程同步(C# 和 Visual Basic)。 备注 lock 关键字可确保当一个线程位于代码的临界区时,另一个线程不会进入该临界区。 如果其他线程尝试进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。 线程处理(C# 和 Visual Basic) 这节讨论了线程处理。 lock 关键字在块的开始处调用 Enter,而在块的结尾处调用 Exit。 ThreadInterruptedException 引发,如果 Interrupt 中断等待输入 lock 语句的线程。 通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。 常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则: 如果实例可以被公共访问,将出现 lock (this) 问题。 如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。 由于进程中使用同一字符串的任何其他代码都将共享同一个锁,所以出现 lock("myLock") 问题。 最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。 在 lock 语句的正文不能使用 等待 关键字。 示例 下面演示在 C# 中使用未锁定的线程的简单示例。 C#
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//using System.Threading; class ThreadTest { public void RunMe() { Console.WriteLine("RunMe called"); } static void Main() { ThreadTest b = new ThreadTest(); Thread t = new Thread(b.RunMe); t.Start(); } } // Output: RunMe called |
示例 下例使用线程和 lock。 只要 lock 语句存在,语句块就是临界区并且 balance 永远不会是负数。 C#
|
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 |
// using System.Threading; class Account { private Object thisLock = new Object(); int balance; Random r = new Random(); public Account(int initial) { balance = initial; } int Withdraw(int amount) { // This condition never is true unless the lock statement // is commented out. if (balance < 0) { throw new Exception("Negative Balance"); } // Comment out the next line to see the effect of leaving out // the lock keyword. lock (thisLock) { if (balance >= amount) { Console.WriteLine("Balance before Withdrawal : " + balance); Console.WriteLine("Amount to Withdraw : -" + amount); balance = balance - amount; Console.WriteLine("Balance after Withdrawal : " + balance); return amount; } else { return 0; // transaction rejected } } } public void DoTransactions() { for (int i = 0; i < 100; i++) { Withdraw(r.Next(1, 100)); } } } class Test { static void Main() { Thread[] threads = new Thread[10]; Account acc = new Account(1000); for (int i = 0; i < 10; i++) { Thread t = new Thread(new ThreadStart(acc.DoTransactions)); threads[i] = t; } for (int i = 0; i < 10; i++) { threads[i].Start(); } } } |
from:https://msdn.microsoft.com/zh-cn/library/c5kehkcz.aspx
View DetailsUnsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.
一.问题描述 014-12-15 20:00:29 4398 [Warning] Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT… ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe Statement: INSERT INTO longxibendi (lxid, l_id, l_aplply, l_types, ctimes) VALUES (75692, 218, 8, 2, 1418644829) ON DUPLICATE KEY UPDATE ctimes=1418644829 一个mysql master 的err log 报上面的错误。 二.问题原因 查了下原因,longxibendi这个表上有2个唯一键。则使用 INSERT… ON DUPLICATE KEY UPDATE ,且当前数据库binlog_format是statement格式,这种sql语句就会报unsafe。 查了下手册 INSERT … ON DUPLICATE KEY UPDATE statements on tables with multiple primary or unique keys. When executed against a table that contains more than one primary or unique key, this statement is considered unsafe, being sensitive to the order in which the storage engine checks the keys, which is not deterministic, and on which the choice of rows updated by the MySQL Server depends. An INSERT … ON DUPLICATE KEY UPDATE statement against a […]
View Detailsmysql报错IP address could not be resolved解决方法
这个警告不会影响数据库的访问 但是当有大量的这种日志产生的时候,数据库之前的错误信息 就会很难去查询了。连接数越多,产生报警日志的频率越高。 一、错误描述 数据库的alert.log中,我们经常会出现下面的警告:
|
1 2 3 4 5 6 7 8 9 10 11 |
IP address '172.16.12.195' could not be resolved: Temporary failure in name resolution IP address '172.16.12.67' could not be resolved: Temporary failure in name resolution IP address '172.16.12.67' could not be resolved: Temporary failure in name resolution IP address '172.16.12.195' could not be resolved: Temporary failure in name resolution IP address '172.16.12.195' could not be resolved: Temporary failure in name resolution IP address '172.16.12.195' could not be resolved: Temporary failure in name resolution IP address '172.16.12.196' could not be resolved: Temporary failure in name resolution IP address '172.16.12.196' could not be resolved: Temporary failure in name resolution IP address '172.16.12.195' could not be resolved: Temporary failure in name resolution IP address '172.16.12.195' could not be resolved: Temporary failure in name resolution IP address '172.16.12.68' could not be resolved: Temporary failure in name resolution |
二、问题产生的原因 出现错误的原因是MYSQL Server在本地内存中维护了一个非本地的Client TCP cache,这个cache中包含了远程Client的登录信息,比如IP地址,hostname等信息。 如果Client连接到服务器后,Mysql首先会在本地TCP池中根据IP地址解析客户端的hostname或者反解析,如果解析不到,就会去DNS中进行解析,如果还是解析失败 就是在error log中写入这样的警告信息。 三、解决的办法: 1、修改配置文件 可以通过两个参数来disable这个功能,在MYSQL的配置文件中[mysqld]中加入下面的参数:
|
1 2 3 |
[mysqld] --skip-host-cache --skip-name-resolve |
重新授权,将所有访问数据库服务器的授权方式都改成IP形式的。
|
1 |
grant all on *.* to ‘root’@’172.16.12.68’identified by ‘123456’; |
2、添加授权。 将所有访问数据库服务器的授权方式都改成IP形式。 不同的用户用不同的用户名和密码。
|
1 2 3 |
grant all on *.* to ‘user_68’@’172.16.12.68’identified by ‘pwd_68’; grant all on *.* to ‘user_67’@’172.16.12.67’identified by ‘pwd_67’; .... |
然后去 mysql数据库下面的 user表 和db表 下面删除掉那些含有含有主机名字的权限记录。 四、总结 1、要么加上
|
1 2 |
--skip-host-cache --skip-name-resolve |
使得MySQL将不再通过DNS解析地址。 2、赋予权限 要么在赋予权限的时候 直接用ip地址,去掉那些用主机名字的权限。 from:http://www.uedsc.com/ip-address-could-not-be-resolved.html
View DetailsEntity Framework 增删改查和事务操作
1、增加对象
|
1 2 3 4 5 6 7 8 9 10 |
DbEntity db = new DbEntity(); //创建对象实体,注意,这里需要对所有属性进行赋值(除了自动增长主键外),如果不赋值,则会数据库中会被设置为NULL(注意是否可空) var user = new User { Name = "bomo", Age = 21, Gender = "male" }; db.User.Add(user); db.SaveChanges(); |
2、删除对象,删除只需要对象的主键
|
1 2 3 4 5 6 7 8 9 10 11 |
DbEntity db = new DbEntity(); //删除只需要主键,这里删除主键为5的行 var user = new User {Id = 5}; //将实体附加到对象管理器中 db.User.Attach(user); //方法一: db.User.Remove(user); //方法二:把当前实体的状态改为删除 //db.Entry(user).State = EntityState.Deleted; db.SaveChanges(); |
3、修改对象 方法一:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
DbEntity db = new DbEntity(); //修改需要对主键赋值,注意:这里需要对所有字段赋值,没有赋值的字段会用NULL更新到数据库 var user = new User { Id = 5, Name = "bomo", Age = 21, Gender = "male" }; //将实体附加到对象管理器中 db.User.Attach(user); //把当前实体的状态改为Modified db.Entry(user).State = EntityState.Modified; db.SaveChanges(); |
方法二:方法一中每次都需要对所有字段进行修改,效率低,而且麻烦,下面介绍修改部分字段
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
DbEntity db = new DbEntity(); //修改需要对主键赋值,注意:这里需要对所有字段赋值,没有赋值的字段会用NULL更新到数据库 var user = new User { Id = 5, Name = "bomo", Age = 21 }; //将实体附加到对象管理器中 db.User.Attach(user); //获取到user的状态实体,可以修改其状态 var setEntry = ((IObjectContextAdapter) db).ObjectContext.ObjectStateManager.GetObjectStateEntry(user); //只修改实体的Name属性和Age属性 setEntry.SetModifiedProperty("Name"); setEntry.SetModifiedProperty("Age"); db.SaveChanges(); |
4、使用事务:使用事务很简单,只要把需要的操作放在 TransactionScope 中,最后提交
|
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 |
DbEntity db = new DbEntity(); using (var scope = new TransactionScope()) { //执行多个操作 var user1 = new User { Name = "bomo", Age = 21, Gender = "male" }; db.User.Add(user1); db.SaveChanges(); var user2 = new User { Name = "toroto", Age = 20, Gender = "female" }; db.User.Add(user2); db.SaveChanges(); //提交事务 scope.Complete(); } |
5、查询:查询通过LinQ查询
|
1 2 3 4 |
DbEntity db = new DbEntity(); //选择部分字段 var user = db.User.Where(u => u.Name == "bomo").Select(u => new {Id = u.Id, Name = u.Name, Age = u.Age}).FirstOrDefault(); //只有调用了FirstOrDefault, First, Single, ToList, ToArray等函数才会执行对数据库的查询 |
from:http://www.cnblogs.com/bomo/p/3331602.html
View Details