繁体   English   中英

避免实体框架中重复项的更简单方法

[英]Easier way of avoiding duplicates in entity framework

任何人都可以提供一种更简单,更自动的方式来执行此操作吗?

我为FilterComboTemplate模型具有以下保存方法。 Webapi已将数据从json转换为ac#模型实体。

因此,我不必在DeviceProperty表中创建重复的条目,而必须依次遍历每个过滤器并从上下文中检索分配的DeviceFilterProperty,并覆盖过滤器中的对象。 请参见下面的代码。

我已经拥有了所有对象ID(如果它们已经存在),因此似乎应该自动处理它,但这也许只是一厢情愿。

public void Save(FilterComboTemplate comboTemplate)
{
    // Set the Device Properties so we don't create dupes
    foreach (var filter in comboTemplate.Filters)
    {
        filter.DeviceProperty = context.DeviceFilterProperties.Find(filter.DeviceFilterProperty.DeviceFilterPropertyId); 
    }

    context.FilterComboTemplates.Add(comboTemplate);
    context.SaveChanges();
}

从这里开始,我将必须检查是否也存在任何过滤器,然后手动更新它们(如果它们与数据库中的过滤器不同),以免在编辑FilterComboTemplate之后不创建全新的集合。

我发现自己在写很多这类代码。 我已经包含下面的其他模型类的一些背景。

public class FilterComboTemplate
{
    public FilterComboTemplate()
    {
        Filters = new Collection<Filter>();
    }

    [Key]
    public int FilterComboTemplateId { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public ICollection<Filter> Filters { get; set; }
}

public class Filter
{
    [Key]
    public int FilterId { get; set; }

    [Required]
    public DeviceFilterProperty DeviceFilterProperty { get; set; }

    [Required]
    public bool Exclude { get; set; }

    [Required]
    public string Data1 { get; set; }
}

public class DeviceFilterProperty
{
    [Key]
    public int DeviceFilterPropertyId { get; set; }

    [Required]
    public string Name { get; set; }
}

从请求绑定之后,似乎对参数进行了一些常规操作。

您可以考虑编写自定义参数绑定以重用代码。 HongMei的博客是一个很好的起点: http : //blogs.msdn.com/b/hongmeig1/archive/2012/09/28/how-to-customize-parameter-binding.aspx

您可以使用方案2中的代码来获取格式化程序绑定,以从主体反序列化模型,然后执行所需的操作。

请参阅博客中的最​​后一步,以指定要自定义的参数类型。

从关于SO的一些 类似 问题来看,EF似乎并不会自动执行某些操作...

它可能不会大量削减代码,但是您可以执行以下操作,在DbContext(或您的特定dataContext)上使用扩展方法:

public static bool Exists<TEntity>(this MyDataContext context, int id) 
{
    // your code here, something similar to
    return context.Set<TEntity>().Any(x => x.Id == id);
    // or with reflection:
    return context.Set<TEntity>().Any(x => {
        var props = typeof(TEntity).GetProperties();
        var myProp = props.First(y => y.GetCustomAttributes(typeof(Key), true).length > 0)
        var objectId = myProp.GetValue(x)
        return objectId == id;
    });
}

这将检查DbContext中是否存在具有该键的对象。 自然地,可以创建类似的方法来实际返回该实体。

代码中有两个“返回”,只需使用您喜欢的一个即可。 前者将迫使您让所有实体都从具有Id属性的“实体”对象继承(这不一定是一件坏事,但是我可以看到这很痛苦……您还需要强制执行TEntity参数: where TEntity : Entity或类似名称)。 用一点点的“反射”解决方案,首先性能可能是个问题,其次我现在没有VS运行,所以我什至不知道它是否可以编译,更不用说工作了!

让我知道是否可行:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM