I tried to solve by myself, but... Looks like I need help from people. I have Business Silverlight application with WCF RIA and EntityFramework. Access to Database I get via LinqToEntites.
Common loading data from database I making by this:
return DbContext.Customers
This code returns full Customers table from DataBase. But sometimes I do not need to show all data. Easy way is use linq filters in client side by next code:
public LoadInfo()
{
...
var LO1 = PublicDomainContext.Load(PublicDomainContext.GetCustomersQuery());
LO1.Completed += LO1Completed;
...
}
private void LO1Completed(object sender, EventArgs eventArgs)
{
...
DatatViewGrid.ItemsSource = null;
DatatViewGrid.ItemsSource = loadOperation.Entities.Where(c=>c ...filtering...);
//or PublicDomainContext.Customers.Where(c=>c ...filtering...)
...
}
However this way has very and very important flaw: all data passing from server to client side via DomainService may be viewed by applications like Fiddler. So I need to come up with another way.
Task: filter recieving data in server side and return this data.
Way #1: LinqToEntites has a beautiful projection method:
//MSDN Example
var query =
contacts.SelectMany(
contact => orders.Where(order =>
(contact.ContactID == order.Contact.ContactID)
&& order.TotalDue < totalDue)
.Select(order => new
{
ContactID = contact.ContactID,
LastName = contact.LastName,
FirstName = contact.FirstName,
OrderID = order.SalesOrderID,
Total = order.TotalDue
}));
But, unfortunately, DomainServices cannot return undefined types, so this way won't work.
Way #2: I found next solution - make separate DTO classes (DataTransferObject). I just read some samples and made on the server side next class:
[DataContract]
public partial class CustomerDTO
{
[DataMember]
public int ISN { get; set; }
[DataMember]
public string FIO { get; set; }
[DataMember]
public string Listeners { get; set; }
}
And based this class I made a row of methods which return filtered data:
[OperationContract]
public List<CustomerDTO> Customers_Common()
{
return DbContext.Customers....Select(c => new CustomerDTO { ISN = c.ISN, FIO = c.FIO, Listeners = c.Listeners }).ToList();
}
And this works fine, all good...
But, there is strange problem: running application locally does not affect any troubles, but after publishing project on the Web Site, DomainService returns per each method HTTP 500 Error ("Not Found" exception). Of course, I cannot even LogIn into my application. DomainService is dead. If I delete last class and new methods from application and republish - all works fine, but without speacial filtering...
The Question: what I do wrong, why Service is dying with new classes, or tell me another way to solve my trouble. Please.
U P D A T E :
Hey, finally I solved this! There is an answer: Dynamic query with WCF RIA Services