Azure DevOps queryByWiql does not query correct project - azure-devops

I would like to know if there is a way for the Azure DevOps dashboard widget to know what project it belongs to or resides in. For example, I have 2 projects. The widget should be able to differentiate between the two, fetch different data, but ultimately do the same thing.
I took a look at the API reference
Here is what I tried:
var projectId = VSS.getWebContext().project.id;
var query = {
query: "SELECT [System.Id] FROM WorkItem WHERE [System.WorkItemType] = 'Epic' AND [System.State] NOT IN ('Closed','Completed','Resolved','Removed', 'Done')"
};
witClient.queryByWiql(query, projectId).then(
function (epics) {
epics.workItems.forEach(epic => {
...
However, I am getting back Epics from projects that the dashboard is not under. Our org has several projects/products that have their own WorkItems.
I verified that the projectId variable maps to the correct project, I just don't know why my query returns Epics that do not belong to the correct project...
I want to create a widget that determines which project it belongs to, and fetch data for only that project.

When you want to have the data of a specific project, be sure that you also refer to it in the WIQL query. You can do this by adding [System.TeamProject] = #project to your query.
var projectId = VSS.getWebContext().project.id;
var query = "SELECT [System.Id] FROM WorkItem WHERE [System.WorkItemType] = 'Epic' AND [System.State] NOT IN ('Closed','Completed','Resolved','Removed', 'Done') AND [System.TeamProject] = #project";
witClient.queryByWiql({ query: query }, projectId).then(function (epics) {
// do your stuff here
});

Related

API to get all available Tasks/Bugs etc for a Project in Azure DevOps

I Want REST API Url to get all available tasks/bugs/epic etc. for given project. I have tried below URL but does not return me anything
https://dev.azure.com/{organization}/{projectname}/_apis/wit/workitems
Thanks
This url https://dev.azure.com/{organization}/{projectname}/_apis/wit/workitems does not work as work item list.
You can try to use WIQL: Wiql - Query By Wiql. Example for tasks:
POST https://dev.azure.com/fabrikam/_apis/wit/wiql?api-version=5.1
Body
{
"query": "Select [System.Id], [System.Title], [System.State] From
WorkItems Where [System.WorkItemType] = 'Task'
AND [System.TeamProject] = 'Your_Project' order by [Microsoft.VSTS.Common.Priority]
asc, [System.CreatedDate] desc"
}
Here is WIQL documentation to create your own query: Syntax for the Work Item Query Language (WIQL)

Query many to many relationship in Linq and EFCore

I'm trying to do the following query in linq, however I'm getting an exception error, though my query looks fine to me. So here is the story:
Diagram
I have a many to many relationship between the users and the organizations. A user can be a part of many organizations, and an organization can have many users.
What Im trying to query
So given a user id, i want to query all the team members (users) i have in all the organizations i belong to. So
Input: User X id (guid), and this user belongs to Organization A, and Organization B
Output:
User A, Organization A
User B, Organization A
User C, Organization B
The Actual Query
I though this would do just that
var user = db.Users.Include(q => q.UserOrganization).SingleOrDefault( q => q.Id == id.ToString());
var members = (from us in db.Users.Include(q => q.UserOrganization)
let orgs = user.UserOrganization.Select(z => z.OrganizationId)
where us.UserOrganization.Any(q => orgs.Contains(q.OrganizationId) )
select new UserResource{
id = Guid.Parse(us.Id),
email = us.Email
}
).ToArray();
My query fails on the where clause, with the error:
Processing of the LINQ expression 'AsQueryable<long>((Unhandled parameter: __Select_0))' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core
Not sure what to change in the query. Please help.
PS: I wrote the query initially in MySql as follows:
SELECT UU.`Id`, UU.`Email`, UUO.`OrganizationId`
FROM aspnetusers AS UU
LEFT JOIN userorganization AS UUO ON UUO.`UserId` = `UU`.Id
WHERE UUO.`OrganizationId` IN
(
SELECT UO.`OrganizationId` FROM aspnetusers AS U
LEFT JOIN userorganization AS UO ON UO.UserId = U.Id
WHERE u.Id = '6caa67e7-69f3-49a3-ad61-10b07d379f10'
)
AND UU.Id != '6caa67e7-69f3-49a3-ad61-10b07d379f10'
The "SingleOrDefault" always executes the Query. User is not an IQueryable.
So the let orgs = user.UserOrganization.Select(z => z.OrganizationId) cannot be translated to SQL, do your var orgs = user.UserOrganization.Select(z => z.OrganizationId) before the Query, in Plain C#. This cannot be used in SQL-Queries.
With orgs being an IList<int> it will work.
But it should be prefered to find a solution that can be solved with one query only. Here you have two.
The SingleOrDefault might be not useful, you go better without, than you have a simple IQueryable. And The "Any" can most often be realized with a simple (Inner) Join, returning only values, if you have a match between to tables. That is the Same as Where - Any - Contains

Conditional include EF with children

According to this article:
https://blogs.msdn.microsoft.com/alexj/2009/10/12/tip-37-how-to-do-a-conditional-include/#comment-5225
I learned how to do a conditional include.
But now I need some lower level children like if a review has Marks, I need to fetch for each review the collection of Marks also. Any idea how to do this?
Query:
var movie = readOnlyRepository.GetById<Movie>(
movieId, false);
var dbquery = from mv in movie
select new
{
mv,
reviews = from review in mv.Reviews
where review.Mark = 10
select review
};
var result = dbquery.AsEnumerable().Select(x=> x.mv).First();
Given that Review has a collection of Marks I need that included in the result.

How to filter records using group functionality in BreezeJs

I'm developing a client app that uses breezejs and Entity Framework 6 on the back end. I've got a statement like this:
var country = 'Mexico';
var customers = EntityQuery.from('customers')
.where('country', '==', country)
.expand('order')
I want to use There may be hundreds of orders that each customer has made. For the purposes of performance, I only want to retrieve the latest order for each customer. This will be based on the created date for the order. In SQL, I could write something like this:
SELECT c.customerId, companyName, ContactName, City, Country, max(o.OrderDate) as LatestOrder FROM Customers c
inner join Orders o on c.CustomerID = o.CustomerID
group by c.customerId, companyName, ContactName, City, Country
If this was run against the northwind database, only the most recent order row is returned for each customer.
How can I write a similar query in breeze, so that it runs on the server side and therefore returns less data to the client. I know I could handle this all on the client but writing some javascript in a querysucceeded method that could be run by the client - but that's not the goal here.
thanks
For a case like this, you should create a special endpoint method that will perform your query.
Then you can use an Entity Framework query to do what you want, using the LINQ syntax.
Here are two Web API examples:
[HttpGet]
public IQueryable<Object> CustomersLatestOrderEntities()
{
// IQueryable<Object> containing Customer and Order entity
var entities = ContextProvider.Context.Customers.Select(c => new { Customer = c, LatestOrder = c.Orders.OrderByDescending(o => o.OrderDate).FirstOrDefault() });
return entities;
}
[HttpGet]
public IQueryable<Object> CustomersLatestOrderProjections()
{
// IQueryable<Object> containing Customer and Order entity
var entities = ContextProvider.Context.Customers.Select(c => new { Customer = c, LatestOrder = c.Orders.OrderByDescending(o => o.OrderDate).FirstOrDefault() });
// IQueryable<Object> containing just data fields, no entities
var projections = entities.Select(e => new { e.Customer.CustomerID, e.Customer.ContactName, e.LatestOrder.OrderDate });
return projections;
}
Note that you have a choice here. You can return actual entities, or you can return just some data fields. Which is right for you depends upon how you are going to use them on the client. If they are just for display in a
non-editable list, you can just return the plain data (CustomersLatestOrderProjections above). If they can potentially
be edited, then return the object containing the entities (CustomersLatestOrderEntities). Breeze will merge the entities
into its cache, even though they are contained inside this anonymous object.
Either way, because it returns IQueryable, you can use the Breeze filtering syntax from the client to further qualify the query.
var projectionQuery = breeze.EntityQuery.from("CustomersLatestOrderProjections")
.skip(20)
.take(10);
var entityQuery = breeze.EntityQuery.from("CustomersLatestOrderEntities")
.where('customer.countryName', 'startsWith', 'C');
.take(10);

Using ObjectQuery Include and using a nested where clause

Using entity framework, I'm trying to get back a customer with order details but I want to filter out those Orders that are active.
Customer is our EntityObject which has a collection of Order EntityObjects. CustomerDetails is our ObjectContext.
The code below will attach all orders but I want to filter and only attach those that are active. (Order.active == true). How can I do this?
I know Include builds up a nested query statement (I can observe by using .ToTraceString().) I was hoping to attach a Where clause to this nested select statement or the Include.
Customer cust;
CustomerDetails custTable = new CustomerDetails();
cust = custTable.Customer
.Where("it.cust_id = " + id)
.Include("Order") // But we only want Order.active == true!!!
.ToList().First();
Untested, but might work?
var temp = custTable.Customer.Where("it.cust_id = " + id).Include("Order");
cust = (from t in temp
where t.Order.active == true
select t).ToList().First();