From fa39e129b50b43ebf085f853b8d885a3f7768e95 Mon Sep 17 00:00:00 2001 From: ili Date: Wed, 23 May 2018 10:45:20 +0500 Subject: [PATCH] gitignore for docs --- .gitignore | 2 +- Doc/articles/releasenotes/2.0.0.md | 556 ++++++++++++++++++ .../releasenotes/Unreleased-Changes.md | 8 + 3 files changed, 565 insertions(+), 1 deletion(-) create mode 100644 Doc/articles/releasenotes/2.0.0.md create mode 100644 Doc/articles/releasenotes/Unreleased-Changes.md diff --git a/.gitignore b/.gitignore index bf6fe9c606..0a822a1a5f 100644 --- a/.gitignore +++ b/.gitignore @@ -44,4 +44,4 @@ linq2db.sln.ide/ #doc [Dd]oc/api /linq2db.github.io -![Dd]oc/articles +![Dd]oc/articles/** diff --git a/Doc/articles/releasenotes/2.0.0.md b/Doc/articles/releasenotes/2.0.0.md new file mode 100644 index 0000000000..1b4b45e605 --- /dev/null +++ b/Doc/articles/releasenotes/2.0.0.md @@ -0,0 +1,556 @@ +# v2.0.0 Release notes + +* [General Changes](#general-changes) + * [Breaking Changes](#breaking-changes) + * [CTE Support](#cte-support) + * [Mapping](#mapping) + * [MappingSchema.EntityDescriptorCreatedCallback](#mappingschemaentitydescriptorcreatedcallback) + * [Fluent Mapping](#fluent-mapping) + * [Dynamic Columns](#dynamic-columns) + * [Calculated Columns](#calculated-columns) + * [Inheritance Mapping](#inheritance-mapping) + * [Other Changes and Fixes](#other-changes-and-fixes-1) + * [SQL Generation](#sql-generation) + * [Extensions](#extensions) + * [Temp Tables API](#temp-tables-api) + * [Bulk Copy](#bulk-copy) + * [Merge](#merge) + * [Schema Provider](#schema-provider) + * [Other Changes and Fixes](#other-changes-and-fixes-4) +* [Provider-specific changes](#provider-specific-changes) + * [Access](#access) + * [DB2](#db2) + * [Firebird](#firebird) + * [Informix](#informix) + * [MySQL and MariaDB](#mysql-and-mariadb) + * [Oracle](#oracle) + * [PostgreSQL](#postgresql) + * [SAP HANA](#sap-hana) + * [SQL CE](#sql-ce) + * [Sybase/SAP ASE](#sybase) + * [SQLite](#sqlite) + * [SQL Server](#sql-server) +* [Changes for developers](#changes-for-developers) +* [I Use Entity Framework](#i-use-entity-framework-feelsbadman) + +## General changes + +Also check provider-specific changes for your provider as this section contains only provider-independent changes. + +## Breaking Changes + +### Changes to target frameworks + +Version 2.0 drops support for legacy frameworks: net4.0, silverlight, windows8 store. +List of supported targets now includes: + +- net45 +- netstandard1.6 +- netstandard2.0 +- netcoreapp2.0 + +Also you can notice that now linq2db nuget package supports all those targets and you don't need to use linq2db.core package if you want to target .net core projects. This package is now deprecated and will not be updated anymore. + +Who will be affected by this change: + +- People that used deprecated frameworks. They should continue use 1.x version or migrate their projects. +- Users of linq2db.core package. They should update their nuget references to use linq2db package. + +### Default enumeration mapping behavior changes for text columns + +Starting from version 2.0, LINQ To DB will use ToString() method to create database value for enums, mapped to text column ([1006](https://github.com/linq2db/linq2db/issues/1006), [1071](https://github.com/linq2db/linq2db/issues/1071)). Prior versions used numeric representation of enumeration value, converted to string. + +How to find out if I'm affected by this change? + +You are affected if you have text columns mapped to enumeration without explicit mappings specified for fields. + +See following example: + +```cs +// enums like that are not affected, because they +// have explicit mappings from enum fields to database values +public enum GoodEnum +{ + [MapValue("1")] + First, + [MapValue("Second")] + Second +} + +// enums like that will change their behavior +public enum BadEnum +{ + // v1.x: "0" used as a database value + // v2: "First" used as a database value + First, + // v1.x: "1" used as a database value + // v2: "Second" used as a database value + Second +} +``` + +We want to say that it is generally bad idea to have no explicit enumeration field mappings as you depend on library behavior, which could change, and changes to enumeration (adding/removing/reordering fields) could lead to mapped value change. + +#### I'm affected. What should I do? + +First of all you can re-enable old behavior using following configuration flag: + +```cs +Configuration.UseEnumValueNameForStringColumns = false; +``` + +But we recommend to add explicit mappings to your enumeration. + +## CTE Support + +This release adds native support for common table expressions, including recursive CTE ([534](https://github.com/linq2db/linq2db/issues/534), [890](https://github.com/linq2db/linq2db/issues/890)). You can read more about this feature [here](xref:CTE). + +## Mapping + +### `MappingSchema.EntityDescriptorCreatedCallback` + +This new callback could be used to modify entity mapping descriptor after creation [(1074)](https://github.com/linq2db/linq2db/issues/1074). + +E.g. you can use it to change columns name notation to snake-case. + +```cs +ms.EntityDescriptorCreatedCallback = (mappingSchema, entityDescriptor) => +{ + // let's imagine we have ToSnakeCase string + // extension method somewhere in our project + entityDescriptor.TableName = entityDescriptor.TableName.ToSnakeCase(); + foreach (var entityDescriptorColumn in entityDescriptor.Columns) + { + entityDescriptorColumn.ColumnName + = entityDescriptorColumn.ColumnName.ToSnakeCase(); + } +}; +``` + +### Fluent Mapping + +#### Custom join predicate exression support for associations + +[961](https://github.com/linq2db/linq2db/issues/961) + +```cs +fluentBuilder + .Entity() + .Association( + e => e.AssociationProperty, + (thisSide, otherSide) => thisSide.Id == otherSide.ID1); +``` + +#### Other Changes and Fixes + +- complex types mapping fixed [(1005)](https://github.com/linq2db/linq2db/issues/1005) + +### Dynamic Columns + +This new feature will allow you to use dynamic columns in your queries ([507](https://github.com/linq2db/linq2db/issues/507), [744](https://github.com/linq2db/linq2db/issues/744), [964](https://github.com/linq2db/linq2db/issues/964),[1083](https://github.com/linq2db/linq2db/issues/1083)). Check [this](https://github.com/linq2db/linq2db/pull/964) PR for more details. + +### Calculated Columns + +You can use expressions to define calculated columns using `IsColumn` property of `ExpressionMethodAttribute` attribute [(1004)](https://github.com/linq2db/linq2db/issues/1004). + +```cs +[Table] +public class Entity +{ + // normal read/write columns + [Column] public string FirstName { get; set; } + [Column] public string LastName { get; set; } + + // read-only expression-based property + [ExpressionMethod(nameof(FullNameExpr), IsColumn = true)] + public string FullName { get; set; } + + private static Expression> FullNameExpr() + { + return e => e.LastName + ", " + e,FirstName; + } +} +``` + +### Inheritance Mapping + +- fixed incorrect query filter generation for left join associations for entities with inheritance mapping [(956)](https://github.com/linq2db/linq2db/issues/956) +- fixed exception when inherited entity selected into property of base type [(1046)](https://github.com/linq2db/linq2db/issues/1046) +- `Update`/`Delete`/`Insert`/`InsertOrReplace` extensions will properly recognize inherited values when passed as parameter of base type. Important: entities without inheritance mapping not affected by this change and query generation will use parameter type as before [(1017)](https://github.com/linq2db/linq2db/issues/1017) +- `LoadWith` fixed to properly load derived entities [(994)](https://github.com/linq2db/linq2db/issues/994) +- fixed several issues with type conversion in expressions between base and derived types ([1057](https://github.com/linq2db/linq2db/issues/1057), [1065](https://github.com/linq2db/linq2db/issues/1065)) +- fixed exception when `LoadWith` called for nullable reference to entity with inheritance mapping [(996)](https://github.com/linq2db/linq2db/issues/996) + +### Other Changes and Fixes + +- fixed `MappingSchema` converters were ignored for enums [(1006)](https://github.com/linq2db/linq2db/issues/1006) +- fixed issue when adding new metadata reader to `MappingSchema.Default` could result in previously added readers being ignored [(1066)](https://github.com/linq2db/linq2db/issues/1066) +- default `char` mapping will now use `Length = 1` [(1091)](https://github.com/linq2db/linq2db/issues/1091) +- improved support of interfaces [(1099)](https://github.com/linq2db/linq2db/issues/1099) + +## SQL Generation + +#### `CROSS/OUTER APPLY` support + +For databases that support `APPLY` joins you can disable this functionality using following flag: + +```cs +// set to true by default +// v2.0-beta5 has typo in property name : PrefereApply +Configuration.PreferApply = false; +``` + +#### Other Changes and Fixes + +- fixed exception generated for some cases when joins optimization enabled and table hints used [(949)](https://github.com/linq2db/linq2db/issues/949) +- fixed SQL generation regression for some complex subqueries [(928)](https://github.com/linq2db/linq2db/issues/928) +- fixed invalid SQL generated for empty select combined with `Take`/`Skip` [(817)](https://github.com/linq2db/linq2db/issues/817) +- fixed issue when joined subquery condition were moved to outer query condition [(922)](https://github.com/linq2db/linq2db/issues/922) + +## Extensions + +#### New `In`/`NotIn` extension methods + +`SqlExtensions` class contains new extension methods `In`/`NotIn`, applied to a value. In general it is just a reverse `Contains` methods to better mimic SQL. + +``` +// filter table by id +// old reverse logic approach +db.Table.Where(r => ids.Contains(r.Id)); + +// now it could be written like you do it in raw SQL +db.Table.Where(r => r.Id.In(ids)); +``` + +### New *Join extension methods ([1076](https://github.com/linq2db/linq2db/issues/1076), [1088](https://github.com/linq2db/linq2db/issues/1088)) + +Additional extension methods added to define join using two queryable sources, join predicate expression and result selector. +Following methods added: `InnerJoin`, `LeftJoin`, `RightJoin`, `FullJoin` and `CrossJoin`. + +```cs +// left outer join +db.Parent.LeftJoin( + db.Child, + (p, c) => p.ParentID == c.ParentID, + (p, c) => new { ParentID = p.ParentID, ChildID = (int?)c.ChildID }); + +// cross join - note that join condition is not applicable here +db.Parent.CrossJoin( + db.Child, + (p, c) => new { ParentID = (int?)p.ParentID, ChildID = (int?)c.ChildID }); +``` + +### Added missing support for table, schema/owner and database name parameters in some methods + +Those optional parameters now available also for following IDataContext extension methods: + +- `InsertOrReplace*` +- `InsertWith*Identity*` +- `Update*` +- `Delete*` + +### Parameters creation in extension builders + +You can add new query parameters from extension builders [(973)](https://github.com/linq2db/linq2db/issues/973). + +```cs +class InWithParametersBuilder : Sql.IExtensionCallBuilder +{ + public void Build(Sql.ISqExtensionBuilder builder) + { + // get extension parameter + var values = builder.GetValue("values"); + // tell linq2db that query uses non-static parameters + builder.Query.IsParameterDependent = true; + + foreach (var value in values) + { + // create query parameter + var param = new SqlParameter(value?.GetType() ?? typeof(object), "p", value); + // add parameter (note that we can add multiple parameters for one placeholder) + builder.AddParameter("values", param); + } + } +} + +public static class Extensions +{ + // note that for values we specify comma as parameters delimiter + [Sql.Extension("{field} IN ({values, ', '})", IsPredicate = true, BuilderType = typeof(InWithParametersBuilder))] + public static bool In(this Sql.ISqlExtension ext, [ExprParameter] T field, params T[] values) + { + throw new NotImplementedException(); + } +} +``` + +### New extensibility points + +#### `LinqExtensions.ProcessSourceQueryable` delegate + +You can use it to preprocess IQueryable sources, passed to other APIs [(1116)](https://github.com/linq2db/linq2db/issues/1116). + +E.g. it is used by our other project [https://github.com/linq2db/linq2db.EntityFrameworkCore](https://github.com/linq2db/linq2db.EntityFrameworkCore) to replace `EntityFramework` queryable provider with `LINQ To DB` provider. + +#### `LinqExtensions.ExtensionsAdapter` interface + +You can override implementation of `LINQ To DB` async methods using this interface. Note that right now it is all-or-nothing interface, so you need to implement all methods you use, even if you want to change behavior of only one method. In this case you need to call original `LINQ To DB` method for others. + +#### `IEntityServices.OnEntityCreated` delegate + +This delegate will be called after entity instantiation for contexts that implement `IEntityServices` interface [(1112)](https://github.com/linq2db/linq2db/issues/1112). It allows you to pre-process or even replace created entity. `LINQ To DB` already implements this interface for default contexts: `DataContext`, `DataConnection` and `RemoteDataContextBase` classes. + +```cs +using (var db = new DataConnection()) +{ + var cnt = 0; + + // just count how many User entities were instantiated + db.OnEntityCreated += e => + { + if (e.Entity is User) + cnt++; + } + + // do some queries +} +``` + +#### `DataContext.OnTraceConnection` callback + +Added trace callback for `DataContext` class similar to one that already exist on `DataConnection` class [(1131)](https://github.com/linq2db/linq2db/issues/1131). + +## Temp Tables API + +New API to create temporary tables added to IDataContext as a set of `CreateTempTable()` extension methods. + +Using this API you can create queryable table, populate it with data, perform queries and then delete by disposing it. + +Example below shows you how can you use merge with client-side source in more effective way by adding those records into temp table and merge them into main table. + +```cs +public void MergePersons(this IDataContext db, IEnumerable persons) +{ + // create new table for existing Person mapping and populate it using bulk copy + using (var tmp = db.CreateTempTable(persons, tableName: "PersonTemp")) + { + db.Persons // target table + .Merge() + .Using(tmp) // use data from temp table + .OnTargetKey() + .InsertWhenNotMatched() // insert new records + .UpdateWhenMatched() // update known records + .DeleteWhenNotMatchedBySource() // delete others + .Merge(); + + } // here dispose will delete temp table +} +``` + +API allows you: + +- specify new table, owner/schema, database name using corresponding parameters +- populate table using data from IQueryable source parameter +- populate table using bulk copy from IEnumerable source parameter and `BulkCopyOptions` +- adjust entity mapping for temporary table using fluent mapping delegate using `setTable` parameter +- call some action on created table before populating it with data using `action` parameter + +## Bulk Copy + +### Documentation + +New [article](xref:Bulk-Copy) created for `BulkCopy` API. It still miss documentation on some options, but most important information is already here. It will be improved in next releases. + +### KeepIdentity option + +`KeepIdentity` option were documented and existing implementations tested/fixed to follow it [(1037)](https://github.com/linq2db/linq2db/issues/1037). + +Setting this option to `true` for `RowByRow` copy mode was never supported and if you have it set to true - starting from version 2.0 it will start throwing exception instead of silently ignore it. Check copy mode support table to see what mode actually used for your provider, as `BulkCopy` will downgrade copy mode, if requested one is not supported by provider. + +## Merge + +### Partial projections in source query improvements + +Now merge will properly detect and throw exception when source query element type contains more fields than query returns. + +```cs +class Person +{ + [PrimaryKey, Column, Identity] public int Id { get; set; } + [Column] public string FirstName { get; set; } + [Column] public string LastName { get; set; } + [Column] public string Title { get; set; } +} + +// bad query +db.Persons.Merge() + // note that Id and Title columns is not selected by query + .Using(db.NewPersons.Select(p => new Person() + { + FirstName = p.LastName, + LastName = p.FirstName + })) + // will throw exception that Id key field missing in source + .OnTargetKey() + // will throw exception that Title field missing in source + .InsertWhenNotMatched(s => new Person() { Title = s.Title }) + .Merge(); +``` + +### Other Changes and Fixes + +- `CROSS JOIN` and `SelectMany` support in source query [(896)](https://github.com/linq2db/linq2db/issues/896) +- `Merge` call will not be available anymore if you didn't specified any operations yet +- fixed exception of empty local source with source type != target type [(1153)](https://github.com/linq2db/linq2db/issues/1153) + +## Schema Provider + +Requesting schema for procedures and functions will wrap it internally in transaction with rollback, when called without transaction. This is done to avoid situations when some providers execute (sic!) procedures instead of just returning their schema. Taking into account such bugs it is recommended to never wrap schema provider calls into transaction and let `LINQ To DB` handle it. + +## Other Changes and Fixes + +- errors during mapping of data from database to mapping class field on selects will now be wrapped into `LinqToDBException` with details what field failed with original error in `InnerException` [(1065)](https://github.com/linq2db/linq2db/issues/1065) +- fixed issue when selected of `NULL` value using `SelectMany` method could have resulted in `default(T)` value for value types even with cast to T? [(1012)](https://github.com/linq2db/linq2db/issues/1012) +- fixed exception passing binary data over WCF [(925)](https://github.com/linq2db/linq2db/issues/925) +- spelling error fixed for `SchemaProvider.ForeignKeyInfo` [(941)](https://github.com/linq2db/linq2db/issues/941) +- enforce server-side evaluation of `Sql.Lower`/`Sql.Upper` functions [(819)](https://github.com/linq2db/linq2db/issues/819) +- fixed case when async code could be blocked on synchronous `Connection.Open` call [(1023)](https://github.com/linq2db/linq2db/issues/1023) +- fixed support for type casts in `LoadWith` expression [(1069)](https://github.com/linq2db/linq2db/issues/1069) +- fixed issue when insert query with sub-query data source will fail on next calls if it has nullable parameter and first call uses `null` for parameter value [(1098)](https://github.com/linq2db/linq2db/issues/1098) +- T4.Models repository was obsolete project and moved to linq2db repo +- removed use of database object `owner` name from many APIs to reduce confusion with having `owner` and `schema` overrides at the same time, meaning the same concept +- T4 templates support in .NET Core projects [(1067)](https://github.com/linq2db/linq2db/issues/1067) +- new `DataConnection.GetRegisteredProviders` method to return list of all registered data providers + +## Provider-specific changes + +### Access + +- handle exceptions from OleDb provider on schema read calls when ACE provider used [(10)](https://github.com/linq2db/linq2db.LINQPad/issues/10) +- schema provider will now return system tables too (`TableInfo.IsProviderSpecific == true`) [(1119)](https://github.com/linq2db/linq2db/issues/1119) + +### DB2 + +* `IBM.Data.DB2.Core` provider support - .NET Core DB2 provider support was added. +* schema provider doesn't return procedures and functions if `GetTables = false` specified [(1068)](https://github.com/linq2db/linq2db/issues/1068) + +### Firebird + +#### Default identifier quotation mode change + +Default identifier quotation mode changed from `FirebirdIdentifierQuoteMode.None` to `FirebirdIdentifierQuoteMode.Auto` [(1120)](https://github.com/linq2db/linq2db/issues/1120). + +Normally it shouldn't affect anybody, as `Auto` mode will quote only invalid and reserved identifiers and they will not work anyway in `None` mode. + +Still, technically it could be a case for people who used quoted identifier in mappings. This is not something you should do, as mapping should contain raw identifers and quotation should be handled by LINQ To DB. If you did that we want to hear why you need to do it and how we can improve LINQ To DB in this area. + +If you are affected by this change, just restore old quotation mode using following code: + +```cs +FirebirdSqlBuilder.IdentifierQuoteMode = FirebirdIdentifierQuoteMode.None; +``` + +#### Other changes and fixes + +- `BulkCopy` will throw exception if `KeepIdentity = true` option specified as this option is not supported for Firebird [(1037)](https://github.com/linq2db/linq2db/issues/1037). Check [BulkCopy](https://github.com/linq2db/linq2db/wiki/Bulk-Copy) documentation for more details +- `DropTable` API will check if dropped objects exist before dropping them [(1120)](https://github.com/linq2db/linq2db/issues/1120) +- fixed support of seconds and milliseconds by `Sql.DatePart` function [(967)](https://github.com/linq2db/linq2db/issues/967) +- detect and escape identifiers that use reserved words in `FirebirdIdentifierQuoteMode.Auto` mode ([1095](https://github.com/linq2db/linq2db/issues/1095), [1110](https://github.com/linq2db/linq2db/issues/1110)) +- `CreateTable`/`DropTable`/`TruncateTable` will respect identifier quotation mode during query generation [(1120)](https://github.com/linq2db/linq2db/issues/1120) +- `FirebirdDataProvider` and `FirebirdSqlOptimizer` classes made public to help users override default implementation [(1000)](https://github.com/linq2db/linq2db/issues/1000) + +### Informix + +- Added delimited identifiers support + +### MySQL and MariaDB + +#### Procedures and functions support by schema provider + +Schema provider for MySQL/MariaDB was updated to return procedures and functions [(991)](https://github.com/linq2db/linq2db/issues/991). Requesting procedures and functions from transaction will throw exception because schema provider need to wrap it internally into transaction to avoid procedure execution due to bug in provider [(792)](https://github.com/linq2db/linq2db/issues/792) + +### Oracle + +#### .NET Core provider support + +Support for [beta](http://www.oracle.com/technetwork/topics/dotnet/downloads/index.html) version of .NET Core provider added. + +#### Other changes and fixes + +- `date` literal generation fixes [(969)](https://github.com/linq2db/linq2db/issues/969) +- schema provider doesn't return procedures and functions if `GetTables = false` specified [(1068)](https://github.com/linq2db/linq2db/issues/1068) +- detect and escape identifiers that use reserved words ([1095](https://github.com/linq2db/linq2db/issues/1095), [1110](https://github.com/linq2db/linq2db/issues/1110)) + +### PostgreSQL + +#### Native bulk copy support + +Version 2.0 adds support for native bulk copy method [(935)](https://github.com/linq2db/linq2db/issues/935). It is available through existing `BulkCopy` LINQ To DB API by specifying `BulkCopyOptions.BulkCopyType = BulkCopyType.ProviderSpecific`. +It is a high-level wrapper over [`COPY`](https://www.postgresql.org/docs/current/static/sql-copy.html) command. + +Note that if you already used this mode for your bulk copy operations it could be a breaking change because now it will use COPY instead of silent fallback to `BulkCopyType.MultipleRows` in previous versions. + +Why it could be a breaking change? Because `COPY` command (we use `BINARY` mode) demands that proper column types specified and will fail if types doesn't match. You will need to add type information to your mappings or switch to other copy method. + +You can read about type requirements more in out new article about `BulkCopy` API [here](https://github.com/linq2db/linq2db/wiki/Bulk-Copy#postgresql-provider-specific-bulk-copy). + +Implementation supports `COPY` API from both npgsql 3.x and npgsql 4.x (4.0 brings breaking changes to API). + +#### Upsert support + +`InsertOrUpdate` API will use `INSERT ON CONFLICT UPDATE` statement for PostgreSQL 9.5+ instead of several statements on previous versions [(948)](https://github.com/linq2db/linq2db/issues/948). + +You will need to use `PostgreSQLVersion.v95` provider version if you don't use version autodetect. + +#### Other changes and fixes + +- improved support for some database types as a part of `BulkCopy` improvements [(1091)](https://github.com/linq2db/linq2db/issues/1091) +- fixed support for following types in `CreateTable` API: `Int16`/`Int64` identity columns, `System.Linq.Binary`, `DataType.VarBinary`, `DataType.NChar(1)`, `char` [(1091)](https://github.com/linq2db/linq2db/issues/1091) +- support for interval type mapping to both `NpgsqlTimeSpan` and `NpgsqlInterval` types [(1091)](https://github.com/linq2db/linq2db/issues/1091) + +### SAP HANA + +#### `BulkCopy` `KeepIdentity` option support + +As a part of `KeepIdentity` option review, support for it added to SAP HANA provider. Check [documentation](https://github.com/linq2db/linq2db/wiki/Bulk-Copy#keepidentity-option-default--false) for more details [(1037)](https://github.com/linq2db/linq2db/issues/1037). + +Note that this option requires support from provider, so make sure you use recent provider version with `enum HanaBulkCopyOptions` having `KeepIdentity` field and not all versions had it. Otherwise `BulkCopy` will throw exception. + +### SQL CE + +#### `BulkCopy` `KeepIdentity` option support + +As a part of `KeepIdentity` option review, support for it added to SQL CE provider. Check [documentation](https://github.com/linq2db/linq2db/wiki/Bulk-Copy#keepidentity-option-default--false) for more details [(1037)](https://github.com/linq2db/linq2db/issues/1037). + +### Sybase + +- `MERGE` insert operation will respect `SkipOnInsert` on identity fields when `InsertWhenNotMatched()` without custom setter used and allow database to generate field's value [(914)](https://github.com/linq2db/linq2db/issues/914) +- requesting procedures and functions from schema provider will throw exception if called from transaction to avoid database corruction due to bug in provider [(792)](https://github.com/linq2db/linq2db/issues/792) + +### SQLite + +- `DateTime.AddDays()` method to `SQL` conversion fixed [(998)](https://github.com/linq2db/linq2db/issues/998) + +### SQL Server + +- `varchar`/`nvarchar` parameters will use 8000/4000 as length to improve query plans caching [(989)](https://github.com/linq2db/linq2db/issues/989) +- `MERGE` will use parameters instead of literals for binary data in client-side (IEnumerable) source +- `MERGE` insert operation will respect `SkipOnInsert` on identity fields when `InsertWhenNotMatched()` without custom setter used and allow database to generate field's value [(914)](https://github.com/linq2db/linq2db/issues/914) +- legacy `MERGE` API will not try to update identity columns anymore on update operation anymore [(1007)](https://github.com/linq2db/linq2db/issues/1007) +- fixed `DropTable` method not dropping table in another database [(1030)](https://github.com/linq2db/linq2db/issues/1030) +- fixed DateTime literal generation [(1107)](https://github.com/linq2db/linq2db/issues/1107) +- fixed incompatibility between `BulkCopy` and `RetryingDbConnection` [(1135)](https://github.com/linq2db/linq2db/issues/1135) + +## Changes for developers + +- Query AST was refactored. See `SelectQuery` class ([936](https://github.com/linq2db/linq2db/issues/936), [938](https://github.com/linq2db/linq2db/issues/938)) +- Tests configuration changed format and use *DataProviders.json files instead of *DataPRoviders.txt. [More details](https://github.com/linq2db/linq2db/blob/master/CONTRIBUTING.md#configure-data-providers-for-tests) +- Project migrated to support latest C# version +- You can use new `ActiveIssueAttribute` to mark tests for non-fixed issues. This will allow to merge test-only PRs immediately +- `SchemaProviderBase` methods `ToTypeName` and `ToValidName` made public ([944](https://github.com/linq2db/linq2db/issues/944), [963](https://github.com/linq2db/linq2db/issues/963)) +- `SqlProviderFlags.CustomFlags` list added to allow store custom provider flags [(1154)](https://github.com/linq2db/linq2db/issues/1154) +- expose `SqlExtensions` class for provider developers + +## I Use Entity Framework (:feelsbadman:) + +Don't worry, check this [new project](https://github.com/linq2db/linq2db.EntityFrameworkCore) we created recently. It is still an early prototype so don't expect it to work flawlessly. We will appreciate your feedback! \ No newline at end of file diff --git a/Doc/articles/releasenotes/Unreleased-Changes.md b/Doc/articles/releasenotes/Unreleased-Changes.md new file mode 100644 index 0000000000..de78d5417f --- /dev/null +++ b/Doc/articles/releasenotes/Unreleased-Changes.md @@ -0,0 +1,8 @@ +This page contains changes and fixes that were not inluded in any release yet and available only through MyGet feed. + +[![MyGet](https://img.shields.io/myget/linq2db/vpre/linq2db.svg)](https://www.myget.org/gallery/linq2db) + +# Will be included into next post-2.0 release + +none yet +