Lamda表达式的拼接

一、方法1
首先拼接类(别管为什么,复制就行…)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace FF
{
    //用户lambda表达式的拼接
    public static class PredicateBuilder
    {

        public static Expression<Func<T, bool>> True<T>() { return f => true; }
        public static Expression<Func<T, bool>> False<T>() { return f => false; }
        public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
        {
            // build parameter map (from parameters of second to parameters of first)  
            var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);

            // replace parameters in the second lambda expression with parameters from the first  
            var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);

            // apply composition of lambda expression bodies to parameters from the first expression   
            return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
        }

        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
        {
            return first.Compose(second, Expression.And);
        }

        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
        {
            return first.Compose(second, Expression.Or);
        }
    }
    public class ParameterRebinder : ExpressionVisitor
    {
        private readonly Dictionary<ParameterExpression, ParameterExpression> map;

        public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
        {
            this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
        }

        public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
        {
            return new ParameterRebinder(map).Visit(exp);
        }

        protected override Expression VisitParameter(ParameterExpression p)
        {
            ParameterExpression replacement;
            if (map.TryGetValue(p, out replacement))
            {
                p = replacement;
            }
            return base.VisitParameter(p);
        }
    }
}

引用 方法

var predicate = FF.PredicateBuilder.True();
//和操作
var predicate = predicate.And(a => a.DeviceID == deviceid);
//或操作
predicate = predicate.Or(a => a.DeviceID == deviceid);

//将predicate 放入条件
var list = db.dbSet.Where(predicate);
//另外记得引用命名空间 这里是 FF
using FF;

二、方法2
增加一个Expression扩展类

public static class ExpressionExt
{
    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
    {          
        return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, expr2.Body), expr1.Parameters);
    }
    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,Expression<Func<T, bool>> expr2)
    {
        return Expression.Lambda<Func<T, bool>>(Expression.OrElse(expr1.Body, expr2.Body), expr1.Parameters);
    }
}

使用方法:

Expression<Func<Models.Content, bool>> exp= s => s.IsDel==false;
            exp = exp.And(s => s.IsHot == true);

Razor的一些写法记录

Razor foreach获取索引方法

@{int i = 0;}
                @foreach (DataRow dr in ((DataTable)ViewData["set"]).Rows)
                {
                    i++;
                        <tr>
                            <td>@i</td>
                            <td>@dr["UserName"]</td>
                            <td>@dr["MPhone"]</td>
                        </tr>
                }

Razor与字符串组合

@foreach (var rd in item.User)
{
  <li>
       <input type="radio" value="@rd.UserName" id="rid@(rd.UserID)" name="radiogroup" />
       <label for="rid@(rd.UserID)">@rd.UserName</label>
  </li>
}

Razor 三元表达式

<div @Html.Raw(i==1?"class='active'":"")>@item.JDName</div>
//否则输出为 class=&39;active&39;

序列不包含任何匹配元素 EF多对多

报错的可能原因可能是EF的映射关系出了问题,如果Class之间有关联,需要手动设置好表关系
如:一个User有多个Device,一个Device可能属于多个User

public partial class User
{
  [Key]
  public int ID { get; set; }
  public string UserName { get; set; }
  public virtual ICollection UserDeivces { get; set; }
}

public partial class Device
{
  [Key]
  public int id { get; set; }
  public string deviceName { get; set; }
  public virtual ICollection UserDeivces { get; set; }
}

public class UserDeivce
{
  [Key]
  public int ID { get; set; }
  public int UserID { get; set; }
  public int DeivceID { get; set; }
  public virtual Model.User User { set; get; }
  public virtual Model.Device Device { set; get; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity()
                .HasRequired(a => a.Device)
                .WithMany(a => a.UserDeivces)
                .HasForeignKey(a => a.DeviceID);

    modelBuilder.Entity()
                .HasRequired(a => a.User)
                .WithMany(a => a.UserDeivces)
                .HasForeignKey(a => a.UserID);
}

ASP.net 微信公众平台JSAPI获取地理位置

ASP.Net获取地理位置
  项目需求需要在公众号内获取用户的地理位置,查了很多资料,大部分都是php的代码,很少有ASP.NET的代码,网上的东西大部分都不全,而且很晦涩,实际上很简单,这里给后来的朋友做个指引。
  JSAPI(不仅仅是地理位置)实际上的机制是,后台获取授权并获取相关数据,并把授权后的内容传入前台的JS里,前台的JS微信已经封装好了,调用即可返回所需数据,而实际的操作过程是,用户进入公众号的时候提示授权地理位置,进入到页面的时候就可以获取到地理位置。

相关步骤:
一、获取授权并取得数据
 1、第一步设置JS接口安全域名:公众号设置 功能设置 JS接口安全域名 设为你的网站域名即可。
 2、第二步 由于此接口需要使用到access_token,所以要获取access_token需要设置IP白名单,需要到公众号里面把服务器的IP填写进去。
 3、第三步授权取数据
 首先开看下微信JS需要的数据(通过后台获取的内容):
 appId 这个是公众号里面的
 timestamp 时间戳
 nonceStr 随机串
 jsApiList
 这个就是你要用什么接口,必须事先声明 比如: jsApiList[‘getLocation’,’playVoice’] 就是说你想调用获取地理位置和播放语音接口,详见:微信官方,我们就用jsApiList[‘getLocation’],其他的不管
 signature
 这个是签名,稍微麻烦一点,具体的获取流程是:通过AppID和secret获取access_token,然后通过access_token获取jsapi_ticket,然后通过签名算法生成signature,这些数据的获取官方都有详细的文档,总得来说要写很多,不怕麻烦看一下官方的文档一个个得写完,我这里用了一个第三方的微信SDK,Senparc,可以在NuGet里搜索Senparc.Weixin.MP就可以,代码很简单

C#代码:
首先记得引用

using Senparc.Weixin.MP.CommonAPIs;
using Senparc.Weixin.MP.Entities;
using Senparc.Weixin.MP.Helpers;

然后是page_load方法

public partial class repair : System.Web.UI.Page
{
 public string noncestr;
 public string timeStamp;
 public string signature;
 protected void Page_Load(object sender, EventArgs e)
 {
   JsApiTicketResult jsApiTicketResult = CommonApi.GetTicket(WeiXin.APPID,WeiXin.APPSECRET);
   string url = "http://XXX.com";//当前页面URL
   noncestr = JSSDKHelper.GetNoncestr();//随机字符
   timeStamp = JSSDKHelper.GetTimestamp();//时间戳
   signature = JSSDKHelper.GetSignature(jsApiTicketResult.ticket, noncestr, timeStamp, url);//获取签名}
 }
}

至此获取了全部所需的内容,如不使用第三方SDK则参考https://mp.weixin.qq.com/wiki?action=doc&id=mp1421141115&t=0.5267792197713446#62

二、前台配置JS,前面已经在后台获取了相关的数据,现在只需要传入前台
 1、在前台页面引入http://res.wx.qq.com/open/js/jweixin-1.2.0.js
 2、把后台获取的内容传递给前台JS变量

wx.config({
    debug: false, 
    appId: '<%=WEB.WeiXin.APPID%>', 
    timestamp:<%=timeStamp%> , 
    nonceStr: '<%=noncestr%>', 
    signature: '<%=signature%>',
    jsApiList: ['getLocation']
    });

 3、调用JSAPI方法:

wx.ready(function () {
 //调用获取地理位置接口
  wx.getLocation({
    type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
    success: function (res) {
      var latitude= res.latitude; // 纬度,浮点数,范围为90 ~ -90
      var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
      var speed = res.speed; // 速度,以米/每秒计
      var accuracy = res.accuracy; // 位置精度
      //代码到此已经获取到了用户的经纬度,以下是项目需求,通过经纬度获取地址的详细信息 比如 中国 北京市 东城区 等。
      
      //腾讯地图api获取地址 需要引用http://map.qq.com/api/js?v=2.exp
      geocoder = new qq.maps.Geocoder({
      complete: function (result) {
        //console.log(result);
         var addr = result.detail.addressComponents;
         var addrStr = addr.country + addr.province + addr.city + addr.district + addr.town + addr.street + addr.streetNumber + addr.village;
        //console.log(addrStr);
        $("#txtAdress").val(addrStr)//地址赋值
        $("#latitude").val(latitude)//经纬度赋值
        $("#longitude").val(longitude)//经纬度赋值
       }
      });

      var coord = new qq.maps.LatLng(latitude, longitude);
      geocoder.getAddress(coord);   
        }
      });
      })
wx.error(function (res) {
  console.log(res);
  alert('验证失败');
 });