GithubHelp home page GithubHelp logo

tmsmith / dapper-extensions Goto Github PK

View Code? Open in Web Editor NEW
1.8K 1.8K 587.0 26.37 MB

Dapper Extensions is a small library that complements Dapper by adding basic CRUD operations (Get, Insert, Update, Delete) for your POCOs. For more advanced querying scenarios, Dapper Extensions provides a predicate system. The goal of this library is to keep your POCOs pure by not requiring any attributes or base class inheritance.

C# 99.19% Batchfile 0.01% PLSQL 0.31% PowerShell 0.44% TSQL 0.05%

dapper-extensions's People

Contributors

balchen avatar danielcrenna avatar davecowart avatar dependabot[bot] avatar essentialnrg avatar fvoronin avatar grofit avatar hfrances avatar jafin avatar jbat1jumper avatar jnpwly avatar joergbattermann avatar kenwarner avatar leapinggorilla avatar lenerson avatar ltines avatar lyphtec avatar markinux avatar mgolus avatar mlaritz avatar mrb0nj avatar pagebrooks avatar pippolino avatar rikard-acst avatar ripvannwinkler avatar rlreis90 avatar rpaschoal avatar steveschoon avatar tmsmith avatar valfrid-ly avatar

Stargazers

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

dapper-extensions's Issues

Another question regarding modifying the Insert routine to handle Sql tables with non-identity ID fields

Thank you for the input - two additional questions:

The AutoMap(CanMap) call above requires passing a type and a propertyinfo reference. The type is obviously "T", but where do I get propertyinfo from?

AutoMap(CanMap(typeof(T), ???));

Your current Insert method as shown below does not include a parameter to specify the mapper to be used. How do I implement the Insert processing using the new mapper?

public static void Insert(this IDbConnection connection, IEnumerable entities, IDbTransaction transaction = null, int? commandTimeout = null) where T : class;

Get<T>(..) in IDatabase and Database

I'm trying to understand how to best use transactions and I have noticed that while the IDatabase interface and others have the Get method with only one required parameter, dynamic id.

However the implementation of Database removes the default null from commandTimeout.

Any clarification on this is appreciated.

Private to Protected member?

In public class ClassMapper, shouldn't _propertyTypeKeyTypeMapping be protected instead of private so extended classes can access it specifically when overriding the AutoMap method?

Also, slightly OT, would you be open to a postgresql dialect pr?

Add Between Predicate

For now, do the simple scenario where the two values are supplied by the consumer. If the user needs to be between two values in the database, they can perform a separate query.

Expression<Func<T, bool>> support

Out of pure curiosity would this even be possible? considering the fact you can easily convert Expressions to predicates. this would allow for decent query support given:

IEnumerable users = DbConnection.GetList(user => user.Name == "NameHere" && user.IsAuthenticated);

would be the equiv to your:

var pg = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List() };
pg.Predicates.Add(Predicates.Field(f => f.Name, Operator.Eq, "NameHere"));
pg.Predicates.Add(Predicates.Field(f => f.IsAuthenticated, Operator.Eq, true));
IEnumerable list = cn.GetList(pg);

Modifying the Insert routine to handle Sql tables with non-identity ID fields

We have an application where the ID values for some of the tables come from a sequence/id-generator source rather than using the SqlServer identity facility.

How would I modify your project to support this? (i.e., have the Insert routine ignore the presence of a field named "id" and use it like any other field)

Dapper Testability

To help with testability add a method to DapperExtensions to fire Dapper methods. This method should allow testing of dapper calls without going dapper.

ex. _connection.Dapper().Execute();

Multithreaded insert on SqlServer returns incorrect identity value

Insert method uses SELECT IDENT_CURRENT to return the identity value of a newly inserted row.
If two threads (or two processes) performs inserts in quick succession, the latter identity value can be returned for both calls to insert. This is bad.

Something more reliable like SCOPE_IDENTITY() as part of the generated "Insert Into" SQL statement could be used instead.

Detect Nullable Types for Identity Columns

In the ClassMapper.AutoMap method please consider added support for nullable types int and Guid:

if (map.PropertyInfo.PropertyType == typeof(int) || map.PropertyInfo.PropertyType == typeof(int?))
{
    map.Key(KeyType.Identity);
}
else if (map.PropertyInfo.PropertyType == typeof(Guid) || map.PropertyInfo.PropertyType == typeof(Guid?))
{
    map.Key(KeyType.Guid);
}
//...

Add Exists Predicate

Add an exists predicate that will allow you to determine if a value exists in another table.

SELECT * FROM Table1 WHERE EXISTS (SELECT 1 FROM Table2 WHERE Table1.Column = Table2.Column)

Insert performance considerations

Hi!

I've tried to insert an entity using conn.Insert(entity) method like

var user = new User { Name = "Test", GroupId = 1 };
conn.Insert(user, tran);

and found that performance of this operation is almost equal to EF4.2.

It would be great to improve this. Simple dapper query with explicit SQL text is 3 times faster than EF. Code is
conn.Execute("INSERT [Users](Name, GroupId) VALUES (@name, @groupId)", user, tran);

Thank you.

Multiple Guids in a Row

Could anyone explain why DE assumes that when I request with conn.Get(id); that i want not the ID field but ParentID field to be treated as primary key?

I hope thats clear. But in further detail:

I have a row with both ID(Guid) and ParentID(Guid), when running generic get, DE skips over ID and uses ParentID as a row key to get it by...

Intentional?

GET<T> method Can not support muti fields query without Key field

code like this:
TB_User_Info{
[Key]
public int PK_ID,
public string sLoginID,
public string sPsw}

DapperExtensions.DapperExtensions.Get<TB_User_Info>(cnn, new {sLoginID=sloginID, sPsw=spsw });

will throw an exception :specified key not in the dictionary ,

in dapperextension.cs line:278

DynamicParameters parameters = new DynamicParameters();
var keys = classMap.Properties.Where(p => p.KeyType != KeyType.NotAKey);
foreach (var key in keys)
{
object value = id;
if (!isSimpleType)
{
value = paramValues[key.Name];//throw exception here
}

                parameters.Add("@" + key.Name, value);
            }

the sql code is
string sql = _sqlGenerator.Get(classMap);
[
SELECT TB_User_Info.PK_ID, TB_User_Info.sName, TB_User_Info.sLoginID, TB_User_Info.sPsw, TB_User_Info.sUid, TB_User_Info.iSex, TB_User_Info.iSta, TB_User_Info.dCreateTime FROM TB_User_Info WHERE TB_User_Info.PK_ID = @PK_ID
]
I think PK_ID=@PK_ID is a bug, it would make the Get method can not support nokey field query, it just a primary key query only method ,
like this:
DapperExtensions.DapperExtensions.Get<TB_User_Info>(cnn, new { PK_ID=1, sLoginID=sloginID, sPsw=spsw });

this code will be okay,but useless

I use mysql db,.net4.0
forgive me for the odd english!

Update<T> method fails using ClassMapper

I found a bug into "DapperImplementor.cs" - code line 130

foreach (var property in ReflectionHelper.GetObjectValues(entity).Where(property => columns.Any(c => c.ColumnName == property.Key)))

Using ClassMapper you need to replace the previous code with the following:

foreach (var property in ReflectionHelper.GetObjectValues(entity).Where(property => columns.Any(c => c.Name == property.Key)))

oracle support

does this support oracle? it seems GetList doesn't support oracle

SQL insert with Guid or Assigned KeyType

Hi,

I'm using Guid primary keys and have created my own ClassMapper returning PropertyMaps to use the DataAnnotation classes to find KeyAttributes, ColumnAttributes etc.

This has all gone fine but the insert statements aren't ideal.

If I configure the PK to be KeyType.Guid or KeyType.Assigned then they get correctly used in the where clause of the update statement and included in the insert statement BUT they are also included in the updates SET part - as only a single parameter is passed this isn't correct (as an asside it's also not performant on Oracle databases as it'll cause FK scans on any related tables)

If I set the column map to return the field as read-only then it doesn't get included in the insert statement but is correctly included only on the WHERE part of the UPDATE.

Example SQL

INSERT INTO [table]([id], [value]) VALUES ( @id, @value ) = GOOD
UPDATE [table] SET [id] = @id, [value] = @value WHERE [id] = @id = BAD
UPDATE [table] SET [value] = @value WHERE [id] = @id = CORRECTED update statement

Personally I would say that the column should be marked as readonly (in fact it's writeonly) and if this is the case then a change is ideally needed in SqlGenerator's Insert method by always including columns that are KeyType.Guid or KeyType.Assigned in the following line.

var columns = classMap.Properties.Where(p => !(p.Ignored || p.IsReadOnly || p.KeyType == KeyType.Identity));

becomes

var columns = classMap.Properties.Where(p => !(p.Ignored || (p.IsReadOnly && p.KeyType == KeyType.NotAKey) || p.KeyType == KeyType.Identity));

cheers,

g

PS Any chance of providing a public property to allow setting of the _sqlGenerator field?

Type conversions

Hi,
I'm not sure it this is the right place to ask this question, but here goes nothing!

I'm using an MSSQL db for my application, but running some tests with Sqlite in memory mode, and using your GetList extension to load a mapped class.

I'm running into a problem whereby by Id columns are ints in MSSQL, but querying these in Sqlite makes them come back as Int64, and then I get a cast exception within the internals of dapper.

I tried implicit casting with a custom ID type as per http://code.google.com/p/dapper-dot-net/issues/detail?id=44, but this is still an issue.

Is there anything in the classmapper than would allow me to force the implicit conversion of the int64 to a long?

Many thanks,
Chris

Update only select columns...

How do I specify columns as Insert and ReadOnly? For example, a table has a CreateDate that is required when inserting, but I don't necessarily want to update this column on update calls. Is there a way to specify such a property in the custom class mapping?

Testability

Move actual implementation of DapperExtensions into a class.
Instantiate this class in the DapperExtensions class with a settable factory

Insert fails

Insert fails because it includes tablename something that isnt supported at all databases. Any solution for this ?

Id only mapped to int (fails with bigint)

In function AutoMap(), 'Id' is set to identity 'only' if its type is int. I tested my tables with bigint (just in case), and discovered that the identity flag doesn't get set. Instead, the property is set to assigned, which causes an insert into the DB to fail because 'Id' is also passed along in the query. Insert(..., T Entity) is also casting the 'Id' to int.

-Great extension otherwise. It worked without glitches until I tried this. I reverted back to int, but thought you might want to know. Thanks!

Related objects. Insert error

Hi! Your extensions are awesome. I've found an issue. If class to be inserted has related object as property (e.g. class User having relational property of type Group), then insert query fails, because it tries to insert Group as parameter. Thanks.

Parameter naming convention is different on Inserts vs Selects

When performing a SELECT, the parameter convention is @ParamNamep0. When performing an INSERT, the parameter convention is @ParamName. Shouldn't these be consistent? See Line 164 on Predicates.cs for an example. As far as I can tell, this problem does not exist for UPDATES and DELETES.

Example classmapper to ignore child collections

I have a POCO that has a child collection, that does not map to a database table. I don't want to insert these child collections automatically, but I cannot find a way to turn this "deep save" functionality off. I was looking for an Ignore attribute or something similar but I couldn't find one. The only other way I could see to do this was through the use of a custom mapper.

My custom mapper is simply doing this:

Type type = typeof(T);
bool keyFound = Properties.Any(p => p.KeyType != KeyType.NotAKey);
foreach (var propertyInfo in type.GetProperties())
{
// Ignore IEnumerable types, as we are using these as entity references
if (propertyInfo.PropertyType.Name == "IEnumerable`1")
{
continue;
}

  ....

}

This seems pretty fugly. Is this the right way forward?

Ben

Add Property Predicate

Add a property predicate that will allow you to compare two columns.

SELECT * FROM TableName WHERE Column1 >= Column2

Operator Like not implemented

It does not seem like there is an implementation for the usage of the Like operator,

Inside of

FieldPredicate GetOperatorString()

I needed to add

case Operator.Like:
return Not ? "NOT LIKE" : "LIKE";

Primary Key not set after Insert

When an entity has a GUID key type, the new Id is generated and set on the entity during the Insert operation. When an entity has an Identity key type, the new id is returned by the insert operation, but it is not set on the entity. Shouldn't this work the same way as the GUID key type?

DE Replacing Guid value on insert.

I have a row with ID and ParentID - both of which are Guid.
On insert, DE generates a comb key for already assigned ParentID (overriding value that should not be overridden).

For my own purposes I added a check for Guid.Empty. This way the value is only assigned when its an empty guid.

Line 306 in DapperExtensions.cs
if (column.KeyType == KeyType.Guid && (Guid)column.PropertyInfo.GetValue(e, null) == Guid.Empty)

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.