一、EF的左连接
在EF中,当在dbset使用join关联多表查询时,连接查询的表如果没有建立相应的外键关系时,EF生成的SQL语句是inner join(内联),对于inner join,有所了解的同学都知道,很多时候这并不是我们的本意,实例如下:
var list = from o in context.CTMS_OD_ORDERS
join d in context.CTMS_SUP_DOCTOR
on o.OWNERDOCID equals d.USERID
join e in context.CTMS_OD_ORDERSEVALUATION
on o.ORDERID equals e.ORDERID
select o;`
EF生成了内连接(inner join)查询,当两个表的任一表的数据不匹配时,查询结果就为空!实际上left join(左联接)才是我们想要的,那么怎么样才能生成left join查询呢?其实只要我们如下改造,EF就能为我们生成left join(左联接)查询!
data = from o in context.CTMS_OD_ORDERS
join d in context.CTMS_SUP_DOCTOR
on o.OWNERDOCID equals d.USERID into dc
from dci in dc.DefaultIfEmpty()
join e in context.CTMS_OD_ORDERSEVALUATION
on o.ORDERID equals e.ORDERID into ec
from eci in ec.DefaultIfEmpty()
where o.USERID == userID && (string.IsNullOrEmpty(type) || o.PRODUCTNAME.Contains(type))
select new ODOrders
{
BalanceStatus = o.BALANCESTATUS,
ChannelOrderID = o.CHANNELORDERID,
ChannelType = o.CHANNELTYPE,
CreateDateTime = o.CREATEDATETIME,
CreateUserID = o.CREATEUSERID,
CreateUserName = o.CREATEUSERNAME,
DocName = dci.DOCNAME,
EvalutionStatus = string.IsNullOrEmpty(eci.ORDERID) ? "0" : "1",
PayTime = o.PAYTIME,
ProductCode = o.PRODUCTCODE,
ProductName = o.PRODUCTNAME,
ProductInstanceId = o.PRODUCTINSTANCEID,
ProductID = o.PRODUCTID,
OrderID = o.ORDERID,
OrderCode = o.ORDERCODE,
OrderStatus = o.ORDERSTATUS,
OrderType=o.ORDERTYPE,
TotalFee = o.TOTALFEE,
UserID=o.USERID,
UserName=o.USERNAME
};
对比上下两种写法,可以看到在on表的后面我们加上了into xx
,还有不要忘记,还需加上from xxx in xx.DefaultIfEmpty()
,重要的就是最后的xx.DefaultIfEmpty()
,它的作用是当连接的表为空时也会有一条空的数据,达到了left join的效果。
二、Linq
Union All/Union/Intersect操作
适用场景:对两个集合的处理,例如追加、合并、取相同项、相交项等等。
Concat(连接)
说明:连接不同的集合,不会自动过滤相同项;延迟。
1.简单形式:
var q = ( from c in db.Customers select c.Phone ).Concat( from c in db.Customersselect c.Fax ).Concat( from e in db.Employees select e.HomePhone );
语句描述:返回所有消费者和雇员的电话和传真。
2.复合形式:
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(合并)
说明:连接不同的集合,自动过滤相同项;延迟。即是将两个集合进行合并操作,过滤相同的项。
var q = ( from c in db.Customers select c.Country ).Union( from e in db.Employeesselect e.Country );
语句描述:查询顾客和职员所在的国家。
Intersect(相交)
说明:取相交项;延迟。即是获取不同集合的相同项(交集)。即先遍历第一个集合,找出所有唯一的元素,然后遍历第二个集合,并将每个元素与前面找出的元素作对比,返回所有在两个集合内都出现的元素。
var q = ( from c in db.Customers select c.Country ).Intersect( from e in db.Employeesselect e.Country );
语句描述:查询顾客和职员同在的国家。
Except(与非)
说明:排除相交项;延迟。即是从某集合中删除与另一个集合中相同的项。先遍历第一个集合,找出所有唯一的元素,然后再遍历第二个集合,返回第二个集合中所有未出现在前面所得元素集合中的元素。
var q = ( from c in db.Customers select c.Country ).Except( from e in db.Employeesselect e.Country );
语句描述:查询顾客和职员不同的国家。
Top/Bottom操作
适用场景:适量的取出自己想要的数据,不是全部取出,这样性能有所加强。
Take
说明:获取集合的前n个元素;延迟。即只返回限定数量的结果集。
var q = ( from e in db.Employees orderby e.HireDate select e) .Take(5);
语句描述:查询出最早5位雇用的雇员。
Skip
说明:跳过集合的前n个元素;延迟。即我们跳过给定的数目返回后面的结果集。
var q = ( from p in db.Products orderby p.UnitPrice descending select p) .Skip(10);
语句描述:查询出第11个最贵产品后面的所有产品。
TakeWhile
说明:直到某一条件成立就停止获取;延迟。即用其条件去依次判断源序列中的元素,返回符合判断条件的元素,该判断操作将在返回false或源序列的末尾结束 。
SkipWhile
说明:直到某一条件成立就停止跳过;延迟。即用其条件去判断源序列中的元素并且跳过第一个符合判断条件的元素,一旦判断返回false,接下来将不再进行判断并返回剩下的所有元素。
Paging(分页)操作
适用场景:结合Skip和Take就可实现对数据分页操作。
var q = ( from c in db.Customers orderby c.ContactName select c) .Skip(50) .Take(10);
语句描述:跳过前50条记录,取出接下来的10条记录,形成乘积表在第6页显示。
var q = ( from p in db.Products where p.ProductID > 50 orderby p.ProductID select p) .Take(10);
SqlMethods操作
在LINQ to SQL语句中,为我们提供了SqlMethods操作,进一步为我们提供了方便,例如Like方法用于自定义通配表达式,Equals用于相比较是否相等。
Like
自定义的通配表达式。%表示零长度或任意长度的字符串;_表示一个字符;[]表示在某范围区间的一个字符;[^]表示不在某范围区间的一个字符。比如查询消费者ID以“C”开头的消费者。
var q = from c in db.Customers where SqlMethods.Like(c.CustomerID, "C%") select c;
比如查询消费者ID没有“AXOXT”形式的消费者:
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
var q = from o in db.Orders where SqlMethods .DateDiffDay(o.OrderDate, o.ShippedDate) < 10 select o;
语句描述:查询所有10天之内的订单。
Compiled Query操作
说明:在之前我们没有好的方法对写出的SQL语句进行编辑重新查询,现在我们可以这样做,看下面一个例子:
//1.创建compiled query NorthwindDataContext db = new NorthwindDataContext(); var fn =CompiledQuery.Compile( (NorthwindDataContext db2, string city) => from c indb2.Customers where c.City == city select c); //2.查询城市为London的消费者,用LonCusts集合表示,这时可以用数据控件绑定 var LonCusts = fn(db, "London"); //3.查询城市为Seattle的消费者var SeaCusts = fn(db, "Seattle");
其他:IQueryable,IEnumerable,List相互转换:
IQueryable,IEnumerable都可以通过ToList()转换为类型。
其次
如果需要反向转换,有两个很好用的方法AsQueryable(),AsEnumerable(),可以顺利将List转换为IQueryable,IEnumerable。
List去重的表达式方法:
users.Where((x,i)=>users.FindIndex(z=>z.name == x.name) == i)
RedirectToAction
RedirectToAction跳转到 Aaea 的重定向:
例如:
1 using System.Web.Mvc; 2 3 namespace web.Areas.FrameSet 4 { 5 public class FrameSetAreaRegistration : AreaRegistration 6 { 7 public override string AreaName 8 { 9 get 10 { 11 return "FrameSet"; 12 } 13 } 14 15 public override void RegisterArea(AreaRegistrationContext context) 16 { 17 context.MapRoute( 18 "FrameSet_default", 19 "FrameSet/{controller}/{action}/{id}", 20 new { controller = "Frame", action = "Main", id = UrlParameter.Optional }, 21 new string[] { "web.Areas.FrameSet.Controllers" } 22 ); 23 } 24 } 25 } 26 27 28 //重定向 29 RedirectToAction("Main", "Frame", new { area = "FrameSet", a = 2, b = "b" });
1 // 2 // 摘要: 3 // Creates a System.Web.Mvc.RedirectResult object that redirects to the specified 4 // URL. 5 // 6 // 参数: 7 // url: 8 // The URL to redirect to. 9 // 10 // 返回结果: 11 // The redirect result object. 12 protected internal virtual RedirectResult Redirect(string url); 13 // 14 // 摘要: 15 // Returns an instance of the System.Web.Mvc.RedirectResult class with the Permanent 16 // property set to true. 17 // 18 // 参数: 19 // url: 20 // The URL to redirect to. 21 // 22 // 返回结果: 23 // An instance of the System.Web.Mvc.RedirectResult class with the Permanent property 24 // set to true. 25 protected internal virtual RedirectResult RedirectPermanent(string url); 26 // 27 // 摘要: 28 // Redirects to the specified action using the action name. 29 // 30 // 参数: 31 // actionName: 32 // The name of the action. 33 // 34 // 返回结果: 35 // The redirect result object. 36 protected internal RedirectToRouteResult RedirectToAction(string actionName); 37 // 38 // 摘要: 39 // Redirects to the specified action using the action name and route values. 40 // 41 // 参数: 42 // actionName: 43 // The name of the action. 44 // 45 // routeValues: 46 // The parameters for a route. 47 // 48 // 返回结果: 49 // The redirect result object. 50 protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues); 51 // 52 // 摘要: 53 // Redirects to the specified action using the action name and route dictionary. 54 // 55 // 参数: 56 // actionName: 57 // The name of the action. 58 // 59 // routeValues: 60 // The parameters for a route. 61 // 62 // 返回结果: 63 // The redirect result object. 64 protected internal RedirectToRouteResult RedirectToAction(string actionName, RouteValueDictionary routeValues); 65 // 66 // 摘要: 67 // Redirects to the specified action using the action name and controller name. 68 // 69 // 参数: 70 // actionName: 71 // The name of the action. 72 // 73 // controllerName: 74 // The name of the controller. 75 // 76 // 返回结果: 77 // The redirect result object. 78 protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName); 79 // 80 // 摘要: 81 // Redirects to the specified action using the action name, controller name, and 82 // route dictionary. 83 // 84 // 参数: 85 // actionName: 86 // The name of the action. 87 // 88 // controllerName: 89 // The name of the controller. 90 // 91 // routeValues: 92 // The parameters for a route. 93 // 94 // 返回结果: 95 // The redirect result object. 96 protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName, object routeValues); 97 // 98 // 摘要: 99 // Redirects to the specified action using the action name, controller name, and 100 // route values. 101 // 102 // 参数: 103 // actionName: 104 // The name of the action. 105 // 106 // controllerName: 107 // The name of the controller. 108 // 109 // routeValues: 110 // The parameters for a route. 111 // 112 // 返回结果: 113 // The redirect result object. 114 protected internal virtual RedirectToRouteResult RedirectToAction(string actionName, string controllerName, RouteValueDictionary routeValues);
RedirectToRoute,跳转到路由的重定向:
例如:
1 public class RouteConfig 2 { 3 /// <summary> 4 /// 注册路由 5 /// </summary> 6 /// <param name="routes">路由控制器</param> 7 public static void RegisterRoutes(RouteCollection routes) 8 { 9 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 10 routes.IgnoreRoute("Draw/{*pathInfo}"); 11 12 13 routes.MapRoute( 14 name: "Default", 15 url: "{controller}/{action}/{id}", 16 defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional } 17 ); 18 routes.MapRoute( 19 "CatchAll", 20 "{*dynamicRoute}", 21 new { controller = "Dynamic", action = "Index" } 22 ); 23 } 24 } 25 26 27 //重定向;若Area 的Controller重定向到 外面的Controller 28 RedirectToRoute("Default", new { controller = "Error", action = "ErrorMessage", message = "" });
1 // 2 // 摘要: 3 // Redirects to the specified route using the specified route values. 4 // 5 // 参数: 6 // routeValues: 7 // The parameters for a route. 8 // 9 // 返回结果: 10 // The redirect-to-route result object. 11 protected internal RedirectToRouteResult RedirectToRoute(object routeValues); 12 // 13 // 摘要: 14 // Redirects to the specified route using the route dictionary. 15 // 16 // 参数: 17 // routeValues: 18 // The parameters for a route. 19 // 20 // 返回结果: 21 // The redirect-to-route result object. 22 protected internal RedirectToRouteResult RedirectToRoute(RouteValueDictionary routeValues); 23 // 24 // 摘要: 25 // Redirects to the specified route using the route name. 26 // 27 // 参数: 28 // routeName: 29 // The name of the route. 30 // 31 // 返回结果: 32 // The redirect-to-route result object. 33 protected internal RedirectToRouteResult RedirectToRoute(string routeName); 34 // 35 // 摘要: 36 // Redirects to the specified route using the route name and route values. 37 // 38 // 参数: 39 // routeName: 40 // The name of the route. 41 // 42 // routeValues: 43 // The parameters for a route. 44 // 45 // 返回结果: 46 // The redirect-to-route result object. 47 protected internal RedirectToRouteResult RedirectToRoute(string routeName, object routeValues); 48 // 49 // 摘要: 50 // Redirects to the specified route using the route name and route dictionary. 51 // 52 // 参数: 53 // routeName: 54 // The name of the route. 55 // 56 // routeValues: 57 // The parameters for a route. 58 // 59 // 返回结果: 60 // The redirect-to-route result object. 61 protected internal virtual RedirectToRouteResult RedirectToRoute(string routeName, RouteValueDictionary routeValues);
转从:http://blog.sina.com.cn/s/blog_497dbcd10100a81s.html
转从:https://www.cnblogs.com/shanshanlaichi/p/6666093.html