正在进行的工作/实体克隆

时间:2016-03-10 20:40:48

标签: c# entity-framework design-patterns entity-framework-6

我首先使用代码并且有许多实体需要进行正在进行的工作"每个版本。传统上,我们通过使用前缀" wip克隆所有这些实体的表来实现此模式。"版。虽然这个系统有效,但代码中存在很多丑陋,我希望使用Entity Framework找到更清晰,更少突兀的解决方案。

理想情况下,我喜欢接近这个的东西:

new BasicComponentConfigurator()

从我的挖掘中我觉得这可能是可能的。我发现我可以添加一个规则来加上前缀" wip。"在我的桌子前面(How to Add Table Prefix In Entity Framework Code First Globally?

还找到了多个架构的帖子处理(Entity Framework and multiple schemas)参考了这篇文章(http://romiller.com/2011/05/23/ef-4-1-multi-tenant-with-code-first/

我遇到的一些问题是使用迁移来创建数据库。如果我有多个DBContext的迁移开始变得混乱,那么第二篇文章他们根本不工作,因为他们没有给DBContext提供一种构建方式,因此迁移失败。

有没有人知道实现这种模式的干净方法。我喜欢尽可能不突兀。实体不应该意识到他们有2个可以坚持的地方(Work in Progress& Real Version)。我知道我可以通过向实体添加标志来做到这一点,但我觉得还有另一种方式。

1 个答案:

答案 0 :(得分:1)

您可以有2个班级(LivePersonWipPerson)继承您当前的Person班级。然后,您将告诉Entity Framework将每个类映射到不同的表。

EF配置:

modelBuilder.Entity<LivePerson>()
    .Map(m => m.MapInheritedProperties()
        .ToTable("Persons"));

modelBuilder.Entity<WipPerson>()
    .Map(m => m.MapInheritedProperties()
        .ToTable("WipPersons"));

然后你可以这样做:

// Create Frank
using (var db = new Db())
{
    // Create Frank
    LivePerson frank = new LivePerson { Name = "Frank" };

    // Clone Frank
    WipPerson wipFrank = Clone<LivePerson, WipPerson>(frank);

    // Add to database and save
    db.Persons.Add(frank);
    db.WipPersons.Add(wipFrank);
    db.SaveChanges();
}

// Edit WIP
using (var db = new Db())
{
    var wipFrank = db.WipPersons.First(/*Todo: Use query*/);

    wipFrank.Notes = "Okay";

    db.SaveChanges();
}

这将为您提供相同内容的副本,但在单独的表中。但是有一个新的复杂性:你必须能够将Person从一种类型克隆到另一种类型。

我使用了这种方法:

private static TOut Clone<TIn, TOut>(TIn obj)
{
    // using Newtonsoft.Json;
    return JsonConvert.DeserializeObject<TOut>(JsonConvert.SerializeObject(obj));
}

如果您的人很简单,可以克隆,我认为这个解决方案可能有用...... 或者至少你可以根据自己的需要集中精力将克隆从一种类型改进到另一种类型。

此解决方案还允许您更进一步,并向WipPerson类添加一些属性,以跟踪创建克隆的时间,创建克隆的人员,最后编辑的人员,{{1}制作克隆等等。