zzzprojects / dapper-plus Goto Github PK
View Code? Open in Web Editor NEWDapper Plus - High-Efficient Bulk Actions (Insert, Update, Delete, and Merge) for .NET
Home Page: https://dapper-plus.net/
Dapper Plus - High-Efficient Bulk Actions (Insert, Update, Delete, and Merge) for .NET
Home Page: https://dapper-plus.net/
I have the following mapping:
DapperPlusManager.Entity<Iccid>().Table("iccid")
.Identity(x => x.Id, "id")
.Key(x => x.Identifier, "identifier")
.Map(x => x.IccidValue, "iccid_value")
.Map(x => x.Status, "status")
.Map(x => x.IdBatch, "id_batch")
.Map(x => x.IdProduct, "id_product")
.Map(x => x.IdManufacturer, "id_manufacturer")
.Map(x => x.IdConsumer, "id_consumer")
.Map(x => x.IdSimType, "id_sim_type")
.Map(x => x.IdSimFormat, "id_sim_format")
.Map(x => x.Pin1, "pin1")
.Map(x => x.Puk1, "puk1")
.Map(x => x.Pin2, "pin2")
.Map(x => x.Puk2, "puk2")
.Map(x => x.Comments, "comments")
.Map(x => x.CreatedBy, "created_by")
.Map(x => x.CreationDate, "creation_date")
.Map(x => x.LastUpdatedBy, "last_updated_by")
.Map(x => x.LastUpdatedDate, "last_updated_date")
.InsertIfNotExists();
For the following entity:
public class Iccid : Resource
{
public decimal IccidValue { get; set; }
public int IdBatch { get; set; }
public int IdProduct { get; set; }
public int IdManufacturer { get; set; }
public int IdConsumer { get; set; }
public int IdSimType { get; set; }
public int IdSimFormat { get; set; }
public string Puk1 { get; set; }
public string Pin1 { get; set; }
public string Puk2 { get; set; }
public string Pin2 { get; set; }
public List<Msisdn> MsisdnList { get; set; } = new List<Msisdn>();
}
public abstract class Resource : BaseAudit
{
public long Id { get; set; }
public string Identifier { get; set; }
public string Comments { get; set; }
public ResourceStatus Status { get; set; }
}
public abstract class BaseAudit
{
public string CreatedBy { get; set; }
public DateTime CreationDate { get; set; }
public string LastUpdatedBy { get; set; }
public DateTime LastUpdatedDate { get; set; }
}
After I do the following insert
transaction.BulkInsert(iccids);
I get the following exception:
System.IndexOutOfRangeException: 'There is no row at position 9804.'
System.IndexOutOfRangeException
HResult=0x80131508
Message=There is no row at position 9804.
Source=System.Data.Common
StackTrace:
at System.Data.RBTree`1.GetNodeByIndex(Int32 userIndex)
at .( , DbCommand )
at .Execute(List`1 actions)
at .(List`1 )
at Z.BulkOperations.BulkOperation.Execute()
at Z.BulkOperations.BulkOperation.BulkInsert()
at Z.Dapper.Plus.DapperPlusAction.Execute()
at Z.Dapper.Plus.DapperPlusActionSet`1.AddAction(String mapperKey, DapperPlusActionKind actionKind, TEntity item)
at Z.Dapper.Plus.DapperPlusActionSet`1.DapperPlusActionSetBuilder(DapperPlusContext context, IDbConnection connection, IDbTransaction transaction, String mapperKey, DapperPlusActionKind actionKind, TEntity item, Func`2[] selectors)
at Z.Dapper.Plus.DapperPlusActionSet`1..ctor(DapperPlusContext context, IDbTransaction transaction, String mapperKey, DapperPlusActionKind actionKind, TEntity item, Func`2[] selectors)
at Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbTransaction transaction, String mapperKey, T item, Func`2[] selectors)
at Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbTransaction transaction, T item, Func`2[] selectors)
at RMMigration.CerillionMigration.Run() in C:\dev\crm\tools\rm-migration\RMMigration\RMMigration\CerillionMigration.cs:line 182
at RMMigration.Program.Main(Boolean cleanDb, Boolean runCerillionMigration, Boolean runSimManagerMigration) in C:\dev\crm\tools\rm-migration\RMMigration\RMMigration\Program.cs:line 42
This exception was originally thrown at this call stack:
[External Code]
RMMigration.CerillionMigration.Run() in CerillionMigration.cs
RMMigration.Program.Main(bool, bool, bool) in Program.cs
I'm trying to insert ~700k entities in a Postgres database. Everything seems fine for item from the iccids list at index 9804. If I insert only some part of the data (~600k) it seems to be working though, which is odd.If I insert the remaining part of the data (~100k) I have the same error System.IndexOutOfRangeException: 'There is no row at position 7318.'
Is it Possible to use DataTable on BulkMerge?
Hello world!
I am using you for bulk insert operation but I updated the other day and now I started getting the error below.
Please support
My code
DapperPlusManager.Entity<TEntity>().Table(typeof(TEntity).Name).Identity("Id").BatchTimeout(12000).BatchSize(50000); using (var connection = new NpgsqlConnection(_connectionString)) { connection.BulkInsert(entityList); }
Error Message : ERROR SqlState: 42601 MessageText: syntax error at or near "ORDER" Position: 510 File: scan.lsd Line: 1150 Routine: scanner_yyerror}
Thank you!
BulkMerge will execute a trigger on the first column but not the second in a two-row batch.
Trigger like this:
CREATE TRIGGER [dbo].[Trigger_MyTable_CreatedOn]
ON [dbo].[MyTable]
FOR INSERT, UPDATE
AS
DECLARE @id int;
DECLARE @currenttime datetime;
SELECT @id=i.Id FROM inserted i;
SET @currenttime=SYSUTCDATETIME();
BEGIN
UPDATE [dbo].[MyTable] SET LastModified=@currenttime WHERE Id=@id;
END
GO
Merge c# code:
DapperPlusManager.Entity<MyTable>().Table("MyTable").Key(myEntity =>
new {myEntity.Column1, myEntity.Column2, myEntity.Column3});
connection.BulkMerge(myEntities);
I'll bulk merge two entities and the result will look like this:
Id | Column1 | Column 2 | Column 3 | LastModified |
---|---|---|---|---|
1 | ... | ... | ... | 2017-11-13 21:54:12.790 |
2 | ... | ... | ... | NULL |
Any ideas?
Here is my code:
class Program
{
static async Task Main(string[] args)
{
//var summary = BenchmarkRunner.Run<DapperTest>();
Stopwatch sw = Stopwatch.StartNew();
await DapperBulkInsert();
sw.Stop();
Console.WriteLine($"time consuming: {sw.ElapsedMilliseconds} ms\r\noperations done");
Console.ReadKey();
}
static async Task DapperBulkInsert()
{
DapperPlusManager.Entity<UserToken>()
.Table($"{nameof(UserToken)}s")
.Identity(x => x.Id);
Console.WriteLine("connect to database");
using (var conn = new MySqlConnection("server=192.168.110.130;database=usercenterdb;uid=root;pwd=P@ssw0rd;charset='latin1';sslmode=none;"))
{
try
{
await conn.OpenAsync();
}
catch (Exception ex)
{
Console.WriteLine($"error: {ex.Message}");
return;
}
Console.WriteLine("insert items");
var rows = Enumerable.Range(0, 100).Select(x => new UserToken()
{
Id = Guid.NewGuid(),
UserId = Guid.Parse("08d56d0b-f8fb-bed7-47d4-332e74ef4ef1")
});
try
{
conn.BulkInsert(rows);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
public class UserToken
{
public UserToken()
{
Expiration = LoginTime.AddHours(2d);
}
public Guid Id { get; set; }
public DateTime Expiration { get; set; }
public int LoginProvider { get; set; } = 0;
public DateTime LoginTime { get; set; } = DateTime.Now;
public Guid UserId { get; set; }
public int State { get; set; } = 0;
}
Then I run this program and get the following result:
How can i fix it, thank you.
Is it possible to use BulkInsert and if the record already exists in the db it skips to insert that record. Lets say my table has a customerid and companyid. If A record with existing values wants to be inserted we skip the insertion for this record. Is it possible?
I'm making a synchronization application, from Firebird to SQL Server. And I'm using BulkInsert from Dapper Plus.
var fbClient = new FirebirdConnect();
using (var source = fbClient.GetConnection())
{
if (source.State == ConnectionState.Closed)
source.Open();
var sqlClient = new AzureConnect();
using (var target = sqlClient.GetConnection())
{
if (target.State == ConnectionState.Closed)
target.Open();
var lastUpdate = connection.Query<DateTime>($"select coalesce((select max(DateSyncTarget) from {metadados.TargetName}), getdate()-10000) LastUpdate").ToList();
var resultSource = source.Query<MyClass>("select * from MyClass");
target.BulkInsert(resultSource.Where(w => w.Data > lastUpdate[0]));
var resultTargert = target.Query<MyClassSource>("select * from MyClass")
source.BulkInsert(resultTargert.Where(w => w.Data > lastUpdate[0]));//Error here
}
}
Everything happens well when I consult the source to do the insertion in the target.
But when I query on target to insert into source, it is giving the following error:
The Provider could not be resolved. You must explicity set the Provider.
Some idea of what causes the error?
Full stack:
em ..(BulkOperation )
em ..(BulkOperation )
em Z.BulkOperations.BulkOperation.BulkInsert()
em Z.Dapper.Plus.DapperPlusAction.Execute()
em Z.Dapper.Plus.DapperPlusAction..ctor(BaseDapperPlusActionSet action, String key, DapperPlusActionKind kind, Object dataSource)
em Z.Dapper.Plus.DapperPlusActionSet1.AddAction(String mapperKey, DapperPlusActionKind actionKind, TEntity item) em Z.Dapper.Plus.DapperPlusActionSet
1.DapperPlusActionSetBuilder(IDbConnection connection, IDbTransaction transaction, String mapperKey, DapperPlusActionKind actionKind, TEntity item, Func2[] selectors) em Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, String mapperKey, T item, Func
2[] selectors)
em Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, T item, Func`2[] selectors)
em Project.Plugins.Utils.Extensions.CommandExtensions.InsertSource[T](IDbConnection connection, IEnumerable result) na D:\Projetos\Project-API-Cloud\project-etl\Project.Plugins.Utils\Extensions\CommandExtensions.cs:linha 52
em Autorizacoes.ERP.LIBSENHA.JobAutorizacoes.Execute(IJobExecutionContext context) na D:\Projetos\Project-API-Cloud\Project-etl\Autorizacoes\JobAutorizacoes.cs:linha 105
my DB column is snake case
CREATE TABLE `my_table` (
`col_a` INT(11) NULL DEFAULT NULL,
`col_b` INT(11) NULL DEFAULT NULL
);
in this case, can't insert well.
using Dapper.Contrib.Extensions;
using Z.Dapper.Plus;
[Table("my_table")]
public class Data
{
public int ColA { get; set; }
public int ColB { get; set; }
}
public void MyInsert()
{
var values = Enumerable.Range(0, 100).Select(x => new Data { ColA = x, ColB = x });
conn.BulkInsert(data);
}
when i changed to snake case, it works.
[Table("my_table")]
public class Data
{
public int col_a { get; set; }
public int col_b { get; set; }
}
but i don't want to change my property to snake case.
i want keep property to pascal case.
i want do like this
DapperPlusManager
.Entity<Data>()
.ColumnIsSnakeCase(true);
or
[Table("my_table")]
public class Data
{
[Column("col_a")]
public int ColA { get; set; }
[Column("col_b")]
public int ColB { get; set; }
}
thank you.
Hello.
I am trying to get info about how many rows were updated and how many inserted.
Is this even possible with BulkMerge operation ?
Possibly to see how many of them failed to update or insert if it's not exception.
Thanks.
When doing bulk CRUD operations I want to know what rows that did not get through and be able to handle these rows in some way, like logging out the row data.
The bulk operations don't work with oracle connections. The error produced is:
The specified invariant name 'Oracle.ManagedDataAccess.Client' wasn't found in the list of registered .NET Data Providers.
However, the .NET Core lib for Oracle Managed Data Access has been installed and Dapper lib is working fine as well.
I cannot figure out what is happening.
Calling different DapperPlusManager.ValidateLicense overloads have different behavior. I think this is a bug, please fix.
There is a typo as highlighted in the screenshot of Dapper-Plus on the homepage http://dapper-plus.net/ as in my screen shot below.
Also the same issue on http://dapper-plus.net/overview as in screen shot.
Hi Guys!
What is the right way to BulkMerge entity that has Point member?
E.g. here is the entity class definition:
[Table("Airport")]
public partial class Airport
{
[Key]
[StringLength(4)]
public string FourLetterCode { get; set; }
[Required]
[StringLength(3)]
public string ThreeLetterCode { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[StringLength(3)]
public string CountryCode { get; set; }
public bool IsDisabled { get; set; }
[Column(TypeName = "datetime")]
public DateTime Timestamp { get; set; }
[Column(TypeName = "geometry")]
public Point Location { get; set; }
public string HotelCompany { get; set; }
public string HotelContact { get; set; }
public string HotelPhone { get; set; }
public string HotelMobile { get; set; }
public string HotelFax { get; set; }
public string HotelEmail { get; set; }
public string HotelRemarks { get; set; }
}
Currently DapperPlus inserts null for the Point type member
Thanks
Hi folks, thanks for all the hard work.
I've just found an issue while bulk inserting information using LocalDateTime from Noda Time. Basically, I have a nullable timestamp without time zone column on my Postgres database, and the bulk insert is inserting a null value regardless of the entity values contained on the collection I'm inserting.
Can I make Dapper.Plus to play nice with Noda Time?
Thanks in advance for your help!!!
Hello.
In my case I need using BulkMegre method inside our transaction. Example source code:
using (var cnn = new SqlConnection("..."))
{
cnn.Open();
using (var tran = cnn.BeginTransaction())
{
cnn.BulkMerge(entities);
}
}
But BulkMerge throw exception: ex.txt
Can you help?
Hello!
I have a main table that should be audited. This table has one-to-many reference to a child table and changes in the child table should not be audited.
I update data in these tables in the single query with BulkUpdate command.
I added AuditMode(AuditModeType.ExcludeAll)
to the mapping for the child table but I still receive AuditEntry for the child table just without values.
I need to completely exclude the child table from auditing, is it possible?
void Main()
{
using (var cnn = new SQLiteConnection("Data Source=G:\\test.sqlite"))
{
var test = (new[] { new Order(1), new Order(2) }).Take(1).ToArray();
IReadOnlyList<Order> test2 = test;
cnn.BulkInsert(test);
cnn.BulkInsert(test2);
}
}
public class Order
{
public Order(int id)
{
Id = id;
}
public int Id { get; set; }
}
BulkInsert(test2) throws an exception because it uses the overload that takes an IEnumerable. Specifically it will fail on DapperPlusAction\Method\Execute.cs line 61.
else if (DataSource.GetType().GetGenericArguments()[0] == typeof (object))
Where it tries to get the generic argument but since it's actually an array, it doesn't have one.
BulkInsert(test) works because even though it is being passed an array, it will be converted into a list at DapperPlusActionSet\Constructor\Constructor.cs line 35.
Hello,
I'm making an Ignore field, but it not working...
The ignore is for a Oracle Database.
This is the Ignore and the update:
DapperPlusManager.Entity<Plugins.Utils.Model.Source.AgriBussines.PEDSENHA>().Ignore(c => c.SolicitacaoAutorizacaoId);
source.UpdateSource(resultTarget);
DapperPlusManager.MapperCache.Clear();
The class:
namespace Plugins.Utils.Model.Source.AgriBussines
{
public class PEDSENHA : BaseSource
{
public string SolicitacaoAutorizacaoId { get; set; }
public int CODI_EMP { get; set; }
public string CODI_SEN { get; set; }
public string SENH_SEN { get; set; }
public DateTime DATA_SEN { get; set; }
}
}
And this is the update method:
public static void UpdateSource<T>(this IDbConnection connection, IList<T> result) where T : BaseSource
{
using (var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted))
{
try
{
transaction.BulkUpdate(result);
transaction.Commit();
}
catch (Exception e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{result.GetType()} - {e.Message}");
Console.ResetColor();
transaction.Rollback();
throw;
}
}
}
I'm gotting this error:
Message :
Missing: SolicitacaoAutorizacaoId
StackTrace:
em Z.BulkOperations.BulkOperation.�()
em �.�.�(BulkOperation )
em Z.BulkOperations.BulkOperation.BulkUpdate()
em Z.Dapper.Plus.DapperPlusAction.Execute()
em Z.Dapper.Plus.DapperPlusAction..ctor(BaseDapperPlusActionSet action, String key, DapperPlusActionKind kind, Object dataSource)
em Z.Dapper.Plus.DapperPlusActionSet1.AddAction(String mapperKey, DapperPlusActionKind actionKind, TEntity item) em Z.Dapper.Plus.DapperPlusActionSet
1.DapperPlusActionSetBuilder(IDbConnection connection, IDbTransaction transaction, String mapperKey, DapperPlusActionKind actionKind, TEntity item, Func2[] selectors) em Z.Dapper.Plus.DapperPlusExtensions.BulkUpdate[T](IDbTransaction transaction, String mapperKey, T item, Func
2[] selectors)
em Z.Dapper.Plus.DapperPlusExtensions.BulkUpdate[T](IDbTransaction transaction, T item, Func2[] selectors) em Plugins.Utils.Extensions.CommandExtensions.UpdateSource[T](IDbConnection connection, IList
1 result) na D:\Projetos\API-Cloud\etl\Plugins.Utils\Extensions\CommandExtensions.cs:linha 188
em SolicitacoesAutorizacao.AgriBusiness.PEDSENHA.JobSolicitacoesAutorizacao.Execute(IJobExecutionContext context)
The main webpage says PRO is free for the month?
Hi
I recently upgraded to Dapper plus 3.0.15 from 3.0.5 in my .Net Core 3.1 project.
I'm currently having problems when saving a new object into an SQLite database: this is the error
Microsoft.Data.Sqlite.SqliteException : SQLite Error 19: 'NOT NULL constraint failed: Car.Id'.
at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader()
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteNonQuery()
at .(DbCommand , BulkOperation , Int32 )
at .( , DbCommand )
at .Execute(List1 actions) at .(List
1 )
at Z.BulkOperations.BulkOperation.Execute()
at Z.BulkOperations.BulkOperation.BulkInsert()
at Z.Dapper.Plus.DapperPlusAction.Execute()
at Z.Dapper.Plus.DapperPlusActionSet1.DapperPlusActionSetBuilder(DapperPlusContext context, IDbConnection connection, IDbTransaction transaction, String mapperKey, DapperPlusActionKind actionKind, IEnumerable
1 items)
at Z.Dapper.Plus.DapperPlusActionSet1..ctor(DapperPlusContext context, IDbConnection connection, String mapperKey, DapperPlusActionKind actionKind, IEnumerable
1 items)
at Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, String mapperKey, T[] items)
at Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, T[] items)
Here is a sample code
using System;
using Microsoft.Data.Sqlite;
using Z.Dapper.Plus;
namespace Sample
{
public class Demo
{
public Demo()
{
DapperPlusManager.Entity<Car>()
.Table(nameof(Car))
.Map(m => m.Id, nameof(Car.Id))
.Map(m => m.Name, nameof(Car.Name))
.Key(x => x.Id);
}
public void SaveNewCar()
{
var car = new Car("VelarX");
using (var cn = new SqliteConnection("test/Sample/garage.db"))
{
cn.BulkInsert(car);
}
}
}
public class Car
{
public Guid Id { get; set; }
public string Name { get; set; }
public Car(string name)
{
Id = Guid.NewGuid();
Name = name;
}
}
}
I have had to downgrade to Dapper plus 3.0.5 for it to work
Hi, we use today dapper plus with our sql servers with great results. We also have a AS/400 DB2 database that is pretty vital in our infrastructure that we would like to do bulk operations to. Is this something you could support?
Hello,
Today i got this error with datetime.
I'm making a simple insert with Bulk, and gotting this execption
SqlDateTime overflow must be between 1/1/1753 12:00:00 AM and 31/12/9999 11:59:59 PM.
StackTrace:
em System.Data.SqlClient.TdsParser.TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc, Boolean sync, TaskCompletionSource
1 completion, Int32 startRpc, Int32 startParam) em System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest) em System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource
1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
em System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) em System.Data.SqlClient.SqlCommand.ExecuteNonQuery() em Z.BulkOperations.SqlActionExecutor.�(SqlCommand �, BulkOperation �, Int32 �) em Z.BulkOperations.SqlActionExecutor.�(DbCommand �, BulkOperation �, Int32 �) em Z.BulkOperations.SqlActionExecutor.�(� , DbCommand ) em �.�.�(List
1 )
em Z.BulkOperations.SqlProvider.�(List1 ) em �.�.�(BulkOperation ) em Z.BulkOperations.BulkOperation.BulkInsert() em Z.Dapper.Plus.DapperPlusAction.Execute() em Z.Dapper.Plus.DapperPlusAction..ctor(BaseDapperPlusActionSet action, String key, DapperPlusActionKind kind, Object dataSource) em Z.Dapper.Plus.DapperPlusActionSet
1.AddAction(String mapperKey, DapperPlusActionKind actionKind, TEntity item)
em Z.Dapper.Plus.DapperPlusActionSet1.DapperPlusActionSetBuilder(IDbConnection connection, IDbTransaction transaction, String mapperKey, DapperPlusActionKind actionKind, TEntity item, Func
2[] selectors)
em Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, String mapperKey, T item, Func2[] selectors) em Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, T item, Func
2[] selectors)
em Project.Plugins.Utils.Extensions.CommandExtensions.Insert[T](IDbConnection connection, IEnumerable result) na D:\Projetos\Project-API-Cloud\Project-etl\Project.Plugins.Utils\Extensions\CommandExtensions.cs:linha 88
em SolicitacoesAutorizacao.ERP.PEDSENHA.JobSolicitacoesAutorizacao.Execute(IJobExecutionContext context)
I'm trying to insert this dates:
Obs.: Yestarday was working fine.
Thanks.
Essentially I am experiencing #28 using MySql.Data 8.0.19 (also tried 6.10.9) and Z.Dapper.Plus 3.0.0 (so as to not get the trial expired exception in Jan 2020).
I know this is usually a problem with the user code and not an issue with Dapper itself, but it seems to have started happening after upgrading to the latest version of Dapper.Plus (v3.0.0).
Here's the stack trace excluding the call from my repo method to BulkInsert():
at Z.Dapper.Plus.DapperPlusAction.Execute() at Z.Dapper.Plus.DapperPlusActionSet1.DapperPlusActionSetBuilder(DapperPlusContext context, IDbConnection connection, IDbTransaction transaction, String mapperKey, DapperPlusActionKind actionKind, IEnumerable1 items, Func2[] selectors)
at Z.Dapper.Plus.DapperPlusActionSet1..ctor(DapperPlusContext context, IDbConnection connection, String mapperKey, DapperPlusActionKind actionKind, IEnumerable1 items, Func2[] selectors) at Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, String mapperKey, IEnumerable1 items, Func2[] selectors) at Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, IEnumerable1 items, Func2[] selectors)
I get this error when attempting to bulk insert into a MySql table. I have confirmed that the column names are identical (down to the casing) between the MySql table and the C# poco. Currently I am getting this exception when attempting to BulkInsert on a single record from the large number of records I was INSERTing before, just to rule out potential nulls in the records. Standard Dapper methods that SELECT from MySql tables are executing without issue leading up to this exception (for what that's worth).
Hi.
I'm trying to use BulkInsert in Dapper-Plus v.1.0.7
Z.Dapper.Plus.DapperPlusExtensions.BulkInsert(cnn, entities);
and in result gettings SQL script like
MERGE INTO [ExtParamHistory] AS DestinationTable
USING
(
SELECT @0_0 AS [ExtParamValue], @0_1 AS [DT], @0_2 AS [UserID], @0_3 AS [TaskID], @0_4 AS [ExtParamID], @0_5 AS [Comment], @0_6 AS [NativeValue], @0_7 AS [ID], @0_8 AS ZZZ_Index
) AS StagingTable
ON 1 = 2
WHEN NOT MATCHED THEN
INSERT ( [ExtParamValue], [DT], [UserID], [TaskID], [ExtParamID], [Comment], [NativeValue] )
VALUES ( [ExtParamValue], [DT], [UserID], [TaskID], [ExtParamID], [Comment], [NativeValue] )
OUTPUT
$action,
StagingTable.ZZZ_Index,
INSERTED.[ID] AS [ID_zzzinserted]
It's making empty useless join/scan on big table. Why it's not using simple insert?
I'm receiving this error when attempting to use the BulkDelete operation on entity loaded classes. Not sure what I'm doing wrong or what I'm missing at this point.
Dapper Version: 1.50.2
Dapper Plus Version: 1.3.18
Database: Sql Server 2014
DapperPlusManager.Entity<Discount>().Table("Discount").Identity(x => x.DiscountId);
var manager = Manager<Part>.Instance;
var query = manager.GetQuery(true, false).Where(a => a.Sku== sku);
if (siteId.HasValue) {
query = query.Where(a => a.SiteId== siteId.Value);
}
if (companyId.HasValue) {
query = query.Where(a => a.CompanyId== companyId.Value);
}
if (vendorId.HasValue) {
query = query.Where(a => a.VendorId== vendorId.Value);
}
var part = query.FirstOrDefault();
if (part != null) {
var priceList = part.PriceList.FirstOrDefault(a => a.CompanyPriceList.ISDEFAULT);
if (priceList != null)
{
var discountsToDelete = priceList.Discount.ToList();
var toInsert = new List<Discount>();
foreach (var priceBreak in priceBreaks) {
toInsert.Add(new Discount() {
PriceListId = priceList.PART_PRICELIST_ID,
Range = priceBreak.Quantity,
Type = ((char)priceBreak.Type).ToString(),
Discount = priceBreak.Discount,
RevenueCost= priceBreak.RevenueCost,
Created = DateTime.Now,
Modified = DateTime.Now,
IsDefault = priceBreak.IsDefault
});
}
var connection = UnityConfig.Container.Resolve<ArgosyEntities>().Database.Connection;
connection.BulkDelete<Discount>(discountsToDelete).BulkInsert<Discount>(toInsert);
}
Stack:
System.Exception: The DestinationTableName cannot be null or empty. You must specify a valid DestinationTableName.
at Z.BulkOperations.BulkOperation.?()
at Z.BulkOperations.BulkOperation.?()
at Z.Dapper.Plus.DapperPlusAction.Execute()
at Z.Dapper.Plus.DapperPlusActionSet1.DapperPlusActionSetBuilder(IDbConnection connection, IDbTransaction transaction, String mapperKey, DapperPlusActionKind actionKind, IEnumerable
1 items, Func2[] selectors) at Z.Dapper.Plus.DapperPlusExtensions.BulkDelete[T](IDbConnection connection, String mapperKey, IEnumerable
1 items, Func2[] selectors) at Z.Dapper.Plus.DapperPlusExtensions.BulkDelete[T](IDbConnection connection, IEnumerable
1 items, Func2[] selectors) at Argosy.BusinessLogic.Services.Public.Managers.PartServiceManager.UpdatePartPriceBreaks(String sku, List
1 priceBreaks, Nullable1 siteId, Nullable
1 companyId, Nullable`1 vendorId) in D:\development\Source\Repos\argosy\Argosy.BusinessLogic\Services\Public\Managers\PartServiceManager.cs:line 110
I have such mapping:
DapperPlusManager.Entity<TestEntity>()
.Key(x => x.Id, "ID")
.Map(x => x.Name, "TestName")
.Output(x => x.Id)
.Table(TableName);
When I save data with BulkInsert it works, but when I query data the "Name" property is empty.
public class TestEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
using (var connection = SessionFactory.OpenConnection())
{
return connection.Query<T>("select * from TestEntity").ToList();
}
Is there a way to get this to work correctly?
I am using Dapper plus to Insert data and now I will like to make a function that inserts data if the object doesn't exists and update the object if it does. I've done this:
public void InsertOrUpdate(List<Person> persons)
{
DapperPlusManager.Entity<Person>("Insert_key")
.Table("fact.Person")
.Key(x => x.PersonId)
.InsertIfNotExists();
_connection.BulkInsert("Insert_key", persons);
DapperPlusManager.Entity<Person>("Update_key")
.Table("fact.Person")
.Key(x => x.PersonId)
.Ignore(x => x.FirstName);
_connection.BulkUpdate("Update_key", persons);
}
This works. It Updates all data for person except the tables in .Ignore(). But instead of choosing columns not to update I would like to choose columns to update. I've tried combinations like this:
DapperPlusManager.Entity<Person>("Merge_key")
.Table("fact.Person")
.Key(x => x.PersonId)
.Map(x => new {x.PhoneNumber, x.Address);
_connection.BulkMerge("Merge_key", persons);
But without any luck.
How can I Insert a new Person if the PersonId does not exists in the column OR update an existing Person with PhoneNumber and Address?
Hello
I had an exception when I executed this code.
DapperPlusManager .Entity<CompanyInfo>() .Key(t => new { t.LinkId, t.Name }); try { db.Database.Connection.BulkMerge(new CompanyInfo() { Name = "Betfair(英國)", LinkId = 2 }); } catch (Exception ex) { throw; }
I have specified more columns as key. I don't know if this is the right thing to do.
Error:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ';
SELECT StagingTable.ZZZ_Index, 'UPDATE' AS $action, DestinationTable.Id
A' at line 6
Hi
I am facing an issue where my model has a timestamp column and bulk update is trying to update that column which sql does not allow.
is there any way I can ignore all timestamp columns from bulk update ?
Thanks
I am using Mono.Data.Sqlite as my database and I am trying to make a bulk insert. It returns the above error. I noticed your documentation has mentioned that DapperPlus supports Sqlite. Am I doing anything wrong?
using Mono.Data.Sqlite;
using Z.Dapper.Plus;
...
string DB_PATH = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "mydb.db");
IDbConnection conn = new SqliteConnection("Data Source=" + DB_PATH + ";Pooling=False;");
DapperPlusManager.Entity<Session>().Table(tableName).Identity(x => x.Id);
List<Session> sessionList = new List<Session>();
for (var i = 1; i <= recordCount; i++)
{
sessionList.Add(new Session() { Id = i, Name = "My session " + i, Code = "My Code " + i });
}
conn.BulkInsert(sessionList); // Error
IGNORE
is supported?Program.cs
using MySqlConnector;
using Z.Dapper.Plus;
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Collections.Generic;
namespace DapperPlusTest
{
[Table("users")]
class User
{
[Column("id")]
public ulong Id { get; set; }
[Column("name")]
public string Name { get; set; }
}
class Program
{
const string Connstr = "userid=root;password=MYPASSWORD;database=MYDB;Host=127.0.0.1;";
static MySqlConnection Connect()
{
var conn = new MySqlConnection(Connstr);
conn.Open();
return conn;
}
static void Main()
{
using var conn = Connect();
var users = new List<User>
{
new User{ Id = 2, Name = "swan" },
new User{ Id = 4, Name = "bear" }
};
conn.DapperPlusMethodBulkInsertIgnore(users);
}
}
}
2, 'swan'
and 4, 'bear'
but, i want to keep exists data(in this case 2, 'dog'
).SELECT * FROM users ;
+--------+----------+
| id | name |
+--------+----------+
| 1 | panda |
| 2 | dog |
| 3 | cat |
+--------+----------+
INSERT IGNORE INTO users (id, name) VALUES (2, 'swan'),(4, 'bear') ;
---
Query OK, 1 row affected, 1 warning (0.02 sec)
Records: 2 Duplicates: 1 Warnings: 1
SELECT * FROM users ;
+--------+----------+
| id | name |
+--------+----------+
| 1 | panda |
| 2 | dog |
| 3 | cat |
| 4 | bear |
+--------+----------+
OS | Windows 10 Pro 2004 64bit |
dotnet | 3.1.302 |
MariaDB | 10.2.12-MariaDB |
Z.Dapper.Plus | 3.0.19 |
MySqlConnector | 1.0.1 |
First, thank you for all the hard work that went into this, this is a really useful tool!
With dots in the name of the app setting/configuration, setting the App Setting in appsettings.json per your documentation works just fine. But if you don't want to check that into your repository, and you use something like Azure DevOps to set your App Service's App Settings during a release pipeline run, this setting can break with dots in the name when your App Service is linux based.
I just wanted to mention this in case your team thought this was worth mentioning in some area of the documentation for future users. This deviated from your current documentation, but our solution ended up being removing the dots from the configuration name, and it all still worked. Even without validating the license in code. Having appsettings with the configuration name "ZDapperPlus" worked just fine.
I have a table where a primary key is a text field (saves the GUI), and when using BulkMerge it returns the error
[An error has occurred, no primary key has been found or resolved.]
I'm trying to insert to varchar column in Sqlite and was getting this error message
The following type 'varchar' is not yet supported for the provider 'SQLiteMicrosoft'.
Is there a reason why varchar is not supported? Is there a workaround?
Hi, I am using the BulkUpdateAsync method to update rows by id (string) with the MySqlConnector driver.
However I get an "Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation '='"
-Error when using the Bulk-Operations. However single updates or updates by non-string columns in bulk seem to work.
Hi,
I try to update one table with this code
DapperPlusManager.Entity<BookingRequest>().Table("BookingRequest").Identity(x => x.Id);
UnitOfWork.Context.Database.Connection.Open();
UnitOfWork.Context.Database.Connection.BulkInsert(booking)
.AlsoBulkInsert(b => b.BookingRequestResults);
UnitOfWork.Context.Database.Connection.Close();
But with no success. The framework ask me to set one null-able integer property inside the class BookingRequest. But must be empty.
Hi Guys,
As I understand you have 2 versions, free and pro. What is the diff and how I can use free version?
If I use nuget version - is it free or pro? And what exactly happens when trial expires.
Thank you
Hello,
I am trying dapper plus bulk inserts and noticed that the bulk insert seems to be failing now where it wasn't in the previous version. Error message is: "Update or insert of view or function 'DestinationTable' failed because it contains a derived or constant field."
Here is the code I am attempting to run:
DapperPlusManager.Entity().Table("dbo.EntryRaw").Identity(x => x.Id);
connection.BulkInsert(entitiesRaw);
I am not attempting to insert into views and I don't have a table/View called DestinationTable. Is this a known issues in this version of dapper plus?
My team would like to use Dapper-Plus using a standardized database interface to force everything to use "Id" when connecting to the DB. The following will break throwing the error below on connection.BulkInsert(models). This also occurs on BulkUpdate, which has a stacktrace below
System.Exception: 'Cannot find the constant value from the expression'
Calling Code:
public class LocationBaseDataService : BaseDataService<LocationModel>
{
public LocationBaseDataService() : base("Locations"){}
}
Create Portion of Base Class:
public class BaseDataService<TModel> : IDataService<TModel> where TModel : IUniqueModel
{
private readonly string _tableName;
public BaseDataService(string tableName)
{
_tableName = tableName;
DapperPlusManager.Entity<TModel>().Identity(x => x.Id).Table(tableName);
}
public int Create(TModel model)
{
using (var connection = new SqlConnection(AppConfigManager.GetDbConnectionString()))
{
connection.Open();
var models = new List<TModel>() { model };
connection.BulkInsert(models);
}
return model.Id;
}
Can this error be fixed, or at least as a short term, enhance the error messages to show this scenario isn't supported?
System Info:
Dapper: 1.50.5
Z.Dapper.Plus : 1.3.22
DB: Azure DB
How about there are multiple primary keys in a model? it also can handle?
thanks!
Thank for you created a so exciting tool,when i use the dapper-plus to connect sqlite, i meet the exception, i think this may because of dapper-plus not support sqlite.
Exception: The following type 'varchar ' is not yet supported for the provider 'SQLiteMicrosoft'. Please report the issue to our support team: [email protected]
Looking forward to support it.
Thanks.
Test.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MySqlConnector" Version="1.0.0" />
<PackageReference Include="Z.Dapper.Plus" Version="3.0.17" />
</ItemGroup>
</Project>
Program.cs
using MySqlConnector;
using Z.Dapper.Plus;
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Collections.Generic;
namespace DapperPlusTest
{
[Table("users")]
class User
{
[Column("id")]
public ulong Id { get; set; }
[Column("name")]
public string Name { get; set; }
}
class Program
{
const string Connstr = "userid=root;password=MYPASSWORD;database=MYDB;Host=127.0.0.1;";
static MySqlConnection Connect()
{
var conn = new MySqlConnection(Connstr);
conn.Open();
return conn;
}
static void Main()
{
using var conn = Connect();
var users = new List<User>
{
new User{ Id = 1, Name = "name001" },
new User{ Id = 2, Name = "name002" },
new User{ Id = 3, Name = "name003" },
};
conn.BulkInsert(users);
}
}
}
dotnet run
Unhandled exception. System.Exception: The Provider could not be resolved. You must explicitly set the Provider.
at Z.BulkOperations.BulkOperation.()
at Z.BulkOperations.BulkOperation.Execute()
at Z.BulkOperations.BulkOperation.BulkInsert()
at Z.Dapper.Plus.DapperPlusAction.Execute()
at Z.Dapper.Plus.DapperPlusActionSet`1.AddAction(String mapperKey, DapperPlusActionKind actionKind, TEntity item)
at Z.Dapper.Plus.DapperPlusActionSet`1.DapperPlusActionSetBuilder(DapperPlusContext context, IDbConnection connection, IDbTransaction transaction, String mapperKey, DapperPlusActionKind actionKind, TEntity item, Func`2[] selectors)
at Z.Dapper.Plus.DapperPlusActionSet`1..ctor(DapperPlusContext context, IDbConnection connection, String mapperKey, DapperPlusActionKind actionKind, TEntity item, Func`2[] selectors)
at Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, String mapperKey, T item, Func`2[] selectors)
at Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, T item, Func`2[] selectors)
at DapperPlusTest.Program.Main() in D:\Programs\VC\DapperPlusTest\DapperPlusTest\Program.cs:line 41
Use MySqlConnector 0.69.8
instead of MySqlConnector 1.0.0
OS | Windows 10 Pro 2004 64bit |
dotnet | 3.1.302 |
MariaDB | 10.2.12-MariaDB |
Hi, guys!
In our current project, we use auditing functionality:
private static void UseAuditing(BulkOperation operation, List<AuditEntry> auditEntries)
{
operation.AuditEntries = auditEntries;
operation.UseAudit = true;
}
together with the BulkMerge
method for creating and updating entities.
The thing is once a trigger on a table is enabled, we got the following exception:
The target table 'DestinationTable' of the DML statement cannot have any enabled triggers if the statement contains an OUTPUT clause without INTO clause.
Can it be fixed? And is there a workaround for now?
Lets say that I have this configuration:
DapperPlusManager.Entity<StationEntity>()
.Table("Station");
In DB I have [raw].[Station] how to solve this to insert items like this
connection.BulkInsert(items);
to different schema then dbo?
For .net core I'm using Microsoft.Data.Sqlite instead of System.Data.Sqlite, I'm getting the exception : The Provider could not be resolved. You must explicity set the Provider
Is Microsoft.Data.Sqlite.SqliteConnection not supported?
If I put the baseline config then my XML columns aren't mapping to my XElement Model properties.
Here's what my Mapper looks like:
DapperPlusManager.Entity<Members>().Table("Members")
.Identity(x => x.MemberID)
.Output("MetricsXML", "MetricsXML"); //added to test, but no luck
.Map(member => member.MetricsXML.ToString(), "MetricsXML"); //added to test, but no luck
My Member model has a property of type XElement called MetricsXML. This maps to a SQL table with an XML type column by the same name. This mapping works using regular Dapper and other ORMs.
When using Output, Map or MapValue I get the exception: System.Exception: 'Cannot find the constant value from the expression.'
I was just wandering around and saw this
In Z.Dapper.Plus\DapperPlusAction\Method\Execute.cs
_configInsert
is used for each DapperPlusActionKind
, instead of just for .Insert
?
Not sure if intended or not, but since names mismatch and config
indeed has different configs for different operations, it smells to me
if (Kind == DapperPlusActionKind.Insert)
{
ApplyConfig(bulkOperation, config._configInsert);
bulkOperation.BulkInsert();
}
else if (Kind == DapperPlusActionKind.Update)
{
ApplyConfig(bulkOperation, config._configInsert);
bulkOperation.BulkUpdate();
}
else if (Kind == DapperPlusActionKind.Delete)
{
ApplyConfig(bulkOperation, config._configInsert);
bulkOperation.BulkDelete();
}
else if (Kind == DapperPlusActionKind.Merge)
{
ApplyConfig(bulkOperation, config._configInsert);
bulkOperation.BulkMerge();
}
Regards
I'm trying to test the library and I'm taking this error when running BulkInsert.
Follow my code
private OracleConnection _conn;
public OcupacaoDb()
{
if (_conn != null) return;
var strConnection = ConfigurationManager.ConnectionStrings["Oracle"].ConnectionString;
_conn = new OracleConnection { ConnectionString = strConnection };
if (_conn.State == ConnectionState.Closed)
_conn.Open();
}
using (var bulk = new BulkOperation<OcupacaoOracle>(_conn))
{
// easy to use
bulk.DestinationTableName = "Ocupacao";
bulk.BulkInsert(ocupacaoList);
}
Hi,
I have the following problem in trying to BulkInsert several entities into a table. The code looks like this:
using (var dapperDb = new NpgsqlConnection(_connectionString))
{
dapperDb.Open();
await dapperDb.BulkActionAsync(x => x.BulkInsert(insert)); // also x.BulkMerge(insert) do the same behaviour
}
'insert' is just a List of 50 Elements with objects of a class with no special stuff inside, just simple data objects like string and int.
After executing the code above, only the last element of that list is inserted into the DB table and no other element. Calling the method again, then the same behaviour applies as described, only the last element is added to the DB table and so on. So I have to call the method 50 times to add all elements which is definitely not intended.
Is there some special option in dapper to get this working with Npgsql? Or do I have to set something special in the PostgreSQL database to get the Bulk methods work?
Versions I used:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.