EF 常会遇到的一些问题

目录:

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的时候就不会报错了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值