MongoDB custom Query in Spring Data Mongo - spring-data-mongodb

Someone can help me make a Query(Mongo), with new in Mongodb type(example):
#Override
public Long maxCodigoSecuencia() {
final Query query = new Query().limit(1).with(new Sort(Sort.Direction.DESC, "codigo_secuencia"));
Oportunidad oportunidad = mongoTemplate.findOne(query, Oportunidad.class);
return oportunidad.getCodidoSecuencia();
}
Entity(MongoDB):
Opportunity
String commercial (id)
String statu ( enum)
String product ( id)
Dto filter:
dtoFilter
List<String> commercial (id of comercial)
List<String> statu ( enum of status)
List<String> product ( id of product)
I get from front a dtoFilter with a list of commercial id, a string listing with state enumerated and a string listing with product id. That I look for all the "Opportunities" that coincide with the listings (an AND)
Someone can help me with the search query.
Thank you

You can $or criteria for each of the document.
Something like
#Override
public List<Oportunidad> getOportunidads(DtoFilter dtoFilter) {
List<String> commercial = dtoFilter.getCommercial();
List<String> statu = dtoFilter.getStatu();
List<String> product = dtoFilter.getProduct();
List<Criteria> andCriteria = new ArrayList<>();
for(int i=0; i < commercial.size(); i++) {
andCriteria.add(Criteria.where("commercial").is(commercial.get(i)).and("statu").is(statu.get(i)).and("product").is(product.get(i)));
}
Criteria orCriteria = new Criteria().orOperator(andCriteria.toArray(new Criteria[andCriteria.size()]));
return mongoTemplate.find(new Query().addCriteria(orCriteria), Oportunidad.class);
}

Related

Custom Query with Pageable. Spring Data MongoDB ( 1.10.9 )

I have created a custom repository:
// my repository:
#SuppressWarnings("unused")
#Repository
public interface PrlRepository extends MongoRepository<Prl, String>, PrlRepositoryCustom {
// my interface:
public interface PrlRepositoryCustom {
List<Prl> find(FilterPrlDTO filterPrlDTO);
}
// my implementation
#Override
public List<Prl> find(FilterPrlDTO filterPrlDTO) {
List<Criteria> andCriteria = new ArrayList<>();
if (filterPrlDTO.getInicioCaduca() != null) {
andCriteria.add(Criteria.where("caducidad").gte(filterPrlDTO.getInicioCaduca()));
}
if (filterPrlDTO.getFinCaduca() != null) {
andCriteria.add(Criteria.where("caducidad").lte(filterPrlDTO.getFinCaduca()));
}
if (filterPrlDTO.getActivo() != null) {
andCriteria.add(Criteria.where("activo").is(filterPrlDTO.getActivo()));
}
Criteria orCriteria = new Criteria().andOperator(andCriteria.toArray(new Criteria[andCriteria.size()]));
return mongoOperations.find(new Query().addCriteria(orCriteria), Prl.class);
}
It works correctly, but I need it to be Pageable.
Can someone help me how to implement it? I've been looking at forums and documentation but I do not see anything that I can serve
Thank you very much.
MongoRepository actually implements PagingAndSortingRepository which allows you to implement pagination.
You can pass the Pageable request along with the Query class, here is a sample of how to do it:
Pageable pageable = new PageRequest(pageNumber, dataSize);
Query query = new Query();
public Page<T> findAll(Query query, Pageable pageable) {
Long count = count(); //Issue a count query here for the collection
List<T> list = findAll(query.with(pageable));
return new PageImpl<T>(list, pageable, count);
}
For more information and samples look here:
SimpleMongoRepository example
Structure to search with large filters, which will enter the Criteria based on the search parameters and the result is paged:
public Page<AccionOportunidad> filter(Pageable pageable) {
Query query = new Query();
// criterias
query.addCriteria(Criteria.where("id").in("xxx"));
query.with(pageable);
List<AccionOportunidad> list = mongoOperations.find(query, AccionOportunidad.class);
return PageableExecutionUtils.getPage(list, pageable,
() -> mongoOperations.count(query, AccionOportunidad.class));
}

Splitting row into several nested objects

I've got the following query:
select id, name, email, supervisor, createdBy, createdAt, changedBy, changedAt from XXX
Now, I'd like to map each row into something that looks like this:
public class Organisation{
public int Id{get; set; }
public string Name{get; set; }
public ContactInfo Contact{get;set;}
public Action CreatedBy{get;set;}
public Action ChangedBy{get;set;}
}
public class ContactInfo{
public string Name{get;set;}
public string Email{get;set;}
}
public class Action{
public string Username{get;set;}
public DateTime At{get;set;}
}
I've seen some examples that show how to partition the info, but it seems like will not work in this example. Can it be done or should I map my query into a helper object which will then be mapped into these classes?
Thanks.
Luis
Dapper allows you to map a single row to multiple objects. This is a
key feature if you want to avoid extraneous querying and eager load
associations.
You can read about it more here
Below is an example:
[Test]
public void Test_Multi()
{
using (var conn = new SqlConnection(#"Data Source=.\sqlexpress;Integrated Security=true; Initial Catalog=foo"))
{
var result = conn.Query<Organisation, ContactInfo, Action, Action, Organisation>(
#"select Id = 100, Name = 'Foo',
Name = 'Contact Name', Email = 'contact#foo.com',
Username = 'The Creator', At = '12/25/2017',
Username = 'The Modifier', At = '12/26/2017' ",
(org, contact, cretedBy, changedBy) =>
{
org.Contact = contact;
org.CreatedBy = cretedBy;
org.ChangedBy = changedBy;
return org;
}, splitOn: "Id, Name, Username, Username").First();
Assert.That(result.Id, Is.EqualTo(100));
Assert.That(result.Contact.Email, Is.EqualTo("contact#foo.com"));
Assert.That(result.CreatedBy.Username, Is.EqualTo("The Creator"));
Assert.That(result.ChangedBy.Username, Is.EqualTo("The Modifier"));
}
}

How do I return one-to-many records in a specific order with Dapper and multi-mapping?

From Github:
Dapper allows you to map a single row to multiple objects. This is a
key feature if you want to avoid extraneous querying and eager load
associations.
Example:
Consider 2 classes: Post and User
> class Post {
> public int Id { get; set; }
> public string Title { get; set; }
> public string Content { get; set; }
> public User Owner { get; set; } }
>
> class User {
> public int Id { get; set; }
> public string Name { get; set; } }
Now let us say that we want to map a query that joins both the posts
and the users table. Until now
if we needed to combine the result of 2 queries, we'd need a new
object to express it but it makes more sense in this case to put the
User object inside the Post object.
When I do this (My classes are different names, but same construct), I get a Post and a User, a Post and a User. I'm using the Web API, so this is all JSON, if that matters. This is the way I'd see it if I did straight SQL in the Management Studio, you get the many rows and the corresponding User records
What if I want to send back the JSON that has the User once and all the posts in an array, then the next User, array of posts, etc.
id title content id name
1 Article1 Content1 55 Smith
2 Article2 Content2 55 Smith
3 Article3 Content3 55 Smith
I get the JSON back that has the User information over and over (as expected but not wanted). It's backwards.
What I want is a JSON object that has a format like this (I think this is correct):
{
"User": 55,
"Name": "Smith",
"Post": [
{
"id": 1,
"title": "title1",
"content":"MyContent1"
},
{
"id": 2,
"title": "title2",
"content":"MyContent2"
},
{
"id": 3,
"title": "title3",
"content":"MyContent2"
}
]
}
How do I do this? Right now I get the reverse. I thought I would simply change the classes around, but I did not because of the instructions on Github, the "makes more sense" part. I am using this,
(List<Post>)db.Query<Post, User, Paper>(sqlString, (post, user) => { post.user = user; return post; }, splitOn: "id");
I know I don't need the splitOn here, but in my real query the name is different than id.
This is pretty close:
https://www.tritac.com/developers-blog/dapper-net-by-example/
public class Shop {
public int? Id {get;set;}
public string Name {get;set;}
public string Url {get;set;}
public IList<Account> Accounts {get;set;}
}
public class Account {
public int? Id {get;set;}
public string Name {get;set;}
public string Address {get;set;}
public string Country {get;set;}
public int ShopId {get;set;}
}
var lookup = new Dictionary<int, Shop>()
conn.Query<Shop, Account, Shop>(#"
SELECT s.*, a.*
FROM Shop s
INNER JOIN Account a ON s.ShopId = a.ShopId
", (s, a) => {
Shop shop;
if (!lookup.TryGetValue(s.Id, out shop)) {
lookup.Add(s.Id, shop = s);
}
if (shop.Accounts == null)
shop.Accounts = new List<Account>();
shop.Accounts.Add(a);
return shop;
},
).AsQueryable();
var resultList = lookup.Values;
It makes the first object identifier. Not sure if I can use it like that or not. But this does do the array of books like I was asking, and I did not have to create a special object. Originally, it was supposed to be on Google Code, but I couldn't find this test on Github.
Since your SQL query is returning the flat records, i suggest you create a flat POCO and use dapper to map the result set to a collection of this. Once you have data in this collection, you can use LINQ GroupBy method to group it the way you want.
Assuming you have classes like
public class User
{
public int Id { set;get;}
public string Name { set;get;}
public IEnumerable<Post> Posts { set;get;}
}
public class Post
{
public int Id { set;get;}
public string Title{ set;get;}
public string Content { set;get;}
}
Now create the POCO for the flat result set row
public class UserPost
{
public int Id { set; get; }
public string Title { set; get; }
public string Content { set; get; }
public int UserId { set; get; }
public string Name { set; get; }
}
Now update your SQL query to return a result set with column name matching the above properties.
Now use Dapper to get the flat records
var userposts= new List<UserPost>();
using (var conn = new SqlConnection("YourConnectionString"))
{
userposts = conn.Query<UserPost>(query).ToList();
}
Now apply GroupBy
var groupedPosts = userposts.GroupBy(f => f.UserId, posts => posts, (k, v) =>
new User()
{
UserId = k,
Name = v.FirstOrDefault().Name,
Posts = v.Select(f => new Post() { Id = f.Id,
Title= f.Title,
Content = f.Content})
}).ToList();
Another option is to use .QueryMultiple
[Test]
public void TestQueryMultiple()
{
const string sql = #"select UserId = 55, Name = 'John Doe'
select PostId = 1, Content = 'hello'
union all select PostId = 2, Content = 'world'";
var multi = _sqlConnection.QueryMultiple(sql);
var user = multi.Read<User>().Single();
user.Posts = multi.Read<Post>().ToList();
Assert.That(user.Posts.Count, Is.EqualTo(2));
Assert.That(user.Posts.First().Content, Is.EqualTo("hello"));
Assert.That(user.Posts.Last().Content, Is.EqualTo("world"));
}
Update:
To return multiple users and their posts:
[Test]
public void TestQueryMultiple2()
{
const string sql = #"select UserId = 55, Name = 'John Doe'
select UserId = 55, PostId = 1, Content = 'hello'
union all select UserId = 55, PostId = 2, Content = 'world'";
var multi = _sqlConnection.QueryMultiple(sql);
var users = multi.Read<User>().ToList();
var posts = multi.Read<Post>().ToList();
foreach (var user in users)
{
user.Posts.AddRange(posts.Where(x => x.UserId == user.UserId));
}
Assert.That(users.Count, Is.EqualTo(1));
Assert.That(users.First().Posts.First().Content, Is.EqualTo("hello"));
Assert.That(users.First().Posts.Last().Content, Is.EqualTo("world"));
}

Dapper - What is the most efficient way to query Many-To-Many relationship?

I am new to Dapper and trying to figure out how to query a Many-To-Many relationship.
I've looked around SO and Google but could not find an example.
I have a simple Many-To-Many scenario with 3 tables:
Albums table:
Artists table:
and the Many-To-Many table:
These are my POCOS:
public class Artist
{
public long Id { get; set; }
public string Name { get; set; }
}
public class Album
{
public long Id { get; set; }
public string Name { get; set; }
public List<Artist> Artists { get; set; }
}
Can someone provide the "correct" and efficient way to get a list of albums, and each album contains it's artists (the artists should have their Name property filled also) ?
I'm sure you must have found the solution by now. This could be helpful, may not be the neatest way to code it.
Is it possible to replicate Album and Artist classes?
If so, this is what i would do.
public List<Artist> GetAll()
{
using (SqlConnection conn = new SqlConnection(Conn.String))
{
conn.Open();
using (var multi = conn.QueryMultiple(StoredProcs.Artists.GetAll, commandType: CommandType.StoredProcedure))
{
var artists = multi.Read<Artist, AlbumArtist, Artist>((artist, albumArtist) =>
{
artist.albumArtist = albumArtist;
return artist;
}).ToList();
var albums = multi.Read<Album, AlbumArtist, Album>(
(album, albumArtist, album) =>
{
album.albumArtist = album;
return albums;
}).ToList();
conn.Close();
return artists;
}
}
}
Here's how the proc would look like
CREATE PROCEDURE [dbo].[YourProcName]
AS
BEGIN
SET NOCOUNT ON;
SELECT * from Artist a
left join AlbumArtist aa
on a.ArtistId = aa.ArtistId;
EXEC dbo.Album_GetAll
WITH RESULT SETS UNDEFINED;
END
Hope this helps.

Manually map column names with class properties

I am new to the Dapper micro ORM. So far I am able to use it for simple ORM related stuff but I am not able to map the database column names with the class properties.
For example, I have the following database table:
Table Name: Person
person_id int
first_name varchar(50)
last_name varchar(50)
and I have a class called Person:
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Please note that my column names in the table are different from the property name of the class to which I am trying to map the data which I got from the query result.
var sql = #"select top 1 PersonId,FirstName,LastName from Person";
using (var conn = ConnectionFactory.GetConnection())
{
var person = conn.Query<Person>(sql).ToList();
return person;
}
The above code won't work as the column names don't match the object's (Person) properties. In this scenario, is there anything i can do in Dapper to manually map (e.g person_id => PersonId) the column names with object properties?
Dapper now supports custom column to property mappers. It does so through the ITypeMap interface. A CustomPropertyTypeMap class is provided by Dapper that can do most of this work. For example:
Dapper.SqlMapper.SetTypeMap(
typeof(TModel),
new CustomPropertyTypeMap(
typeof(TModel),
(type, columnName) =>
type.GetProperties().FirstOrDefault(prop =>
prop.GetCustomAttributes(false)
.OfType<ColumnAttribute>()
.Any(attr => attr.Name == columnName))));
And the model:
public class TModel {
[Column(Name="my_property")]
public int MyProperty { get; set; }
}
It's important to note that the implementation of CustomPropertyTypeMap requires that the attribute exist and match one of the column names or the property won't be mapped. The DefaultTypeMap class provides the standard functionality and can be leveraged to change this behavior:
public class FallbackTypeMapper : SqlMapper.ITypeMap
{
private readonly IEnumerable<SqlMapper.ITypeMap> _mappers;
public FallbackTypeMapper(IEnumerable<SqlMapper.ITypeMap> mappers)
{
_mappers = mappers;
}
public SqlMapper.IMemberMap GetMember(string columnName)
{
foreach (var mapper in _mappers)
{
try
{
var result = mapper.GetMember(columnName);
if (result != null)
{
return result;
}
}
catch (NotImplementedException nix)
{
// the CustomPropertyTypeMap only supports a no-args
// constructor and throws a not implemented exception.
// to work around that, catch and ignore.
}
}
return null;
}
// implement other interface methods similarly
// required sometime after version 1.13 of dapper
public ConstructorInfo FindExplicitConstructor()
{
return _mappers
.Select(mapper => mapper.FindExplicitConstructor())
.FirstOrDefault(result => result != null);
}
}
And with that in place, it becomes easy to create a custom type mapper that will automatically use the attributes if they're present but will otherwise fall back to standard behavior:
public class ColumnAttributeTypeMapper<T> : FallbackTypeMapper
{
public ColumnAttributeTypeMapper()
: base(new SqlMapper.ITypeMap[]
{
new CustomPropertyTypeMap(
typeof(T),
(type, columnName) =>
type.GetProperties().FirstOrDefault(prop =>
prop.GetCustomAttributes(false)
.OfType<ColumnAttribute>()
.Any(attr => attr.Name == columnName)
)
),
new DefaultTypeMap(typeof(T))
})
{
}
}
That means we can now easily support types that require map using attributes:
Dapper.SqlMapper.SetTypeMap(
typeof(MyModel),
new ColumnAttributeTypeMapper<MyModel>());
Here's a Gist to the full source code.
This works fine:
var sql = #"select top 1 person_id PersonId, first_name FirstName, last_name LastName from Person";
using (var conn = ConnectionFactory.GetConnection())
{
var person = conn.Query<Person>(sql).ToList();
return person;
}
Dapper has no facility that allows you to specify a Column Attribute, I am not against adding support for it, providing we do not pull in the dependency.
For some time, the following should work:
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
I do the following using dynamic and LINQ:
var sql = #"select top 1 person_id, first_name, last_name from Person";
using (var conn = ConnectionFactory.GetConnection())
{
List<Person> person = conn.Query<dynamic>(sql)
.Select(item => new Person()
{
PersonId = item.person_id,
FirstName = item.first_name,
LastName = item.last_name
}
.ToList();
return person;
}
Here is a simple solution that doesn't require attributes allowing you to keep infrastructure code out of your POCOs.
This is a class to deal with the mappings. A dictionary would work if you mapped all the columns, but this class allows you to specify just the differences. In addition, it includes reverse maps so you can get the field from the column and the column from the field, which can be useful when doing things such as generating sql statements.
public class ColumnMap
{
private readonly Dictionary<string, string> forward = new Dictionary<string, string>();
private readonly Dictionary<string, string> reverse = new Dictionary<string, string>();
public void Add(string t1, string t2)
{
forward.Add(t1, t2);
reverse.Add(t2, t1);
}
public string this[string index]
{
get
{
// Check for a custom column map.
if (forward.ContainsKey(index))
return forward[index];
if (reverse.ContainsKey(index))
return reverse[index];
// If no custom mapping exists, return the value passed in.
return index;
}
}
}
Setup the ColumnMap object and tell Dapper to use the mapping.
var columnMap = new ColumnMap();
columnMap.Add("Field1", "Column1");
columnMap.Add("Field2", "Column2");
columnMap.Add("Field3", "Column3");
SqlMapper.SetTypeMap(typeof (MyClass), new CustomPropertyTypeMap(typeof (MyClass), (type, columnName) => type.GetProperty(columnMap[columnName])));
An easy way to achieve this is to just use aliases on the columns in your query.
If your database column is PERSON_ID and your object's property is ID, you can just do
select PERSON_ID as Id ...
in your query and Dapper will pick it up as expected.
Taken from the Dapper Tests which is currently on Dapper 1.42.
// custom mapping
var map = new CustomPropertyTypeMap(typeof(TypeWithMapping),
(type, columnName) => type.GetProperties().FirstOrDefault(prop => GetDescriptionFromAttribute(prop) == columnName));
Dapper.SqlMapper.SetTypeMap(typeof(TypeWithMapping), map);
Helper class to get name off the Description attribute (I personally have used Column like #kalebs example)
static string GetDescriptionFromAttribute(MemberInfo member)
{
if (member == null) return null;
var attrib = (DescriptionAttribute)Attribute.GetCustomAttribute(member, typeof(DescriptionAttribute), false);
return attrib == null ? null : attrib.Description;
}
Class
public class TypeWithMapping
{
[Description("B")]
public string A { get; set; }
[Description("A")]
public string B { get; set; }
}
Before you open the connection to your database, execute this piece of code for each of your poco classes:
// Section
SqlMapper.SetTypeMap(typeof(Section), new CustomPropertyTypeMap(
typeof(Section), (type, columnName) => type.GetProperties().FirstOrDefault(prop =>
prop.GetCustomAttributes(false).OfType<ColumnAttribute>().Any(attr => attr.Name == columnName))));
Then add the data annotations to your poco classes like this:
public class Section
{
[Column("db_column_name1")] // Side note: if you create aliases, then they would match this.
public int Id { get; set; }
[Column("db_column_name2")]
public string Title { get; set; }
}
After that, you are all set. Just make a query call, something like:
using (var sqlConnection = new SqlConnection("your_connection_string"))
{
var sqlStatement = "SELECT " +
"db_column_name1, " +
"db_column_name2 " +
"FROM your_table";
return sqlConnection.Query<Section>(sqlStatement).AsList();
}
Messing with mapping is borderline moving into real ORM land. Instead of fighting with it and keeping Dapper in its true simple (fast) form, just modify your SQL slightly like so:
var sql = #"select top 1 person_id as PersonId,FirstName,LastName from Person";
If you're using .NET 4.5.1 or higher checkout Dapper.FluentColumnMapping for mapping the LINQ style. It lets you fully separate the db mapping from your model (no need for annotations)
This is piggy backing off of other answers. It's just a thought I had for managing the query strings.
Person.cs
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public static string Select()
{
return $"select top 1 person_id {nameof(PersonId)}, first_name {nameof(FirstName)}, last_name {nameof(LastName)}from Person";
}
}
API Method
using (var conn = ConnectionFactory.GetConnection())
{
var person = conn.Query<Person>(Person.Select()).ToList();
return person;
}
The simple solution to the problem Kaleb is trying to solve is just to accept the property name if the column attribute doesn't exist:
Dapper.SqlMapper.SetTypeMap(
typeof(T),
new Dapper.CustomPropertyTypeMap(
typeof(T),
(type, columnName) =>
type.GetProperties().FirstOrDefault(prop =>
prop.GetCustomAttributes(false)
.OfType<ColumnAttribute>()
.Any(attr => attr.Name == columnName) || prop.Name == columnName)));
The easier way (same as #Matt M's answer but corrected and added fallback to default map)
// override TypeMapProvider to return custom map for every requested type
Dapper.SqlMapper.TypeMapProvider = type =>
{
// create fallback default type map
var fallback = new DefaultTypeMap(type);
return new CustomPropertyTypeMap(type, (t, column) =>
{
var property = t.GetProperties().FirstOrDefault(prop =>
prop.GetCustomAttributes(typeof(ColumnAttribute))
.Cast<ColumnAttribute>()
.Any(attr => attr.Name == column));
// if no property matched - fall back to default type map
if (property == null)
{
property = fallback.GetMember(column)?.Property;
}
return property;
});
};
for all of you who use Dapper 1.12, Here's what you need to do to get this done:
Add a new column attribute class:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property]
public class ColumnAttribute : Attribute
{
public string Name { get; set; }
public ColumnAttribute(string name)
{
this.Name = name;
}
}
Search for this line:
map = new DefaultTypeMap(type);
and comment it out.
Write this instead:
map = new CustomPropertyTypeMap(type, (t, columnName) =>
{
PropertyInfo pi = t.GetProperties().FirstOrDefault(prop =>
prop.GetCustomAttributes(false)
.OfType<ColumnAttribute>()
.Any(attr => attr.Name == columnName));
return pi != null ? pi : t.GetProperties().FirstOrDefault(prop => prop.Name == columnName);
});
I know this is a relatively old thread, but I thought I'd throw what I did out there.
I wanted attribute-mapping to work globally. Either you match the property name (aka default) or you match a column attribute on the class property. I also didn't want to have to set this up for every single class I was mapping to. As such, I created a DapperStart class that I invoke on app start:
public static class DapperStart
{
public static void Bootstrap()
{
Dapper.SqlMapper.TypeMapProvider = type =>
{
return new CustomPropertyTypeMap(typeof(CreateChatRequestResponse),
(t, columnName) => t.GetProperties().FirstOrDefault(prop =>
{
return prop.Name == columnName || prop.GetCustomAttributes(false).OfType<ColumnAttribute>()
.Any(attr => attr.Name == columnName);
}
));
};
}
}
Pretty simple. Not sure what issues I'll run into yet as I just wrote this, but it works.
Kaleb Pederson's solution worked for me. I updated the ColumnAttributeTypeMapper to allow a custom attribute (had requirement for two different mappings on same domain object) and updated properties to allow private setters in cases where a field needed to be derived and the types differed.
public class ColumnAttributeTypeMapper<T,A> : FallbackTypeMapper where A : ColumnAttribute
{
public ColumnAttributeTypeMapper()
: base(new SqlMapper.ITypeMap[]
{
new CustomPropertyTypeMap(
typeof(T),
(type, columnName) =>
type.GetProperties( BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(prop =>
prop.GetCustomAttributes(true)
.OfType<A>()
.Any(attr => attr.Name == columnName)
)
),
new DefaultTypeMap(typeof(T))
})
{
//
}
}

Resources