DapperLib / Dapper

Dapper - a simple object mapper for .Net
https://www.learndapper.com/
Other
17.47k stars 3.67k forks source link

Dapper Contrib, please remove annoying plural table naming #655

Closed ghost closed 7 years ago

ghost commented 7 years ago

My table name is "settings", not "settingss" with two"ss". Of course I can use data annotation, and rename my table to "settings" but it makes no sense what so ever... and only adds extra overhead uneless someone somehow maps up the entire english dictionary :P

NickCraver commented 7 years ago

I very much disagree here. A row on the table is a "Setting" (what you'd generally call your C# class), the collection is called "Settings". For example if I have a table of jobs, a row and the POCO are a Job, the table is Jobs. In code I wouldn't call a single thing "Jobs", I'd call it a "Job". This is true for most projects and people, and hence it's Dapper's default behavior.

To change this would be massively breaking (and a net loss for everyone using it today - the direction is only a breaking one). By that I mean, it could help no one using this library today - it can only make people without attributes fail unexpectedly.

The data annotations are there for use cases where people don't wish to follow conventions, so that option is still available to you.

ghost commented 7 years ago

Shure I get you point. But then what should I call my military class, perhaps militarie...

NickCraver commented 7 years ago
[Table("Militaries")]
public class Military
{
   // Properties
}
BrettRossier commented 6 years ago

That reasoning doesn't work...

ActivityLog -> ActivityLogs?? (Log is already plural) Military -> Militaries (Military can be plural by itself if it's referring to a group of members, not armies of different nation-states, which is the only thing Militaries can refer to.)

Arguing about this is a bit absurd, why can't we just have an option to skip the wacky pluralization rules??

joelmandell commented 6 years ago

Yeah and sometimes you don't even have control over the database design

BrettRossier commented 6 years ago

Exactly. Using the Military example + having no control of schema, how do I know ahead of time what kind of pluralization is going to be applied? I either have to guess, or worse, get an unexpected exception that tells me what pluralization was actually applied (an issue I'm currently facing).

NickCraver commented 6 years ago

Please see #722 for discussions on V2 where we plan to make this much more flexible than it is today.

naokmoon commented 5 years ago

That tool should have a configuration to allow user to put "True" or "False" for plural convention (as the entity framework does), because I always worked with Singular convention for both POCO and SQL Table names for the companies I was in.

It could be a simple section in the Web.config / App.config or a new .config file to set configurations for every ConnectionStringName

Its true that plural convention makes sense when u read "Select id,name from users" since there is many users inside the table. But we are not naming table, but naming an entity.

this query make more sens in singular :

SELECT id, name FROM user JOIN country ON user.country_id = country.id WHERE country.name = 'Canada';

That would make less sense if the ON clause read users.country_id. I invite you to read this : https://www.teamten.com/lawrence/programming/use-singular-nouns-for-database-table-names.html

ebleme commented 5 years ago

I preferred Dapper to Ado.Net because Dapper gives me more freedom. But this "s" suffix caused me to question Dapper.

Also I am not an English speaker and generating Tables and clasesses with Turkish Language. You can not make a global assumption about naming conventions.

LukePoga commented 4 years ago

wow has this been fixed? i was looking for a new tool and this is an insane limitation. a simple true/false setting on plurals would cover 99% of database people. most companies i know use singular names! what a crazy decision.

LukePoga commented 4 years ago

thank god it has been fixed:

Dapper.Contrib supports the Table attribute. Use it to manually specify the name of the table that an entity uses. See the docs for further information.

Alternatively there is a static delegate on SqlMapperExtensions called TableNameMapper. You can replace this with an implementation that performs the pluralization. PluralizationService in the framework can help you here.

It is used as follows:

SqlMapperExtensions.TableNameMapper = (type) => { // do something here to pluralize the name of the type return type.Name; };

softgandhi commented 3 years ago

I believe dapper core itself should provide a static or instance configuration to set if we want to use all Singular for table name. something like:

SqlMapperExtensions.TableNameMapper = (type) => {
// do something here to pluralize the name of the type
return type.Name;
};

Plurals are always confusing and failures in automations. some of the instances are: for class Person -> it makes Persons but it should be People for class Status -> it makes Statuss but I don't know what the hell it's plural is for class Brass -> it makes Brasss but it should be Brasses.

Its incorrect, breaks in automation/custom scaffolding, and mostly confusing, specially for non native English developers.

softgandhi commented 3 years ago

I very much disagree here. A row on the table is a "Setting" (what you'd generally call your C# class), the collection is called "Settings". For example if I have a table of jobs, a row and the POCO are a Job, the table is Jobs. In code I wouldn't call a single thing "Jobs", I'd call it a "Job". This is true for most projects and people, and hence it's Dapper's default behavior.

To change this would be massively breaking (and a net loss for everyone using it today - the direction is only a breaking one). By that I mean, it could help no one using this library today - it can only make people without attributes fail unexpectedly.

The data annotations are there for use cases where people don't wish to follow conventions, so that option is still available to you.

I understand its a breaking change, but I believe a Global level or static properties can be set via extension methods which sets the flag to use Singular.

something like:

IDbConnection conn;
conn.UseSingular(true);

It would be great to see if dapper supports singular natively in next version. Thank you very much for making such a great tool. I love dapper.

andrericardo commented 3 years ago

The pluralization also breaks for tables such as RateIndex becomes RateIndexs. I would prefer not to add [Table] to my entities when following a Clean Architecture where my entities are pure POCOs, adding the annotations would mean adding Dapper Contrib package to CleanArchitecture.Core. Example https://github.com/ardalis/CleanArchitecture/blob/master/src/CleanArchitecture.Core/Entities/ToDoItem.cs, this solution uses EF but in the Core project does not reference EF, only in Infrastructure. If using Dapper Contrib would need to add the Dapper Contrib package to it in order to map tables that do not pluralize nicely. So any option that avoids adding Dapper Contrib to my Core project I'll prefer it. My solution was to add in the constructor of my Repository the code above from @LukePoga to replace SqlMapperExtensions.TableNameMapper.

maccurt commented 3 years ago

I can't believe this was ever the default...

rafajrcarvalho commented 1 year ago

You can set: SqlMapperExtensions.TableNameMapper = (type) => $"[{type.Name}]"; To remove pluralization and automatically add brackets on the table names (to avoid 'User' Keyword, for example.)

kirkebarrett commented 1 year ago

I'd sure love a dapper.contrib method to clear this:

private static readonly ConcurrentDictionary<RuntimeTypeHandle, string> TypeTableName = new ConcurrentDictionary<RuntimeTypeHandle, string>();

then we can change the table mappings to other tablenames/dbs in same session.

Once the Table Mapper Delegate is set, it goes into the dictionary above, and that is checked in GetTableName() before the delegate is invoked again, with no way i can find to clear that dict.

giammin commented 1 year ago

sorry but i don't get all of this...

why ask for complex and convoluted configurations that lead also to breaking changes

there is an attribute for it... just use it

kirkebarrett commented 1 year ago

sorry but i don't get all of this...

why ask for complex and convoluted configurations that lead also to breaking changes

there is an attribute for it... just use it

If you don't "get it" then just shake your head and move on, perhaps, vs being a snark, sir. Clearly we all know to use the tag. Clearly, us other devs have a use case. Most likely, that is trying to use same class against different tables names with same fields. There's a point, that's why we come here, not to be smacked. We all love that we can change the initial type to name table in code, but the issue is doing so again. Once the tablename is in the dictionary, it can't be cleared or reset. So, nothing breaking, just a new method to clear the TypeTableName dictionary. Even cleared, it would, as the code shows, reload the tablenames in downstream use. The answer is to use Query(), but not having to write SQL for the object is the advantage of the Get/GetAll.