Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have a reoccuring code block in my EntityFramework backed repository which I would like to genericise somehow and call as a method, so reuse the code rather than repeat it.

The current code block looks like this:

    // Archive deleted MyItems sections
    _t.MyItems.Where(x => x.ValidTo == null && !team.MyItems.Contains(x)).ToList().ForEach(x => x.ValidTo = DateTime.Now);

    // Add or update MyItems sections
    foreach (var MyItemsSection in team.MyItems)
    {
        if (MyItemsSection.Id == default(int))
        {
            MyItemsSection.ValidFrom = DateTime.Now;
            _t.MyItems.Add(MyItemsSection);
        }
        else
        {
            var _MyItemsSection = _t.MyItems.FirstOrDefault(x => x.Id == MyItemsSection.Id);
            context.Entry(_MyItemsSection).CurrentValues.SetValues(MyItemsSection);
        }
    }

_t is the EntityFramework connected object graph, while team is an identical type of object graph that has been disconnected and possibly updated externally. The goal here is to sync the two object graphs so the changes are persisted.

I need to pass in _t.MyItems and team.MyItems, where MyItems are to be genericised so the same method works for MyOtherItems and MySocks, MyUnderPants etc.

Is this at all possible?

share|improve this question

closed as not a real question by Jeff Vanzella, Corbin, Trevor Pilley, Anton Golov, almaz Dec 2 '12 at 12:53

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

2  
The downvote button's title is "This question does not show any research effort; it is unclear or not useful". So, what have you tried? –  ANeves Nov 23 '12 at 17:48
    
@ANeves - research and solution added in new answer if you are interested. Sometimes its the lack of knowing where to look that precludes the ability to do the research. –  Moo Nov 27 '12 at 13:35
    
I know... e.g.: it is really difficult to find info on ?? until one discovers its name - "null-coallescing operator". –  ANeves Nov 27 '12 at 14:11

1 Answer 1

In answer to my own question, here is the answer - what I was missing was the fact that you can require the incoming type as implementing a specific interface, and still have it available as the type wanted.

So, here is what I came up with:

public void UpdateEntities<TEntity>(ICollection<TEntity> pocoCollection, ICollection<TEntity> dbCollection)
        where TEntity : class, IEntity
    {
        // Archive deleted entities
        dbCollection.Where(x => x.ValidTo == null && !pocoCollection.Contains(x)).ToList().ForEach(x => x.ValidTo = DateTime.Now);

        // Add or update entities
        foreach (var entity in pocoCollection)
        {
            if (entity.Id == default(int))
            {
                entity.ValidFrom = DateTime.Now;
                dbCollection.Add(entity);
            }
            else
            {
                var _entity = dbCollection.FirstOrDefault(x => x.Id == entity.Id);
                context.Entry(_entity).CurrentValues.SetValues(entity);
            }
        }
    }

The part which I was looking for was the where TEntity : class, IEntity

In this solution, I have to make sure that my entities implement the interface IEntity, which simply is:

public interface IEntity
{
    int Id { get; set;}
    DateTime ValidFrom { get; set; }
    DateTime? ValidTo { get; set; }
}

This allows the compiler to quit complaining about the use of those properties, while I can still use the actual type so Entity Framework is also satisfied and left less confused about whats going on.

Hope this helps someone else.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.