【问题标题】:Easier way of avoiding duplicates in entity framework在实体框架中避免重复的更简单方法
【发布时间】:2012-10-11 16:15:23
【问题描述】:

谁能提供一种更简单、更自动化的方法?

对于 FilterComboTemplate 模型,我有以下保存方法。数据已通过 webapi 从 json 转换为 c# 模型实体。

所以我不会在 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; }
}

【问题讨论】:

    标签: c# entity-framework entity-framework-4 asp.net-web-api


    【解决方案1】:

    从 SO 上的some similar questions 来看,似乎 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,所以我什至不知道它是否编译好,更不用说工作了!

    让我知道这是否有效:)

    【讨论】:

      【解决方案2】:

      从request绑定后,参数好像有一些常用的操作。

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

      您可以使用场景 2 中的代码来获取格式化程序绑定以从主体反序列化模型并在此之后执行您想要的操作。

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

      【讨论】:

      • 老实说,这似乎并不比我已经在做的更容易
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-10
      • 2020-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多