WCF Data Service Query error
-
2012年3月22日 14:28
Hi,
I would like to filter the properties I return from the WCF Data Service but I am getting the error below:
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<LabellerWebTest.LabellerDataServiceRef.SiteClientMailing>' to 'System.Collections.ObjectModel.Collection<LabellerWebTest.LabellerDataServiceRef.SiteClientMailing>'. An explicit conversion exists (are you missing a cast?)
This is the code I have used. Could someone please shed some light on how I can achieve this:
LabellerDataServiceRef.DocketHubEntities ctx = new LabellerDataServiceRef.DocketHubEntities(new Uri(@"http://localhost:2332/LabellerDataService.svc", UriKind.RelativeOrAbsolute));
public IEnumerable<SiteClient> GetSiteClient()
{
var companies = (from sc in ctx.SiteClients.Expand("SiteClientMailing")
orderby sc.ClientName
select new SiteClient
{
SiteClientID = sc.SiteClientID,
ClientName = sc.ClientName,
SiteClientMailings = (from m in sc.SiteClientMailings
orderby m.ClientName
select new SiteClientMailing
{
ClientName = m.ClientName,
PlannedMailingDate = m.PlannedMailingDate})
});Cheers
C
すべての返信
-
2012年3月22日 15:00モデレータ
There are three problems with your query:
1) WCF DS Client doesn't support orderby in the expansion. So the orderby you specified for the SiteClientMailings will not work.
2) The error comes from the C# compiler which is complaining that your SiteClientMailings property is Collection<T> but you're assigning an IEnumerable<T> to it. I think just a simple cast might solve this problem.
3) Since you prescribed the shape of the result using select statements, the usage of Expand() method is not needed and I think it will also cause failures.
Thanks,
Vitek Karas [MSFT]
-
2012年3月22日 16:11
Hi Vitek,
Thanks for your help.
2 - Could you please show me where and how to cast it?
3 - I think the expand is causing problems as you mentioned but how can I get all the child SiteClientMailings if I do not use expand? Please also note that I am trying to limit the properties returned by the method.
Cheers
C
-
2012年3月22日 18:22モデレータ
2 - Just add (Collection<LabellerWebTest.LabellerDataServiceRef.SiteClientMailing>) in front of your inner query (from ...).
3 - The fact that you have an inner query for the SiteClientMailings will tell the LINQ translator to expand it already.
Thanks,
Vitek Karas [MSFT]
-
2012年3月22日 19:23
Hi Vitek,
Thanks again. I will try this tomorrow since I do not have the computer with me at the moment.
I will let you know how I get on.
I had an idea but I would like your suggestion to see if this is the right approach. Would that be better if I created a ?
I have tried creating a custom model to encapsulate the EF model where I return only one properties of Department - ID but also return some properties of the related Employees that are in that departmet.
However, I get an error to do with Data services not liking complex properties.
Is it possible to achive what I need?
[DataServiceKey(ID)]
public class DepartmentModel
{public int ID { get; set; }
public IQueryable<EmployeeModel> Employees}
[DataServiceKey(ID)]
public class EmployeeModel
{
public int ID { get; set; }
public string FirstName { get; set; }
}public class DataModel
{
public DataModel()
{
using (var dbContext = new ODataDemoEntities())
{
Departments = from d in dbContext.Departments
select new DepartmentModel
{
ID = d.DepartmentID,
Employees = (from e in d.Employees
select new EmployeeModel
{
ID = e.EmployeeID,
FirstName = e.FirstName
}
)
};public IQueryable<EmployeeModel> Employees { get; private set; }
public IQueryable<DepartmentModel> Departments { get; private set; }
}
Cheers
C
-
2012年3月22日 22:55モデレータ
I don't see anything particularly wrong with the above. Could you please post the exception along with its callstack when you get a chance?
Thanks,
Vitek Karas [MSFT]
-
2012年3月23日 10:58
Hi Vitek,
How are you?
I have casted the inner query as you suggested but I get another error during run time:
Error translating Linq expression to URI: Initializing instances of the entity type LabellerWebTest.LabellerDataServiceRef.SiteClient with the expression Convert(sc.SiteClientMailings.Select(m => new SiteClientMailing() {ClientName = m.ClientName, PlannedMailingDate = m.PlannedMailingDate})) is not supported.}
I am posting below my Test Repository class that calls the WCF Data Service and the WCF Data Service. Could you spot anything could be causing this error?
I did not realise it was so difficult to flat the objects and limit the number of properties returned by WCF Data Services :-)
Cheers
TestRepository
public class TestRepository : ILabellerRepositoryDataService, IDisposable
{
LabellerDataServiceRef.DocketHubEntities ctx = new LabellerDataServiceRef.DocketHubEntities(new Uri(@"http://localhost:2332/LabellerDataService.svc", UriKind.RelativeOrAbsolute));
public IEnumerable<LabellerDataServiceRef.SiteClient> GetSiteClient()
{
var companies = (from sc in ctx.SiteClients
select new LabellerDataServiceRef.SiteClient
{
SiteClientID = sc.SiteClientID,
ClientName = sc.ClientName,
SiteClientMailings =
(Collection<LabellerWebTest.LabellerDataServiceRef.SiteClientMailing>)(from m in sc.SiteClientMailings
select new LabellerDataServiceRef.SiteClientMailing
{
ClientName = m.ClientName,
PlannedMailingDate = m.PlannedMailingDate})
});return companies;
}public void Dispose()
{
throw new NotImplementedException();
}
}WCF Data Service
[System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class LabellerDataService : DataService<DocketHubEntities>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;config.UseVerboseErrors = true;
config.MaxBatchCount = 40;
}
} -
2012年3月23日 20:00
Any help? Thanks
C
-
2012年4月25日 22:40モデレータ
Hi Claudio,
Change your code to be :
var companies = (from sc inctx.SiteClients select new LabellerDataServiceRef.SiteClient { SiteClientID = sc.SiteClientID, ClientName = sc.ClientName, SiteClientMailings = new List<LabellerWebTest.LabellerDataServiceRef.SiteClientMailing>( from m in sc.SiteClientMailings select new LabellerDataServiceRef.SiteClientMailing { ClientName = m.ClientName, PlannedMailingDate = m.PlannedMailingDate }) });Phani Raj Astoria http://blogs.msdn.com/PhaniRaj
-
2012年4月26日 11:19
Hi Phani Raj,
Thanks for your reply and sample code. Unfortunately I get this error when I try you code?
Cannot implicitly convert type 'System.Collections.Generic.List<LabellerWebTest.LabellerDataServiceRef.SiteClientMailing>' to 'System.Collections.ObjectModel.Collection<LabellerWebTest.LabellerDataServiceRef.SiteClientMailing>'
Do you have any ideas what I have to do to fix it?
Cheers
New Code Below
--------------------LabellerDataServiceRef.DocketHubEntities ctx = new LabellerDataServiceRef.DocketHubEntities(new Uri(@"http://localhost:2332/LabellerDataService.svc", UriKind.RelativeOrAbsolute));
public IEnumerable<LabellerDataServiceRef.SiteClient> GetSiteClient()
{
var companies = (from sc in ctx.SiteClients
select new LabellerDataServiceRef.SiteClient
{
SiteClientID = sc.SiteClientID,
ClientName = sc.ClientName,
SiteClientMailings =
new List<LabellerWebTest.LabellerDataServiceRef.SiteClientMailing>(
from m in sc.SiteClientMailings
select new LabellerDataServiceRef.SiteClientMailing
{
ClientName = m.ClientName,
PlannedMailingDate = m.PlannedMailingDate
})
});
return companies;
} -
2012年4月26日 15:49モデレータ
Hi Claudio,
I didn't know that the left hand side type was Collection<T>,
try changing the property assignment to be :
SiteClientMailings =
new Collection<LabellerWebTest.LabellerDataServiceRef.SiteClientMailing>( new List<LabellerWebTest.LabellerDataServiceRef.SiteClientMailing>(
from m in sc.SiteClientMailings
select new LabellerDataServiceRef.SiteClientMailing
{
ClientName = m.ClientName,
PlannedMailingDate = m.PlannedMailingDate
}) )This way, you use the constructor of Collection<T> which takes a List<T> instance.
Phani Raj Astoria http://blogs.msdn.com/PhaniRaj
-
2012年5月1日 8:21
Hi Phani Raj,
Sorry for the long time I took to anwser back but I have finally had time to have a look at it.
I tried your new sample code and got this error message:
"
Initializing instances of the entity type LabellerWebTest.LabellerDataServiceRef.SiteClient with the expression new Collection`1(new List`1(sc.SiteClientMailings.Select(m => new SiteClientMailing() {ClientName = m.ClientName, PlannedMailingDate = m.PlannedMailingDate}))) is not supported."
Do you have any ideas why I am getting this message? Is there a way to fix it?
Cheers
This is the full code:
LabellerDataServiceRef.DocketHubEntities ctx = new LabellerDataServiceRef.DocketHubEntities(new Uri(@"http://localhost:2332/LabellerDataService.svc", UriKind.RelativeOrAbsolute));
public IEnumerable<LabellerDataServiceRef.SiteClient> GetSiteClient()
{
var companies = (from sc in ctx.SiteClients
select new LabellerDataServiceRef.SiteClient
{
SiteClientID = sc.SiteClientID,
ClientName = sc.ClientName,
SiteClientMailings = new Collection<LabellerWebTest.LabellerDataServiceRef.SiteClientMailing>
(new List<LabellerWebTest.LabellerDataServiceRef.SiteClientMailing>
(
from m in sc.SiteClientMailings
select new LabellerDataServiceRef.SiteClientMailing
{
ClientName = m.ClientName,
PlannedMailingDate = m.PlannedMailingDate
}))
});
return companies;
}

