[Improvement] Better support of custom member mappers in linq queries #243

Open
MaceWindu opened this Issue Jun 28, 2013 · 7 comments

Comments

Projects
None yet
3 participants
@MaceWindu
Contributor

MaceWindu commented Jun 28, 2013

Recently I've added a lot of improvements to enum mapping in queries when mapping attributes specified on entity or entity fields. We still have issues here, but I think it's much better now.
Situation with member mappers is almost the same - they are usable only in very simple use-cases.
We should have better support for member mappers:

  1. Create tests (e.g. take tests from EnumMapping.cs and write similar tests using TimeSpanBigIntMapper member mapper)
  2. Fix failing tests
@igor-tkachev

This comment has been minimized.

Show comment
Hide comment
@igor-tkachev

igor-tkachev Jul 17, 2013

Owner

All these issues are solved in linq2db. Maybe it's better to switch to it?

Owner

igor-tkachev commented Jul 17, 2013

All these issues are solved in linq2db. Maybe it's better to switch to it?

@jogibear9988

This comment has been minimized.

Show comment
Hide comment
@jogibear9988

jogibear9988 Jul 19, 2013

@igor-tkachev:

Only for Information! Can you tell me whats the difference of your two Projects is (linq2db and bltoolkit)? Which one is Prefered to use? And has Linq2DB all the features of BLToolKit? Or wich one is Faster, wich one better designed?

@igor-tkachev:

Only for Information! Can you tell me whats the difference of your two Projects is (linq2db and bltoolkit)? Which one is Prefered to use? And has Linq2DB all the features of BLToolKit? Or wich one is Faster, wich one better designed?

@igor-tkachev

This comment has been minimized.

Show comment
Hide comment
@igor-tkachev

igor-tkachev Jul 19, 2013

Owner

LinqToDB is a replacement of BLToolkit within the scope of Linq and database support.

Most of the components are completely redesigned (data connection, data providers, mapping, metadata reader, etc).

New services have been and will be added. Schema provider has been implemented, so you can discover your database structure in a general way. This service is a basis of data model generator (see https://github.com/linq2db/t4models/tree/master/Tests/LinqToDB).

In addition, I am going to add a DDL service, improve Linq support, and support for new databases.

Actually, BLToolkit is 8 years old and now its design is exhausted. You see how much efforts we made to improve enum mapping. LinqToDB does not have this issue by default.

Performance is improved as well and now The Dapper is not the absolute performance leader :)

Owner

igor-tkachev commented Jul 19, 2013

LinqToDB is a replacement of BLToolkit within the scope of Linq and database support.

Most of the components are completely redesigned (data connection, data providers, mapping, metadata reader, etc).

New services have been and will be added. Schema provider has been implemented, so you can discover your database structure in a general way. This service is a basis of data model generator (see https://github.com/linq2db/t4models/tree/master/Tests/LinqToDB).

In addition, I am going to add a DDL service, improve Linq support, and support for new databases.

Actually, BLToolkit is 8 years old and now its design is exhausted. You see how much efforts we made to improve enum mapping. LinqToDB does not have this issue by default.

Performance is improved as well and now The Dapper is not the absolute performance leader :)

@jogibear9988

This comment has been minimized.

Show comment
Hide comment
@jogibear9988

jogibear9988 Jul 19, 2013

Ok, thanks for the Information! So I'll think maybe we also switch to Linq2DB, if all features we use from BLToolkit are there (we don't need to hurry, it's working at the Moment!) But as we only use DB Access of BLToolKit, I think it's not a Big Task.
Does Linq2DB already also support MemberMappers like the ones we created in BLToolkit (XMLSerialisationMapper, TimespanBigIntMapper, etc?). And I see you added support for FluentConfiguration yesterday.

Ok, thanks for the Information! So I'll think maybe we also switch to Linq2DB, if all features we use from BLToolkit are there (we don't need to hurry, it's working at the Moment!) But as we only use DB Access of BLToolKit, I think it's not a Big Task.
Does Linq2DB already also support MemberMappers like the ones we created in BLToolkit (XMLSerialisationMapper, TimespanBigIntMapper, etc?). And I see you added support for FluentConfiguration yesterday.

@igor-tkachev

This comment has been minimized.

Show comment
Hide comment
@igor-tkachev

igor-tkachev Jul 19, 2013

Owner

I do not think you need MemberMapper any more. Your can easily create mapping in the following way:

mappingSchema.SetConverter<MyType,byte[]>(value => ConvertMyTypeToByteArray(value));
mappingSchema.SetConverter<byte[],MyType>(value => ConvertByteArrayToMyType(value));

FluentMappingBuilder is different from what you implemented in BLToolkit. It's based on metadata reader and you can add any info as an attribute to a type or a type member.

Owner

igor-tkachev commented Jul 19, 2013

I do not think you need MemberMapper any more. Your can easily create mapping in the following way:

mappingSchema.SetConverter<MyType,byte[]>(value => ConvertMyTypeToByteArray(value));
mappingSchema.SetConverter<byte[],MyType>(value => ConvertByteArrayToMyType(value));

FluentMappingBuilder is different from what you implemented in BLToolkit. It's based on metadata reader and you can add any info as an attribute to a type or a type member.

@jogibear9988

This comment has been minimized.

Show comment
Hide comment
@jogibear9988

jogibear9988 Jul 19, 2013

Ah OK,

But with this it looks like I could specify TypeConverter only at base of a
Type, not at base of a Property, so that means every same Type is useing the
same Converter! We have Places where we use a List and Convert it
sometimes to XML, and sometimes to CSV via the MemberMapper. Is this still
possible at any way?

(And sorry for dumping this Issue!)

Ah OK,

But with this it looks like I could specify TypeConverter only at base of a
Type, not at base of a Property, so that means every same Type is useing the
same Converter! We have Places where we use a List and Convert it
sometimes to XML, and sometimes to CSV via the MemberMapper. Is this still
possible at any way?

(And sorry for dumping this Issue!)

@igor-tkachev

This comment has been minimized.

Show comment
Hide comment
@igor-tkachev

igor-tkachev Jul 19, 2013

Owner

From my experience, this is a bad practice. For example, you have a class Table1 with a Column1 of uint type and you map it to binary. Then you have Table2 with a Column2 of uint type but you map it to time range. You can write the following code:

from t1 in Table1
from t2 in Table2
where t1.Column1 == t2.Column2 && t1.Column1 + 1 < 54 && t2.Column2 > 42

This is correct C# code, but what should be generated? The most significant feature of Linq to SQL is that we have type-safe SQL, but using this practice, you bring some ambiguity in your data model and break the whole idea. As a result it creates more problems than it solves.

There are at least two ways to avoid this.

  1. You can add an additional property. In our example, Table1 will have now two properties: Column1 of binary type and Column1AsUInt of uint type where Column1AsUInt is not a database field with conversion logic inside. Same for Table2.
  2. Create new types: struct BinaryAsUInt { public uint Value; } and struct TimeRangeAsUInt { public uint Value; } and add the conversion logic into mapping schema.

I prefer the second one. It is clear, easy to see, and straightforward.

Owner

igor-tkachev commented Jul 19, 2013

From my experience, this is a bad practice. For example, you have a class Table1 with a Column1 of uint type and you map it to binary. Then you have Table2 with a Column2 of uint type but you map it to time range. You can write the following code:

from t1 in Table1
from t2 in Table2
where t1.Column1 == t2.Column2 && t1.Column1 + 1 < 54 && t2.Column2 > 42

This is correct C# code, but what should be generated? The most significant feature of Linq to SQL is that we have type-safe SQL, but using this practice, you bring some ambiguity in your data model and break the whole idea. As a result it creates more problems than it solves.

There are at least two ways to avoid this.

  1. You can add an additional property. In our example, Table1 will have now two properties: Column1 of binary type and Column1AsUInt of uint type where Column1AsUInt is not a database field with conversion logic inside. Same for Table2.
  2. Create new types: struct BinaryAsUInt { public uint Value; } and struct TimeRangeAsUInt { public uint Value; } and add the conversion logic into mapping schema.

I prefer the second one. It is clear, easy to see, and straightforward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment