目录:
1:MVC4 违反了引用完整性约束: 在此关系的主对象和依赖对象之间,定义引用约束的属性值不一致
2:对一个或多个实体的验证失败
3:模型生成过程中检测到一个或多个验证错误:
4:更新条目出错
5:在 LINQ to Entities 查询中无法构造实体或复杂类型
6:角色中的对象无法自动添加到上下文中,因为它是使用NoTracking合并选项检索的
7:违反了多重性约束。关系“PA_Mod.Context.TourOrder_ShippingAddress”
8: 附加类型“...”的实体失败,因为相同类型的其他实体已具有相同的主键值
9:LINQ to Entities 不支持指定的类型成员
10:已经打开的与此command相关联的Datareader 必须首先关闭
详解:
1:MVC4 违反了引用完整性约束: 在此关系的主对象和依赖对象之间,定义引用约束的属性值不一致
原因:
主表和从表 修改的时候 关系不明确了 也就是说从表可能跟主表关联的id 是 null值 导致该数据的时候不明确
一对一关系的话 要给值赋一下对应关系的值内容 一对多可能关系 会带出来
所以有一对一关系 然后出现这个问题的时候 要看一下主表对应的从表是不是 关系的id值是null
eg:
public bool UpdateTourOrdersUserId(TourOrder tourOrder,string newUserId, string oldUserId, string opname)
{
bool result = true;
if (tourOrder != null && !string.IsNullOrWhiteSpace(oldUserId))
{
using (var trans = DbContext.Database.BeginTransaction())
{
try
{
//下面三行没加 是会报错的 因为对应的一对一关系id 值是null 所以把关系加上了
tourOrder.ShippingAddress.ShippingAddressId = tourOrder.TourOrderId;
tourOrder.PriceDetail.TourPriceId = tourOrder.TourOrderId;
tourOrder.TripSetting.TripSettingsId = tourOrder.TourOrderId;
tourOrder.UserEmail = newUserId;
DbContext.Entry(tourOrder).State = EntityState.Modified;
result = DbContext.SaveChanges() > 0;
if (result)
{
var content = "Change UserId:" + oldUserId + " to " + tourOrder.UserEmail;
new LogDal().SetLog(DbContext, opname, "TourOrders", OPType.Update, content);
}
trans.Commit();
}
catch (Exception e)
{
trans.Rollback();
result = false;
}
}
}
return result;
}
2:对一个或多个实体的验证失败
解决方法:
try catch 获取异常后对 ex进行监视
using (var trans = DbContext.Database.BeginTransaction())
{
try
{
DbContext.TourPackageList.Add(package);
DbContext.SaveChanges();
trans.Commit();
isSuccess = true;
}
catch (Exception ex)
{
isSuccess = false;
trans.Rollback();
}
}
一步一步的找到错误的原因 如下图 看是 字段长度还是 字段为空导致的
如果字段为空是因为 关联的表影响的 而不是自己要修改的表 可以这样做
TourOrder mod = new TourOrder();//新建修改表对象 要改的内容
mod.TourOrderId = tourorderid;
mod.BusCode = changebusname;
DbContext.TourOrders.Attach(mod); //attach 然后改实体状态 要改的字段
DbEntityEntry<TourOrder> entry = DbContext.Entry<TourOrder>(mod);
entry.State =System.Data.Entity.EntityState.Unchanged;
entry.Property("BusCode").IsModified = true;
DbContext.Configuration.ValidateOnSaveEnabled = false;//关闭实体验证
DbContext.SaveChanges();
3:模型生成过程中检测到一个或多个验证错误:
因为 Dependent Role 属性不是键属性,Dependent Role 多重性的上限必须为“*”。
原因:有数据的表不能加非空外键 解决:把从表的外键设置为不可空 要么给外键加上Required 要么
就是Nullable<T>
如果是一对一关系的话 需要从表 把一个字段设置为主键加外键 【key,ForeignKey()】这样才能知道谁是主
否则关系找不到
4:更新条目出错
删除的话先删除从表 然后在删除主表 如果出现有外键关系错误的 记得看一下 是否级联删除 如果没有可能删除有问题
添加的话如果说 id不能为null 查看数据库是不是 主键自增 没有自增的话会报错
5:在 LINQ to Entities 查询中无法构造实体或复杂类型
原理: linq 选择数据时候 不能new 已知的对象,只能匿名的。 但是如果从一个 List 列表 就可以new 已知的类。
var listdata = from t in DbContext.FAQList.ToList() //这个t z两张表如果没有一个tolist的话就会报错有一个 就能select new faq 这个现有类
join z in DbContext.FAQzhList on t.Id equals z.FaqId
select new FAQ
{
Id=t.Id,
Question = z.Question,
Answer = z.Answer,
Visible=t.Visible,
GroupOrder=t.GroupOrder
};
6:角色中的对象无法自动添加到上下文中,因为它是使用NoTracking合并选项检索的。
在定义关系之前,将实体显式附加到ObjectContext
AsNoTracking 是不更改内容 只查询,之后想要更改 必须attach 更改状态然后去改
7:违反了多重性约束。关系“PA_Mod.Context.TourOrder_ShippingAddress”
的角色“TourOrder_ShippingAddress_Target”具有多重性 1 或 0..1.
个人研究是因为 相同表的内容 如果重复查询俩次出来 就会出现这个问题
一般情况延迟加载和代理开启的情况带有代理关系的对象 查一个主对象A 另外的对象B会带出来 如果这时候在用 db.B是会报这个错误的 因为这个B对象A这边其实占用着的
如果说不知道什么情况带出来的B 是空对象(可能是model的时候设置set的时候有判断逻辑)
也可以关闭代理 然后自己include 贪婪加载出来,然后用一个对象来使用
比如: A B一对一 那么要用到A B俩个表数据 可以var mod= A.include(t=>t.B).条件 之后再用mod.B 就可以了
8: 附加类型“...”的实体失败,因为相同类型的其他实体已具有相同的主键值
个人研究是因为 相同表的内容 attach了俩次出现这个问题 如过说主表延迟加载已经把从表的数据带出来了 主表attach了 那么从表就不要attach 修改的时候直接 查出来也不asnotracking 然后赋值 直接savechange就行了
9:LINQ to Entities 不支持指定的类型成员
也就是说 linq 有些内容识别不了 不是数据库中真实存在的model 【notmappad】 或者一些 方法识别不了
解决方案:要不在linq使用之前 用变量先代表 linq中在用变量 也可以先查出来tolist放内存中 然后再用notmap的字段
方法不识别可以使用sqlfuncton
10:已经打开的与此command相关联的Datareader 必须首先关闭
原因是因为数据库 在连接的情况下 没有关闭 就又进行一次连接
一般是foreach时候 先建立连接去查 循环实体内容 然后循环体内又去连接数据库报错
解决方案 一般是 将要循环的内容进行 tolist放到内容 关闭数据库 这样循环里面在去dbcontext的时候就不会报错了