保留封装,保留存储库,实体框架,代码优先
本文关键字:保留 代码 框架 封装 存储 实体 | 更新日期: 2023-09-27 18:07:58
我有一种情况,我将尝试极大地简化它,在这种情况下,对象上的方法应该创建一个不同类的新的持久对象。我怎样才能做到这一点,同时保持对存储库的忽略和封装?
在这个例子中,我们有小部件和小部件的容器。当出售或购买小部件时,将创建一个WidgetEvent(在其他地方)并将其添加到容器的WidgetEvents列表中。我们总是可以通过对widgeteevents集合求和来查询容器中现有的片段的数量。在某些时候,一个worker调用并说容器是空的,即使容器中仍然应该有一些小部件。在这种情况下,我们调用"SetComplete"方法,它会创建一个最终的WidgetEvent来清空容器。
public class TestContext : DbContext
{
public DbSet<WidgetEvent> WidgetEvents { get; set; }
public DbSet<WidgetContainer> WidgetContainers { get; set; }
}
public class WidgetEvent
{
public int Id { get; set; }
public int Amount {get;set;}
public WidgetContainer Container {get;set;}
}
public class WidgetContainer
{
public int Id { get; set; }
public virtual ICollection<WidgetEvent> WidgetEvents {get;set;}
public int GetPiecesOnHand()
{
return WidgetEvents.Sum(a=> a.Amount);
}
public void SetComplete()
{
if (GetPiecesOnHand() != 0)
{
WidgetEvents.Add(new WidgetEvent() { Amount = -GetPiecesOnHand() });
}
}
}
在我看来,适当的封装将使这个事件的创建保持在类定义内。它使阅读代码的人更容易理解。但是我也看到,如果不向类中引入一些存储库知识,就无法使这个新的WidgetEvent持久。
我该怎么做?您可以假设我在其他地方有一个用于WidgetEvents的工厂。如果您想知道,SaveChanges没有意识到WidgetEvent已经创建。
编辑:这返回252500这是正确的。我想这让我对赛道变化有点困惑,但很高兴知道这是有效的。我几天前做了这样的事情,认为它不起作用。
using (var context = new TestContext())
{
WidgetContainer acontainer = new WidgetContainer();
acontainer.WidgetEvents = new List<WidgetEvent>();
context.WidgetContainers.Add(acontainer);
acontainer.WidgetEvents.Add(new WidgetEvent() { Container = acontainer, Amount = 25 });
Console.WriteLine(acontainer.GetPiecesOnHand());
context.SaveChanges();
}
using (var context = new TestContext())
{
WidgetContainer acontainer = context.WidgetContainers.Find(1);
Console.WriteLine(acontainer.GetPiecesOnHand());
acontainer.SetComplete();
Console.WriteLine(acontainer.GetPiecesOnHand());
context.SaveChanges();
}
using (var context = new TestContext())
{
WidgetContainer acontainer = context.WidgetContainers.Find(1);
Console.WriteLine(acontainer.GetPiecesOnHand());
}
如果WidgetContainer
被附加到(=由)实体框架上下文跟踪,而不给类一个对上下文(或存储库)的引用,它实际上应该工作。
例如这样的代码…
var widgetContainer = context.WidgetContainers.Find(1);
// or:
// var widgetContainer = context.WidgetContainers.Create();
// widgetContainer.Id = 1;
// context.WidgetContainers.Attach(widgetContainer);
widgetContainer.SetComplete();
context.SaveChanges();
…应该将新的WidgetEvent
插入到数据库中,并且与widgetContainer
具有外键关系,因为EF更改跟踪将在调用SaveChanges
时识别已添加到WidgetEvents
集合的新事件。
重要的是,在调用 SetComplete
之前,widgetContainer
必须附加到上下文。