i am trying to make a where condition in my doctrine Query;
the condition should be;
return all Sent Messages where:
sender = A and receiver = B
or
B; sender = B and receiver = A
below is my query; only the first condition is being returned from the query.
public function getMessageHistory()
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select(array('u'))
->from('Messages\Entity\Messages','u')
->where ('u.senderUserId = :senderId AND u.receiverUserId = :receiverId')
->orWhere('u.senderUserId = :receiverId AND u.receiverUserId = :senderId')
->setParameter('senderId',(int)$this->getUserId())
->setParameter('receiverId',(int)$this->getRecipientId());
$query = $qb->getQuery();
return $data = $query->getArrayResult();
}
thank you in advance for your help
I would build this way:
$qb->select(array('u'))
->from('Messages\Entity\Messages','u')
->where(
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->eq( 'u.senderUserId', ':senderId' ),
$qb->expr()->eq( 'u.receiverUserId', ':receiverId' )
),
$qb->expr()->andX(
$qb->expr()->eq( 'u.senderUserId', ':receiverId' ),
$qb->expr()->eq( 'u.receiverUserId', ':senderId' )
),
)
)
->setParameter('senderId',(int)$this->getUserId())
->setParameter('receiverId',(int)$this->getRecipientId());
Related
Please tell me how in such a data structure (simplified for better understanding) to bring all the children of the entity into one list:
fun main() {
val listOfEntities = listOf(
Entity(
name = "John",
entities = listOf(
Entity(
name = "Adam",
entities = listOf()
),
Entity(
name = "Ivan",
entities = listOf(
Entity(
name = "Henry",
entities = listOf(
Entity(
name = "Kate",
entities = listOf(
Entity(
name = "Bob",
entities = listOf()
)
)
)
)
)
)
)
)
)
)
val result = listOfEntities.flatMap { it.entities }.map { it.name }
println(result)
}
data class Entity(
val name: String,
val entities: List<Entity>
)
I expect to see following result:
[John, Adam, Ivan, Henry, Kate, Bob]
I try to use flatMap, but it did not lead to the expected result.
Thank you in advance!
You can traverse the tree of Entities recursively like this:
fun List<Entity>.flattenEntities(): List<Entity> =
this + flatMap { it.entities.flattenEntities() }
Then you can call
val result = listOfEntities.flattenEntities().map { it.name }
to obtain the desired result.
You could do it like this
fun List<Entity>.flatten(): List<String> {
return flatMap { listOf(it.name) + it.entities.flatten()}
}
and then
val result = listOfEntities.flatten()
After some research, I made this UNION query work in my Repository class:
class PostRepository extends ServiceEntityRepository {
// ...
public function getLatestPostsOfUser ($limit = 10) : ?array {
$sql = <<<SQL
SELECT p.id, p.title, p.content, p.images, p.parent_id, p.parent_type, p.created, p.last_modified FROM cms_posts p
LEFT JOIN cms_user_follow ON (p.parent_type = cms_user_follow.followed_entity_type AND p.parent_id = cms_user_follow.followed_entity_id)
WHERE cms_user_follow.user_id = {$this->currentUser->getId()}
UNION
SELECT p.id, p.title, p.content, p.images, p.parent_id, p.parent_type, p.created, p.last_modified FROM cms_posts p
LEFT JOIN project_memberships ON (p.parent_type = 'Project' AND p.parent_id = project_memberships.project_id)
WHERE project_memberships.user_id = {$this->currentUser->getId()} and project_memberships.status = 1
ORDER BY created DESC
LIMIT $limit
SQL;
$res = [];
try {
$rsm = (new ResultSetMapping())
->addEntityResult(Post::class, 'p')
->addFieldResult('p', 'id', 'id')
->addFieldResult('p', 'title', 'title')
->addFieldResult('p', 'content', 'content')
->addFieldResult('p', 'images', 'images')
->addFieldResult('p', 'parent_id', 'parentId')
->addFieldResult('p', 'parent_type', 'parentType')
->addFieldResult('p', 'created', 'created')
->addFieldResult('p', 'last_modified', 'lastModified')
;
$res = $this->getEntityManager()->createNativeQuery($sql, $rsm)->getArrayResult();
} catch (DBALException $e) {
}
return $res;
}
}
It involves an awefull lot of manual field mapping, so I was wondering wheather there is an automatic solution to this?
Many thx!
It looks like Doctrine can do something like this under the hood and also apply the mappings automatically:
$qb = $this->em->createQueryBuilder();
$where = $qb->expr()->andX(
$qb->expr()->eq('f.followedEntityId', ':parentId'),
$qb->expr()->eq('f.followedEntityType', ':parentType'),
$qb->expr()->eq('f.following', 1),
$qb->expr()->eq('u.allowEmailNotifications', 1),
$qb->expr()->eq('u.enabled', 1),
);
$qb->select('f', 'u')
->from(UserFollow::class, 'f')
->leftJoin(
User::class,
'u',
Join::WITH,
'f.userId = u.id'
)
->where($where)
->setParameters([
'parentId' => $post->getParentId(),
'parentType' => $post->getParentType()
])
;
$usersAndFollowings = $qb->getQuery()->getResult();
$usersAndFollowings is then a flat array with both entities alternating: [UserFollow, User, UserFollow, User, ...]
You'll probably want to process it afterwards, so that connected UserFollow and User entities are together in a sub array.
I'm trying to do a simple query. I want to have a list with a string and a Guid and a sub-list with a decimal and a string. I have my query this way but it keeps getting error when translated to Entity Framework what am I doing wrong?
Thanks in advance
var a = ( from c in DbContext.CC
join icc in DbContext.ICC c.Id equals icc.CCId
join i in DbContext.I on icc.IId equals i.Id
join p in DbContext.P on i.PId equals p.Id
select new
{
GuidId = p.Id,
StringN = p.StringN,
CCString = c.CCString ,
DecimalValue = icc.DecimalValue
}).GroupBy(x => new { x.GuidId , x.StringN }).
Select(x => new Model
{
GuidId = x.Key.GuidId ,
StringN = x.Key.StringN ,
Values= x.Select(y => new OtherModel
{
DecimalValue = y.DecimalValue ,
CCString = y.CCString
})
}
).OrderBy(x => x.StringN );
Error:
The LINQ expression '(GroupByShaperExpression:
KeySelector: new {
GuidId = (p.Id),
StringN = (p.Name)
},
ElementSelector:new {
GuidId = (ProjectionBindingExpression: GuidId ),
StringN = (ProjectionBindingExpression: StringN ),
CCString = (ProjectionBindingExpression: CCString ),
DecimalValue = (ProjectionBindingExpression: DecimalValue )
}
)
.Select(y => new OtherModel{
DecimalValue = y.DecimalValue ,
CCString = y.CCString
}
)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
It is SQL limitation. You cannot select grouped items, only Key and aggregation result is allowed.
Add AsEnumerable to your LINQ query to do grouping on the client side:
var a = (
from c in DbContext.CC
join icc in DbContext.ICC c.Id equals icc.CCId
join i in DbContext.I on icc.IId equals i.Id
join p in DbContext.P on i.PId equals p.Id
select new
{
GuidId = p.Id,
StringN = p.StringN,
CCString = c.CCString,
DecimalValue = icc.DecimalValue
})
.AsEnumerable()
.GroupBy(x => new { x.GuidId , x.StringN })
.Select(x => new Model
{
GuidId = x.Key.GuidId,
StringN = x.Key.StringN,
Values = x.Select(y => new OtherModel
{
DecimalValue = y.DecimalValue,
CCString = y.CCString
})
})
.OrderBy(x => x.StringN);
I am trying to make formula field for the salesforce field. the condition is given below.
if Company = "WIL" And (ShippingCountry = "United States" Or "USA") then
"US"
elseif Company = "WST" And (ShippingCountry = "United States" Or "US") then
"USA"
elseif ShippingCountry <> "" then
ShippingCountry
elseif Company = "WIL" then
"US"
elseif Company = "WST" then
"USA"
else
""
end if
The trailheads are always a good start. I would suggest Use Formula Fields and Advanced Formulas.
The documentation pages about Formula Operators and Functions might be useful too.
Keep in mind that you must use fields API Names, not labels, so it's Company__c.
If Company__c is not a picklist field:
IF( AND(Company__c = 'WIL', OR(ShippingCountry = 'United States', ShippingCountry = 'USA')),
'US',
IF( AND(Company__c = 'WST', OR(ShippingCountry = 'United States', ShippingCountry = 'US')),
'USA',
IF( NOT( ISBLANK(ShippingCountry) ),
ShippingCountry,
IF( Company__c = 'WIL',
'US',
IF(Company__c = 'WST', 'USA', '')
)
)
)
)
If Company__c is a picklist field you should use ISPICKVAL(picklist_field, literal_value), so the formula would be:
IF( AND( ISPICKVAL(Company__c, 'WIL'), OR(ShippingCountry = 'United States', ShippingCountry = 'USA')),
'US',
IF( AND(ISPICKVAL(Company__c, 'WST'), OR(ShippingCountry = 'United States', ShippingCountry = 'US')),
'USA',
IF( NOT( ISBLANK(ShippingCountry) ),
ShippingCountry,
IF( ISPICKVAL(Company__c, 'WIL'),
'US',
IF( ISPICKVAL(Company__c, 'WST'), 'USA', '')
)
)
)
)
I am trying to link between header table and the fact table in order to get correct values:
Formules =
VAR Top1 = SELECTEDVALUE ( EnteteRapportAgentClient[Top] )
VAR Middle = SELECTEDVALUE ( EnteteRapportAgentClient[Middle] )
VAR BottomIndex = SELECTEDVALUE ( EnteteRapportAgentClient[Index3] )
VAR a = SELECTEDVALUE ( Dim_DateFicheAgent[ID_DateFicheAgent] )
VAR b = SELECTEDVALUE ( 'Seniority banking'[banking seniority] )
VAR Bottom = SELECTEDVALUE ( EnteteRapportAgentClient[Bottom] )
VAR Val =
SWITCH (
TRUE (),
Top1 = "Nombre de leads", [Lead] + 0,
Top1 = "Affaires nouvelles"
&& BottomIndex <> 0, CALCULATE (
COUNTROWS (
FILTER (
Fact_AN,
(
Fact_AN[banking seniority] <= b
&& NOT ISBLANK ( Fact_AN[banking seniority] )
&& Fact_AN[Code_Produit ]
= LOOKUPVALUE (
Dim_Produit[Code_Produit ],
Dim_Produit[Dim5Rapport], Middle,
Dim_Produit[Dim6Rapport], Bottom
)
)
)
),
DATESBETWEEN (
Dim_DateFicheAgent[ID_DateFicheAgent],
NEXTDAY (
SAMEPERIODLASTYEAR (
LASTDATE ( Dim_DateFicheAgent[ID_DateFicheAgent] )
)
),
LASTDATE ( Dim_DateFicheAgent[ID_DateFicheAgent] )
)
),
Middle = "Affaires nouvelles", [AN] + 0,
Middle = "Total AN", [AN] + 0,
Middle = "Taux Transfo", DIVIDE ( [AN], [Lead] )
)
VAR ValF = IF ( Middle = "Taux Transfo", FORMAT ( Val, "0.0%" ), FORMAT ( Val, "0" ) )
VAR Val2 = IF ( ValF = "0", "", ValF )
RETURN
Val2
I get an error
I put here a pbix file. https://drive.google.com/file/d/1OwE52NRyq_W13u2N84pnNVw1lnatmOSw/view?usp=drivesdk
There's a lot going on there but that particular error likely comes from LOOKUPVALUE not returning a unique value.