保留封装,保留存储库,实体框架,代码优先

本文关键字:保留 代码 框架 封装 存储 实体 | 更新日期: 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必须附加到上下文