How can I use EF to add multiple child entities to an object when the child has an identity key?

后端 未结 5 1358
北恋
北恋 2021-01-02 02:23

We are using EF5 and SQL Server 2012 the following two classes:

public class Question
{
    public Question()
    {
        this.Answers = new List

        
5条回答
  •  既然无缘
    2021-01-02 02:32

    If you have correctly declared the Id as Key and as being DBGenerated identity. Then EF will allow you ADD many of these to the context before saving. You can NOT ATTACH items with the same key. Attach is meant for offline data, put in context, set its state and save type scenarios.

    You have either used the Same instance twice and with EF tracking by default caused a mess. Or somehow used ATTACH twice. Make sure you are handling your instances cleanly.*

    eg

    public class BaseEntityLongConfiguration : EntityTypeConfiguration where T : BaseObjectLong {
        public BaseEntityLongConfiguration(DatabaseGeneratedOption DGO = DatabaseGeneratedOption.Identity) {
    
            // Primary Key
            this.HasKey(t => t.Id);
    
            // Properties
            //Id is an indent allocated by DB
            this.Property(t => t.Id).HasDatabaseGeneratedOption(DGO); // default to db generated
    
            this.Property(t => t.RowVersion)   // for concurrency
                .IsRequired()
                .IsFixedLength()
                .HasMaxLength(8)
                .IsRowVersion();
        }
    }
    

    A just tried a simple Test to check it works (in ef5)

    public class ExampleLog  {
        public virtual long Id   { get; set; }
        public virtual string MessageText { get; set; }
    }
    
    [TestMethod]
        public void ExampleLogTest() {
            var e1 = new ExampleLog();
            e1.MessageText = "example1";
            var e2 = new ExampleLog();
            e2.MessageText = "example2";
            _context.Set().Add(e1);
            _context.Set().Add(e2);
         var res =   _context.SaveChanges();
          Debug.WriteLine("result expected 2->" + res.ToString());
        }
    

    edit: At request, adding save Respository pattern, BAsic sample, error handling removed

    public class RepositoryBase : where TPoco :    BaseObject {
        public RepositoryBase(BosBaseDbContext context) { Context = context; }
    

    ....

       /// 
        /// Add new POCO 
        /// 
        public virtual OperationResult Add(TPoco poco) {
            var opResult = new OperationResult();
            try {
              Context.Set().Add(poco);
            }
            catch (Exception ex) {
             .... custom error tool
                return opResult;
            }
            return opResult;
        }
         /// 
        /// Poco must already be attached,, detect chnages is triggered
        /// 
        public virtual OperationResult Change(TPoco poco) {
            var opResult = new OperationResult();
            try {    // ONLY required if NOT using chnage tracking enabled
                Context.ChangeTracker.DetectChanges();
            }
            catch (Exception ex) {
             .... custom error tool
                return opResult;
            }
            return opResult;
        }
    

提交回复
热议问题