1

Closed

Entity not found in model.

description

Hello Jonathan,

First of all, thank you for your great work!

I am encountering the same problem - and it is probably due to my limited coding experience, so I hope you can spare the time to be of assistance.

I am attempting to use the SqlBulkInsert as described in your article:
     var entities = Mapper.Map<List<ENTITYTYPENAME>>(entities);

using (var ctx = new DatabaseContext("XXXXXX"))
            {
                var test = ctx.GetModel();
                ctx.SqlBulkInsert(entities);

            }
When I inspect the different variables during runtime, test doesn't seem to contain any tables or entities under Conceptual and Storage.
Furthermore SqlBulkInsert throws the above mentioned error.

An excerpt of my Dbcontext is shown here:
public class DatabaseContext : DbContext, IDatabaseContext
    {
        public DatabaseContext(string connectionString)
            : base(connectionString)
        {
        }

        // TODO: FIX CONNECTION STRING
        public DatabaseContext()
            : base(
                "XXXXXXX"
                )
        {
        }

        public IDbSet<ENTITY1> entity1 { get; set; }
        public IDbSet<ENTITY2> entity2 { get; set; }
        public IDbSet<ENTITY3> entity3 { get; set; }
        public IDbSet<ENTITY4> entity4 { get; set; }
        public IDbSet<Account> Accounts { get; set; }
        public IDbSet<User> Users { get; set; }
        public IDbSet<Customer> Customers { get; set; }

        public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
        {
            return base.Set<TEntity>();
        }
.........................
I can't seem to figure out the problem - but I sure do hope it's one made on my side of things :)

Thank you in advance!

file attachments

Closed Jun 4, 2014 at 12:38 AM by Jonathan_Magnan

comments

Jonathan_Magnan wrote Apr 7, 2014 at 10:31 AM

Thank a lot Aherforth,

The problem is pretty obvious with your example.

You are using IDbSet instead of DbSet like all examples I tried.

In the next release (next week-end), any class which inherit of IDbSet will be compatible with “Code First Model”.

Jonathan

cowpy wrote Apr 7, 2014 at 12:28 PM

Thanks a lot to you.

My english is terrible... I‘m sorry for that i didn't describe my problem timely and detailedly.
Today,I Bogged down in it.I also used IDbSet.
Finally,I change IDbSet to DbSet and use AddRange or RemoveRange Method of DbSet .
I will have a try with DbSet using Z.Extentsion.

In fact, I use EF follow the project NopCommerce.
In its framework ,i try to use Z.Extension's BulkSqlInsert.

Thank you for your great work!

wrote Apr 7, 2014 at 11:34 PM

Jonathan_Magnan wrote Apr 8, 2014 at 12:39 AM

Fixed in version 1.1.3.1

Don't worry with your English cowpy ;)

You can try again, this should be now compatible with anything which inherit from IDbSet<>

wrote Apr 9, 2014 at 7:47 AM

cowpy wrote Apr 9, 2014 at 7:47 AM

Hi, I update Z.EXTENTSION to 1.1.3.1 .
But the problem seems to be not caused by IDBSET,
I guess it may be casuse by the definition of context class.
In your context class,the DbSet<Student> is already define before compiling,
but in the framework of my sample it's dynamic ? :
 public class CodeFirstContext : DbContext
    {
        public CodeFirstContext() : base("CodeFirstConnectionString")
        {
        }

        public DbSet<Student> Students { get; set; }
        public DbSet<Standard> Standards { get; set; }
        public DbSet<TestMappingFizz2> TestMappingFizzs { get; set; }
        public DbSet<TestMappingCodeFirst> TestMappingCodeFirsts { get; set; }
        public DbSet<BulkCopyTestCodeFirst> BulkCopyTestCodeFirsts { get; set; }
    }

    public class Student
    {
        public int StudentID { get; set; }
        public string StudentName { get; set; }
    }

    public class Standard
    {
        public int StandardId { get; set; }
        public string StandardName { get; set; }
        public string Description { get; set; }
    }

    [Table("BulkCopyTest")]
    public class BulkCopyTestCodeFirst
    {
        [Column(Order = 0)]
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int ID1 { get; set; }

        [Column(Order = 1)]
        [Key]
        public int ID2 { get; set; }

        public bool? ValueBit { get; set; }
        public int? ValueInt { get; set; }

        [MaxLength(50)]
        public string ValueString { get; set; }
    }
....
I have worte a sample in the attach.
I attempting to add SqlBulkInsert in my project framework, may be i use it in the wrong way.
i also try some other ways, Only when I directly define DbSet<TestTable> in AppObjectContent,
exception is not 'Entity not found in model ' ...
1.my context class:
public class AppObjectContent : DbContext, IDbContext, IDisposable
    {
        private static readonly string nameOrConnectionString = "MyConnection";

        public AppObjectContent()
            : base(nameOrConnectionString)
        {
            //((IObjectContextAdapter) this).ObjectContext.ContextOptions.LazyLoadingEnabled = true;
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //dynamically load all configuration
            System.Type configType = typeof(TestTableMap);   //any of your configuration classes here
            var typesToRegister = Assembly.GetAssembly(configType).GetTypes()
            .Where(type => !String.IsNullOrEmpty(type.Namespace))
            .Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));

            //var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
            //.Where(type => !String.IsNullOrEmpty(type.Namespace))
            //.Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
            foreach (var type in typesToRegister)
            {
                dynamic configurationInstance = Activator.CreateInstance(type);
                modelBuilder.Configurations.Add(configurationInstance);
            }
            //...or do it manually below. For example,
            //modelBuilder.Configurations.Add(new LanguageMap());

            base.OnModelCreating(modelBuilder);
        }

        /// <summary>
        /// Attach an entity to the context or return an already attached entity (if it was already attached)
        /// </summary>
        /// <typeparam name="TEntity">TEntity</typeparam>
        /// <param name="entity">Entity</param>
        /// <returns>Attached entity</returns>
        protected virtual TEntity AttachEntityToContext<TEntity>(TEntity entity) where TEntity : BaseEntity, new()
        {
            //little hack here until Entity Framework really supports stored procedures
            //otherwise, navigation properties of loaded entities are not loaded until an entity is attached to the context
            var alreadyAttached = Set<TEntity>().Local.FirstOrDefault(x => x.Id == entity.Id);
            if (alreadyAttached == null)
            {
                //attach new entity
                Set<TEntity>().Attach(entity);
                return entity;
            }
            else
            {
                //entity is already loaded.
                return alreadyAttached;
            }
        }

        public void SqlBulkInsertTest<TEntity>(IEnumerable<TEntity> entities) where TEntity : BaseEntity
        {
            Z.ExtensionMethods.EntityFramework.DbContexttExtension.SqlBulkInsert(this, entities);

        }
...
  1. mapping class:
public class TestTableMap:EntityTypeConfiguration<TestTable>
    {
        public TestTableMap()
        {
            this.ToTable("TestTable");
            this.HasKey(v => v.Id); 
        }
    }
3.entity class:
  /// <summary>
    /// TestTable
    /// </summary>
    public class TestTable : App.Core.Data.BaseEntity
    {
       
        /// <summary>
        /// content
        /// </summary>
        public string Content { get; set; }
    }
  1. this is the Repository :
  public class Repository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity
    {

        
        #region IDbSet
        private readonly IDbContext _context;

        private IDbSet<TEntity> _entities;

        public Repository(IDbContext context)
        {
            this._context = context;
        }

        private IDbSet<TEntity> Entities
        {
            get
            {
                if (_entities == null)
                    _entities = _context.Set<TEntity>();
                return _entities;
            }
        }
        #endregion

        #region
        public virtual IQueryable<TEntity> Table
        {
            get
            {
                return this.Entities;
            }
        }

        /// <summary>
        /// RETURN INSERTED ID
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Insert(TEntity entity)
        {
            try
            {
                if (entity == null)
                    throw new ArgumentNullException("entity");

                this.Entities.Add(entity);

                this._context.SaveChanges();
            }
            catch (DbEntityValidationException dbEx)
            {
                var msg = string.Empty;

                foreach (var validationErrors in dbEx.EntityValidationErrors)
                    foreach (var validationError in validationErrors.ValidationErrors)
                        msg += string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine;

                var fail = new Exception(msg, dbEx);
                //Debug.WriteLine(fail.Message, fail);
                throw fail;
            }
            return entity.Id;
        }

        public TEntity GetById(object id)
        {
            return this.Entities.Find(id);
        }
when use:
 public class TestService
    {
        #region Fields,Init

        private readonly IRepository<TestTable> _testRepo;
        private readonly AppObjectContent _objContext;
        private readonly IDataProvider _dataProvider;
        private readonly IEfTransaction _efTran;

        public TestService()
        {
            _objContext = new AppObjectContent();
            _testRepo = new Repository<TestTable>(_objContext);
            _efTran = new EfTransaction();
        }

        #endregion Fields,Init
        #region BulkInsert
        public void SqlBulkInsertTest(IEnumerable<TestTable> entities)
        {
            _testRepo.BulkInsert(entities);
        }

        #endregion
        #region Methods

        public virtual TestTable GetById(int? id)
        {
            if (!id.HasValue)
                throw new ArgumentNullException("参数为空");
            var re = _testRepo.GetById(id);
            return re;
        }

        public virtual int Insert(TestTable entity)
        {
            if (entity == null)
                throw new ArgumentNullException("参数为空");
            var re = _testRepo.Insert(entity);
            return re;
        }
I'm still on groping stage in EF coding.
I don't konw whether Nopcommerce framework is dbfirst or codefirst,my be codefirst?
If you have some time ,hope you can spare some time help to check the sample code,
or How I can use the 'Z' properly.

annother problem
In the Documentation.chm , there are many errors..
e.g:
[Missing <summary> documentation for "T:Z.ExtensionMethods.EntityFramework.DbContexttExtension"]

in DatabaseExtension.ExecuteEntities<T> Method (, Action<DbCommand>)
[Missing <summary> documentation for "M:Z.ExtensionMethods.EntityFramework.DatabaseExtension.ExecuteEntities``1(System.Data.Entity.Database,System.Action{System.Data.Common.DbCommand})"]

wrote Apr 9, 2014 at 8:10 AM

cowpy wrote Apr 9, 2014 at 8:10 AM

samplecode

wrote Apr 9, 2014 at 10:30 AM

Jonathan_Magnan wrote Apr 9, 2014 at 10:40 AM

Thank you again cowpy,

Dynamically context is a little bit harder to do and is not supported yet. I have found an example which I hope that work. I will try it this and add it this week-end if I have enough time.

Jonathan_Magnan wrote Apr 9, 2014 at 11:00 AM

I have added notice in my article to at least advice other people who will try that dynamically code first is not supported yet.

I will try my best to make it possible in the next release.

cowpy wrote Apr 10, 2014 at 1:16 AM

Don't need so urgent.
You should fix it when you have enough time.

Thanks.

Jonathan_Magnan wrote Apr 14, 2014 at 4:19 AM

I always have time for people interesting in my project ;)

I tested your example and it’s worked like a charm with the new version. I now support dynamic code first model, complex type, TPC and TPH.

wrote Apr 14, 2014 at 4:20 AM

wrote Jun 4, 2014 at 12:38 AM