Coder Social home page Coder Social logo

igor-tkachev / bltoolkit Goto Github PK

View Code? Open in Web Editor NEW
296.0 296.0 112.0 248.71 MB

Business Logic Toolkit for .NET

License: MIT License

PLSQL 0.23% C# 95.44% CSS 0.05% HTML 1.59% PowerShell 0.09% XSLT 0.74% Batchfile 0.18% PLpgSQL 0.06% TSQL 1.08% Visual Basic .NET 0.55%

bltoolkit's People

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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 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  avatar  avatar  avatar

bltoolkit's Issues

Ternary operator (first, CanBeNull = true; then, CanBeNull = false)

Hello,

thank you very much for fixing #38 so quickly!

I would like to report another issue/feature request. I have a class (let's call it "Top") which is associated with another class (say, "Middle"). This association can be null. The Middle class, however, is associated with the Bottom class. And that association cannot be null. What is proper way to deal with this situation? In earlier versions, ternary expression were possible in the select statement. In my project, this problem comes up several times.

l_DbManager.GetTable().Select (T => T.Middle == null : null ? T.Middle.Bottom);

This causes BLToolkit to throw a NotImplementedException in TableBuilder.cs:703. Currently, I am avoiding the exception by using:

l_DbManager.GetTable().Select (T => T.Middle.Bottom);

This returns T.Middle.Bottom not as null but as an "empty" object with the default values such as Id == Guid.Empty.

Best regards,

Sebastian

Model

public class Top {

    public Guid Id { get; set; }

    public Guid MiddleId { get; set; }

    [Association(CanBeNull = true, ThisKey = "MiddleId", OtherKey = "Id")]
    public Middle Middle { get; set; }
}

public class Middle {
    public Guid Id { get; set; }

    public Guid BottomId { get; set; }

    [Association(CanBeNull = false, ThisKey = "BottomId", OtherKey = "Id")]
    public Bottom Bottom { get; set; }
}

public class Bottom {
    public Guid Id { get; set; }
}

Returning collections with sub-collections

Given the classic parent -> children tables, where a parent can have one or more children, I'm trying to return a list of parents with the corresponding children.

var query = from p in db.Parent
            where p.ParentId == 100
            select new { p.Name, p.Children }

This assumes an association in the Parent model like this:

[Association(ThisKey = "ParentId", OtherKey = "ChildParentId")]
public List<Child> Children { get; set; }

When trying to run this query I get:

Argument type 'Child' does not match the corresponding member type 'System.Collections.Generic.List`1[Child]'

If I try to bypass the association, like this:

var query = from p in db.Parent
            where p.ParentId == 100
            select new 
            { 
              p.Name, 
              Children  = (from c in db.Child 
                           where c.ChildParentId == p.ParentId 
                           select c).ToList() 
            }

I get:

Multiple queries are not allowed. Set the 'LinqToDB.Common.Configuration.Linq.AllowMultipleQuery' flag to 'true' to allow multiple queries.

Would it be possible for "simple" queries for BLT to rewrite the query as a join and do the parsing of the results automatically? LINQ to SQL allows this pattern, and since it's very common, porting applications from LINQ to SQL to BLT would be very time consuming. We would have to have custom "parsing" ourselves for each query result set.

Is there perhaps a different way something like this could be achieved with BLT?

Thank you.

Feature request: fluent configuration

Attributes as a configuration markup are not very good.
It would be superb If I could use something like this code from Entity Framewrok:

public class DepartmentTypeConfiguration : EntityTypeConfiguration<Department>
{
  public DepartmentTypeConfiguration()
  {
    ToTable("Units");

    Property(d => d.Name).
      IsRequired().
      HasMaxLength(50);

    Property(d => d.DepartmentID).
      HasDatabaseGenerationOption(DatabaseGenerationOption.None);

    HasMany(d => d.Courses).
        WithRequired(c => c.Department).
        HasForeignKey(c => c.DepartmentID).
        WillCascadeOnDelete();

    Ignore(d => d.Administrator); 

  } 
}

public class SchoolEntities : DbContext
{
  public DbSet<Department> Departments { get; set; }

  protected override void OnModelCreating(ModelBuilder modelBuilder)
  {
    base.OnModelCreating(modelBuilder);

    modelBuilder.Configurations.Add(new DepartmentTypeConfiguration());
  }
}

BLToolkit mapping & .Net types

I have a SQL table contining a geography column, which uses the SqlGeography clr type behind the covers:

CREATE TABLE Place
    Name varchar
    Position geography
...

I defined a mapping class:

public class Place
{
    public string Name{get;set;}
    public SqlGeography Position{get;set;}
}

After mapping (either through or Map.DataReaderToObject, or by using Linq), the Position property is empty.

Any idea how to overcome this?

Regards,

sql_variant and MappingSchema

Hi.

I trying use sql_variant.
In model i have object Value property.
When i'm trying to use this from linq, i got error:

[code]
Member 'Value.Value' is not a table column.

at BLToolkit.Data.Linq.Builder.TableBuilder.TableContext.GetField(Expression expression, Int32 level, Boolean throwException) in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\Builder\TableBuilder.cs:line 1061
at BLToolkit.Data.Linq.Builder.TableBuilder.TableContext.FindTable(Expression expression, Int32 level, Boolean throwException) in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\Builder\TableBuilder.cs:line 1094
at BLToolkit.Data.Linq.Builder.TableBuilder.TableContext.ConvertToSql(Expression expression, Int32 level, ConvertFlags flags) in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\Builder\TableBuilder.cs:line 691
at BLToolkit.Data.Linq.Builder.UpdateBuilder.BuildSetter(ExpressionBuilder builder, IBuildContext into, List1 items, IBuildContext ctx, MemberInitExpression expression, Expression path) in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\Builder\UpdateBuilder.cs:line 155 at BLToolkit.Data.Linq.Builder.UpdateBuilder.BuildSetter(ExpressionBuilder builder, BuildInfo buildInfo, LambdaExpression setter, IBuildContext into, List1 items, IBuildContext sequence) in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\Builder\UpdateBuilder.cs:line 119
at BLToolkit.Data.Linq.Builder.InsertOrUpdateBuilder.BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\Builder\InsertOrUpdateBuilder.cs:line 28
at BLToolkit.Data.Linq.Builder.MethodCallBuilder.BuildSequence(ExpressionBuilder builder, BuildInfo buildInfo) in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\Builder\MethodCallBuilder.cs:line 22
at BLToolkit.Data.Linq.Builder.ExpressionBuilder.BuildSequence(BuildInfo buildInfo) in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\Builder\ExpressionBuilder.cs:line 180
at BLToolkit.Data.Linq.Builder.ExpressionBuilder.BuildT in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\Builder\ExpressionBuilder.cs:line 151
at BLToolkit.Data.Linq.Query1.GetQuery(IDataContextInfo dataContextInfo, Expression expr) in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\Query.cs:line 130 at BLToolkit.Data.Linq.Table1.GetQuery(Expression expression, Boolean cache) in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\TableT.cs:line 106
at BLToolkit.Data.Linq.Table1.System.Linq.IQueryProvider.Execute[TResult](Expression expression) in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\TableT.cs:line 177 at BLToolkit.Data.Linq.LinqExtensions.InsertOrUpdate[T](Table1 target, Expression1 insertSetter, Expression1 onDuplicateKeyUpdateSetter) in D:\Projects\Venus\Libs\BLToolkit\Source\Data\Linq\LinqExtensions.cs:line 584
...
[/code]

As i see, thit is unsupported in MappingSchema class (simple ignore this field declaration).
If in model, i apply [MapField("Value")] to object - all looks fine.

So it is error in MappingSchema class or no?

MapObjectToDictionary with TypeExtension.GetExtensions work wrong

EnumToValueTest test work fine, ObjToDicTest discard

Test

public class MapEnumTest
{
    public class TestObj
    {
        [MapField("country_code")]
        public CountryCodeEnum Country { get; set; }
        [MapField("other")]
        public OtherEnum Other { get; set; }
    }

    public enum CountryCodeEnum
    {
        [MapValue("AFA")]
        AF,
        [MapValue("ALA")]
        AL,
        [MapValue("DZA")]
        DZ,
        [MapValue("ASA")]
        AS,
        [MapValue("ADA")]
        AD
    }

    public enum OtherEnum
    {
        [MapValue("v1")]
        EnumValue1,
        [MapValue("v2")]
        EnumValue2
    }

    [Test]
    public void EnumToValueTest()
    {
        Map.Extensions = TypeExtension.GetExtensions("Map.xml");

        Assert.AreEqual("AL", Map.EnumToValue(CountryCodeEnum.AL));
        Assert.AreEqual(101, Map.EnumToValue(OtherEnum.EnumValue2));
    }

    [Test]
    public void ObjToDicTest()
    {
        var obj = new TestObj();
        obj.Country = CountryCodeEnum.DZ;
        obj.Other = OtherEnum.EnumValue2;

        var sh = new MappingSchema();
        sh.Extensions = TypeExtension.GetExtensions("Map.xml");
        var pars = sh.MapObjectToDictionary(obj);

        Assert.AreEqual("DZ", pars["country_code"]);
        Assert.AreEqual(101, pars["other"]);
    }
}

Map.xml file:

?xml version="1.0" encoding="utf-8" ?>
Types
xmlns = "urn:schemas-bltoolkit-net:typeext"
xmlns:m = "urn:schemas-bltoolkit-net:mapping">

Type Name='CountryCodeEnum'>
Member Name='AF' MapValue='AF' MapValue-Type='System.String'/>
Member Name='AL' MapValue='AL' MapValue-Type='System.String'/>
Member Name='DZ' MapValue='DZ' MapValue-Type='System.String'/>
Member Name='AS' MapValue='AS' MapValue-Type='System.String'/>
Member Name='AD' MapValue='AD' MapValue-Type='System.String'/>
/Type>

Type Name='OtherEnum'>
Member Name='EnumValue1' MapValue='100' MapValue-Type='System.Int32' />
Member Name='EnumValue2' MapValue='101' MapValue-Type='System.Int32' />
/Type>

/Types>

Bind parameters(command parameters) vs hard/plain query

Hello
The Bltoolkit project uses statements with bind variables throughout the application. Bind variables are good for performance, as Oracle does not need to hard-parse the query every time it is executed. However, in some cases, bind variables lead to major performance problems. One of the more significant problems we faced was the issue of bind variables in SQL LIKE predicates. By default Bltoolkit uses bind variables in passing query criteria values entered by our application users. In many cases, where users used trailing wildcards (asterisk), Oracle 10g/11g Optimizer’s calculated query paths that were inefficient, resulting in queries that took from several minutes to an hour.

A more detailed explanation that oracle gave us is the following :
"yes the optimizer calculate the cardinalty and the cost when bind variables are used different than that when laterals are used.
this is limitation to CBO when using bind variables , see See Note 212809.1 Limitations of the Oracle Cost Based Optimizer

Also please note If your application uses bind variables against columns whose data is skewed and different plans are optimal depending on different
column data then you are going to have problems with some data and not with others depending on which value you use first in your queries.
There isn't really any way around this since there is not a single plan that is good for all values. The only real solution is to change the application to use literals for this kind of select where the value is critical. This would mean that cursors were not shared but also that the optimizer has a good chance of picking an acceptable access path for the query.

From the optimizer point of view we do not recommend the use of bind variables for queries where data values are critical to the selection of a good plan. Bind variables are recommended for situations where cursors are frequently executed with different column values and would otherwise cause shared pool fragmentation and contention.
"

So, would you give a thought for letting a user choose (or making a bltoolkit configuration option) whether Bltoolkit uses command parameters or generates hard/plain query to send to the database server?
I could do this by myself in the Bltoolkit fork, but I wanted to get your feeling about this, before passing to act.

Best regards,
Valeriu

Critical: After Upgrade: Dbmanager opening connection for simple SQL... without need.

...which blows on our end (not allowed to open additional connectiosn by admins). We also reconfigure conenction default schema after opening, which BlToolkit does not - but that is not relevant here, it just makes the issue obvious. The following code - when activating the commented out WHERE clause - blows because it uses a new connection. Breakpoint in OpenConnection is triggered.

We ugpradeed from a 4.0 version to the current 4.1.8 and are currently rolling back for exact this reason - blows our code.

The following sequence:

        var c1 = DataManager.Get<Profile>().First();
        System.Diagnostics.Debug.Assert(c1 != null);
        var c2 = DataManager.Get<InsOption>().First();
        System.Diagnostics.Debug.Assert(c2 != null);

        var insNr = trade.InstrumentNumber;
        var sideNr = side.ActualSideId.Value;

        foreach (var dbleg in DataManager.Get<Profile>()
            .GroupJoin(DataManager.Get<InsOption> (),
                x => new { x.InsNum, x.ParamSeqNum, LegId = x.ProfileSeqNum},
                y => new { y.InsNum, y.ParamSeqNum, LegId = y.OptionSeqNum },
                (x, y) => new { Profile = x, InsOption = y }
            )
            .SelectMany(
                y => y.InsOption.DefaultIfEmpty(),
                (x, y) => new { x.Profile, InsOption = x.InsOption.FirstOrDefault() }
            )
            //.Where(x => x.Profile.InsNum == insNr && x.Profile.ParamSeqNum == sideNr)
            .OrderBy(x => x.Profile.ProfileSeqNum)
        )
        {

When the Where clause is removed, the SQL statement is successfully submited to the database. The DbManager has an always open connection.

Now, this is a simple join with aprameters. NOTHING in there asks for a secondary cnonection, especially not the where clause. In act I dare saying that as the resulting SQL is (with where clause):

This runs the whole statement on one connection only. No in memory merging. As such, the opening of a connection in BlToolkit is a code error. There is no need for an already connected DbManager to establish another connection.

The stack trace for opening the connection is:

BLToolkit.4.DLL!BLToolkit.Data.DbManager.OpenConnection() Line 211 C#
[External Code]
BLToolkit.4.DLL!BLToolkit.Data.DbManager.OnInitCommand(System.Data.IDbCommand command) Line 464 + 0x1e bytes C#
[External Code]
BLToolkit.4.DLL!BLToolkit.Data.DbManager.Parameter(System.Data.ParameterDirection parameterDirection, string parameterName, object value) Line 1553 + 0x1e bytes C#
BLToolkit.4.DLL!BLToolkit.Data.DbManager.Parameter(string parameterName, object value) Line 1368 + 0x19 bytes C#
BLToolkit.4.DLL!BLToolkit.Data.DbManager.AddParameter(System.Collections.Generic.ICollection<System.Data.IDbDataParameter> parms, string name, BLToolkit.Data.Sql.SqlParameter parm) Line 160 + 0x27 bytes C#
BLToolkit.4.DLL!BLToolkit.Data.DbManager.GetParameters(BLToolkit.Data.Linq.IQueryContext query, BLToolkit.Data.DbManager.PreparedQuery pq) Line 146 + 0x1c bytes C#
BLToolkit.4.DLL!BLToolkit.Data.DbManager.BLToolkit.Data.Linq.IDataContext.SetQuery(BLToolkit.Data.Linq.IQueryContext queryContext) Line 52 + 0x1a bytes C#
BLToolkit.4.DLL!BLToolkit.Data.Linq.Query<PROJECT.Adapters.EndurAdapters.Database.InsOption>.SetCommand(BLToolkit.Data.Linq.IDataContext dataContext, System.Linq.Expressions.Expression expr, object[] parameters, int idx) Line 348 + 0x52 bytes C#
BLToolkit.4.DLL!BLToolkit.Data.Linq.Query<PROJECT.Adapters.EndurAdapters.Database.InsOption>.RunQuery(BLToolkit.Data.Linq.IDataContextInfo dataContextInfo, System.Linq.Expressions.Expression expr, object[] parameters, int queryNumber) Line 327 + 0x5c bytes C#
BLToolkit.4.DLL!BLToolkit.Data.Linq.Query<PROJECT.Adapters.EndurAdapters.Database.InsOption>.Map(System.Collections.Generic.IEnumerable<System.Data.IDataReader> data, BLToolkit.Data.Linq.QueryContext queryContext, BLToolkit.Data.Linq.IDataContextInfo dataContextInfo, System.Linq.Expressions.Expression expr, object[] ps, System.Func<BLToolkit.Data.Linq.QueryContext,BLToolkit.Data.Linq.IDataContext,System.Data.IDataReader,System.Linq.Expressions.Expression,object[],PROJECT.Adapters.EndurAdapters.Database.InsOption> mapper) Line 988 + 0x200 bytes C#
[External Code]
BLToolkit.4.DLL!BLToolkit.Data.Linq.Builder.GroupByBuilder.GroupByContext.Grouping<<>f__AnonymousType49<long,long,long>,PROJECT.Adapters.EndurAdapters.Database.InsOption>.GetItems() Line 180 + 0xfc bytes C#
BLToolkit.4.DLL!BLToolkit.Data.Linq.Builder.GroupByBuilder.GroupByContext.Grouping<<>f__AnonymousType49<long,long,long>,PROJECT.Adapters.EndurAdapters.Database.InsOption>.GetEnumerator() Line 191 + 0x1a bytes C#
[External Code]
BLToolkit.4.DLL!BLToolkit.Data.Linq.Query<<>f__AnonymousType4a<PROJECT.Adapters.EndurAdapters.Database.Profile,PROJECT.Adapters.EndurAdapters.Database.InsOption>>.Map(System.Collections.Generic.IEnumerable<System.Data.IDataReader> data, BLToolkit.Data.Linq.QueryContext queryContext, BLToolkit.Data.Linq.IDataContextInfo dataContextInfo, System.Linq.Expressions.Expression expr, object[] ps, System.Func<BLToolkit.Data.Linq.QueryContext,BLToolkit.Data.Linq.IDataContext,System.Data.IDataReader,System.Linq.Expressions.Expression,object[],<>f__AnonymousType4a<PROJECT.Adapters.EndurAdapters.Database.Profile,PROJECT.Adapters.EndurAdapters.Database.InsOption>> mapper) Line 989 + 0xbf bytes C#

The final stack trace of the error is:

BLToolkit.Data.DataException was unhandled by user code
Message=Verbindung ist schon geöffnet (Translation: Connection is arleady open)
Source=BLToolkit.4
StackTrace:
at BLToolkit.Data.DbManager.OnOperationException(OperationType op, DataException ex) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 593
at BLToolkit.Data.DbManager.HandleOperationException(OperationType op, Exception ex) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 4418
at BLToolkit.Data.DbManager.ExecuteOperation(OperationType operationType, Action operation) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 4384
at BLToolkit.Data.DbManager.OpenConnection() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 211
at BLToolkit.Data.DbManager.get_Connection() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 186
at BLToolkit.Data.DbManager.OnInitCommand(IDbCommand command) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 464
at BLToolkit.Data.DbManager.get_SelectCommand() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 401
at BLToolkit.Data.DbManager.get_Command() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 385
at BLToolkit.Data.DbManager.Parameter(ParameterDirection parameterDirection, String parameterName, Object value) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 1553
at BLToolkit.Data.DbManager.Parameter(String parameterName, Object value) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 1368
at BLToolkit.Data.DbManager.AddParameter(ICollection1 parms, String name, SqlParameter parm) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.Linq.cs:line 160 at BLToolkit.Data.DbManager.GetParameters(IQueryContext query, PreparedQuery pq) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.Linq.cs:line 146 at BLToolkit.Data.DbManager.BLToolkit.Data.Linq.IDataContext.SetQuery(IQueryContext queryContext) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.Linq.cs:line 52 at BLToolkit.Data.Linq.Query1.SetCommand(IDataContext dataContext, Expression expr, Object[] parameters, Int32 idx) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Query.cs:line 348
at BLToolkit.Data.Linq.Query1.<RunQuery>d__11.MoveNext() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Query.cs:line 327 at BLToolkit.Data.Linq.Query1.d__60.MoveNext() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Query.cs:line 988
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at BLToolkit.Data.Linq.Builder.GroupByBuilder.GroupByContext.Grouping2.GetItems() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Builder\GroupByBuilder.cs:line 180
at BLToolkit.Data.Linq.Builder.GroupByBuilder.GroupByContext.Grouping2.GetEnumerator() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Builder\GroupByBuilder.cs:line 191 at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable1 source)
at lambda_method(Closure , QueryContext , IDataContext , IDataReader , Expression , Object[] )
at BLToolkit.Data.Linq.Query1.<Map>d__60.MoveNext() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Query.cs:line 989 at PROJECT.Adapters.EndurAdapters.TradeAdapter.GetSideLegs(Trade trade, TradeSide side) in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.EndurAdapters\TradeAdapter.cs:line 670 at PROJECT.Adapters.EndurAdapters.TradeAdapter.FillLegs(Trade trade, TradeSide side) in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.EndurAdapters\TradeAdapter.cs:line 382 at PROJECT.Adapters.EndurAdapters.TradeAdapter.FillSides(Trade trade) in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.EndurAdapters\TradeAdapter.cs:line 364 at PROJECT.Adapters.EndurAdapters.TradeAdapter.EnrichTrade(Trade trade, Header header, PwrPhyParam pwrPhyParam, InsOption insOption, PhysHeader physHeader, Instruments instrument, Int32 insClass, Boolean evaluateSidesAndInfos) in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.EndurAdapters\TradeAdapter.cs:line 520 at PROJECT.Adapters.EndurAdapters.TradeAdapter.DoProcess(TradeRequest request) in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.EndurAdapters\TradeAdapter.cs:line 106 at PROJECT.Adapters.Shared.Adapter1.Process(Request request) in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.Shared\Adapter,T.cs:line 38
at PROJECT.Adapters.EndurAdapters.Tests.EndurTradeAdapterTests.ProcessRequest() in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.EndurAdapters.Tests\TradeAdapterTests.cs:line 80
InnerException: System.InvalidOperationException
Message=Verbindung ist schon geöffnet
Source=Oracle.DataAccess
StackTrace:
at Oracle.DataAccess.Client.OracleConnection.Open()
at BLToolkit.Data.DbManager.ExecuteOperation(OperationType operationType, Action operation) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 4379
InnerException:

Even better, when I bring the query into the original form (which started it all):

foreach (var dbleg in DataManager.Get<Profile>()
                .GroupJoin(DataManager.Get<InsOption> (),
                    x => new { x.InsNum, x.ParamSeqNum, LegId = x.ProfileSeqNum},
                    y => new { y.InsNum, y.ParamSeqNum, LegId = y.OptionSeqNum },
                    (x, y) => new { Profile = x, InsOption = y }
                )
                .SelectMany(
                    y => y.InsOption.DefaultIfEmpty(),
                    (x, y) => new { x.Profile, InsOption = x.InsOption.FirstOrDefault() }
                )
                .Where(x => x.Profile.InsNum == trade.InstrumentNumber && x.Profile.ParamSeqNum == side.ActualSideId.Value)
                .OrderBy(x => x.Profile.ProfileSeqNum)
            )

(note that trade and side are input parameters defined before), then the connection tried to be used is closed (? this makes no sense) and being opened.

BLToolkit.Data.DataException was unhandled by user code
Message=ORA-00942: table or view does not exist
Source=BLToolkit.4
StackTrace:
at BLToolkit.Data.DbManager.OnOperationException(OperationType op, DataException ex) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 593
at BLToolkit.Data.DbManager.HandleOperationException(OperationType op, Exception ex) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 4418
at BLToolkit.Data.DbManager.ExecuteOperation[T](OperationType operationType, Func1 operation) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 4404 at BLToolkit.Data.DbManager.ExecuteReaderInternal(CommandBehavior commandBehavior) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 607 at BLToolkit.Data.DbManager.ExecuteReader(CommandBehavior commandBehavior) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 3600 at BLToolkit.Data.DbManager.ExecuteReaderInternal() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 602 at BLToolkit.Data.DbManager.ExecuteReader() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 3587 at BLToolkit.Data.DbManager.BLToolkit.Data.Linq.IDataContext.ExecuteReader(Object query) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.Linq.cs:line 255 at BLToolkit.Data.Linq.Query1.d__11.MoveNext() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Query.cs:line 329
at BLToolkit.Data.Linq.Query1.<Map>d__60.MoveNext() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Query.cs:line 988 at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)
at BLToolkit.Data.Linq.Builder.GroupByBuilder.GroupByContext.Grouping2.GetItems() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Builder\GroupByBuilder.cs:line 180 at BLToolkit.Data.Linq.Builder.GroupByBuilder.GroupByContext.Grouping2.GetEnumerator() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Builder\GroupByBuilder.cs:line 191
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable1 source) at lambda_method(Closure , QueryContext , IDataContext , IDataReader , Expression , Object[] ) at BLToolkit.Data.Linq.Query1.d__60.MoveNext() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Query.cs:line 989
at PROJECT.Adapters.EndurAdapters.TradeAdapter.GetSideLegs(Trade trade, TradeSide side) in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.EndurAdapters\TradeAdapter.cs:line 667
at PROJECT.Adapters.EndurAdapters.TradeAdapter.FillLegs(Trade trade, TradeSide side) in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.EndurAdapters\TradeAdapter.cs:line 382
at PROJECT.Adapters.EndurAdapters.TradeAdapter.FillSides(Trade trade) in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.EndurAdapters\TradeAdapter.cs:line 364
at PROJECT.Adapters.EndurAdapters.TradeAdapter.EnrichTrade(Trade trade, Header header, PwrPhyParam pwrPhyParam, InsOption insOption, PhysHeader physHeader, Instruments instrument, Int32 insClass, Boolean evaluateSidesAndInfos) in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.EndurAdapters\TradeAdapter.cs:line 520
at PROJECT.Adapters.EndurAdapters.TradeAdapter.DoProcess(TradeRequest request) in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.EndurAdapters\TradeAdapter.cs:line 106
at PROJECT.Adapters.Shared.Adapter1.Process(Request request) in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.Shared\Adapter,T.cs:line 38 at PROJECT.Adapters.EndurAdapters.Tests.EndurTradeAdapterTests.ProcessRequest() in D:\Work\GloRi\trunk\vs\PROJECT\PROJECT.Adapters.EndurAdapters.Tests\TradeAdapterTests.cs:line 80 InnerException: Oracle.DataAccess.Client.OracleException Message=ORA-00942: table or view does not exist Source=Oracle Data Provider for .NET ErrorCode=-2147467259 DataSource=XXXXX Number=942 Procedure="" StackTrace: at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx\* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck) at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx\* pOpoSqlValCtx, Object src, Boolean bCheck) at Oracle.DataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior) at Oracle.DataAccess.Client.OracleCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior) at BLToolkit.Data.DbManager.<>c__DisplayClass12.<ExecuteReaderInternal>b__11() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 610 at BLToolkit.Data.DbManager.ExecuteOperation[T](OperationType operationType, Func1 operation) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DbManager.cs:line 4396
InnerException:

Plus a call to connection open.

Conclusions:

There is something broken with connection opening / closing here.

  • On the first error, BlToolkit tries to open an already open connection wrongly.
  • On the second code version, a closed connection is opened. The code makes clear that BlToolkit should ahve no need for it - for some reason the connecton was closed without my intervention and knowledge - which is inefficient and not callede for. Originalyl the Dbmanager was created with an IDbConnection and I do NOT expect it to close it without an error or me asking..

Last test: I wrap everything in begin / commit transaction on bltoolkit level.

The same call to OpenConnection. The connection is closed. This is now not only an error (as inefficient) as in by chance, ti is illegal (as in voiding the transaction contract) because this means the open transaction had been commited or rolled back.

I fail to see so far where the connection gets closed - totally. Just that at one point it gets closed.

AllowMultipleQuery error

Hi,

Just migrated from BLT 4.1.6 to 4.1.8 and now I have problem with multiple queries. It throws an error "Multiple queries are not allowed. Set the 'BLToolkit.Common.Configuration.Linq.AllowMultipleQuery' flag to 'true' to allow multiple queries.".
After I set the AllowMultipleQuery flag to true, it throws me another error "No coercion operator is defined between types 'System.String' and 'System.Char'.".

the query looks like this

return ( from p in db.Poduzeca
                     where p.PoduzecaID == iPoduzecaID
                     select new
                     {
                         p.Sifra,
                         p.Naziv,
                         ZiroRacun = ( from zrp in db.ZiroRacuniPoduzeca.Where( x => x.PoduzecaID == p.PoduzecaID )
                                       from ban in db.Banke.Where( x => x.BankeID == zrp.BankeID )
                                       select ban.VodeciBroj + "-" + zrp.BrojRacuna ).FirstOrDefault(),
                     } ).ToDataTable();

Sorry it's not translated. If you need it I can create some test tables translated in english.
Anyway this previous code was working in the 4.1.6 version.

BLT loading time

Hi,

It's me again :)

I'm writing some unit tests for my CMS engine. I'm using BLT Nuget and I noticed that BLT is taking very long to load (over 10s). My tests without BLT start immediately, but first test with instantiating DbManager takes more that 10 secs.
While this is fine for production, on testing/debuging it's really painful.

Can anything be done to improve BLT loading performance?
BLTGen maybe? Does that thing works for BLT 4?

Regards,
Marko

An error using "let" with an "Association" property

The following expression:

       var q = from package in DbManager.Packages
               let jobs = package.PackageJobs
               select new
                   {
                       package.PackageID,
                       count = jobs.Count()
                   };

fails with an exception:

 System.ArgumentException : Property 'Int64 PackageID' is not defined for type '<>f__AnonymousType9`2[Spx.Xms.BusinessLogic.DataStorage.Package,System.Collections.Generic.List`1[Spx.Xms.BusinessLogic.DataStorage.Job]]'
at System.Linq.Expressions.Expression.Property(Expression expression, PropertyInfo property)
at System.Linq.Expressions.Expression.MakeMemberAccess(Expression expression, MemberInfo member)
at BLToolkit.Data.Linq.Builder.TableBuilder.TableContext.AssociationHelper`1.GetExpression(Expression parent, AssociatedTableContext association)
at BLToolkit.Data.Linq.Builder.TableBuilder.TableContext.GetContext(Expression expression, Int32 level, BuildInfo buildInfo)
at BLToolkit.Data.Linq.Builder.SelectContext.<>c__DisplayClass54.<GetContext>b__50(Int32 n, IBuildContext ctx, Expression ex, Int32 l, Expression _)
. . .

It can be fixed by just removing "let". The following expression works fine:

       var q = from package in DbManager.Packages
              select new
                   {
                       package.PackageID,
                       count = package.PackageJobs.Count()
                   };

OdpDataProvider & TIMESTAMP column

Hello,

It seems that when I use a Linq query with a "where" clause on a TIMESTAMP column, the milliseconds is missing is the query.

This is a sample to be clearer.

CREATE TABLE TIMESTAMP_TEST(
    ID_TIMESTAMP_TEST    NUMBER(10),
    TIMEMEDIA                        TIMESTAMP
);

[TableName("TIMESTAMP_TEST")]
public class TIMESTAMP_TEST
{
    public long ID_TIMESTAMP_TEST { get; set; }
    public DateTime TIMEMEDIA { get; set; }
}

public class UnitTests
{
    public void Run()
    {
        var db = new BaseDbManager(new OdpDataProvider(), GetConnection(DbServer, DbLogin, DbPassword));
        var t = db.GetTable<TIMESTAMP_TEST>();

        var now = DateTime.Now;
        var data = new TIMESTAMP_TEST{ID_TIMESTAMP_TEST = 1, TIMEMEDIA = now};

        t.Insert(data);

        var query = from d in db.GetTable<TIMESTAMP_TEST>()
                             where d.TIMEMEDIA = now
                             select d;

         // Display 0
        Console.WriteLine(query.Count());
    }
}

Add InsertOrUpdate() overload

Would be great if InsertOrUpdate(this Table<T> table, T obj) overload was implemented.

Because now we have only InsertOrUpdate(this Table<T> table, Expression<Func<T>> insertSetter, Expression<Func<T, T>> onDuplicateKeyUpdateSetter) method and we have to manually specify all the necessary fields 2 times.
This is time consuming and error prone (if during future changes/refactoring we add a new field to an entity class, we may forget to change our lambda expressions in the InsertOrUpdate() method).

ExpressionBuilder.ConvertLikePredicate() crashes when parsing query

Consider the following classes

  public class Root
  {
    public int ID { get; set; }
    public string Value { get; set; }
    public int InfoID { get; set; }
  }

  public class Leaf
  {
    public int    ID         { get; set; }
    public int    RootID     { get; set; }
    public string LeafValue  { get; set; }
  }

and corresponding SQL tables

CREATE TABLE Root(
    ID int NOT NULL,
    Value nvarchar(50) NOT NULL,
    InfoID int NULL
) 

CREATE TABLE [Leaf](
    [ID] [int] NOT NULL,
    [RootID] [int] NOT NULL,
    [LeafValue] [nvarchar](50) NOT NULL
) 

The following code crashes when parsing q2 query:

    [Test]
    public void CrashTest()
    {
      using (var db = new DbManager())
      {
        var roots = db.GetTable<Root>();
        roots.Delete();
        roots.Insert(() => new Root { ID = 1, Value = "First", InfoID = 1 });
        roots.Insert(() => new Root { ID = 2, Value = "Second", InfoID = 1 });
        roots.Insert(() => new Root { ID = 3, Value = "Third", InfoID = 1 });

        var leafs = db.GetTable<Leaf>();
        leafs.Delete();
        leafs.Insert(() => new Leaf { ID = 1, RootID = 1, LeafValue = "blabla" });
        leafs.Insert(() => new Leaf { ID = 2, RootID = 2, LeafValue = "blahblah" });

        var part = "i"; // If you create part as const then there will be no crash
        Expression<Func<Root, bool>> selector = r => r.Value.Contains(part);

        var q1 = from r in roots select r;
        q1 = q1.Where(selector);

        var q2 = from l in leafs
                 join r in q1 on l.RootID equals r.ID
                 select l;

        foreach (var leaf in q2)
        {
          Debug.WriteLine(leaf.LeafValue);
        }
      }
    }

Stack trace
System.ArgumentException : An item with the same key has already been added.
at System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add) at BLToolkit.Data.Linq.Builder.ExpressionBuilder.ConvertLikePredicate(IBuildContext context, MethodCallExpression expression, String start, String end) in ExpressionBuilder.SqlBuilder.cs: line 1792 at BLToolkit.Data.Linq.Builder.ExpressionBuilder.ConvertPredicate(IBuildContext context, Expression expression) in ExpressionBuilder.SqlBuilder.cs: line 1174 at BLToolkit.Data.Linq.Builder.ExpressionBuilder.BuildSearchCondition(IBuildContext context, Expression expression, List1 conditions) in ExpressionBuilder.SqlBuilder.cs: line 2001
at BLToolkit.Data.Linq.Builder.ExpressionBuilder.BuildWhere(IBuildContext parent, IBuildContext sequence, LambdaExpression condition, Boolean checkForSubQuery) in ExpressionBuilder.SqlBuilder.cs: line 38
at BLToolkit.Data.Linq.Builder.WhereBuilder.BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) in WhereBuilder.cs: line 20
at BLToolkit.Data.Linq.Builder.MethodCallBuilder.BuildSequence(ExpressionBuilder builder, BuildInfo buildInfo) in MethodCallBuilder.cs: line 22
at BLToolkit.Data.Linq.Builder.ExpressionBuilder.BuildSequence(BuildInfo buildInfo) in C:\Projects\bl-toolkit\bltoolkit.4.1\Source\Data\Linq\Builder\ExpressionBuilder.cs: line 178
at BLToolkit.Data.Linq.Builder.JoinBuilder.BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) in C:\Projects\bl-toolkit\bltoolkit.4.1\Source\Data\Linq\Builder\JoinBuilder.cs: line 42
at BLToolkit.Data.Linq.Builder.MethodCallBuilder.BuildSequence(ExpressionBuilder builder, BuildInfo buildInfo) in MethodCallBuilder.cs: line 22
at BLToolkit.Data.Linq.Builder.ExpressionBuilder.BuildSequence(BuildInfo buildInfo) in C:\Projects\bl-toolkit\bltoolkit.4.1\Source\Data\Linq\Builder\ExpressionBuilder.cs: line 178
at BLToolkit.Data.Linq.Builder.ExpressionBuilder.Build() in C:\Projects\bl-toolkit\bltoolkit.4.1\Source\Data\Linq\Builder\ExpressionBuilder.cs: line 149
at BLToolkit.Data.Linq.Query1.GetQuery(IDataContextInfo dataContextInfo, Expression expr) in C:\Projects\bl-toolkit\bltoolkit.4.1\Source\Data\Linq\Query.cs: line 134 at BLToolkit.Data.Linq.Table1.GetQuery(Expression expression, Boolean cache) in C:\Projects\bl-toolkit\bltoolkit.4.1\Source\Data\Linq\TableT.cs: line 106
at BLToolkit.Data.Linq.Table1.Execute(IDataContextInfo dataContextInfo, Expression expression) in C:\Projects\bl-toolkit\bltoolkit.4.1\Source\Data\Linq\TableT.cs: line 98 at BLToolkit.Data.Linq.Table1.System.Collections.Generic.IEnumerable.GetEnumerator() in C:\Projects\bl-toolkit\bltoolkit.4.1\Source\Data\Linq\TableT.cs: line 193
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList(IEnumerable1 source) at BLTUnitTests.Tests.TestInternal(Expression1 selector) in Tests.cs: line 49
at BLTUnitTests.Tests.Test() in Tests.cs: line 66

BLToolkit generates a wrong SQL text for boolean properties.

SQL Script (MS SQL):

CREATE TABLE Test_Bool (
  Name VARCHAR(16) NULL,
  Is_Hidden Bit DEFAULT 0 NOT NULL);
GO

INSERT INTO Test_Bool VALUES ('Name 1', 0);
INSERT INTO Test_Bool VALUES ('Name 2', 1);
INSERT INTO Test_Bool VALUES ('Name 3', 0);
INSERT INTO Test_Bool VALUES ('Name 4', 1);
INSERT INTO Test_Bool VALUES ('Name 5', 0);
INSERT INTO Test_Bool VALUES ('Name 6', 1);
GO

Entity class:

[TableName(Name="Test_Bool")]
public partial class Test_Bool
{
  [Nullable             ] public string Name     { get; set; } // varchar(16)
  [MapField("Is_Hidden")] public bool   IsHidden { get; set; } // bit
}

Following fragment of code generates a valid SQL
and returns a valid result (3 objects in the list):

var boolQuery = from tb in model.Test_Bool
                where tb.IsHidden == true
                select tb;
var list = boolQuery.ToList();

// Generated SQL:
// SELECT
// [tb].[Name],
// [tb].[Is_Hidden] as [IsHidden]
// FROM
// [Test_Bool] [tb]
// WHERE
// [tb].[Is_Hidden] = 1

Changing a LINQ condition to "true == tb.IsHidden"
makes BLToolkit to generate an erroneous SQL

var boolQuery = from tb in model.Test_Bool
                where true == tb.IsHidden
                select tb;
var list = boolQuery.ToList(); // returns 6 objects

// Generated SQL:
// SELECT
// [tb].[Name],
// [tb].[Is_Hidden] as [IsHidden]
// FROM
// [Test_Bool] [tb]

Subquery Error

        using (var db = new NorthwindDB())
        {
            BLToolkit.Common.Configuration.Linq.AllowMultipleQuery = true;
            var query = from a in db.Employee
                        select new Employee
                        {
                            EmployeeID = a.EmployeeID,
                            EmployeeTerritories = (from b in a.EmployeeTerritories select b),
                            Orders = (from c in a.Orders select c),
                            ReportsToEmployee = a.ReportsToEmployee
                        };

            foreach (var customer in query)
            {
                //int i = customer.Orders.Count();
            }

        }

Using above query, can't get "Orders". Gives me bellow error:

The binary operator Equal is not defined for the types 'System.Nullable`1[System.Int32]' and 'System.Int32'.

This is because "EmployID" in Orders table is Nullable (int?).

What would be alternate solution to resolve this error without change datatype of "EmployID" in "Orders", from nullable to non-nullable?

Problem with DateTime and Array initializer

In the following uni tests:

    [Test]
    public void ContainsWithDateTimeInlineTest()
    {
        var query = from asset in DbManager.OEAssets
                    where new DateTime?[] { DateTime.Now }.Contains(asset.LastConnected)
                    select asset;
        Action action = () => query.Count();
        action.ShouldNotThrow();
    }

    [Test]
    public void ContainsWithDateTimeVariableTest()
    {
        var dateTime = new DateTime?[] { DateTime.Now };
        var query = from asset in DbManager.OEAssets
                    where dateTime.Contains(asset.LastConnected)
                    select asset;
        Action action = () => query.Count();
        action.ShouldNotThrow();
    }

The first one works and the second one fails. the only difference between them is the usage of a local variable in the second test

Impossible to use high precision DateTime types...

One year later, new version - same old problem ;) This time no workaround.

This class:

[TableName("Instrument", Owner = "Mkt")]
public class MktInstrument {

    /// <summary>
    /// The unique Id of the instrument.
    /// </summary>
    [MapField (), PrimaryKey(), Identity()]
    public int Id { get; set; }

    /// <summary>
    /// The Id of the symbol the instrument is attached to.
    /// </summary>
    [MapField ()]
    public int SymbolRef { get; set; }

    /// <summary>
    /// The Timestamp of the entry.
    /// </summary>
    [MapField ()]
    public DateTime Timestamp { get; set; }

with this query:

        using (DataManager manager = new DataManager(_DatabaseConfig)) {
            manager.GetRepository<MktInstrument>().Insert (
                () => new MktInstrument() {
                    SymbolRef = mktSymbol.Id,
                    Timestamp = timestamp,
                }
            );

(non relevant fields taken out)

rounds.

DataManager just wrapps a DbManager - GetRepository maps to the GetTable method.

The culprit is that the parameter for timestmap is DateTime.

The generated query is:

INSERT INTO [Mkt].[Instrument] 
(
    [SymbolRef],
    [Timestamp],
)
VALUES
(
    @Id,
    @timestamp1,
)

The Timestamp field in the database is DateTime2(7).

The parameter used (@timestamp1) is: DbType: System.Data.DbType.DateTime

I need full precision - I use the last digits of the DateTime to "index it" (i.e. provide an order for elements with the same timestamp). This is severely ingrained into the whole codebase.

This seems to be the culprit. Is there any way to override that type? I tried adding a BLToolkit.DataAccess.DbTypeAttribute but it is ignored (parameter value still DateTime). The DateTime value in the parameter is correct, so it seems totally to be the bad data type.

Any help please? ;)

On Monday, January 10, 2011 6:35:49 AM UTC+1, NetTecture wrote:
Hello,

I am trying to write out tick consistent DateTime2(7) values into SQL
Server. I pretty much plan to use th last digits below milliseconds to
order the data I get (in actuall 25ms intervals).

I write, for example:

  •            TimeOfDay        {05:00:07.4250141}        System.TimeSpan 
    

And in the database I then find:

2010-12-14 05:00:07.4270000

This clarly has been rounded ;) Which sadly is not good for me.

Anyone an idea where to fix this?

On Monday, January 10, 2011 6:35:49 AM UTC+1, NetTecture wrote:
Hello,

I am trying to write out tick consistent DateTime2(7) values into SQL
Server. I pretty much plan to use th last digits below milliseconds to
order the data I get (in actuall 25ms intervals).

I write, for example:

  •            TimeOfDay        {05:00:07.4250141}        System.TimeSpan 
    

And in the database I then find:

2010-12-14 05:00:07.4270000

This clarly has been rounded ;) Which sadly is not good for me.

Anyone an idea where to fix this?

On Monday, January 10, 2011 6:35:49 AM UTC+1, NetTecture wrote:
Hello,

I am trying to write out tick consistent DateTime2(7) values into SQL
Server. I pretty much plan to use th last digits below milliseconds to
order the data I get (in actuall 25ms intervals).

I write, for example:

  •            TimeOfDay        {05:00:07.4250141}        System.TimeSpan 
    

And in the database I then find:

2010-12-14 05:00:07.4270000

This clarly has been rounded ;) Which sadly is not good for me.

Anyone an idea where to fix this?

Upsert

Hi,

No question here, I just want to point to a possible performance improvement.

I'm creating some custom indexing logic for a CMS and following construct appeared few times in my code:

if (db.Update(indexState) == 0)
db.Insert(indexState);

This can be optimized to save one database round-trip by generating one Upsert command instead of two separate commands.
I'm almost sure that you have already considered this, but just want to be sure.

Regards,
Marko

Reuse of a local variable for a subquery

In the following test:

    [Test]
    public void Test2()
    {
        InitializeData();
        UpdateDb();

        BLToolkit.Data.DbManager.TurnTraceSwitchOn();
        BLToolkit.Data.DbManager.WriteTraceLine = (s1, s2) =>
        {
            Console.WriteLine(s1);
            Console.WriteLine(s2);
        };

        var assetIds = from job in DbManager.Jobs
                       where job.PercentDownloaded == 10
                       select job.OEAssetID;

        var q = from asset in DbManager.OEAssets
                where assetIds.Contains(asset.OEAssetID)
                select asset;

        var assets = q.ToArray();
        assets.Should().HaveCount(1);
        assets.First().OEAssetID.Should().Be(m_asset2.OEAssetID);

        assetIds = from job in DbManager.Jobs
                        where job.PackageId.Location == m_folder.FolderName
                        select job.OEAssetID;

        q = from asset in DbManager.OEAssets
                 where assetIds.Contains(asset.OEAssetID)
                 select asset;

        assets = q.ToArray();
        assets.Should().HaveCount(3);
    }

BLToolkit generates the same SQL for both query executions. To fix this problem just use not "assetIds" but a separated local variable with a new name.

missing sqlite and firebird client dll references

Hello

I have downloaded the last version source project from this repository
after rebuilding i get several errors. the cause is:

Missing a reference to SQLite dll
Missing a reference to firebird client.dll

I have solved it installing the folders Firebird an SQLite from an older version in the Redist folder and adding references to the dlls inside

hope this helps

Datareader already open when sharing connection between sessions in SQL Server

Hello

I have a WEB application with about one hundred users accessing concurrently and using BLToolKit succesfully.

However sometimes ( may be once a mounth, when workload is great ), I get this error repeatedly :

"There is already an open DataReader associated with this Command which must be closed first"

and y have to restart the services.

My app shares the DBManager connection object for all seassons within a singleton pattern. I use SQL Server 2008. Searching the internet, i found that this is a popular issue, not exclusive from BLtoolkit. It is said that the solution is to enable MARS in connection string. The parameter is "MultipleActiveResultSets=True". However this did not solve the problem.

I hope I have isolated the failure in this code snippet, inspired in this post http://ayende.com/blog/1482/static-thread-safety :

using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Diagnostics;
using BLToolkit.Data;
using BLToolkit.Data.DataProvider;

using System.Threading;


static class Program
{
    static DbManager shared_db ; 

    static void Main()
    {
        SqlDataProvider dp = new SqlDataProvider();

        try
        {
            shared_db = new DbManager(dp, "Data Source=sharepointer;Database=Northwind;Integrated Security=SSPI;MultipleActiveResultSets=True");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
            throw ex;
        }

        Thread t1 = new Thread(GetData);
        Thread t2 = new Thread(GetData);

        t1.Start();
        t2.Start();

        Console.ReadKey();

    }

    private static void GetData()
    {
        Console.WriteLine("Thread iniciado");
        shared_db.SetCommand("SELECT EmployeeID FROM Employees");
        Thread.Sleep(500); // if I comment this, I get NullReferenceException instead

        using (var rd = shared_db.ExecuteReader())
        {
            int i = 0;
            while (rd.Read())
            {
                Console.WriteLine("{0}", ++i);
                Thread.Sleep(500);
            }
        }
    }
}

I have done a great effort in solving outside the bltoolkit library it but the only thing I get is to delay de failure. Is very important to me to get my app stable, i would appreciate any help. Anything i can do, please make me know.

Thanks from Bilbao.

Edu

The detailed exception i get is the following :

BLToolkit.Data.DataException was unhandled
Message="Ya hay un DataReader abierto asociado a este comando, debe cerrarlo primero."
Source="BLToolkit.3"
StackTrace:
en BLToolkit.Data.DbManager.OnOperationException(OperationType op, DataException ex)
en BLToolkit.Data.DbManager.HandleOperationException(OperationType op, Exception ex)
en BLToolkit.Data.DbManager.ExecuteOperation[T](OperationType operationType, Func1 operation) en BLToolkit.Data.DbManager.ExecuteReaderInternal(CommandBehavior commandBehavior) en BLToolkit.Data.DbManager.ExecuteReader(CommandBehavior commandBehavior) en BLToolkit.Data.DbManager.ExecuteReaderInternal() en BLToolkit.Data.DbManager.ExecuteReader() en Linq.Demo.Program.GetData() en C:\Documents and Settings\eduardo\Escritorio\undersat\igor-tkachev-bltoolkit-d03a435\Demo\Linq\Demo\Program.cs:línea 62 en System.Threading.ThreadHelper.ThreadStart_Context(Object state) en System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) en System.Threading.ThreadHelper.ThreadStart() InnerException: System.InvalidOperationException Message="Ya hay un DataReader abierto asociado a este comando, debe cerrarlo primero." Source="System.Data" StackTrace: en System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) en System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command) en System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) en System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) en System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) en System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) en System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) en System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior) en BLToolkit.Data.DbManager.<>c__DisplayClass4.<ExecuteReaderInternal>b__3() en BLToolkit.Data.DbManager.ExecuteOperation[T](OperationType operationType, Func1 operation)

MemberMapper and Insert<T>(T obj)

If a type or a property is decorated with MemberMapper attribute, then extension method

Insert(this DbManager dataContext, T obj)

fails with error "No mapping exists from object type to a known managed provider native type..."

PEVerify complains about assembly generated with AssemblyBuilderHelper

I experienced strange behavior when using the overload of AssemblyBuilderHelper.DefineType which takes a parent type.
When the supplied base type is a user defined type (Base) PEVerify cannot load the generated type.

The following example saves two assemblies to disk.

public class Base
{
}

internal class Program
{
  private static void Main(string[] args)
  {
    PlainReflection();

    BLReflectionHelper();
  }

  private static void PlainReflection()
  {
    var assemblyName = new AssemblyName { Name = "Test-PlainReflection" };
    var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
    var module = assembly.DefineDynamicModule("Test-Plain-Reflection.dll");

    module.DefineType("TestClass", TypeAttributes.Public, typeof(Base)).CreateType();

    assembly.Save("Test-Plain-Reflection.dll");
  }

  private static void BLReflectionHelper()
  {
    var assmebly = new AssemblyBuilderHelper("Test-BLReflectionHelper.dll");

    assmebly.DefineType("TestClass", typeof(Base)).Create();
    //assmebly.DefineType("TestClass").Create(); // without the base class the generated assembly peverifys without errors
    //assmebly.DefineType("TestClass", typeof(List<string>)).Create(); // also works, the custom base class is the problem

    assmebly.Save();
  }
}

PEVerify gives the following output.

C:\ReflectionTest\bin\Debug>peverify Test-Plain-Reflection.dll

Microsoft (R) .NET Framework PE Verifier.  Version  4.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.

All Classes and Methods in Test-Plain-Reflection.dll Verified.

C:\ReflectionTest\bin\Debug>peverify Test-BLReflectionHelper.dll /verbose

Microsoft (R) .NET Framework PE Verifier.  Version  4.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.

[token  0x02000002] Type load failed.
1 Error(s) Verifying Test-BLReflectionHelper.dll

I looked at the generated IL, but unfortunately I do not know how to diagnose such errors or where to start (0x02000002 is the TypeDef token for the generated type). - Any hints on this in general?
Also the AssemblyBuilderHelper implementation does not do anything too fancy, so I can not imagine where things go wrong.

ILDASM - MetaInfo (plain reflection)
ILDASM - MetaInfo (BLToolkit)

I am using the latest version of BLToolkit from NuGet (4.1.6.) for .NET 4 on Windows XP 32bit.

PS: Thanks for your great work!

Incorect mapping of null byte[] to nullable varbinary

[TableName(Name="SomeData")]
public partial class SomeData
{
    [PrimaryKey(1)] public int    KeyID { get; set; } // int(10)
    public byte[] Data      { get; set; } // varbinary(-1)
}

.....

DataModel.SomeData.Insert(() => new SomeData() { KeyID = 1, Data = null });

Exception is:
Implicit conversion from data type nvarchar to varbinary(max) is not allowed. Use the CONVERT function to run this query.

A bit more details and a working bugfix is here:
http://rsdn.ru/forum/prj.rfd/4511321.flat.aspx#4511321

SqlQuery building exception

Файл: Data/Sql/QueryVisitor.cs
Строка: 813
sc.Into = t ?? sc.Into;
вызывает при определенных условия NullRef..Exception.
Рассмотрел весь блок кода:

var s = (SqlQuery.InsertClause)element;
var t = s.Into != null ? (SqlTable)ConvertInternal(s.Into, action) : null;
var i = Convert(s.Items, action);

if (t != null && !ReferenceEquals(s.Into, t) || i != null && !ReferenceEquals(s.Items, i))
{
  var sc = new SqlQuery.InsertClause();
  sc.Into = t ?? sc.Into;
  sc.Items.AddRange(i ?? s.Items);
  sc.WithIdentity = s.WithIdentity;

  newElement = sc;
}

думаю должно быть:
sc.Into = t ?? s.Into;

для "заполнения" из предыдущего объекта как и с Items и WithIdentity.

Cast() is added unnecessary when translating to SQL

var q = from ... select mp.Price * (1.0m - s.Discount / 100.0m);

mp.Price is of decimal type and s.Discount is of int type

The resulting SQL is:
... mp.Price * (1 - Cast(s.Discount as Decimal(10,0)) / 100) ...

The cast of s.Discount is unnecessary (and may lead to reducing performance?).

System.NullReferenceException in CounterAspect.cs

This happened twice already. As far as I can tell it is random. I retried the execution with the same data, and it worked. I don't know if this is an issue with bltoolkit, or my implementation. I was using bltoolkit 4.0. I switched to bltoolkit 4.1 (current snapshot) and will see if this helps.

Stack trace:
System.NullReferenceException: Object reference not set to an instance of an object.
at BLToolkit.Aspects.CounterAspect.BeforeCall(InterceptCallInfo info) in d:\cruisecontrol\workingcopies\BizTalkToCaWebService\BLToolkit.4\Aspects\CounterAspect.cs:line 32
at BLToolkit.Aspects.Interceptor.Intercept(InterceptCallInfo info) in d:\cruisecontrol\workingcopies\BizTalkToCaWebService\BLToolkit.4\Aspects\Interceptor.cs:line 14
at DAL.Code.Logging.BLToolkitExtension.LogAccessor.ReceiptConfirmationLogInsert(String ConsigneeShipRefNum, String DocumentId, DateTime DocumentDateTime, String OrderNumber, Nullable`1& NewLogID)
at Bll.Logging.LogManager.ReceiptConfirmationLogInsert(String consigneeShipRefNum, String documentId, DateTime documentDateTime, String orderNumber) in d:\cruisecontrol\workingcopies\BizTalkToCaWebService\BLL\Code\Logging\LogManager.cs:line 111

CounterAspect.cs:

27    protected override void BeforeCall(InterceptCallInfo info)
28    {
29          if (!IsEnabled || Thread.GetData(_counterSlot) != null)
30              return;
31
32          _counter.RegisterCall(info);
33
34          Thread.SetData(_counterSlot, _counter);
35    }

LogManager.cs:

106        private int? ReceiptConfirmationLogInsert(string consigneeShipRefNum, string documentId, DateTime documentDateTime, string orderNumber)
107        {
108            int? newLogID = null;
109            try
110            {
111                Accessor.ReceiptConfirmationLogInsert(consigneeShipRefNum, documentId, documentDateTime, orderNumber, out newLogID);
112            }
113            catch (Exception exc)
114            {
115                ErrorLog errorLog = ErrorLog.GetDefault(null);
116                errorLog.ApplicationName = CommonFunctions.GetApplicationName();
117                errorLog.Log(new Error(exc));
118            }
119
120            return newLogID;
121        }

constructor of the base class for the LogManager.cs

    public ManagerBase()
    {
        _accessor = TypeAccessor<T>.CreateInstanceEx();
    }

Wrong calculation of the discriminator index in a query with a subquery.

Hello,

I would appreciate your help regarding the following issue:

Model (reduced to the minimum necessary to cause an exception.):

public abstract class Base {
    public Guid Id { get; set; }

    [MapIgnore]
    public virtual TypeCodeEnum TypeCode {
        get { 
            return TypeCodeEnum.Base;
         }
    }
}

[InheritanceMapping(Code = (int)TypeCodeEnum.A1, Type = typeof(A1), IsDefault = false)]
[InheritanceMapping(Code = (int)TypeCodeEnum.A2, Type = typeof(A2), IsDefault = false)]
public abstract class A  :  Base {     

    [Association(CanBeNull = true, ThisKey = "Id", OtherKey = "Id")]
    public List<B> Bs { get; set; }

    [MapField(IsInheritanceDiscriminator = true)]
     public override TypeCodeEnum TypeCode
     {
          get
          {
              return TypeCodeEnum.A;
            }
       }
}
[TableName("A")]
public class A1 : A { 
     MapField(IsInheritanceDiscriminator = true)]
     public override TypeCodeEnum TypeCode
     {
          get
          {
              return TypeCodeEnum.A1;
            }
       }
 }

[TableName("A")]
public class A2 : A { 
     MapField(IsInheritanceDiscriminator = true)]
     public override TypeCodeEnum TypeCode
     {
          get
          {
              return TypeCodeEnum.A2;
            }
       }
}

public class B : Base {

}

LINQ Query:

var l_Result = l_DbManager.GetTable<A>()
    .Where(A => !A.Bs.Any())
    .ToList()

Exception:
Invalid cast from System.Guid to System.Int32
System.InvalidCastException: Invalid cast from System.Guid to System.Int32

The SQL query is created and executed correctly against the database. The data is successfully retrieved from the database. The exception occurs during mapping. The first actual retrieved value is 1711, the second one is the Guid ID. The mapper, however, expects the first value to be a Guid and the second one to be an integer. And the reason for this, I think, is that _index[0] in the TableBuilder points to A.Id, wheras _index[1] points to A.TypeCode. Hence, dindex is equal to 1 instead of 0. Or, to put it the other way around, the sql query should select A.Id before it A.TypeCode.

Best regards,

Sebastian

Image field error

Ok this is error is really weird.

In my table I have a column of data type 'image' and it is set to 'allow null'. I define it in the code as following

private Binary _MyImage;
[MapField( "MyImage", Storage = "_MyImage" ), Nullable]
public Binary MyImage { get { return _MyImage; } set { _MyImage = value; } }

When I try to insert or update the row in table I get the error "Operand type clash: nvarchar is incompatible with image".
This is the example of code that is causing the error.

var iNewID = db.SomeTable.InsertWithIdentity( () => new SomeTable
{
    MyImage = myImageData
} );

Now the weird thing is that when "myImageData" contains some data then the saving works, but when myImageData == null then the previous error is thrown. When I change "MyImage = myImageData" into "MyImage = null" then it also works with no errors.

I hope you will understand, if you need any more info just let me know.

4.1.1 GroupJoin talking to wrong table?

In addition to #25 there is the behavior that the subselects are not handled and genrate an eroror.

The following query is used for the subselect:

SELECT 
    y.param_seq_num as ParamSeqNum, 
    y.option_seq_num as OptionSeqNum, 
    y.ins_num as InsNum, 
    y.put_call as PutCall, 
    y.strike as Strike, 
    y.end_exercise_date as ExerciseDate 
FROM 
    ins_option y 
WHERE 
    y.ins_num = :InsNum1 AND y.param_seq_num = :ParamSeqNum1 AND 
    y.option_seq_num = :LegId 

This results in an error:

ORA-00942: table or view does not exist

It executes fine within SqlDeveloper - IF the table is prfixed with a schema ("prod.ins_option" instead of "ins_option"). this is not unexpected - tables sit in different schema depending whether they are for production of development, so we have the schema not in the mapping but in our own handcrafted configuration and are changing the schema in the IDbConnection factory (wich we always create for a specific IDbConnection). This error eludes me, the noly reason I can see for it to happen is if somehow the schema gets changed or a new connection opened.

The same code (as in error #25) works fine with 4.0.

Oracle Stored Proc parameter incorrectly formed.

Calling a simple stored procedure

CREATE OR REPLACE PROCEDURE BETA_AUTO_UPDATE
   (
      AutoId IN NUMBER,
      Rule  IN NVARCHAR2,  
      Nam  IN NVARCHAR2,
      Loc IN NVARCHAR2
   )
IS
BEGIN 

UPDATE Beta_Auto
SET RuleGuid = Rule,        
    Name = Nam,
    Location = Loc
WHERE Id=AutoId;

COMMIT;
EXCEPTION 
 WHEN OTHERS THEN 
         RAISE_APPLICATION_ERROR(-20001, 'ERROR OCCURED DURING UPDATE');


END BETA_AUTO_UPDATE;
/


with 

        Beta_Auto Betar = new Beta_Auto();
        Betar.ID = 1;
        Betar.RuleGuid = "RuleGuid1";
        Betar.Name = "Jim";
        Betar.Location = "Loc1";

        OracleDb.BeginTransaction();
        OracleDb.SetSpCommand("Beta_Auto_UPDATE", OracleDb.CreateParameters(Betar)).ExecuteNonQuery();
        OracleDb.CommitTransaction();

fails to call the SP with correct params.

Exam of in params with 'pl/sql developer' and the script

select  c.name                      BIND, 
       substr(c.value_string,1,25) VAL
from    v$sqlarea a, 
    v$sql_bind_capture c
where   a.sql_id = c.sql_id 
and     a.hash_value = '3436831386'
order by a.last_active_time desc, c.name asc
;

returns the following:

SAddr          User              Add          hashValue    Sql ID                  SQL
2EB602DC CORRULES 28688690 824224538 aw4h7z0sk1asu   Begin Beta_Auto_UPDATE(AUTOID=>:v0, RULE=>:v1, NAM=>:v2, LOC           OPEN

found

2EB602DC    CORRULES    286879F4    3436831386  65qp2av6dmsnu   UPDATE BETA_AUTO SET RULEGUID = :B4 , NAME = :B3 , LOCATION             PL/SQL CURSOR CACHED


SQL> select  c.name                      BIND,
  2          substr(c.value_string,1,25) VAL
  3  from    v$sqlarea a,
  4          v$sql_bind_capture c
  5  where   a.sql_id = c.sql_id
  6  and     a.hash_value = '824224538 '
  7  order by a.last_active_time desc, c.name asc
  8  ;

BIND                           VAL
------------------------------ -------------------------
:V0
:V1
:V2
:V3

with second statement, (after marshalling of param should have been completed)

BIND                           VAL
------------------------------ -------------------------
:B1                                 NULL
:B2
:B3
:B4

The paramater collection isn't being marshalled correctly in the ODP provider.

Tried the following

        [SprocName("Beta_Auto_Update")]
        public abstract void UpdateByKey(int Id, string RuleGuid, string Name, string Location);

Didn't work but worked for sql.

Pearly Soames.

InsertOrUpdate() should not require PK to be included in the setter

...because there can be another unique key and the row to be inserted can make that unique key constraint fail.

Here is a real life example (it's MySql):

CREATE TABLE rabase.supplier_stock(
  ID INT(11) NOT NULL AUTO_INCREMENT,
  ManufacturerID INT(11) UNSIGNED NOT NULL,
  SupplierID INT(11) UNSIGNED NOT NULL,
  PartN VARCHAR(20) NOT NULL,
  Available INT(11) NOT NULL,
  IsDeleted TINYINT(1) NOT NULL DEFAULT 0,
  TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (ID),
  INDEX FK_supplier_stock_suppliers_ID (SupplierID),
  UNIQUE INDEX UK_supplier_stock (ManufacturerID, SupplierID, PartN),
  CONSTRAINT FK_supplier_stock_manufacturers_ID FOREIGN KEY (ManufacturerID)
  REFERENCES rabase.manufacturers (ID) ON DELETE RESTRICT ON UPDATE RESTRICT,
  CONSTRAINT FK_supplier_stock_suppliers_ID FOREIGN KEY (SupplierID)
  REFERENCES rabase.suppliers (ID) ON DELETE RESTRICT ON UPDATE RESTRICT
)
    [TableName(Name="supplier_stock")]
    public partial class SupplierStockAvailability
    {
        [Identity, PrimaryKey(1)              ] public int      ID             { get; set; } // int(10)
                                                public int      ManufacturerID { get; set; } // int(10)
                                                public int      SupplierID     { get; set; } // int(10)
                                                public string   PartN          { get; set; } // varchar(20)
                                                public int      Available      { get; set; } // int(10)
                                                public bool     IsDeleted      { get; set; } // tinyint(3)
        [                         NonUpdatable] public DateTime TS             { get; set; } // timestamp
    }
dataContext.SupplierStock.InsertOrUpdate(
    () => new SupplierStockAvailability
                    {
                        ManufacturerID = manufacturerID,
                        SupplierID = supplierID,
                        PartN = partN,
                        Available = available
                    },
    ss => new SupplierStockAvailability { Available = available, IsDeleted = false }));

Here we need to update a table based on a ManufacturerID+SupplierID+PartN unique key (the ID primary key is used for synchronizing tables in other queries).

In my case I think I could make ManufacturerID+SupplierID+PartN a primary key and make ID a unique key. But what if I had more than one unique key? Or what if table's DDL changing could be a problem (or, for example, unique key has NULL columns, or UK is too long to be a PK, or UK is not good to be a clustered index, etc.)?

DataAccessor::GetSqlQueryAttribute should be virtual

Just checked how it's used from DataAccessorBuilder:

.ldarg_0 .call (typeof(MethodBase), "GetCurrentMethod") .castclass (typeof(MethodInfo)) .callvirt (_baseType, "GetSqlQueryAttribute", _bindingFlags, typeof(MethodInfo))

There's assumption that it could overridden, but not.

Bug in DbManager InsertBatch when not using transaction

in SqlDataProviderBase when using with ms sqlServer

public override int InsertBatch<T>(
        DbManager                      db,
        string                         insertText,
        IEnumerable<T>                 collection,
        MemberMapper[]                 members,
        int                            maxBatchSize,
        DbManager.ParameterProvider<T> getParameters)
    {
        if (db.Transaction != null)
            return base.InsertBatch(db, insertText, collection, members, maxBatchSize, getParameters);

        var idx = insertText.IndexOf('\n');
        var tbl = insertText.Substring(0, idx).Substring("INSERT INTO ".Length).TrimEnd('\r');
        var rd  = new BulkCopyReader(members, collection);
        var bc  = new SqlBulkCopy((SqlConnection)db.Connection)
        {
            BatchSize            = maxBatchSize,
            DestinationTableName = tbl,
        };

        bc.WriteToServer(rd);

        return rd.Count;
    }

bc.WriteToServer(rd) fails
Reason:
BulkCopyReader member collection indices are not aligned with SqlBulkCopy class metadata

DbManager.AssignParameterValues bug

AssignParameterValues(object) doesn't assign defaut value of nullable property to the parameter. To reproduce this bug you may use this unit test

public class DataTypeTest2
{
   [MapField("DataTypeID")]
   public int ID;

   public Single? Single_ { get; set; }
}

[TestFixture]
public class DbManagerTest
{
   //...
   #if MSSQL
   [Test]
   #endif
   public void AssignParameterValuesTest()
   {
    string connectionString = DbManager.GetConnectionString(null);

    DataTypeTest2 obj = new DataTypeTest2 { Single_ = 0F };

    using (DbManager db = new DbManager(new SqlConnection(connectionString)))
    {
      db.SetCommand("INSERT INTO DataTypeTest (Single_) VALUES (@Single_)", db.Parameter("@Single_", 1.5F, DbType.Single));
    db.AssignParameterValues(obj);
    Assert.AreEqual(obj.Single_, db.Parameter("@Single_").Value);
    }
   }
}

4.1.1: GroupJoin / Select Many not resulting in efficient SQL

The following LINQ statement:

     foreach (var dbleg in DataManager.Get<Profile>()
            .GroupJoin(DataManager.Get<InsOption> (),
                x => new { x.InsNum, x.ParamSeqNum, LegId = x.ProfileSeqNum},
                y => new { y.InsNum, y.ParamSeqNum, LegId = y.OptionSeqNum },
                (x, y) => new { Profile = x, InsOption = y }
            )
            .SelectMany(
                y => y.InsOption.DefaultIfEmpty(),
                (x, y) => new { x.Profile, InsOption = x.InsOption.FirstOrDefault() }
            )
            .Where(x => x.Profile.InsNum == insnum && x.Profile.ParamSeqNum == paramseqnum)
            .OrderBy(x => x.Profile.ProfileSeqNum)
        )
        {

is diong a join between two tables and as such should be quite efficient in one statement. It is an outer join - for every profile there is maximum one InsOption anyway.

Sadly, I get an error (the query works find under 4.0 and is the enxt step stopping us from 4.1.x adoption) in DbManager.cs line 604, which reads:
_dataProvider.GetDataReader(_mappingSchema, SelectCommand.ExecuteReader(commandBehavior)));

The query generated is:

SELECT 
y.param_seq_num as ParamSeqNum, 
y.option_seq_num as OptionSeqNum, 
y.ins_num as InsNum, 
y.put_call as PutCall, 
y.strike as Strike, 
y.end_exercise_date as ExerciseDate 
FROM 
ins_option y 
WHERE 
y.ins_num = :InsNum1 AND y.param_seq_num = :ParamSeqNum1 AND 
y.option_seq_num = :LegId 

This indicates an error somewhere (will try to find out what it is exactly) but it also indicates this join is handled on an item by item bases instead of an outer join. If that is to be expected - I need the syntax for an outer join ;) When pulling 120.000 legs this results in 119.999 additional SQL statements executing with significant performance overhead.

ORA-00942: table or view does not exist

Incorrect integer column mapping for update statement select clause fail.

On sql server 2k8.

Have the following mapping.

public partial class Gamma_Abort
{
    [PrimaryKey(1)]
    public int ID { get; set; } // int(10)
    public string ExpressGuid { get; set; }  // nvarchar(50)
    public int Bast { get; set; } // int(10)
    public string Condition { get; set; } // nvarchar(200)
    public string A { get; set; } // nvarchar(100)
    [Nullable]
    public string B { get; set; } // nvarchar(100)
}

Using the following data accessor to perform an update.

public abstract class AbortAccessor : DataAccessor<Gamma_Abort>
{  
        [GammaQuery(
        SqlText = "UPDATE CorrRules.Gamma_Abort SET Condition=@Cond ,A=@A, B=@B WHERE ID=Id AND ExpressGuid=@EGuid AND Bast=BBast",
        OracleText = "UPDATE Gamma_Abort SET Condition=:Cond, A=:A, B=:B WHERE ID=:Id AND ExpressGuid=:EGuid AND Bast=:BBast")]
        public abstract void UpdateAbortByKey(string Cond, string A, string B,int Id, string EGuid, int BBast);
}

which fails with the following exception.

BLToolkit.Data.DataException was caught
Message=Invalid column name 'BBast'.
Source=BLToolkit.4
StackTrace:
at BLToolkit.Data.DbManager.OnOperationException(OperationType op, DataException ex)
at BLToolkit.Data.DbManager.HandleOperationException(OperationType op, Exception ex)
at BLToolkit.Data.DbManager.ExecuteOperation[T](OperationType operationType, Func1 operation) at BLToolkit.Data.DbManager.ExecuteNonQueryInternal() at BLToolkit.Data.DbManager.ExecuteNonQuery() at GammaDIL.Common.Accessor.BLToolkitExtension.AbortAccessor.UpdateAbortByKey(String Cond, String A, String B, Int32 Id, String EGuid, Int32 BBast) at GammaDIL.Repository.Abort.UpdateAbort(String Cond, String A, String B, Int32 Ident, String ExpressGuid, Int32 Tok) in C:\Users\Administrator\Documents\Visual Studio 2010\Projects\FluentTest\RufusRulesGen\Repository\Abort.cs:line 82 InnerException: System.Data.SqlClient.SqlException Message=Invalid column name 'BBast'. Source=.Net SqlClient Data Provider ErrorCode=-2146232060 Class=16 LineNumber=1 Number=207 Procedure="" Server=STEGSTORLECK-MI\FIERCE State=1 StackTrace: at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() at BLToolkit.Data.DbManager.ExecuteOperation[T](OperationType operationType, Func1 operation)
InnerException:

Tried a whole number of combinations to fix it. Finally tried changing param from int to string.

public abstract class AbortAccessor : DataAccessor<Gamma_Abort>
{  
        [GammaQuery(
        SqlText = "UPDATE CorrRules.Gamma_Abort SET Condition=@Cond, B=@B WHERE ID=Id AND ExpressGuid=@EGuid AND A=@A",
        OracleText = "UPDATE Gamma_Abort SET Condition=:Cond, A=:A, B=:B WHERE ID=:Id AND ExpressGuid=:EGuid AND A=:A")]
        public abstract void UpdateAbortByKey(string Cond, string A, string B,int Id, string EGuid, int BBast);
}

And it worked fine. I think it's something to do with parsing the int's based column incorrectly.

Pearly.

Wrong SQL is generated?

The method:

  public static DataTable GetClosureRequests(
    int? supplierID, bool? supplierNotified)
  {
   using (var db = new DataModel())
   {
    var q =
     from cr in db.ClosureRequests
       join ...
     where
      ...
      (supplierID == null || s.ID == supplierID) &&
      (supplierNotified == null || cr.SupplierNotified == supplierNotified)
      ...

Call:

ClosureRequestsAccessor.GetClosureRequests(null, null);

SQL:

SELECT 
  ...
FROM
  ...
WHERE
  ...
  AND (NULL IS NULL OR s.ID = NULL)
  AND (0 IS NULL OR cr.SupplierNotified = 0) /* <---- should be (NULL IS NULL OR cr.SupplierNotified = NULL) ? */

(I think you know the pattern used in the WHERE clause)

Am I missing something or is it a bug?

Enum mapping to char not working

Given the following enum:

public enum WorkflowRunStateType
{
    [MapValue('S')]
    InstanceData,

    [MapValue('M')]
    InstanceMetaData
}

The following query:

xxx.Where(x => x.Id == runId && x.Entry == WorkflowRunStateType.InstanceMetaData).First();

runs into a conversion exception:

public static Int32 ToInt32(String p) { return p == null? Configuration.NullableValues.Int32 : Int32.Parse(p);

The call stack is:

System.FormatException was unhandled by user code
Message=Input string was not in a correct format.
Source=mscorlib
StackTrace:
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at BLToolkit.Common.Convert.ToInt32(String p) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Common\Convert.generated.cs:line 1466
at BLToolkit.Common.Convert.ToInt32(Object p) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Common\Convert.generated.cs:line 1570
at BLToolkit.Mapping.MappingSchema.ConvertToInt32(Object value) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Mapping\MappingSchema.cs:line 218
at BLToolkit.Data.DataProvider.OdpDataProvider.OdpMappingSchema.ConvertToInt32(Object value) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DataProvider\OdpDataProvider.cs:line 694
at BLToolkit.Mapping.MappingSchema.ConvertChangeType(Object value, Type conversionType, Boolean isNullable) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Mapping\MappingSchema.cs:line 941
at BLToolkit.Mapping.MappingSchema.ConvertChangeType(Object value, Type conversionType) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Mapping\MappingSchema.cs:line 810
at BLToolkit.Data.DataProvider.OdpDataProvider.OdpMappingSchema.ConvertChangeType(Object value, Type conversionType) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\DataProvider\OdpDataProvider.cs:line 1119
at BLToolkit.Mapping.MemberMapper.MapFrom(Object value, MapMemberInfo mapInfo) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Mapping\MemberMapper.cs:line 716
at BLToolkit.Mapping.MemberMapper.MapFrom(Object value) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Mapping\MemberMapper.cs:line 657
at BLToolkit.Mapping.DefaultMemberMapper.SetValue(Object o, Object value) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Mapping\DefaultMemberMapper.cs:line 17
at BLToolkit.Mapping.ObjectMapper.SetValue(Object o, Int32 index, Object value) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Mapping\ObjectMapper.cs:line 653
at BLToolkit.Mapping.ValueMapping.DefaultValueMapper.Map(IMapDataSource source, Object sourceObject, Int32 sourceIndex, IMapDataDestination dest, Object destObject, Int32 destIndex) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Mapping\ValueMapping.cs:line 26
at BLToolkit.Data.Linq.Query1.MapDataReaderToObject(Type destObjectType, IDataContext dataContext, IDataReader dataReader, Int32 slotNumber) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Query.cs:line 530 at lambda_method(Closure , Query1 , QueryContext , IDataContext , IDataReader , MappingSchema , Expression , Object[] )
at BLToolkit.Data.Linq.Query1.<Map>d__3a.MoveNext() in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Query.cs:line 395 at System.Linq.Enumerable.First[TSource](IEnumerable1 source)
at BLToolkit.Data.Linq.Query1.<MakeElementOperator>b__4a(QueryContext ctx, IDataContextInfo db, Expression expr, Object[] ps) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\Query.cs:line 640 at BLToolkit.Data.Linq.Table1.System.Linq.IQueryProvider.Execute[TResult](Expression expression) in D:\Work\GloRi\trunk\vs\BlToolkit\Source\Data\Linq\TableT.cs:line 179
at System.Linq.Queryable.First[TSource](IQueryable1 source) at Rwe.Glori.Runtime.Workflow.Persistence.InstanceStoreIo.LoadInstance(Guid instanceId, IDictionary2& instanceData, IDictionary`2& instanceMetadata) in D:\Work\GloRi\trunk\vs\Rwe.Glori\Rwe.Glori.Runtime.Workflow\Persistence\InstanceStoreIo.cs:line 100
at Rwe.Glori.Runtime.Workflow.Persistence.WorkflowInstanceStore.SharedLoadWorkflow(InstancePersistenceContext context, Guid instanceId) in D:\Work\GloRi\trunk\vs\Rwe.Glori\Rwe.Glori.Runtime.Workflow\Persistence\WorkflowInstanceStore.cs:line 102
at Rwe.Glori.Runtime.Workflow.Persistence.WorkflowInstanceStore.ProcessLoadWorkflow(InstancePersistenceContext context, LoadWorkflowCommand command) in D:\Work\GloRi\trunk\vs\Rwe.Glori\Rwe.Glori.Runtime.Workflow\Persistence\WorkflowInstanceStore.cs:line 80
at Rwe.Glori.Runtime.Workflow.Persistence.WorkflowInstanceStore.TryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout) in D:\Work\GloRi\trunk\vs\Rwe.Glori\Rwe.Glori.Runtime.Workflow\Persistence\WorkflowInstanceStore.cs:line 53
at System.Runtime.DurableInstancing.InstancePersistenceContext.ExecuteAsyncResult.RunLoopCore(Boolean synchronous)
at System.Runtime.DurableInstancing.InstancePersistenceContext.ExecuteAsyncResult..ctor(InstanceHandle initialInstanceHandle, InstancePersistenceCommand command, Transaction transaction, TimeSpan timeout)
InnerException:

it seems that the MapValue attribute gets ignored and it tries to convert the "base numeric value" of the enum, instead of the char that should be replacing it.

Saving the mapped class before works, so this sees t obe an isolated issue in the query processing.

ObjectBinder SharpDeveloper bug

SharpDevelop Version : 4.1.0.7794-beta-b0b8c13c
.NET Version : 4.0.30319.1
OS Version : Microsoft Windows NT 5.1.2600 Service Pack 2
Current culture : Russian (Russia) (ru-RU)
Current UI language : en
Working Set Memory : 118876kb
GC Heap Memory : 33762kb

Unhandled WPF exception
Exception thrown:
System.TypeAccessException: Attempt by security transparent method 'BLToolkit.ComponentModel.Design.TypeEditor.GetEditStyle(System.ComponentModel.ITypeDescriptorContext)' to access security critical type 'System.ComponentModel.Design.Data.DataSourceProviderService' failed.

Assembly 'BLToolkit.4, Version=4.1.5.0, Culture=neutral, PublicKeyToken=b1d3f6ab3aadaca3' is marked with the AllowPartiallyTrustedCallersAttribute, and uses the level 2 security transparency model. Level 2 transparency causes all methods in AllowPartiallyTrustedCallers assemblies to become security transparent by default, which may be the cause of this exception.
at BLToolkit.ComponentModel.Design.TypeEditor.GetEditStyle(ITypeDescriptorContext context)
at System.Windows.Forms.PropertyGridInternal.GridEntry.get_Flags()
at System.Windows.Forms.PropertyGridInternal.PropertyDescriptorGridEntry.get_NeedsDropDownButton()
at System.Windows.Forms.PropertyGridInternal.PropertyGridView.SelectRow(Int32 row)
at System.Windows.Forms.PropertyGridInternal.PropertyGridView.SelectGridEntry(GridEntry gridEntry, Boolean fPageIn)
at System.Windows.Forms.PropertyGridInternal.PropertyGridView.Refresh(Boolean fullRefresh, Int32 rowStart, Int32 rowEnd)
at System.Windows.Forms.PropertyGridInternal.PropertyGridView.Refresh()
at System.Windows.Forms.PropertyGrid.Refresh(Boolean clearCached)
at System.Windows.Forms.PropertyGrid.set_SelectedObjects(Object[] value)
at ICSharpCode.SharpDevelop.Gui.PropertyPad.UpdateSelectedObjectIfActive(PropertyContainer container)
at ICSharpCode.FormsDesigner.FormsDesignerViewContent.UpdatePropertyPadSelection(ISelectionService selectionService)
at ICSharpCode.FormsDesigner.FormsDesignerViewContent.UpdatePropertyPad()
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

---- Recent log messages:
18:22:02.816 [1] DEBUG - TypeResolutionService: AssemblyResolveEventHandler: System.Design.resources, Version=4.0.0.0, Culture=en, PublicKeyToken=b03f5f7f11d50a3a
18:22:02.816 [1] DEBUG - Forms designer: Initializing nested service container of ДатаГрид [System.Windows.Forms.DataGridView] using Reflection
18:22:02.940 [1] DEBUG - Forms designer: Initializing nested service container of objectBinder1 [BLToolkit.ComponentModel.ObjectBinder] using Reflection
18:22:02.972 [1] DEBUG - Forms designer: DesignerLoader loaded, HasSucceeded=True
18:22:02.987 [1] DEBUG - FormsDesigner loaded, setting ActiveDesignSurface to System.ComponentModel.Design.DesignSurface
18:22:02.987 [1] DEBUG - IDEContainer: Connecting property grid to service provider
18:22:03.096 [1] DEBUG - TypeResolutionService: AssemblyResolveEventHandler: System.resources, Version=4.0.0.0, Culture=en, PublicKeyToken=b77a5c561934e089
18:22:03.096 [1] DEBUG - TypeResolutionService: AssemblyResolveEventHandler: System.resources, Version=4.0.0.0, Culture=en, PublicKeyToken=b77a5c561934e089
18:22:03.128 [1] INFO - Form Designer: END INITIALIZE
18:22:03.128 [1] DEBUG - FormsDesigner view content activated, setting ActiveDesignSurface to System.ComponentModel.Design.DesignSurface
18:22:03.128 [1] DEBUG - ActiveContentChanged to ICSharpCode.FormsDesigner.FormsDesignerViewContent
18:22:03.159 [1] DEBUG - ParseInformationUpdated C:\Documents and Settings\prog\Мои документы\Dropbox\Унф\Унф\Журналы\Организации.cs new!=null:True
18:22:03.596 [1] DEBUG - TypeResolutionService: AssemblyResolveEventHandler: System.Drawing.resources, Version=4.0.0.0, Culture=en, PublicKeyToken=b03f5f7f11d50a3a
18:22:03.596 [1] DEBUG - TypeResolutionService: AssemblyResolveEventHandler: System.Drawing.resources, Version=4.0.0.0, Culture=en, PublicKeyToken=b03f5f7f11d50a3a
18:22:05.032 [1] DEBUG - ActiveContentChanged to ICSharpCode.SharpDevelop.Gui.ToolsPad
18:22:06.920 [1] DEBUG - ActiveContentChanged to ICSharpCode.FormsDesigner.FormsDesignerViewContent
18:22:07.076 [1] DEBUG - Initializing MyToolBoxItem: BLToolkit.ComponentModel.ObjectBinder
18:22:07.108 [1] DEBUG - Initializing MyToolBoxItem: BLToolkit.ComponentModel.ObjectBinder
18:22:07.123 [1] WARN - TODO: Add Assembly reference : BLToolkit.4, Version=4.1.5.0, Culture=neutral, PublicKeyToken=b1d3f6ab3aadaca3
18:22:07.154 [1] DEBUG - Forms designer: Initializing nested service container of objectBinder2 [BLToolkit.ComponentModel.ObjectBinder] using Reflection
18:22:07.170 [1] DEBUG - Forms designer: ComponentChanged: objectBinder2 [BLToolkit.ComponentModel.ObjectBinder], Member=TrayLocation, OldValue={X=0,Y=0}, NewValue={X=138,Y=17}; Loading=False; Unloading=False
18:22:07.217 [1] DEBUG - Forms designer: Component added/removed/renamed, Loading=False, Unloading=False
18:22:07.217 [1] DEBUG - SelectedToolUsedHandler
18:22:07.217 [1] DEBUG - Checking for reference to CustomComponent: BLToolkit.ComponentModel.ObjectBinder
18:22:07.310 [1] DEBUG - SelectedToolUsedHandler

---- Post-error application state information:
Installed 3rd party AddIns:
Workbench.ActiveContent: ICSharpCode.FormsDesigner.FormsDesignerViewContent
ProjectService.OpenSolution: [Solution: FileName=C:\Documents and Settings\prog\Мои документы\Dropbox\Унф\Унф.sln, HasProjects=True, ReadOnly=False]
ProjectService.CurrentProject: [CSharpProject: Унф]

MapValue not working as expected on properties...

....of type Enumeration.

Given:

  • An Enumeration of financial instrument types, inherits from BYTE.
    Product = 2,
  • A property
    [MapField ()]
    [MapValue(InstrumentType.Product, "p")]
    public InstrumentType Type { get; set; }

Entry in the database: 2, not "p".

Explanation?

I want to map the type to specific values but NOT have MapVlue on the enumeration - which is defined in an assmbly that should not have any references to BlToolkit.

Am I wrong in my assumptions? How should I do that?

Oracle: Memory leak thanks to broken drivers.

Ok, i stumbled over this one recently and had a fix - maybe you want to implement it (we still us a very old version).

Your oracle driver uses a lot of OracleDecimal classes. Under specific circumstances those do not only leak memory thanks to oracle stupidity, they also STUCK YOUR FINALIZER THREAD. So no finalization will occur. This is related to them demanding a funny threading model within the finalizer of an internal reference used in OracleDecimal.

If you modify your use of OracleReader to use GetDecimal - not GetOracleDecimal - this issue is worked around.

This is documented in https://forums.oracle.com/forums/thread.jspa?threadID=361188 - referencing bug 4921932 which in the most current drivers nuder .NET 4.0 STILL exists. Caused a data pump from me to loose about a gigabyte... per 10 seconds.

Unless you map TO and FROM OracleDecimal in the mapped to classes, the loss of possible precision makes no difference (because at the end it ends up as Decimal anyway).

Linq error

Hi, when I run this Linq query

from sp in db.Taxes
join sp2 in
   (
       ( from subSP in db.Taxes
         where
           subSP.TaxTypeID == iTaxTypeID &&
           subSP.ChangeDate <= DateTime.Today
         group subSP by new
         {
             subSP.TaxTypeID
         } into g
         select new
         {
             TaxTypeID = g.Key.TaxTypeID,
             ChangeDate = g.Max( p => p.ChangeDate )
         } ) )
     on new { sp.TaxTypeID, sp.ChangeDate } equals new { sp2.TaxTypeID, sp2.ChangeDate }
select sp.Tax

I get the following error
base {System.SystemException} = {"Sequence contains no matching element"}

I have tried the very same code in Linq2SQL and it works with no problems.

Issue with Join not working in 4.1 (SelectContext.cs)

I run into a problem that I get NotImplementedException in SelectContext.cs thrown at line 938 because the case ExpressionType.Parameter :path does not "match".

The items in question are for the innerloop (levelExpression == Lambda.Parameters[i]:

? Lambda
{(x, y) => new <>f__AnonymousType205(trade = x.trade, insOption = x.insOption, header = x.header, pwrPhyParam = x.pwrPhyParam, instrument = y)} Body: {new <>f__AnonymousType205(trade = x.trade, insOption = x.insOption, header = x.header, pwrPhyParam = x.pwrPhyParam, instrument = y)}
CanReduce: false
DebugView: ".Lambda #Lambda1<System.Func3[<>f__AnonymousType1f4[Succub.Adapters.TrinionAdapters.Database.AbTran,Succub.Adapters.TrinionAdapters.Database.PwrPhyParam,Succub.Adapters.TrinionAdapters.Database.InsOption,Succub.Adapters.TrinionAdapters.Database.Header],System.Collections.Generic.IEnumerable1[Succub.Adapters.TrinionAdapters.Database.Instruments],<>f__AnonymousType205[Succub.Adapters.TrinionAdapters.Database.AbTran,Succub.Adapters.TrinionAdapters.Database.InsOption,Succub.Adapters.TrinionAdapters.Database.Header,Succub.Adapters.TrinionAdapters.Database.PwrPhyParam,System.Collections.Generic.IEnumerable1[Succub.Adapters.TrinionAdapters.Database.Instruments]]]>(\r\n <>f__AnonymousType1f4[Succub.Adapters.TrinionAdapters.Database.AbTran,Succub.Adapters.TrinionAdapters.Database.PwrPhyParam,Succub.Adapters.TrinionAdapters.Database.InsOption,Succub.Adapters.TrinionAdapters.Database.Header] $x,\r\n System.Collections.Generic.IEnumerable1[Succub.Adapters.TrinionAdapters.Databas e.Instruments] $y) {\r\n .New <>f__AnonymousType205[Succub.Adapters.TrinionAdapters.Database.AbTran,Succub.Adapters.TrinionAdapters.Database.InsOption,Succub.Adapters.TrinionAdapters.Database.Header,Succub.Adapters.TrinionAdapters.Database.PwrPhyParam,System.Collections.Generic.IEnumerable1[Succub.Adapters.TrinionAdapters.Database.Instruments]](\r\n $x.trade,\r\n $x.insOption,\r\n $x.header,\r\n $x.pwrPhyParam,\r\n $y)\r\n}" Name: null NodeType: Lambda Parameters: Count = 2 ReturnType: {Name = "<>f__AnonymousType205" FullName = "<>f__AnonymousType205[[Succub.Adapters.TrinionAdapters.Database.AbTran, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Succub.Adapters.TrinionAdapters.Database.InsOption, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Succub.Adapters.TrinionAdapters.Database.Header, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Succub.Adapters.TrinionAdapters.Database.PwrPhyParam, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Collections.Generic.IEnumerable1[[Succub.Adapters.TrinionAdapters.Database.Instruments, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}
TailCall: false
Type: {Name = "Func3" FullName = "System.Func3[[<>f__AnonymousType1f4[[Succub.Adapters.TrinionAdapters.Database.AbTran, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Succub.Adapters.TrinionAdapters.Database.PwrPhyParam, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Succub.Adapters.TrinionAdapters.Database.InsOption, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Succub.Adapters.TrinionAdapters.Database.Header, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Collections.Generic.IEnumerable1[[Succub.Adapters.TrinionAdapters.Database.Instruments, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[<>f__AnonymousType205 [[Succub.Adapters.TrinionAdapters.Database.AbTran, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Succub.Adapters.TrinionAdapters.Database.InsOption, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Succub.Adapters.TrinionAdapters.Database.Header, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Succub.Adapters.TrinionAdapters.Database.PwrPhyParam, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Collections.Generic.IEnumerable1[[Succub.Adapters.TrinionAdapters.Database.Instruments, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}
? levelExpression
{x}
CanReduce: false
DebugView: "$x"
IsByRef: false
Name: "x"
NodeType: Parameter
Type: {Name = "<>f__AnonymousType205" FullName = "<>f__AnonymousType205[[Succub.Adapters.TrinionAdapters.Database.AbTran, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Succub.Adapters.TrinionAdapters.Database.InsOption, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Succub.Adapters.TrinionAdapters.Database.Header, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Succub.Adapters.TrinionAdapters.Database.PwrPhyParam, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Collections.Generic.IEnumerable`1[[Succub.Adapters.TrinionAdapters.Database.Instruments, Succub.Adapters.TrinionAdapters, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}

The query in question is complicated.query comsisting of 5 GroupJoin statements and the ne that supposedly blows up is the third. The statement worked perfectly with 4.0 and the old LINQ parser.

The comparison shows that both x are different types - this may come frmo our naming standard to use (x,y) on pretty much all joins.

The statement in question is:

        DataManager.Get<AbTran>()
            .GroupJoin(
                DataManager.Get<InsOption>(),
                x => new {Id = x.InsNum},
                y => new {Id = y.InsNum},
                (trade, insOption) => new {trade, insOption}
            )
            .SelectMany(
                y => y.insOption.DefaultIfEmpty(),
                (x, y) => new {trade = x.trade, insOption = y}
            )
            .GroupJoin(
                DataManager.Get<Header>(),
                x => new {Id = x.trade.InsNum},
                y => new {Id = y.InsNum},
                (x, y) => new {trade = x.trade, insOption = x.insOption, header = y}
            )
            .SelectMany(a => a.header.DefaultIfEmpty(),
                        (x, a) => new {trade = x.trade, insOption = x.insOption, header = a}
            )
            .GroupJoin(
                DataManager.Get<PwrPhyParam>(),
                x => new {Id = x.trade.InsNum},
                y => new {Id = y.InsNum},
                (x, y) => new {trade = x.trade, insOption = x.insOption, header = x.header, pwrPhyParam = y}
            )
            .SelectMany(z => z.pwrPhyParam.DefaultIfEmpty(),
                        (x, z) => new {trade = x.trade, pwrPhyParam = z, insOption = x.insOption, header = x.header}
            )
            .GroupJoin(
                DataManager.Get<Instruments>(),
                x => new {Id = x.trade.InsType},
                y => new {Id = y.IdNumber},
                (x, y) =>
                new
                    {
                        trade = x.trade,
                        insOption = x.insOption,
                        header = x.header,
                        pwrPhyParam = x.pwrPhyParam,
                        instrument = y
                    }
            )
            .SelectMany(z => z.instrument.DefaultIfEmpty(),
                        (x, z) =>
                        new
                            {
                                trade = x.trade,
                                instrument = z,
                                insOption = x.insOption,
                                header = x.header,
                                pwrPhyParam = x.pwrPhyParam
                            }
            )
            .GroupJoin(
                DataManager.Get<PhysHeader>(),
                x => new {Id = x.trade.InsNum},
                y => new {Id = y.InsNum},
                (x, y) =>
                new
                    {
                        trade = x.trade,
                        instrument = x.instrument,
                        insOption = x.insOption,
                        header = x.header,
                        pwrPhyParam = x.pwrPhyParam,
                        physHeader = y
                    }
            )
            .SelectMany(a => a.physHeader.DefaultIfEmpty(),
                        (x, a) =>
                        new
                            {
                                trade = x.trade,
                                instrument = x.instrument,
                                insOption = x.insOption,
                                header = x.header,
                                pwrPhyParam = x.pwrPhyParam,
                                physHeader = a
                            }
            )

            .Where(x =>
                   x.trade.DealTrackingNum == request.DealId
                   && x.trade.TranNum == request.TransactionId
            )
            .FirstOrDefault();

Minor? bug in generating GROUP BY clause

The following linq query

var q =
    from
        ss in db.SupplierStock
            join m in db.Manufacturers
                on ss.ManufacturerID equals m.ID
            join s in db.Suppliers
                on ss.SupplierID equals s.ID
    where
        ss.IsDeleted == false && Sql.DateDiff(Sql.DateParts.Day, ss.TS, Sql.CurrentTimestamp) > 31
    orderby
        ss.TS
    group ss by
        new { ss.ManufacturerID, ss.SupplierID, ManufacturerName = m.Name, SupplierName = s.Name }
        into g
    select
            new { SupplierName = g.Key.SupplierName, ManufacturerName = g.Key.ManufacturerName, TS = g.Max(ss => ss.TS) };

generates the following sql:

SELECT
    s.Name,
    m.ShortName as Name1,
    Max(ss.TS) as c1
FROM
    supplier_stock ss
        INNER JOIN manufacturers m ON ss.ManufacturerID = m.ID
        INNER JOIN suppliers s ON ss.SupplierID = s.ID
WHERE
    ss.IsDeleted = 0 AND TIMESTAMPDIFF(Day, ss.TS, CURRENT_TIMESTAMP) > 31
GROUP BY
    ss.ManufacturerID,
    ss.SupplierID,
    m.ShortName,
    s.Name,
    s.Name /* <-------------------------------------- EXTRA FIELD */
ORDER BY
    ss.TS

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.