• EntityFramework MergeOption运用


    最近尝试在sharepoint里面使用EF访问本地的数据库,由于sharepoint只能引用.net3.5的程序集,所以就只能使用EF1.1版本了,(吐槽一下:这个版本的EF由于是最早版本,所以不支持调用 存储过程:-(),下面说下具体遇到的问题吧。


    首先了解下MergeOption

    是ObjectContext管理查询返回的实体四种方式,他们分别是:

    1.AppendOnly——如果要获取的实体在上下文里面,就直接从上下文里面取到,如果不在的话就把取出来的实体附加到上下文里面,这个是默认的方式,这种方式的好处就是会首先从内存里面找你要的实体,比较快。

    2.NoTracking——上下文不存实体,这种方式就是说每次都从数据库里面取数据。

    3.OverwriteChanges——如果要获取的实体在上下文中,那么该实体的值会被数据库的值覆盖,然后再返回,如果不在的话就把取出来的实体附加到上下文里面。

    4.PreserveChanges——如果要获取的实体在上下文中,那么该实体中被用户修改的属性保持不变,其余的属性用数据库的值覆盖,如果不在的话话就把取出来的实体附加到上下文里面。


    我遇到的问题

    在上下文中构造了一个实体,将该实体标记为添加,该实体的一个流水号字段FlowCode是由数据库触发器自动生成的

    BasicInfo binfo = new BaicInfo();
    //主键
    ; Guid tempGuid=binfo.UIID = GUID.NewGuid();
    binfo.Discription= "Test"; binfo.Type=1; ctx.BasicInfoEntities.Add(binfo);

    然后ctx.SaveChanges();数据库触发器会给该记录自动生成FlowCode字段,于是就理所当然的想在该上下文中根据主键获取该记录的FlowCode,

    string flowCode=ctx.BasicInfoEntities.Where(x=>x.UIID==tempGuid).FirstOrDefault().FlowCode;
    

    但是奇怪的是取不到这个FlowCode,可是数据库里面明明这个字段的被触发器生成了,是有值的啊,郁闷,:-(,google了一番有所发现,原来在同一上下文中,调用SaveChanges()的时候EF会生成一大堆的SQL到数据库,数据库就会咔咔的执行,但是触发器是是在数据库里面执行的,所以数据库并不会通知EF说,你让我帮你插入一条数据的时候FlowCode字段的值是我用触发器生成的,这个值是多少多少,然后EF会更新到ObjectStateManger这个Entity对应的Entry里面。此时上下文里面的binfo实体的数据即使不是最新的(相对于数据库)它状态是UnChanged,又由于默认的MergeOption是AppendOnly,所以我们再去根据主键获取实体的时候会返回上下文中的实体,这样一来就当然取不到FlowCode的值了。


    解决办法:重写MergeOption为NoTracking

    方法一:永久设置实体集MergeOption为NoTracking

    ctx.BasicInfoEntities.MergeOption = MergeOption.NoTracking;
    

    方法二:只设置该次调用为NoTracking

    string flowCode=ctx.BasicInfoEntities.Execute(MergeOption.NoTracking).Where(x=>x.UIID==tempGuid).FirstOrDefault().FlowCode;
    

    这样就可以告诉EF从数据库取该实体的数据了,触发器生成的FLowCode就取出来鸟。  

  • 相关阅读:
    LAMP企业架构读写分离
    docker技术入门(2)
    docker技术入门(1)
    终极实验
    java——并查集 UnionFind
    java——字典树 Trie
    java——线段树 SegmentTree
    java——最大堆 MaxHeap
    java——链表映射 LinkedListMap
    java——数据结构
  • 原文地址:https://www.cnblogs.com/afutureBoss/p/afutureboss.html
Copyright © 2020-2023  润新知