Simple condition with ProjectTo doesn't work - .net-core

I have the problem with ProjectTo.
I have that Select map:
var posts = await appContext.Posts
.Select(x => new PostListReadModel()
{
IsAnonymous = x.IsAnonymous,
Publisher = !x.IsAnonymous ?
new PostPublisherReadModel()
{
Id = x.PublisherId,
Nick = x.Publisher.Nick,
PhoneNumber = x.Publisher.PhoneNumber,
Avatar = x.Publisher.Avatar
} :
null
})
.ToListAsync();
As you can see, I have a mapping condition for the Publisher property. Very simple condition.
It translates to sql like this:
SELECT p.IsAnonymous, NOT (p.IsAnonymous), p.PublisherId, u.Nick, u.PhoneNumber, i.Id, i.DateCreated, i.DateUpdated, i.FileName
FROM posts AS p
INNER JOIN users AS u ON p.PublisherId = u.Id
LEFT JOIN images AS i ON u.AvatarId = i.Id
And it works.
Now, I want to use ProjectTo. And I have a map configuration like this:
CreateMap<User, PostPublisherReadModel>();
CreateMap<Post, PostListReadModel>()
.ForMember(dest => dest.IsAnonymous, opt => opt.MapFrom(src => src.IsAnonymous))
.ForMember(dest => dest.Publisher, opt => opt.Condition(src => !src.IsAnonymous))
.ForAllOtherMembers(opt => opt.Ignore());
It translates to sql like this:
SELECT p.IsAnonymous, FALSE, i.Id, i.DateCreated, i.DateUpdated, i.FileName, u.Id, u.Nick, u.PhoneNumber
FROM posts AS p
INNER JOIN users AS u ON p.PublisherId = u.Id
LEFT JOIN images AS i ON u.AvatarId = i.Id
and it naturally doesn't work.
Is it an automapper error or am i doing something wrong?
P.S.: DbProvider: Pomelo.EntityFrameworkCore.MySql Version=3.1.0

Related

Get a child count using Bookshelf

I want to have child count for every record in table A. How do I query if I have sql statement like this
SELECT A.*, (SELECT COUNT(*) FROM B WHERE B.a_id = A.id) AS TOT FROM A
You may be able to achieve this using knex QueryBuilder
A
.query(qb => {
qb.select('(SELECT count(*) FROM B WHERE B.id = A.id) AS count');
})
.fetchAll()
.then(data => {
// Data retrieval
})
.catch(err => {
// Error management
})

How to count current week publish node by specific user in drupal

How to count current week publish node by specific user in drupal for specific content-type ?
Something like this should work:
// select the number of nodes that is of a specific content type and
// were created this week by the named user
function <theme>_post_count($user_name, $content_type) {
$query = "SELECT COUNT(*) node_count FROM {node} n
INNER JOIN {users} u ON u.name = :user_name && u.uid = n.uid
WHERE n.type = :content_type &&
WEEK(FROM_UNIXTIME(n.created)) = WEEK(CURRENT_TIMESTAMP())";
$result = db_query($query,
array(
':user_name' => $user_name,
':content_type' => $content_type
))->fetch();
return $result->node_count;
}
You could easily modify the above query to take a uid instead of a user name and so on.
You would then call this function like this:
print 'Articles added by admin during this week: '.<theme>_post_count('admin', 'article');

Is there a way to select a columns from a joined table without explicitly listing all columns?

I'm trying to use JoinSqlBuilder to select a data from one of the joined tables, and can't find a way to do that unless I list all columns from that table. Hopefully I'm missing something and it actually can be done.
This is approximately what I have:
var sql = new JoinSqlBuilder<Product, Product>()
.Join<Product, Customer>(src => src.Id, dst => dst.Id)
.Where<Customer>(x => x.Id == Id);
and I want to select everything from a product table. The query above throws an exception complaining about column name collisions, so its clearly does a select from both tables.
Edit: In the end I want to have this sql (never mind the design, its not a real thing):
select
p.* //<-- This is the piece that I'm struggling with
from product p inner join customer c on p.id on c.productId
where blah;
Looks like OrmLite want me to explicitly list all columns I want to return, which I want to avoid.
Note: I'm using 3.9.71 of servicestack. I've not looked at the 4.0 implementation yet.
I think you have a FK relationship problem with your join. Assuming that a product has a customer FK named (CustID), it'd look like this. Additionally, you'd need a POCO to represent the result set, if you are returning a "combination" of the results. I don't think you'll want to return both "ID" columns, and instead return a FK column.
return _factory.Run<ProductCustomer>(conn=>
{
var jn = new JoinSqlBuilder<Product, Customer>();
jn = jn.Join<Product, Customer>(srcProd => srcProd.CustId,
dstCust => dstCust.Id, // set up join Customer.id -> Product.CustId
p => new { p.Id, p.OtherField}, // product table fields returned
c => new { c.Name, c.AddressId}, // customer fields returned
null, //where clause on the product table
cust=>cust.Id = customerId // where clause on the customer table
);
var sql = jn.ToSQL();
return conn.FirstOrDefault<ProductCustomer>(sql);
}
Hope this helps.
Edit: After your Edit, try this:
// set up join Customer.id -> c.ProductId
jn = jn.Join<Product, Customer>(srcProd => srcProd.Id, dstCust => dstCust.productId)
.Where<Customer>(c=>c.Id == custIdParameter);
var sql = jn.ToSql();
You can add a ".Where" again for the
Where<Product>(p=>p.id == foo);
if you need to add more product with your BLAH. This should get you close.
Have you tried the SelectAll extension method?
var sql = new JoinSqlBuilder<Product, Product>()
.Join<Product, Customer>(src => src.Id, dst => dst.Id)
.SelectAll<Product>()
.Where<Customer>(x => x.Id == Id);

How to sort in linq to sql for a joined table?

i have these tables in short:
Table: RPG
Coloumns: RPGID, Name
Table: RPGCharacter
Coloumns: CharID, RPGID, Name
Table: RPGPosts
Coloumns: PostID, CharID, Text, timestamp
So in Database the relation is:
1 RPG has X Characters and 1 Character has X Posts.
I get the information with this code:
public static List<RPG> GetAllRPGs()
{
using (RPGDataContext dc = new RPGDataContext())
{
return (from a in dc.RPGs where !a.IsHided && !a.IsDeleted select a).ToList();
}
}
The Problem is:
How to sort these list by the LAST post (TIMESTAMP-Coloumn of the RPGPOst-Table)?
Assuming you've got appropriate navigation properties set up, something like this should work:
var results =
(from a in dc.RPGs
where !a.IsHided && !a.IsDeleted
orderby a.Characters.SelectMany(c => c.Posts).Select(p => p.Timestamp).Max()
select a)
.ToList();
Or possibly:
var results =
(from a in dc.RPGs
where !a.IsHided && !a.IsDeleted
orderby a.Characters
.SelectMany(c => c.Posts)
.OrderByDescending(p => p.Timestamp)
.Select(p => p.Timestamp)
.FirstOrDefault()
select a)
.ToList();

LINQ Query in DataTable

I have a DataTable named dt. It has two Columns named atype_code and module.
Now i need to query a module based on specific atype_code.
Here is the code i wrote but not working.
DataTable dt = GetATypeCodeList();
var accType = (from myAccType in dt.AsEnumerable()
where myAccType.Field<string>("atype_code") == aTypeCode.Trim()
select myAccType.Field<string>("module"));
acctype is a System.Data.EnumerableRowCollection<System.String>.
Since you've said that you
need to query a module based on specific atype_code
, i assume that you want only one module with the given atype_code.
Then you should either use Single/SingleOrDefault or First/FirstOrDefault.
String firstModule = dt.AsEnumerable()
.Where(r => r.Field<string>("atype_code") == aTypeCode.Trim())
.Select(r => r.Field<string>("module"))
.FirstOrDefault();
// or
String singleModule = dt.AsEnumerable()
.Where(r => r.Field<string>("atype_code") == aTypeCode.Trim())
.Select(r => r.Field<string>("module"))
.SingleOrDefault();
Enumerable.Single throws an exception if there is more than one matching element. That can be useful to validate the data.
Edit:
Here's the query-syntax:
IEnumerable<String> modules =
from myAccType in dt.AsEnumerable()
where myAccType.Field<string>("atype_code") == aTypeCode.Trim()
select myAccType.Field<string>("module");
String module = modules.FirstOrDefault(); // returns null if no matching modules were found

Resources