1

Can anyone provide an easier more automatic way of doing this?

I have the following save method for a FilterComboTemplate model. The data has been converted from json to a c# model entity by the webapi.

So I don't create duplicate entries in the DeviceProperty table I have to go through each filter in turn and retrieve the assigned DeviceFilterProperty from the context and override the object in the filter. See the code below.

I have all the object Id's if they already exist so it seems like this should be handled automatically but perhaps that's just wishful thinking.

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();
}

From here I'm going to have to check whether any of the filters exist too and then manually update them if they are different to what's in the database so as not to keep creating a whole new set after an edit of a FilterComboTemplate.

I'm finding myself writing a lot of this type of code. I've included the other model classes below for a bit of context.

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; }
}
Neil
  • 4,949
  • 7
  • 42
  • 82

2 Answers2

0

It seems that you have some common operations for parameters after it's bound from request.

You may consider to write custom parameter bindings to reuse the code. HongMei's blog is a good start point: http://blogs.msdn.com/b/hongmeig1/archive/2012/09/28/how-to-customize-parameter-binding.aspx

You may use the code in Scenario 2 to get the formatter binding to deserialize the model from body and perform the operations your want after that.

See the final step in the blog to specify the parameter type you want customize.

Hongye Sun
  • 3,828
  • 1
  • 23
  • 18
0

Judging from some similar questions on SO, it does not seem something EF does automatically...

It's probably not a massive cut on code but you could do something like this, an extension method on DbContext (or on your particular 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;
    });
}

This will check if an object with that key exists in the DbContext. Naturally a similar method can be created to actually return that entity as well.

There are two "returns" in the code, just use the one you prefer. The former will force you to have all entities inherit from an "Entity" object with an Id Property (which is not necessarily a bad thing, but I can see the pain in this... you will also need to force the TEntity param: where TEntity : Entity or similar). Take the "reflection" solution with a pinch of salt, first of all the performance may be a problem, second of all I don't have VS running up now, so I don't even know if it compiles ok, let alone work!

Let me know if that works :)

Community
  • 1
  • 1
Tallmaris
  • 7,485
  • 3
  • 25
  • 57