0

I am using entity framework to interface with a database and I would like to create a generic insert function!

I have got it working with standalone tables i.e. add a new record to Customer table which uses the Set function to get the table of the correct type. But the problem is that cross reference tables are mapped into lists in entity framework - conforming to an object orientated interface (so I understand why). However, how can I account for such inserts in a generic manor, as in general I will be dealing with whole entities however I have a few scenarios where I need to deal with the lists inside an entity.

Of course I can create specific methods to deal with these specific cases but I really want to avoid doing this!

One idea I have had is too create a dictionary of Type, Action, the type being types of DTO's associated with list inserts the service may receive and the action being specific insert code for dealing with the lists, that way I can still use the generic insert function, and just check if there are any "insert rules" in the dictionary that should be executed opposed to the generic insert code. This way from a client programming perspective only the one insert function is ever used. BUT this still requires writing specific insert code - which I really would like to avoid.

I don't have that much experience with EF - so what I would like to know is do I have any cleaner options for getting around this problem?

Code demonstrating my issue:

Normal generic insert -

public void InsertRecord(object newRecord, )
    {
        using (PIRSDBCon db = new PIRSDBCon())
        {
            var table = db.Set(newRecord.GetType());
            table.Add(newRecord);                
            db.SaveChanges();
        }
    }

as you can see this handles standard inserts into tables

Insert into cross reference table -

public void InsertCarerCheck(int carer_id, Check newCheck)
    {            
        using (PIRSDBCon db = new PIRSDBCon())
        {
            Foster_Carers carer_record = (from c in db.Foster_Carers
                             where c.foster_carer_id == carer_id
                             select c).SingleOrDefault();


            carer_record.Checks1.Add(newCheck);
            db.SaveChanges();
        }            
    }

Checks1 is a list property generated by EF for a cross reference table linking a foster carer and a check record. How can scenarios like this be accounted for in a generic insert function?

Sam
  • 586
  • 1
  • 6
  • 25
  • Do you have the existing code that you want to make generic? – Willem de Jong Oct 09 '13 at 09:47
  • @WillemdeJong - What do you mean sorry? I have already created the generic insert which works fine. However this is not the case for cross reference tables, as for example to add a new Customer "Check" you have to get the customer's record using there ID and then access the Checks List (which is what EF maps such cross reference tables too). Does that answer your question? :/ – Sam Oct 09 '13 at 09:51
  • Possible duplicate? http://stackoverflow.com/questions/17748956/how-to-create-generic-ef-insert-method – Colin Oct 09 '13 at 09:53
  • @Colin - no, that question is related to creating a generic insert for standard entities, my issue is specific to cross reference entities and the way they are mapped by EF =) – Sam Oct 09 '13 at 10:08
  • Then I don't understand the question. At risk of repeating @WillemdeJong 's request. Can you show some code for "cross reference tables" that isn't generic that you would like to make generic? – Colin Oct 09 '13 at 10:13
  • @Colin - Okay so, a normal insert can be generic, because you can use the _Set(Type)_ function to get any EF entity based on the type you pass it, yeah? However in order to insert a cross referenced record you need to do so via a specific entity record property, not directly into the entity, but into a property of the entity! Do you see the problem? I will add some code to demonstrate the issue. – Sam Oct 09 '13 at 10:17
  • @Colin - just added the code, please let me know if that makes things clearer? And if there is anything else I can do to add clarity to the question - Thanks – Sam Oct 09 '13 at 10:33
  • You are using EF in a way that destroys most of its benefits. You are using it like typed datasets. You should reuse the same context for the entire unit of work, not just for single-row CRUD. – usr Oct 09 '13 at 10:54
  • @usr - okay, could you please explain a litte, I don't quite understand what you mean - I am relatively new to EF and would love some guidance regards this. Thanks – Sam Oct 09 '13 at 11:02
  • I recommend you look at the generic repository and unit of work patterns. http://stackoverflow.com/a/19180319/150342 and http://stackoverflow.com/a/4458250/150342 – Colin Oct 09 '13 at 11:08
  • @Colin - okay, so essentially this is very similar to what I am trying to achieve but instead it is put into a base class for models to inherit and override functions when and as required... right? The only reservation I have with that is that I am using WCF and the CRUD functions are a part of the ServiceContract and this would require adding another layer of mapping (from the DTO to the MODEL which would then call the MODEL crud function then map the model to the actual entity for instering etc. into the database) - although I do feel I a bit lost in all of this right now. Thanks – Sam Oct 09 '13 at 11:21
  • @Colin - okay I have researched the repository pattern, and whilst it does look very good, I'm not sold on using it for a WCF self-hosted application where it would require creating helper functions within the service contract and then mapping the DTO to the Model (which implements IRepository) - I can completely see the benefit of this pattern for MVC ASP.NET based programming! Does my thinking sound fair to you? Maybe I am missing something. Also - it would still mean overriding the Insert function for specific entities... sooo I'm not sure what to do now :/ – Sam Oct 09 '13 at 13:27
  • Mapping between DTO's or ViewModel's is recommended in MVC too. Check out AutoMapper and ValueInjector – Colin Oct 09 '13 at 14:37

0 Answers0