Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ambiguous match found. #111

Open
DiomedesDominguez opened this issue Jun 20, 2016 · 15 comments
Open

Ambiguous match found. #111

DiomedesDominguez opened this issue Jun 20, 2016 · 15 comments

Comments

@DiomedesDominguez
Copy link

DiomedesDominguez commented Jun 20, 2016

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
Copy link
Author

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

@bilal-fazlani
Copy link
Owner

Show me the code of how u tried the bulk insert

@bilal-fazlani
Copy link
Owner

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

@DiomedesDominguez
Copy link
Author

DiomedesDominguez commented Jun 26, 2016

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));
            }
        }

@bilal-fazlani
Copy link
Owner

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

@DiomedesDominguez
Copy link
Author

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

@bilal-fazlani
Copy link
Owner

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

@DiomedesDominguez
Copy link
Author

DiomedesDominguez commented Jul 1, 2016

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

@patrickmichalina
Copy link

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

@bilal-fazlani
Copy link
Owner

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

On 18-Jul-2016 11:59 am, "Patrick Michalina" notifications@github.com
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
#111 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADPSr76cVX98pEk8XJb8ueKAO3r3JU_qks5qWx1JgaJpZM4I5WMF
.

@patrickmichalina
Copy link

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)

@DiomedesDominguez
Copy link
Author

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;

@bilal-fazlani
Copy link
Owner

Okay I will try this

On Mon, Jul 18, 2016 at 7:44 PM Diomedes Ignacio Domínguez Ureña <
notifications@github.com> 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
#111 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADPSr7Ah3MeaP2MLXeZ14Hx-vQGZ6aWjks5qW4pggaJpZM4I5WMF
.

@logid
Copy link

logid commented Jul 22, 2016

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 <
notifications@github.com> 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 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();

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

#111 (comment),
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
#111 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AJ1rQSfskZivbzXgOFek8mnUokYopBvxks5qXK0QgaJpZM4I5WMF.

@patrickmichalina
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants