zzzprojects / Dapper-Plus

Dapper Plus - High-Efficient Bulk Actions (Insert, Update, Delete, and Merge) for .NET
https://dapper-plus.net/
383 stars 85 forks source link

An error occured while resolving mapping by name. See the inner exception for details ---> System.Exception: Missing Colum #82

Closed shubhamkwn closed 2 years ago

shubhamkwn commented 3 years ago

Hey @JonathanMagnan , I am using the dapperplus manager but I also encounter the same error and I am trying to use context.RefreshModels() but unable to use.

My senario is that the primary key of a table is trying to map with other primary key of table using Map fun but it is throwing the error as Mising Column .

Run-time exception (line 35): An error occured while resolving mapping by name. See the inner exception for details

Stack Trace:

[System.Exception: Missing Colum : Description
On entity : Person
On Table : [Person]]
at Z.BulkOperations.BulkOperation.(String , Boolean , Boolean , Boolean )
at Z.BulkOperations.BulkOperation.()

[System.Exception: An error occured while resolving mapping by name. See the inner exception for details]
at Z.BulkOperations.BulkOperation.()
at Z.BulkOperations.BulkOperation.Execute()
at Z.BulkOperations.BulkOperation.BulkInsert()
at Z.Dapper.Plus.DapperPlusAction.Execute()
at Z.Dapper.Plus.DapperPlusAction..ctor(BaseDapperPlusActionSet action, String key, DapperPlusActionKind kind, Object dataSource)
at Z.Dapper.Plus.DapperPlusActionSet1.AddAction(String mapperKey, DapperPlusActionKind actionKind, TEntity item) at Z.Dapper.Plus.DapperPlusActionSet1.DapperPlusActionSetBuilder(DapperPlusContext context, IDbConnection connection, IDbTransaction transaction, String mapperKey, DapperPlusActionKind actionKind, TEntity item, Func2[] selectors) at Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, String mapperKey, T item, Func2[] selectors)
at Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, T item, Func`2[] selectors)
at Program.Main() :line 35
shubhamkwn commented 3 years ago

@JonathanMagnan I open a new issue please check it and give the solution

JonathanMagnan commented 3 years ago

Note: related to https://github.com/zzzprojects/EntityFramework-Extensions/issues/313

JonathanMagnan commented 3 years ago

Hello @shubhamkwn ,

What do you mean by My senario is that the primary key of a table is trying to map with other primary key of table using Map.

Could you give you more information about this Description column which is missing?

How do look your entity, table, and mapping related to Person and Description column?

JonathanMagnan commented 3 years ago

Hello @shubhamkwn ,

Since our last conversation, we haven't heard from you.

Don't hesitate to provide further information so that we can assist you better!

Looking forward to hearing from you,

Jon

shubhamkwn commented 3 years ago

Hey @JonathanMagnan ,

When I tried to use DapperPlusManager.Entity() .Map(order => order.Description, "Detail")

There is a list that contains properties including Description but the table of a database contains all properties exactly except "Description" instead of this it contains the "Detail" property and I tried to map before merging the records.

When the code tried to BulkMerge it throws the errors as I posted above.

shubhamkwn commented 3 years ago

@JonathanMagnan

public class Person 
    {
        public int PersonId { get; set; }
        public string Detail { get; set; }
        public decimal TotalPrice { get; set; }
        public int TotalQuantity { get; set; }
    }
    DapperPlusManager.Entity<Person>().Table("Person")
                        .Key(x=>x.PersonId)
            .Map(x=>x.Description, "Detail");

command.CommandText = @"   
CREATE TABLE [Orders]
(
    [PersonId] [INT] NOT NULL,
    [Detail] [VARCHAR](20) NULL,
    [TotalPrice] [Money] NULL,
    [TotalQuantity] [int] NULL,
    [IsDeleted] bit NULL,
    CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED 
    (
        `[PersonId]` ASC
    )
) ";

Something Like this

JonathanMagnan commented 3 years ago

Seem to work fine for me: https://dotnetfiddle.net/yulMdB

However, if you start mapping, you need to map all properties.

We currently don't support partial mapping + auto mapping.

Let me know if you can reproduce it

JonathanMagnan commented 3 years ago

Hello @shubhamkwn

Since our last conversation, we haven't heard from you.

Are you still encountering the issue with your mapping?

Don't hesitate to provide an example so that we can help you better!

Looking forward to hearing from you,

Jon

JonathanMagnan commented 3 years ago

Hello @JonathanMagnan

A simple reminder that we are here to assist you!

Feel free to provide an example so that we can help you better.

Best regards,

Jon

guillemurano commented 2 years ago

I'm getting this same error "An error occured while resolving mapping by name. See the inner exception for details" with something like this:

public class User
{
    public User()
    {
    }

    public long Id { get; set; }
    public long PartnerId { get; set; }
    public string Name { get; set; } = string.Empty!;
    public string CompanyTown { get; set; } = string.Empty!;
    public MatchDescription MatchType { get; set; } = MatchDescription.Foreign;
    public virtual Partner Partner {get; set;}
}

public void BulkInsert(ICollection<User> users)
 { 
        using var connection = DBConnection.GetConnection();

        DapperPlusManager.Entity<User>()
                .Table("schema.user")
                .Ignore(am => am.Id)
                .Ignore(am => am.Partner)
                .Key(am => new {am.PartnerId, am.Name})
                .Map(am => am.PartnerId, "partner_id")
                .Map(am => am.Name, "name")
                .Map(am => am.CompanyTown, "company_town")
                .Map(am => am.MatchType.Name, "match_type");

        connection.BulkInsert(users);
}

CREATE TABLE IF NOT EXISTS user (
       partner_id  INT NOT NULL
      ,name                 VARCHAR(50)
      ,company_town  VARCHAR(50)
      ,match_type            VARCHAR(20)
      ,PRIMARY KEY (partner_id, name)
      ,FOREIGN KEY (match_type) REFERENCES match_desc("name")
      ,FOREIGN KEY (partner_id) REFERENCES partner(partner_id)
      );
JonathanMagnan commented 2 years ago

Hello @guillemurano ,

The issue happen because of how we did the mapping which is confusing. A source column can be mapped to multiple destination columns.

So when you do : .Key(am => new {am.PartnerId, am.Name})

The PartnerId is still mapped to the "PartnerId" column name even if you specified later a Map to "partner_id".

So your mapping should look like this:

using var connection = DBConnection.GetConnection();

var context = new DapperPlusContext(connection);
context.Entity<User>()
    .Table("schema.user")
    .Ignore(am => am.Id)
    .Ignore(am => am.Partner)
    .Key(am => am.PartnerId, "partner_id")
    .Key(am => am.Name, "name")
    .Map(am => am.CompanyTown, "company_town")
    .Map(am => am.MatchType.Name, "match_type");

context.BulkInsert(invoices);

Note that I also used a context instance mapping in my example which is the right way to do it in a method: https://dapper-plus.net/getting-started-mapping#instance-context-mapping

(You currently keep override the global mapping the way you did it every time you can the BulkInsert which may lead to some issues in concurrency scenario.)

Let me know if that fixed your issue.

Best Regards,

Jon

guillemurano commented 2 years ago

Thanks, the instance context mapping was the key to solve my issue.