更容易避免实体框架中的重复

时间:2012-10-11 16:15:24

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

任何人都可以提供更简单,更自动的方式吗?

我有一个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; }
}

2 个答案:

答案 0 :(得分:0)

从请求绑定参数后,似乎有一些常见的参数操作。

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

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

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

答案 1 :(得分:0)

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中是否存在具有该键的对象。当然,也可以创建一个类似的方法来实际返回该实体。

有两个&#34;返回&#34;在代码中,只需使用您喜欢的那个。前者将迫使您让所有实体继承自&#34;实体&#34;具有Id属性的对象(这不一定是坏事,但我可以看到这里的痛苦......你还需要强制TEntity参数:where TEntity : Entity或类似的)。 采取&#34;反思&#34;有一点盐的解决方案,首先表现可能是一个问题,其次我现在没有VS跑起来,所以我甚至不知道它是否编好,更不用说工作了!

如果有效,请告诉我:))