实战EntityFramework

删除对象一定要在同一个context

我尝试这在两个方法中使用两个context(Container)实例来进行一个获得一个删除,结果我获得的”The object cannot be deleted because it was not found in the ObjectStateManager“错误;后来尝试在一个方法体中共享一个容器,正常删除;所以删除一定要在同一个容器中来进行处理,因为delete本身是将Entity的状态设置为删除,前提是容器中已经装载了改实体;实体的装载是发生在一次”GetObjectByID“之类的Get操作之后,所以一个新建的容器,直接处理之前别的容器获得Entity,当然找不到了。所以对于封装容器操作,最好做一个全局的容器,这样比较有意义,少new很多实例,而且可以保证行为一致性。

EntityKey

检索对象,少不了EntityKey,一下是代码:

IEnumerable<KeyValuePair<string, object>> entityKeyValues = new KeyValuePair<string, object>[] 
{
    new KeyValuePair<string, object>("Id", pID) 
};
string[] names = pEntity.GetType().ToString().Split('.');
string entitySetName = "Model1Container." + names[names.Length - 1];
Model1Container context = new Model1Container();
EntityKey key = new EntityKey(entitySetName, entityKeyValues);
object obj = context.GetObjectByKey(key);

enttiySetName是亮点,如何来确定他的值呢?看容器定义文件

public Model1Container() : base("name=Model1Container", "Model1Container")

默认实例传送的”defaultContainerName“就是”Model1Container“,然后,实体集的名字就是容器的名称+类名;

检索方式

以下两种方式都是可以,复杂一点的查询可以使用第一种,对于单表操作返回字段没有特殊处理的使用第二种即可:
方法一:
var query = from p in container.workflowsequeuece
            where p.WFID == wf.Id && !p.PassedFlg.Value
            select p;
方法二:
container.workflowsequeuece.Where(p => p.WFID == wf.Id && !p.PassedFlg.Value);

获取自增Identity

在EF中context.SaveChanges()方法,会将标记为Added行写会到DB中,同时,如果列是自增的,那么会自动填充主键列;
我早起对于workflow表没有设定自增,此事生成了EDMX文件,以后再修改为自增,即使同步EF,也没有生效;于是手工操作:
 
<EntityType Name="workflow">
  <Key>
    <PropertyRef Name="Id" />
  </Key>
  <Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
  <Property Name="Name" Type="varchar" MaxLength="100" />
  <Property Name="Description" Type="varchar" />
 …
</EntityType>
下划线部分即表示该列被标记为自增主键;

context共享谨慎

每次查询操作都需要先创建一个context,如果只是使用一个context将会导致一个问题:你获取的数据时缓存的数据;如果需要实时获取数据,需要每次都new一个context是正道。
原文地址:https://www.cnblogs.com/xiashiwendao/p/3556839.html