none
How to add new entity to DB without collection retreiving? RRS feed

  • Question

  • var he = new LogHistoryEntry
                                 {
                                     ActionId = action.Id,
                                     ObjectId = logObject.Id,
                                     UserId = user.Id,
                                     Info = msg,
                                     Item = s.Id,
                                     Date = DateTime.Now
                                 };
    
                    ctx.LogHistoryEntries.AddObject(he);
                    ctx.SaveChanges();
    
    Works fine besides one little thing. The whole table of LogEntries is pulled from db.
    I just want to add entity and forget about it (Add,Save,Detach), nothing more.
    Thursday, November 24, 2011 4:32 PM

Answers

  •  

    The call to Add adds the record to the ObjectContext and because it does not exist in the ObjectContext it will be placed in the insert list for the next SaveChanges. There may be a Select sent after the insert to support change tracking but not sure about that.

     


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Friday, November 25, 2011 5:02 PM

All replies

  • Kind of hack which I don't like but it works:

     public static void LogChanges(ObjectContext context, string msg, int itemId, int userId, int logActionId, int logObjectId)
     {
                context.ExecuteStoreCommand(
                    "insert into log_history (object_id,action_id,item,info,user_id,date) values ({0},{1},{2},{3},{4},GETDATE())",
                    logObjectId, logActionId, itemId, msg, userId);
     }
    

    Separation of Model and Storage is broken. :(

    Friday, November 25, 2011 9:49 AM
  • Hi Voronin_Pavel;

    The code you posted should not be causing the complete table of LogEntries to be downloaded. Please post the code from instantiating the ObjectContext to the saving of the record.

     


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Friday, November 25, 2011 2:18 PM
  •  

    var context = new Entities();
    
    var parser = entities.Parsers.FirstOrDefault(p => p.Name == "Script Parsing Robot");
    
    if (parser == null)
    {
             parser = new Parser {Name = "Script Parsing Robot"};
             context.Parsers.Add(parser);
             context.SaveChanges();
    
             var user = context.Users.First(u => u.Name == "Robot");
             var action = context.LogActions.First(a => a.SysName == "create");
             var logObject = context.LogObjects.First(a => a.SysName == "parser");
             var msg = "New Parser Created.";
             var he = new LogHistoryEntry
             {
                    ActionId = action.Id,
                    ObjectId = logObject.Id,
                    UserId = user.Id,
                    Info = msg,
                    Item = parser.Id,
                    Date = DateTime.Now
              };
    
               context.LogHistoryEntries.AddObject(he);//request to db here
               context.SaveChanges();
    }
    


    Friday, November 25, 2011 2:39 PM
  • Hi Voronin_Pavel;

    Sorry but I do not see anything in the code posted that would cause the complete table of LogEntries to be downloaded on the submit changes. How are you determining that this is happening?

     


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Friday, November 25, 2011 3:02 PM
  • Here is what profiler returns:

    exec sp_executesql N'SELECT 
    [Extent1].[id] AS [id], 
    [Extent1].[object_id] AS [object_id], 
    [Extent1].[action_id] AS [action_id], 
    [Extent1].[item] AS [item], 
    [Extent1].[info] AS [info], 
    [Extent1].[date] AS [date], 
    [Extent1].[user_id] AS [user_id]
    FROM [dbo].[log_history] AS [Extent1]
    WHERE [Extent1].[user_id] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=4
    

    Friday, November 25, 2011 3:04 PM
  •  

    First this query is not pulling down all the records in the table. But it should be a Insert and not a Select.

    Can you place a breakpoint on the last closing } in the above code and execute it, Then when the breakpoint is hit look at profiler and see what was sent.

     


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Friday, November 25, 2011 4:04 PM
  • This Select comes from the call to Add(), not SaveChanges()...

    And I have no idea why EF asks for all log entries corresponding to certain user.

    Friday, November 25, 2011 4:08 PM
  •  

    The call to Add adds the record to the ObjectContext and because it does not exist in the ObjectContext it will be placed in the insert list for the next SaveChanges. There may be a Select sent after the insert to support change tracking but not sure about that.

     


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Friday, November 25, 2011 5:02 PM
  • The problem is trivial. 

    I use generated POCO with fixups and lazy loading enabled. Thus call to AddObject() triggers db roundtrips when navigation properties are accessed.

    Monday, December 12, 2011 8:58 AM