
未定义键。请为该 EntityType 定义键 基于未定义任何键的类型 解决方法
提示这个错误,两个地方考虑
可能是模型没有加[Key],加上这个,如果还是报这个错误,检查下你的模型代码,是不是没有写{get;set;},遇到好几次这种..
月度归档: 2018 年 2 月
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('验证失败');
});