- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是一些演示我的问题的测试代码:
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using NUnit.Framework;
namespace EFGraphInsertLookup
{
public class GraphLookup
{
public int ID { get; set; }
public string Code { get; set; }
}
public class GraphChild
{
public int ID { get; set; }
public virtual GraphRoot Root { get; set; }
public virtual GraphLookup Lookup { get; set; }
}
public class GraphRoot
{
public int ID { get; set; }
public virtual ICollection<GraphChild> Children { get; set; }
}
public class TestDbContext : DbContext
{
public DbSet<GraphRoot> GraphRoots { get; set; }
public DbSet<GraphChild> GraphChildren { get; set; }
public DbSet<GraphLookup> GraphLookups { get; set; }
public TestDbContext()
{
GraphLookups.ToList();
}
}
public class TestDbInit : DropCreateDatabaseAlways<TestDbContext>
{
protected override void Seed(TestDbContext context)
{
base.Seed(context);
context.GraphLookups.Add(new GraphLookup { Code = "Lookup" });
context.SaveChanges();
}
}
[TestFixture]
public class Tests
{
[Test]
public void MainTest()
{
Database.SetInitializer<TestDbContext>(new TestDbInit());
var lookupCtx = new TestDbContext();
var firstLookup = lookupCtx.GraphLookups.Where(l => l.Code == "Lookup").Single();
var graph = new GraphRoot
{
Children = new List<GraphChild> { new GraphChild { Lookup = firstLookup } }
};
var ctx = new TestDbContext();
ctx.GraphRoots.Add(graph); // Creates a new lookup record, which is not desired
//ctx.GraphRoots.Attach(graph); // Crashes due to dupe lookup IDs
ctx.SaveChanges();
ctx = new TestDbContext();
graph = ctx.GraphRoots.Single();
Assert.AreEqual(1, graph.Children.First().Lookup.ID, "New lookup ID was created...");
}
}
}
我的愿望是让 GraphLookup 充当查找表,其中记录链接到其他记录,但记录永远不会通过应用程序创建。
我遇到的问题是当查找实体在不同的上下文中加载时,例如当它被缓存时。因此,保存记录的上下文不会跟踪该实体,并且当调用 GraphRoot DbSet 上的 Add 时,查找以 Added 的 EntityState 结束,但实际上它应该是 Unchanged。
如果我改为尝试使用附加,则会因重复键而导致崩溃,因为两个查找实体最终出现在上下文中。
解决这个问题的最佳方法是什么?请注意,我已经大大简化了实际问题。在我的实际应用程序中,这是通过位于 EF DBContext 之上的几个不同的存储库层、工作单元和业务服务类发生的。因此,我可以以某种方式在 DBContext 中应用的通用解决方案将是更受欢迎的。
最佳答案
如果您将现有实体(例如从缓存中)带入另一个 DbContext
,您将必须显式管理实体状态。这导致了两个简单的结论:不要混合来自多个上下文的实体,除非你确实需要,并且当你这样做时,明确设置你附加的所有实体的状态 .
您可以尝试一种缓存方法。创建一个简单的缓存管理器类,可能是静态的。对于要缓存的每个实体类型,都有一个看起来像这样的 GetMyEntity(int myEntityId, DbContext context)
方法:
public MyEntity GetMyEntity(int entityId, MyContext context)
{
MyEntity entity;
// Get entity from context if it's already loaded.
entity = context.Set<MyEntity>().Loaded.SingleOrDefault(q => q.EntityId == entityId);
if (entity != null)
{
return entity;
}
else if (this.cache.TryGetValue("MYENTITY#" + entityId.ToString(), out entity)
{
// Get entity from cache if it's present. Adapt this to whatever cache API you're using.
context.Entry(entity).EntityState = EntityState.Unchanged;
return entity;
}
else
{
// Load entity if it's not in the context already or in the cache.
entity = context.Set<MyEntity>().Find(entityId);
// Add loaded entity to the cache. Adapt this to specify suitable rules for cache item expiry if appropriate.
this.cache["MYENTITY#" + entityId.ToString()] = entity;
return entity;
}
}
请原谅任何拼写错误,但希望您明白了。您可能会看到这可以被推广,因此您也不必为每个实体类型使用一种方法。
编辑:
以下代码可能有助于展示如何分离一切,除了您实际想要添加的实体。
// Add a single entity.
context.E1s.Add(new1);
var dontAddMeNow = (from e in context.ChangeTracker.Entries()
where !object.ReferenceEquals(e.Entity, new1)
select e).ToList();
foreach (var e in dontAddMeNow)
{
e.State = System.Data.EntityState.Unchanged; // Or Detached.
}
编辑2:
下面的代码展示了预加载引用数据如何解决您的问题。
E2 child = new E2 { Id = 1 };
context.Entry(child).State = System.Data.EntityState.Unchanged;
E1 new1 = new E1
{
Child = child
};
// Add a single entity.
context.E1s.Add(new1);
Debug.Assert(context.Entry(new1.Child).State == System.Data.EntityState.Unchanged);
Debug.Assert(context.Entry(new1).State == System.Data.EntityState.Added);
关于c# - Entity Framework - 避免 "lookup"实体最初在另一个上下文中加载时获得添加状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14648354/
我有一个使用 Sinch SDK 和 CallKit 实现的 VOIP 应用程序。一切正常,除了设备插入耳机时。在后一种情况下,当通话开始时,音频仍通过设备的主扬声器路由。如果我在通话期间拔下并重
我需要将大量复杂(20 多个属性)对象过滤成多个子列表。要创建子列表,我有一个过滤器规范列表。要求是:a) 不允许一个项目成为两个子列表的一部分,并且 b) 必须能够在处理完成后获取所有未分割的项目。
我有一个简单的 .share-toggle 切换链接。当您点击它时,Facebook 评论插件应该会显示。它最初应该被 Conceal 问题是,如果我使用 css Conceal 它,然后单击切换按钮
我正在尝试制作一个功能类似于 android 市场的图库,您可以在其中滚动(左/右)以查看免费或付费应用程序等...还可以在布局中上下滚动。 到目前为止,我只是让它加载了两个布局,它们都有一个简单的“
大家好,我是网络开发的新手,最近刚刚完成我对网络设计的第一次尝试。我偶然发现了一个我找不到解决方案的问题。在 webkit-browsers 中,我的一个 ul-lists(导航)最初呈现在错误的位置
我遇到了这个问题。我在 ISP 上使用 Umbraco CMS 启动了一个 ASP.NET 网站。(这只是一个非常基本的信息网站。没什么特别的。) 但是,当我想要访问该网站时,第一个页面加载需要很长时
在我的 iPhone 应用程序中,我使用 UITabBarController 布置了三个选项卡。第一个选项卡(在应用启动时加载)使用本地数据加载,速度非常快。 虽然第二个选项卡从网络下载 XML 文
我有这样的风格: #cytoscape-container { width: 100%; height: 100%; margin: 0 aut
我在这里看到了几篇关于 SO 的帖子,但它们在功能和结构上过于具体,而我正在寻找的是我或任何人都可以在任何地方使用的更通用的东西。 我只需要有一个按钮,单击该按钮可以在 3 类之间循环。但如果出现必须
我在 http://www.raven.dima.neoturbine.net/ 有一个网页我正在努力。顶部导航在 IE 8、Firefox 3.6 和适用于 Android 的 Dolphin 浏览
我想将主机的用户/组与 docker 机器同步,以使(开发人员)能够编辑容器内部或外部的文件。有一些这样的想法:Handling Permissions with Docker Volumes这会创建
向通知列表/栏发布推送通知时,.contentText 和 .number 最初不显示(.ticker、.icon 和 .contentTitle 显示正常)。但是,在发布另一个通知(具有不同的 ID
我实现了以下 MKMapView 方法,该方法在添加注释后运行。我在 Interface Builder 中将我的 MKMapView map (parishMap) 设置为“显示用户位置”,并且在加
我是一名优秀的程序员,十分优秀!