删除对象一定要在同一个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是正道。