Giter Club home page Giter Club logo

declarativesql's Introduction

DeclarativeSql

Important

This project has already stopped development. Please consider using QLimitive as an alternative.

This library provides attribute-based table mapping and simple database access. It mainly contains following features.

  • Unified connection to the some databases (SQL Server / Oracle / MySQL / SQLite etc.)
  • Attribute-based simple SQL generation
  • Super easy CRUD access based Dapper
  • Automatically set CreatedAt / ModifiedAt column.
  • High availability connection support by master/slave approach

Releases

Support Platform

  • .NET Framework 4.6.1+
  • .NET Standard 2.0+
  • .NET 5.0+

Attribute-based O/R mapping information

DeclarativeSql that is also inspired by Entity Framework provides attribute-based database mapping. Following code is its sample. Generates SQL and performs O/R mapping that based on these attributes and types.

using System;
using DeclarativeSql.Annotations;

namespace SampleApp
{
    [Table(DbKind.SqlServer, "T_Person", Schema = "dbo")]  // Customize table name per database
    public class Person
    {
        [PrimaryKey]  // Primary key constraint
        [AutoIncrement]  // Automatically numbering
        public int Id { get; set; }

        [Unique(0)]  // Unique constraint by index
        public string Email { get; set; }

        [Column(DbKind.SqlServer, "名前")]  // Customize column name per database
        public string Name { get; set; }

        [AllowNull]  // Nullable
        public int? Age { get; set; }

        [CreatedAt]  // Set datetime when row is inserted
        [DefaultValue(DbKind.SqlServer, "SYSDATETIME()")]
        public DateTimeOffset CreatedOn { get; set; }

        [ModifiedAt]  // Set datetime when row is updated
        [DefaultValue(DbKind.SqlServer, "SYSDATETIME()")]
        public DateTimeOffset UpdatedOn { get; set; }
    }
}

SQL generation

This library also provides automatic sql generation feature using above meta data. You can get very simple and typical sql using QueryBuilder class. Of course it's completely type-safe.

//--- Query records with specified columns that matched specified condition
var sql
    = QueryBuilder.Select<Person>
    (
        this.DbProvider,
        x => x.Age >= 30,
        x => new { x.Name, x.Age }
    )
    .Statement;

/*
select
    [名前] as [Name],
    [Age] as [Age]
from [dbo].[T_Person]
where
    [Age] >= @p1
*/
//--- If wants OrderBy / ThenBy, allows you to write like following
using (var builder = new QueryBuilder<Person>(DbProvider.SqlServer))
{
    builder.Select(x => new { x.Id, x.Name });
    builder.Where(x => x.Name == "xin9le");
    builder.OrderByDescending(x => x.Name);
    builder.ThenBy(x => x.CreatedOn);
    var sql = builder.Build().Statement;
}

/*
select
    [Id] as [Id],
    [名前] as [Name]
from [dbo].[T_Person]
where
    [名前] = @p1
order by
    [名前] desc,
    [CreatedOn]
*/
//--- Insert record to SQL Server
var sql = QueryBuilder.Insert<Person>(DbProvider.SqlServer).Statement;

/*
insert into [dbo].[T_Person]
(
    [Email],
    [名前],
    [Age],
    [CreatedOn],
    [UpdatedOn]
)
values
(
    @Email,
    @Name,
    @Age,
    SYSDATETIME(),
    SYSDATETIME()
)
*/
//--- Update records with specified columns that matched specified condition
var sql
    = QueryBuilder.Update<Person>
    (
        DbProvider.SqlServer,
        x => x.Age < 35 || x.Name == "xin9le",
        x => new { x.Name, x.Age }
    )
    .Statement;

/*
update [dbo].[T_Person]
set
    [名前] = @Name,
    [Age] = @Age,
    [UpdatedOn] = SYSDATETIME()
where
    [Age] < @p1 or [名前] = @p2
*/

QueryBuilder class also provides some other overload functions and Count / Delete / Truncate methods, and so on.

Dapper integration

This library automates typical CRUD operations completely using above sql generation feature and Dapper. By using expression tree, you can specify target column and filter records. Provided method names are directly described the CRUD operations, so you can understand and use them easily.

//--- Query all records
var p1 = connection.Select<Person>();

//--- Query all records with specified columns
var p2 = connection.Select<Person>(x => new { x.Id, x.Name });

//--- Query 'ID = 3' records only
var p3 = connection.Select<Person>(x => x.Id == 3);

//--- Query 'ID = 3' records with specified columns
var p4 = connection.Select<Person>
(
    x => x.Id == 3,
    x => new { x.Id, x.Name }
);
//--- Insert specified data
var p5 = connection.Insert(new Person { Name = "xin9le", Age = 30 });

//--- Insert collection
var p6 = connection.InsertMulti(new []
{
    new Person { Name = "yoshiki", Age= 49, },
    new Person { Name = "suzuki",  Age= 30, },
    new Person { Name = "anders",  Age= 54, },
});

//--- Super easy bulk insert
var p7 = connection.BulkInsert(new []
{
    new Person { Id = 1, Name = "yoshiki", Age= 49, },
    new Person { Id = 2, Name = "suzuki",  Age= 30, },
    new Person { Id = 3, Name = "anders",  Age= 54, },
});

//--- Insert and get generated auto incremented id
var p8 = connection.InsertAndGetId(new Person { Name = "xin9le", Age = 30 });
//--- Update records which is matched specified condition
var p9 = connection.Update
(
    new Person { Name = "test", Age = 23 },
    x => x.Age == 30
);
//--- Delete all records
var p10 = connection.Delete<Person>();

//--- Delete records which is matched specified condition
var p11 = connection.Delete<Person>(x => x.Age != 30);
//--- Truncate table
var p12 = connection.Truncate<Person>();
//--- Count all records
var p13 = connection.Count<Person>();

//--- Count records which is matched specified condition
var p14 = connection.Count<Person>(x => x.Name == "xin9le");

These CRUD methods are provided not only synchronous but also asynchronous.

Enable environment specific feature

BulkInsert / InsertAndGetId (etc.) methods are environment specific feature. If you want to use them, please install following package and call follows once.

dotnet add package DeclarativeSql.MicrosoftSqlClient
dotnet add package DeclarativeSql.SystemSqlClient
MicrosoftSqlClientInitializer.Initialize();
SystemSqlClientInitializer.Initialize();

High availability connection

If you want to create a highly available database configuration, you can use HighAvailabilityConnection. This provides the simple master/slave pattern. High availability can be achieved simply by writing to the master database and reading from the slave database.

public class FooConnection : HighAvailabilityConnection
{
    public FooConnection()
        : base("ConnectionString-ToMasterServer", "ConnectionString-ToSlaveServer")
    {}

    protected override IDbConnection CreateConnection(string connectionString, AvailabilityTarget target)
        => new SqlConnection(connectionString);
}
using (var connection = new FooConnection())
{
    //--- Read from slave database
    var p = connection.Slave.Select<Person>();

    //--- Write to master database
    connection.Master.Insert(new Person { Name = "xin9le" });
}

Of course, by using the same connection string for the master database and for the slave database, a single database environment can be also supported.

Installation

Getting started from downloading NuGet package.

dotnet add package DeclarativeSql

License

This library is provided under MIT License.

Author

Takaaki Suzuki (a.k.a @xin9le) is software developer in Japan who awarded Microsoft MVP for Developer Technologies (C#) since July 2012.

declarativesql's People

Contributors

shika358 avatar xin9le avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

declarativesql's Issues

Move annotations to PCL compatible assembly

Because many classes used for ORM are in PCL assemblies move annotations to separated PCL compatible assembly, this way we can decorate classes without have reference to DeclarativeSql core assembly that is not PCL compatible.

SelectAsyncメソッドの引数null許容の一貫性が無い

①.引数の定義と実処理の一貫性
IDbConnectionExtensions.SelectAsyncにおいて、
引数propertiesがoptional(default = null)であるにも関わらず、メソッド内部にてnull判定を行い、
ArgumentNullExceptionをスローします。

②.IDbConnection/IDbTransactionにおける①の一貫性
①の問題は、IDbTransactionExtensions.SelectAsyncでは発生しません。

⇒①のnullチェックを排除し、nullであれば全列を取得対象とする挙動が正しいと思われます。

commandTimeout を設定できるようにする

現状では Dapper の拡張メソッド Query<T> Execute<T> に対して commandTimeout を渡すことができないため、タイムアウトが規定値のままとなっている。タイムアウト時間を自由を設定できるようにする。

特定のUpdateでエラーが発生する

表題の件ですが、ご確認をお願いできますでしょうか

public class Parent
{
    public long Id{get;set;}
    public string Name{get;set;} 
    [NotMapped]
    public IList<Child> Children{get;set;}
}

public class Child
{
    public long Id{get;set;}
    public string Name{get;set;} 
}

public void Method()
{
    var parent = new Parent {
        Id = 1,
        Name = "Parent",
        Children = new List<Child> {
            new Child{Name = "Child"}
        }
    };

    using (var connection = DbProvider.CreateConnection(DbKind.SqlServer, "ConnectionString"))
    {
        connection.Update(parent, x => x.Id == parent.Id);
    }    
}

上記のようなUpdateを発行した場合、クエリ発行でエラーになります

return this.Connection.Execute(builder.ToString(), param, this.Transaction, this.Timeout);

paramを確認すると、public IList Children{get;set;} の値も含まれているようです
NotMappedの属性をつけていますので、paramに含まれないの正しいように思うのですがいかがでしょうか
Forkした弊社の環境ではとりあえずNotMappedを除外しています
エラーは以下になります

Error
オブジェクトの型 Namespace.Models.ModelName から既知のマネージ プロバイダーのネイティブ型へのマップがありません。

StackTrace
場所 System.Data.SqlClient.MetaType.GetMetaTypeFromValue(Type dataType, Object value, Boolean inferLen, Boolean streamAllowed)
場所 System.Data.SqlClient.SqlParameter.GetMetaTypeOnly()
場所 System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc)
場所 System.Data.SqlClient.SqlCommand.BuildParamList(TdsParser parser, SqlParameterCollection parameters, Boolean includeReturnValue)
場所 System.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior behavior, String commandText, SqlParameterCollection parameters, SqlRPC& rpc)
場所 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
場所 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource1 completion, Int32 timeout, Task& task, Boolean asyncWrite) 場所 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
場所 System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
場所 Dapper.SqlMapper.ExecuteCommand(IDbConnection cnn, CommandDefinition& command, Action2 paramReader) 場所 D:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:行 3397 場所 Dapper.SqlMapper.ExecuteImpl(IDbConnection cnn, CommandDefinition& command) 場所 D:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:行 1346 場所 Dapper.SqlMapper.Execute(IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Nullable1 commandTimeout, Nullable1 commandType) 場所 D:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:行 1221 場所 DeclarativeSql.Dapper.DbOperation.Update[T](T data, Expression1 predicate, Expression1 properties, Boolean setIdentity) 場所 C:\Data\Program\**\Applications\DeclarativeSql\Source\DeclarativeSql.Dapper\DbOperation.cs:行 460 場所 DeclarativeSql.Dapper.IDbTransactionExtensions.Update[T](IDbTransaction transaction, T data, Expression1 predicate, Expression1 properties, Nullable1 timeout, Boolean setIdentity) 場所 C:\Data\Program*
\Applications\DeclarativeSql\Source\DeclarativeSql.Dapper\IDbTransactionExtensions.cs:行 291
場所 ConsoleApplication1.Program.Main(String[] args) 場所 C:\Data\Program_*\Applications\DeclarativeSql\ConsoleApplication1\Program.cs:行 33
場所 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
場所 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
場所 System.Threading.ThreadHelper.ThreadStart()

属性付与の判定を改善する

よりシンプルになるように変更する。

  • Attribute.IsDefinedを利用
  • Attribute.IsDefinedで対応可能な分のオーバーロードを作成
  • メソッド名を 'HasAttribute' から 'Has' に変更

AccessorCache.gettersのキー重複

複数スレッドにて並行で大量のSelectを実行時、DeclarativeSql.Helpers.AccessorCache.LookupGet()メソッド内で、以下の例外が発生します。
System.ArgumentException : 同一のキーを含む項目が既に追加されています。

恐らく、該当メソッド内のgetters.Add(key, getter);がメソッドと共にstaticであるために完全なスレッドセーフでないのではと考えられます。

調査及び改善していただけると幸いです。

以下、例外情報です。

■--- Type
mscorlib.dll
System.ArgumentException

■--- Message
同一のキーを含む項目が既に追加されています。

■--- Source
mscorlib

■--- TargetSite
mscorlib.dll
Insert

■--- StackTrace
   場所 System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   場所 DeclarativeSql.Helpers.AccessorCache.LookupGet(Type type, String memberName)
   場所 DeclarativeSql.Helpers.PredicateParser.ExtractValue(Expression expression)
   場所 DeclarativeSql.Helpers.PredicateParser.ParseBinary(BinaryExpression node)
   場所 DeclarativeSql.Helpers.PredicateParser.VisitBinary(BinaryExpression node)
   場所 System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   場所 DeclarativeSql.Helpers.PredicateParser.<>c__DisplayClass11_0.b__0()
   場所 DeclarativeSql.Helpers.PredicateParser.VisitCore(PredicateElement element, Func`1 baseCall)
   場所 System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
   場所 DeclarativeSql.Helpers.PredicateParser.Parse[T](Expression`1 predicate)
   場所 DeclarativeSql.PredicateSql.From[T](DbKind targetDatabase, Expression`1 predicate)
   場所 DeclarativeSql.Dapper.DbOperation.d__27`1.MoveNext()`

SQLServerのバルクインサートができなくなりました

・状況
SQL Serverのバルクインサートが、バージョン0.2.4までは成功していましたが、
0.2.5にアップデートしてから失敗するようになりました。

・環境
Visual Studio 2013
.Net Framework 4.5.2
SQLServer 2012 Express LocalDB

・詳細
以下のソースを実行すると例外が発生します。

namespace DeclarativeSqlTest
{
public class Test
{
public Int32 Id { get; set; }
public String Name { get; set; }
}

class Program
{
    static void Main( string[] args )
    {
        using ( IDbConnection connection = DbProvider.CreateConnection( DbKind.SqlServer, @"ConnectionString" ) )
        {
            connection.Open();

            connection.BulkInsert( new[]
            {
                 new Test { Id = 1, Name = "AAA" },
                 new Test { Id = 2, Name = "BBB" },
                 new Test { Id = 3, Name = "CCC" },
            } );

            connection.Close();
        }
    }
}

}

System.ArgumentException はハンドルされませんでした。
HResult=-2147024809
Message=列には有効な DataType が必要です。
Source=System.Data
StackTrace:
場所 System.Data.DataColumn.set_DataType(Type value)
場所 DeclarativeSql.Dapper.SqlServerOperation.SetupBulkInsert[T](SqlBulkCopy executor, IEnumerable1 data) 場所 DeclarativeSql.Dapper.SqlServerOperation.BulkInsert[T](IEnumerable1 data)
場所 DeclarativeSql.Dapper.IDbConnectionExtensions.BulkInsert[T](IDbConnection connection, IEnumerable1 data, Nullable1 timeout)
場所 DeclarativeSqlTest.Program.Main(String[] args) 場所 c:\Users\XXX\Documents\Visual Studio 2013\Projects\DeclarativeSqlTest\DeclarativeSqlTest\Program.cs:行 22
場所 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
場所 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
場所 System.Threading.ThreadHelper.ThreadStart()
InnerException:

対応方法があればご教示お願いいたします。

条件式でEnumerable.Containsを使えるようにする

var ids = Enumerable.Range(1, 5).Where(x => x % 2 == 0);
var records = connection.Select<Person>(x => ids.Contains(x => x.Id));

内部的に以下のようなSQLを投げて結果を受け取る。

select * from Person
where Id in (2, 4)

bulk insertの戻り値にAuto Incrementで自動採番されたidの配列か最初のidを返して欲しい。

SQL Sever、MySQL、Oracleなど複数DB対応を検討しており、本ライブラで解決したいと考えております。
insert後にエンティティのid列に確定したid値を設定する利用方法を想定しており、InsertAndGetメソッドのbulk insert版をイメージしています。
ご検討頂ければ幸いです。

お忙しいとは思いますが、よろしくお願いいたします。

Transactions

Hi,

Is there any way to pass through a transaction to the Insert methods? I'd like to roll back a previous insert if the next one fails.

params引数を削除する

params 引数は新たな仮引数を追加することもできず、メソッドの拡張性を大きく損なっているため廃止する。

Update single columns

Hi,

when I call an Update methode, not only the provided values are update but all columns. Is this a bug or am I doing something wrong?

[Table("MEZ_BoxCall")]
public class MEZ_BoxCall
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }
    public int BoxId { get; set; }
    public DateTime CallTimeStamp { get; set; }
    public DateTime? FinishTimeStamp { get; set; }
    public int? ForkLiftId { get; set; }
    public bool? Finished { get; set; }
    public int? Quantity { get; set; }
    public bool? Canceled { get; set; }
    public int? BoxCallTypeId { get; set; }
    [MaxLength(25)]
    public string MaterialNr { get; set; }
    [MaxLength]
    public string Caller { get; set; }
}

connection.Update(new MEZ_BoxCall()
{
Canceled = true
}, b => b.ID == boxCall.ID);

Regards Mario

VB.netでのQueryBuilderのSelectが正しく動作しない

内容

VB.netで使用した場合に、SQLのSelectでカラムが表示されません。
そもそもVB.netには、対応していないのでしょうか。

Dim builder = New QueryBuilder(Of User)(DbProvider.SqlServer)
builder.Select(Function(x) New With{x.Id})
var sql = builder.Build().Statement
Console.WriteLine(sql)

結果

selec
from [dbo].[User]

Configure Schema on runtime

Now DeclarativeSql determine TableMappingInfo.Schema on declaring class.
Its specification will be difficult to create a program to access the database that has different schema(tables are same).

So I would be great if DeclarativeSql have the option of determining schema on runtime.

OrderByについて

SelectでOrderByができるようにご検討いただけないでしょうか。

PrimitiveSql.CreateSelect(x => x.Id, x => x.Name);
connection.Select(x => x.Id, x => x.Name);

のようなシンプルなクエリの場合、
以下のように

select
Id,
Name
from Person
order by
SortOrder

SortOrderなど任意の並び順を指定することが多いです。
(あくまで私の利用の範囲ですが。)
ご検討くださればと存じます。

AutoIncrement 属性を追加

現状、自動採番の列を表す属性は EntityFramework に倣って [DatabaseGenerated(DatabaseGeneratedOption.Identity)] のみとしている。記述が煩雑な上にわかりにくいので、[AutoIncrement] をエイリアス機能として用意する。

ReflectionTypeLoadException when calling Assembly.GetTypes()

実行時に ReflectionTypeLoadException が発生することがある。

参考

対処

  1. 参照している Dapper のバージョンによる問題の可能性があるので、対象とする Dapper を最新バージョンとする。
  2. 実行時エラーが出ないよう GetLoadableTypes() メソッドを取り入れる

Count値の取得にExecuteScalarを利用する

internalなマッピング型を経由して取得していたが、それを廃止して簡素化する。

//--- これまで
var count = connection.Query<CountResult>(sql).Count;

//--- これから
var count = connection.ExecuteScalar<ulong>(sql);

transaction/connectionのインターフェース不一致

IDbTransactionExtensionは、Dapperの提供するIDbConnectionへの機能をTransaction向けに拡張したものと認識しています。
このIDbTransactionExtensionにおいて、QueryAsyncメソッドなど一部をサポート外となっていますが、transactionを指定した上でQueryAsyncの代替となるような(queryを自作した上で、任意のModelを使用できる)方法はありますか?

SQL ServerのBulkInsertで例外

SQL ServerでNullableなフィールドを含む
BulkInsertをおこなうと例外が発生します。

SqlServerOperationのSetupBulkInsertメソッドで
Nullableな型をAddしていることが原因のようです。

ご確認くださればと存じます。

発生する例外は以下です

System.NotSupportedException はハンドルされませんでした。
  HResult=-2146233067
  Message=DataSet は System.Nullable<> をサポートしていません。
  Source=System.Data
  StackTrace:
       場所 System.Data.DataColumn..ctor(String columnName, Type dataType, String expr, MappingType type)
       場所 System.Data.DataColumnCollection.Add(String columnName, Type type)
       場所 DeclarativeSql.Dapper.SqlServerOperation.SetupBulkInsert[T](SqlBulkCopy executor, IEnumerable`1 data) 場所 C:\Users\Administrator\Downloads\DeclarativeSql-master\DeclarativeSql-master\Source\DeclarativeSql.Dapper\SqlServerOperation.cs:行 96
       場所 DeclarativeSql.Dapper.SqlServerOperation.BulkInsert[T](IEnumerable`1 data) 場所 C:\Users\Administrator\Downloads\DeclarativeSql-master\DeclarativeSql-master\Source\DeclarativeSql.Dapper\SqlServerOperation.cs:行 42
       場所 DeclarativeSql.Dapper.IDbConnectionExtensions.BulkInsert[T](IDbConnection connection, IEnumerable`1 data, Nullable`1 timeout) 場所 C:\Users\Administrator\Downloads\DeclarativeSql-master\DeclarativeSql-master\Source\DeclarativeSql.Dapper\IDbConnectionExtensions.cs:行 202
       場所 ConsoleApplication1.Program.Main(String[] args) 場所 C:\Users\Administrator\Downloads\DeclarativeSql-master\DeclarativeSql-master\ConsoleApplication1\Program.cs:行 41
       場所 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       場所 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       場所 System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

バインド変数とインスタンスプロパティの数が違うとUpdateに失敗する

少なくともOracle (ODP.NET) 利用時、以下のSQLとパラメーターでUpdateに失敗する。

update dbo.Person
set
    Name = :Name
where
    Id = :Id
class Person
{
    public int Id { get;set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

バインド変数で利用されるパラメーターの個数と、指定されたインスタンスが持つプロパティの数が違うのが問題。数に相違が出ないように調整する。

transaction.Updateが実行できない

バージョン:v0.2.0-rc3
環境:SQL Server2012

1. transaction.Update(person);
2. transaction.Update(person, x => x.Name == "名前");
3. transaction.Update(person, x => x.Name == "名前", x => x.Name); 
4. transaction.Update(person, x => x.Name == "名前",x => new {x.Name,x.SortNo}); 

1と3は実行可能ですが、2と4では例外が発生します。
引数に誤りがあればご指摘いただけますでしょうか。
ご確認お願いします。

BulkInsert が Oracle 環境下で動作しない

command.Connection の設定時にを返す。

型 'System.Data.Common.DbConnection' を 'Oracle.ManagedDataAccess.Client.OracleConnection' に暗黙的に変換できません。明示的な変換が存在します (cast が不足していないかどうかを確認してください)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.