tracker-enabled-dbcontext icon indicating copy to clipboard operation
tracker-enabled-dbcontext copied to clipboard

Ambiguous match found.

Open DiomedesDominguez opened this issue 9 years ago • 15 comments

StackTrace
`   at System.RuntimeType.GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
   at System.Type.GetProperty(String name, BindingFlags bindingAttr)
   at EntityFramework.MappingAPI.Extensions.TypeExtensions.GetProperty(Type type, String propertyName, Char separator) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Extensions\TypeExtensions.cs:line 79
   at EntityFramework.MappingAPI.Mappers.MapperBase.MapProperty(EntityMap entityMap, EdmProperty edmProperty, Int32& i, String& prefix) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Mappers\MapperBase.cs:line 488
   at EntityFramework.MappingAPI.Mappers.MapperBase.MapEntity(String typeFullName, EdmType edmItem) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Mappers\MapperBase.cs:line 357
   at EntityFramework.MappingAPI.Mappings.DbMapping..ctor(DbContext context) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Mappings\DbMapping.cs:line 82
   at EntityFramework.MappingAPI.EfMap.Get(DbContext context) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\EfMap.cs:line 60
   at EntityFramework.MappingAPI.Extensions.MappingApiExtensions.Db(DbContext ctx, Type type) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Extensions\MappingApiExtensions.cs:line 51
   at TrackerEnabledDbContext.Common.Configuration.DbMapping..ctor(ITrackerContext context, Type entityType)
   at TrackerEnabledDbContext.Common.Auditors.LogAuditor.CreateLogRecord(Object userName, EventType eventType, ITrackerContext context)
   at TrackerEnabledDbContext.Common.CoreTracker.AuditAdditions(Object userName, IEnumerable`1 addedEntries)
   at TrackerEnabledDbContext.Identity.TrackerIdentityContext`6.SaveChanges(Object userName)
   at TrackerEnabledDbContext.Identity.TrackerIdentityContext`6.SaveChanges()
   at GTM.Repositories.Base.Repository`1.Save() in E:\DEV\MSPDIDU\Go To Market\Go to market\GTM.Repositories\Base\Repository.cs:line 194
   at GTM.Repositories.Base.Repository`1.AddOrUpdate(TE model) in E:\DEV\MSPDIDU\Go To Market\Go to market\GTM.Repositories\Base\Repository.cs:line 88
   at GTM.Services.Base.Service`2.AddOrUpdate(TE model) in E:\DEV\MSPDIDU\Go To Market\Go to market\GTM.Services\Base\Service.cs:line 73
   at GTM.Services.Service.AlmacenService.Guardar(AlmacenViewModel viewModel) in E:\DEV\MSPDIDU\Go To Market\Go to market\GTM.Services\Service\AlmacenService.cs:line 87
   at GTM.Web.Controllers.AlmacenesController.Save(AlmacenViewModel model) in E:\DEV\MSPDIDU\Go To Market\Go to market\GTM.Web\Controllers\AlmacenesController.cs:line 112`

DiomedesDominguez avatar Jun 20 '16 04:06 DiomedesDominguez

This happened to me in previos version, when I tried to create a bulk insert of the AuditLogDetails table.

DiomedesDominguez avatar Jun 20 '16 04:06 DiomedesDominguez

Show me the code of how u tried the bulk insert

bilal-fazlani avatar Jun 20 '16 05:06 bilal-fazlani

What is the type of exception ? how to reproduce it ?

bilal-fazlani avatar Jun 24 '16 18:06 bilal-fazlani

public override int SaveChanges()
        {
            try
            {
                var result = 0;
                foreach (var ent in ChangeTracker.Entries().Where(c => c.State == EntityState.Added || c.State == EntityState.Modified))
                {
                    using (var auditer = new LogAuditor(ent))
                    {
                        var eventType = EventType.Modified;
                        if (ent.State == EntityState.Added)
                        {
                            eventType = EventType.Added;
                        }

                        base.SaveChanges();

                        var record = auditer.GetLogRecord(UserId, eventType, this);
                        if (record == null) continue;
                        var detailAuditor = new LogDetailsAuditor(ent, record);
                        var details = detailAuditor.GetLogDetails().ToList();

                        if (details.Count <= 0) continue;
                        Logs.Add(record);
                        base.SaveChanges();

                        this.BulkInsert(details);
                        base.SaveChanges();
                    }
                }

                result = base.SaveChanges();

                return result;
            }
            catch (DbEntityValidationException ex)
            {
                var msg = new StringBuilder();

                foreach (var error in ex.EntityValidationErrors.SelectMany(errors => errors.ValidationErrors))
                    msg.Append($"{error.ErrorMessage}<br/>");

                throw new Exception(msg.ToString().Remove(msg.Length - 5, 5));
            }
        }

DiomedesDominguez avatar Jun 26 '16 01:06 DiomedesDominguez

You have made this change to source code ? or overridden the method ? what is this class ?

bilal-fazlani avatar Jun 26 '16 07:06 bilal-fazlani

I made this change outside the source code, overridden the method, in my DBContext.

DiomedesDominguez avatar Jun 26 '16 20:06 DiomedesDominguez

You are adding logs n bulk and calling savechanges method, wouldn't it try to insert logs again ?

bilal-fazlani avatar Jul 01 '16 08:07 bilal-fazlani

It shouldn't because Log Details is empty before the bulk.

DiomedesDominguez avatar Jul 01 '16 13:07 DiomedesDominguez

Same error here but I am doing nothing special. Any insert into the database yields this. I am getting this during Seed()

patrickmichalina avatar Jul 18 '16 06:07 patrickmichalina

Can u send me a small application with minimal code to reproduce this problem ?

On 18-Jul-2016 11:59 am, "Patrick Michalina" [email protected] wrote:

Same error here but I am doing nothing special. Any insert into the database yields this. I am getting this during Seed()

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bilal-fazlani/tracker-enabled-dbcontext/issues/111#issuecomment-233243269, or mute the thread https://github.com/notifications/unsubscribe-auth/ADPSr76cVX98pEk8XJb8ueKAO3r3JU_qks5qWx1JgaJpZM4I5WMF .

bilal-fazlani avatar Jul 18 '16 06:07 bilal-fazlani

This started happening on the latest version. I started on a new database and added the new table for metadata. This is thrown on a very basic Seed method. A small class nothing interesting. Both Fluent API and Attribute configuration.

System.Reflection.AmbiguousMatchException: Ambiguous match found.
   at System.RuntimeType.GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
   at System.Type.GetProperty(String name, BindingFlags bindingAttr)
   at EntityFramework.MappingAPI.Extensions.TypeExtensions.GetProperty(Type type, String propertyName, Char separator) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Extensions\TypeExtensions.cs:line 79
   at EntityFramework.MappingAPI.Mappers.MapperBase.MapProperty(EntityMap entityMap, EdmProperty edmProperty, Int32& i, String& prefix) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Mappers\MapperBase.cs:line 488
   at EntityFramework.MappingAPI.Mappers.MapperBase.MapEntity(String typeFullName, EdmType edmItem) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Mappers\MapperBase.cs:line 357
   at EntityFramework.MappingAPI.Mappings.DbMapping..ctor(DbContext context) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Mappings\DbMapping.cs:line 82
   at EntityFramework.MappingAPI.EfMap.Get(DbContext context) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\EfMap.cs:line 60
   at EntityFramework.MappingAPI.Extensions.MappingApiExtensions.Db(DbContext ctx, Type type) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Extensions\MappingApiExtensions.cs:line 51
   at TrackerEnabledDbContext.Common.Configuration.DbMapping..ctor(ITrackerContext context, Type entityType)
   at TrackerEnabledDbContext.Common.Auditors.LogAuditor.CreateLogRecord(Object userName, EventType eventType, ITrackerContext context, ExpandoObject metadata)
   at TrackerEnabledDbContext.Common.CoreTracker.AuditChanges(Object userName, ExpandoObject metadata)
   at CallSite.Target(Closure , CallSite , CoreTracker , Object , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3[T0,T1,T2](CallSite site, T0 arg0, T1 arg1, T2 arg2)
   at TrackerEnabledDbContext.TrackerContext.SaveChanges(Object userName)
   at TrackerEnabledDbContext.TrackerContext.SaveChanges()
   at System.Data.Entity.Migrations.DbMigrator.SeedDatabase()
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.SeedDatabase()
   at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
   at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
   at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
   at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)

patrickmichalina avatar Jul 18 '16 06:07 patrickmichalina

To replicate what @patrickmichalina says, make a Master-detail application, something like Country-states-cities. For some reason, when it try to save the log, explote because the multiple insert in log's details. To fix it, I created this extension method:

//mLog and mLogsDetails classes have the same structure as an old version of Log and LogDetails

        public static void SaveLogs(this DbContext context, List<mLog> logs )
        {
            foreach (var log in logs)
            {
                var commandString = new StringBuilder(@"DECLARE @LogId AS BIGINT
INSERT INTO dbo.mLogs ( EventDate , EventType , RecordId , TableName , UserId)");
                var lastUnionLength = " UNION ALL".Length + 1;

                commandString =
                    commandString.AppendLine(
                        $"SELECT '{log.EventDate.ToString("yyyy/MM/dd hh:mm:ss.fff")}',{(byte)log.EventType},{log.RecordId},'{log.TableName}',{log.UserId}");

                commandString = commandString.AppendLine("SELECT @LogId = @@IDENTITY");
                commandString = commandString.AppendLine("INSERT INTO dbo.mLogsDetails ( LogId , ColumnName , OldValue , NewValue )");

                commandString = log.LogDetails
                                   .Aggregate(commandString, 
                                   (current, detail) => 
                                   current.AppendLine($"SELECT @LogId, '{detail.ColumnName}', '{(string.IsNullOrEmpty(detail.OldValue) ? "" : detail.OldValue)}', '{(string.IsNullOrEmpty(detail.NewValue) ? "" : detail.NewValue)}' UNION ALL"));

                commandString.Remove(commandString.Length - lastUnionLength, lastUnionLength).ToString();
                context.Database.ExecuteSqlCommand(commandString.ToString());
            }

        }

And in the SaveChanges method I have this:

                var logs = new List<mLog>();

                foreach (var ent in ChangeTracker.Entries().Where(p => p.State == EntityState.Modified))
                {
                    using (var auditer = new LogAuditor(ent))
                    {
                        var state = EventType.Modified;
                        if (ent.Entity is IBaseEntity)
                        {
//This is a particulary of the system, so please ignore it
                            state = (ent.Entity as IBaseEntity).Estado == EstadoRegistro.Eliminado ? EventType.Deleted : EventType.Modified;
                        }

                        var record = auditer.GetLogRecord(UserId, state, this);
                        if (record == null) continue;

                        logs.Add(record);
                    }
                }

                var addedEntries = ChangeTracker.Entries().Where(p => p.State == EntityState.Added).ToList();
                var result = base.SaveChanges();
                foreach (var ent in addedEntries)
                {
                    using (var auditer = new LogAuditor(ent))
                    {
                        var record = auditer.GetLogRecord(UserId, EventType.Added, this);
                        if (record == null) continue;
                        logs.Add(record);
                    }
                }

                if (logs.Count == 0) return result;
                this.SaveLogs(logs);

                return result;

DiomedesDominguez avatar Jul 18 '16 14:07 DiomedesDominguez

Okay I will try this

On Mon, Jul 18, 2016 at 7:44 PM Diomedes Ignacio Domínguez Ureña < [email protected]> wrote:

To replicate what @patrickmichalina https://github.com/patrickmichalina says, make a Master-detail application, something like Country-states-cities. For some reason, when it try to save the log, explote because the multiple insert in log's details. To fix it, I created this extension method:

//mLog and mLogsDetails classes have the same structure as an old version of Log and LogDetails

    public static void SaveLogs(this DbContext context, List<mLog> logs )
    {
        foreach (var log in logs)
        {
            var commandString = new StringBuilder(@"DECLARE @LogId AS BIGINTINSERT INTO dbo.mLogs ( EventDate , EventType , RecordId , TableName , UserId)");
            var lastUnionLength = " UNION ALL".Length + 1;

            commandString =
                commandString.AppendLine(
                    $"SELECT '{log.EventDate.ToString("yyyy/MM/dd hh:mm:ss.fff")}',{(byte)log.EventType},{log.RecordId},'{log.TableName}',{log.UserId}");

            commandString = commandString.AppendLine("SELECT @LogId = @@IDENTITY");
            commandString = commandString.AppendLine("INSERT INTO dbo.mLogsDetails ( LogId , ColumnName , OldValue , NewValue )");

            commandString = log.LogDetails
                               .Aggregate(commandString,
                               (current, detail) =>
                               current.AppendLine($"SELECT @LogId, '{detail.ColumnName}', '{(string.IsNullOrEmpty(detail.OldValue) ? "" : detail.OldValue)}', '{(string.IsNullOrEmpty(detail.NewValue) ? "" : detail.NewValue)}' UNION ALL"));

            commandString.Remove(commandString.Length - lastUnionLength, lastUnionLength).ToString();
            context.Database.ExecuteSqlCommand(commandString.ToString());
        }

    }

And in the SaveChanges method I have this:

            var logs = new List<mLog>();

            foreach (var ent in ChangeTracker.Entries().Where(p => p.State == EntityState.Modified))
            {

using (var auditer = new

LogAuditor(ent)) { var state = EventType.Modified; if (ent.Entity is IBaseEntity) {//This is a particulary of the system, so please ignore it state = (ent.Entity as IBaseEntity).Estado == EstadoRegistro.Eliminado ? EventType.Deleted : EventType.Modified; }

                    var record = auditer.GetLogRecord(UserId, state, this);

if (record == null) continue

;

                    logs.Add(record);
                }
            }

            var addedEntries = ChangeTracker.Entries().Where(p => p.State == EntityState.Added).ToList();
            var result = base.SaveChanges();
            foreach (var ent in addedEntries)
            {

using (var auditer = new

LogAuditor(ent)) { var record = auditer.GetLogRecord(UserId, EventType.Added, this);

if (record == null) continue

; logs.Add(record); } }

            if (logs.Count == 0) return result;
            this.SaveLogs(logs);

            return result;

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/bilal-fazlani/tracker-enabled-dbcontext/issues/111#issuecomment-233340819, or mute the thread https://github.com/notifications/unsubscribe-auth/ADPSr7Ah3MeaP2MLXeZ14Hx-vQGZ6aWjks5qW4pggaJpZM4I5WMF .

bilal-fazlani avatar Jul 19 '16 10:07 bilal-fazlani

Please don gt disgturb mhy email Den 7/19/2016 12:55 PM, skrev Bilal:

Okay I will try this

On Mon, Jul 18, 2016 at 7:44 PM Diomedes Ignacio Domínguez Ureña < [email protected]> wrote:

To replicate what @patrickmichalina https://github.com/patrickmichalina says, make a Master-detail application, something like Country-states-cities. For some reason, when it try to save the log, explote because the multiple insert in log's details. To fix it, I created this extension method:

//mLog and mLogsDetails classes have the same structure as an old version of Log and LogDetails

public static void SaveLogs(this DbContext context, List<mLog> logs ) { foreach (var log in logs) { var commandString = new StringBuilder(@"DECLARE @LogId AS BIGINTINSERT INTO dbo.mLogs ( EventDate , EventType , RecordId , TableName , UserId)"); var lastUnionLength = " UNION ALL".Length + 1;

commandString = commandString.AppendLine( $"SELECT '{log.EventDate.ToString("yyyy/MM/dd hh:mm:ss.fff")}',{(byte)log.EventType},{log.RecordId},'{log.TableName}',{log.UserId}");

commandString = commandString.AppendLine("SELECT @LogId = @@IDENTITY"); commandString = commandString.AppendLine("INSERT INTO dbo.mLogsDetails ( LogId , ColumnName , OldValue , NewValue )");

commandString = log.LogDetails .Aggregate(commandString, (current, detail) => current.AppendLine($"SELECT @LogId, '{detail.ColumnName}', '{(string.IsNullOrEmpty(detail.OldValue) ? "" : detail.OldValue)}', '{(string.IsNullOrEmpty(detail.NewValue) ? "" : detail.NewValue)}' UNION ALL"));

commandString.Remove(commandString.Length - lastUnionLength, lastUnionLength).ToString(); context.Database.ExecuteSqlCommand(commandString.ToString()); }

}

And in the SaveChanges method I have this:

var logs = new List<mLog>();

foreach (var ent in ChangeTracker.Entries().Where(p => p.State == EntityState.Modified)) {

using (var auditer = new

LogAuditor(ent)) { var state = EventType.Modified; if (ent.Entity is IBaseEntity) {//This is a particulary of the system, so please ignore it state = (ent.Entity as IBaseEntity).Estado == EstadoRegistro.Eliminado ? EventType.Deleted : EventType.Modified; }

var record = auditer.GetLogRecord(UserId, state, this);

if (record == null) continue

;

logs.Add(record); } }

var addedEntries = ChangeTracker.Entries().Where(p => p.State == EntityState.Added).ToList(); var result = base.SaveChanges(); foreach (var ent in addedEntries) {

using (var auditer = new

LogAuditor(ent)) { var record = auditer.GetLogRecord(UserId, EventType.Added, this);

if (record == null) continue

; logs.Add(record); } }

if (logs.Count == 0) return result; this.SaveLogs(logs);

return result;

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub

https://github.com/bilal-fazlani/tracker-enabled-dbcontext/issues/111#issuecomment-233340819, or mute the thread

https://github.com/notifications/unsubscribe-auth/ADPSr7Ah3MeaP2MLXeZ14Hx-vQGZ6aWjks5qW4pggaJpZM4I5WMF .

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/bilal-fazlani/tracker-enabled-dbcontext/issues/111#issuecomment-233597985, or mute the thread https://github.com/notifications/unsubscribe-auth/AJ1rQSfskZivbzXgOFek8mnUokYopBvxks5qXK0QgaJpZM4I5WMF.

logid avatar Jul 22 '16 01:07 logid

Any updates on this issue? I never had such problems before and may have to revert to the previous version of this package, since all my projects are highly normalized.

patrickmichalina avatar Aug 14 '16 21:08 patrickmichalina