SharePoint Web Services Query - linq

Consider the following (working) query. It returns an entire SharePoint row, then I get the value I (really wanted) from the row. How can I return only that value?
var ctx = new webservc.MyDataContext(new Uri("http://uri"));
ctx.Credentials = CredentialCache.DefaultCredentials;
var query = from c in ctx.MyList orderby c.ValIWant descending select c;
foreach (webservc.MyListItem item in query.Take(1))
{
return (int)item.ValIWant;
}
return 0;
I tried doing "select c.ValIWant" but I get an exception as a result. I cannot use LINQ stuff such as ".Max()" because SharePoint does not support it in the WCF Web Services, so I'm trying to stick to simple queries like the one I have above.

Related

How to Convert OData to LINQ supporting GraphDB

The below code is transforming OData filter to LINQ, but it is SQL dependent. I want to connect it with GraphDB, i.e., it should extract entities from graph, but I'm unable to understand how to proceed.
public IQueryable<AssetGroup> Get (ODataQueryOptions<AssetGroup> query)
{
var items = query.ApplyTo(from i in _db.Assets select i);
return (IQueryable < AssetGroup >) items;
}

Returning an odata IQueryable object that differs to the query options

I need to get the following code to work
public IQueryable<BankingDTO> Get(ODataQueryOptions<TillSummaryDTO> options)
{
return((IQueryable<BankingDTO>)options.ApplyTo(this._bankingService.GetBanking()));
}
I would like to query on TillSummaryDTO because it has the field "TillOpID" on it. However I would like to return BankingDTO as this is the end result which contains the group by and sum. When I run the query I receive the error "Cannot apply ODataQueryOptions of 'Bepoz.Presentation.ViewModels.TillSummaryDTO' to IQueryable of 'Bepoz.Presentation.ViewModels.BankingDTO" what is the best practice for this?
The bankingservice.GetBanking method looks like this
var query = from t in _tillSummaryRepository.Table
join w in _workStationRepository.Table on t.TillOpID equals w.WorkstationID
join s in _storeRepository.Table on w.StoreID equals s.StoreID
join v in _venueRepository.Table on s.VenueID equals v.VenueID
select new TillSummaryDTO
{
TillOpID = t.TillOpID,
Cash = t.Cash,
Workstation = new WorkstationDTO()
{
WorkstationID = w.WorkstationID,
Name = w.Name,
Store = new StoreDTO()
{
StoreID = s.StoreID,
StoreGroup = s.StoreGroup,
Name = s.Name,
Venue = new VenueDTO()
{
VenueID = v.VenueID,
VenueGroup = v.VenueGroup,
Name = v.Name,
}
}
}
};
return query.GroupBy(x => x.Workstation.Name)
.Select(x => new BankingDTO()
{
TotalCash = x.Sum(y => y.Cash),
WorkstationName = x.Key
});
The scenario you want to achieve is that you have an entity set of TillSummaryDTO that you want to query, and you would like the return type to be a collection of BankingDTO. The query for the BankingDTO is carried out by applying the query options in the URL onto TillSummaryDTO . But the fact that the BankingDTO and TillSummaryDTO are different kind of types makes it impossible achieve that in a simple Get action method, right?
This scenario can be better resolved by the function feature of the OData protocol that the function takes the TillSummaryDTO collection as input parameter, has some internal complicated logic to query for the right BankingDTO, and returns the BankingDTO instead of TillSummaryDTO.
For the concept of function in OData protocol, you can refer to this link for V4 and section "10.4.2. Functions" of this page for V3.
For implementation, this sample can be referred to for Web API OData V4 and this tutorial can be referred to for Web API OData V3.

Can LINQ be used in Dynamics CRM to get all Accounts not in a Collection?

How can a LINQ query be written to return all Accounts where the account number is not in a List?
The list is going to be pulled from an excel document.
private bool GetAccounts()
{
List<String> accountIds = new List<String>();
accountIds.Add( "[unknown]");
var query = from accounts in context.AccountSet where !accountIds.Contains(accounts.AccountNumber) select accounts;
}
It does not have to be a List.
EDIT
This is what happens when the above query runs - Is this CRM's fault?
I don't believe you can via linq. Here is the where clause limitations from the SDK.
where =>
The left side of the clause must be an attribute name and the right side of the clause must be a value. You cannot set the left side to a constant. Both the sides of the clause cannot be constants.
Supports the String functions Contains, StartsWith, EndsWith, and Equals.
You can get around these limitations by using QueryExpression or FetchExpressions. The query you want would look like this using QueryExpression. The only thing I would mention is if you are expecting a lot of record (5000+ I believe) you will most likely need to implement paging for your function as well.
private static IEnumerable<Account> GetAccounts(IOrganizationService proxy)
{
List<String> accountIds = new List<String>(new string[]{"654321", "12345"});
var results = proxy.RetrieveMultiple(new QueryExpression(Account.EntityLogicalName)
{
ColumnSet = new ColumnSet("accountid", "name", "accountnumber"),
Criteria = new FilterExpression()
{
Conditions = { new ConditionExpression("accountnumber", ConditionOperator.NotIn, accountIds) }
}
});
return results.Entities.Select(x=> x.ToEntity<Account>());
}

LINQ to Entities does not recognize the method 'Boolean CheckMeetingSettings(Int64, Int64)' method

I am working with code first approach in EDM and facing an error for which I can't the solution.Pls help me
LINQ to Entities does not recognize the method 'Boolean
CheckMeetingSettings(Int64, Int64)' method, and this method cannot be
translated into a store expression.
My code is following(this is the query which I have written
from per in obj.tempPersonConferenceDbSet
where per.Conference.Id == 2
select new PersonDetials
{
Id = per.Person.Id,
JobTitle = per.Person.JobTitle,
CanSendMeetingRequest = CheckMeetingSettings(6327,per.Person.Id)
}
public bool CheckMeetingSettings(int,int)
{
///code I have written.
}
Please help me out of this.
EF can not convert custom code to SQL. Try iterating the result set and assigning the property outside the LINQ query.
var people = (from per in obj.tempPersonConferenceDbSet
where per.Conference.Id == 2
order by /**/
select new PersonDetials
{
Id = per.Person.Id,
JobTitle = per.Person.JobTitle,
}).Skip(/*records count to skip*/)
.Take(/*records count to retrieve*/)
.ToList();
people.ForEach(p => p.CanSendMeetingRequest = CheckMeetingSettings(6327, p.Id));
With Entity Framework, you cannot mix code that runs on the database server with code that runs inside the application. The only way you could write a query like this, is if you defined a function inside SQL Server to implement the code that you've written.
More information on how to expose that function to LINQ to Entities can be found here.
Alternatively, you would have to call CheckMeetingSettings outside the initial query, as Eranga demonstrated.
Try:
var personDetails = obj.tempPersonConferenceDbSet.Where(p=>p.ConferenceId == 2).AsEnumerable().Select(p=> new PersonDetials
{
Id = per.Person.Id,
JobTitle = per.Person.JobTitle,
CanSendMeetingRequest = CheckMeetingSettings(6327,per.Person.Id)
});
public bool CheckMeetingSettings(int,int)
{
///code I have written.
}
You must use AsEnumerable() so you can preform CheckMeetingSettings.
Linq to Entities can't translate your custom code into a SQL query.
You might consider first selecting only the database columns, then add a .ToList() to force the query to resolve. After you have those results you van do another select where you add the information from your CheckMeetingSettings method.
I'm more comfortable with the fluid syntax so I've used that in the following example.
var query = obj.tempPersonConferenceDbSet
.Where(per => per.Conference.Id == 2).Select(per => new { Id = per.Person.Id, JobTitle = per.Person.JobTitle })
.ToList()
.Select(per => new PersonDetails { Id = per.Id,
JobTitle = per.JobTitle,
CanSendMeetingRequest = CheckMeetingSettings(6327, per.Person.Id) })
If your CheckMeetingSettings method also accesses the database you might want to consider not using a seperate method to prevent a SELECT N+1 scenario and try to express the logic as part of the query in terms that the database can understand.

Convert Loop To Linq - Model Creation

I'm converting an entity object to a model that can be passed around my application without the extra overhead (As well as generating a couple of extra fields for the view etc.
public IEnumerable<PageModel> GetAllPages()
{
var AllPageO = _session.All<Page>();
IList<PageModel> RetO = new List<PageModel>();
foreach (var AP in AllPageO)
{
RetO.Add(new PageModel(AP));
}
return RetO.AsEnumerable();
}
Can this be converted to a Linq Query, the below does work I get the error
Server Error in '/' Application. Only
parameterless constructors and
initializers are supported in LINQ to
Entities.
public IEnumerable<PageModel> GetAllPages()
{
var AllPageO = _session.All<Page>();
var RetO = from EntityO in AllPageO select new PageModel(EntityO);
return RetO;
}
Resharper actually converts the firt loop into this, which also fails with the same error.
IList<PageModel> RetO = PageO.Select(AP => new PageModel(AP)).ToList();
Thats because entity framework is trying to convert optimize your projection expression into sql.
The easy fix is to enumerate the results before the projection:
var RetO = from EntityO in AllPageO.ToList() select new PageModel(EntityO);

Resources