Guys, can you help me out? :)
I'm using 3.6 version of CSLA.
I have a ReadOnlyListBase object and I want to implement a filter that will use different stored procedures. And I've created custom criteria class to pass a parameter to an overload DataPortal.Fetch method.
it goes like this:
#region Factory methods
public static EmployeesiList GetEmployeesList()
{
return DataPortal.Fetch<EmployeesList>();
}
public static EmployeesiList GetEmployeesByDepartment(string department)
{
return DataPortal.Fetch<EmployeesList>(new DepartmentCriteria(department));
}
private EmployeesList()
{
}
#endregion
#region Data Access
private void DataPortal_Fetch()
{
this.IsReadOnly = false;
RaiseListChangedEvents = false;
using (var ctx = ContextManager<MyDatabaseDataContext>.GetManager(MyApp.DalLinq.Database.MyDatabase))
{
foreach(var data in ctx.DataContext.GetEmployees())
this.Add(EmployeeInfo.GetEmployeeInfo(data));
}
RaiseListChangedEvents = true;
this.IsReadOnly = true;
}
private void DataPortal_Fetch(DepartmentCriteria department)
{
this.IsReadOnly = false;
RaiseListChangedEvents = false;
using (var ctx = ContextManager<MyDatabaseDataContext>.GetManager(MyApp.DalLinq.Database.MyDatabase))
{
foreach(var data in ctx.DataContext.GetEmployeesByDepartment(department.Department))
{
this.Add(EmployeeInfo.GetEmployeeInfo(data));
}
}
this.IsReadOnly = true;
RaiseListChangedEvents = true;
}
#endregion
#region Custom Criteria Classes
[Serializable]
private class DepartmentCriteria
{
private string _department;
public string Department
{
get { return _department; }
}
public DepartmentCriteria(string department)
{
_department = department;
}
}
#endregion
I've also added corresponding overloaded Child_Fetch methods to child object.
Anyway, when I try something like:
_employeesList = EmployeesList.GetEmployeesByDepartment("IT department");
i get DataPortal.Fetch failed (DataPortal.Fetch failed (Invalid operation - fetch not allowed))
What am I missing here? :)
You must be reaching this code in ReadOnlyListBase.cs:
protected virtual void DataPortal_Fetch(object criteria)
{
throw new NotSupportedException(Resources.FetchNotSupportedException);
}
So your code should loke like this:
protected override void DataPortal_Fetch(DepartmentCriteria department)
{
this.IsReadOnly = false;
RaiseListChangedEvents = false;
using (var ctx =
ContextManager<MyDatabaseDataContext>.GetManager(MyApp.DalLinq.Database.MyDatabase))
{
foreach(var data in
ctx.DataContext.GetEmployeesByDepartment(department.Department))
{
this.Add(EmployeeInfo.GetEmployeeInfo(data));
}
}
this.IsReadOnly = true;
RaiseListChangedEvents = true;
}
No, it's not working. I got an error:
'MyApp.Library.EmployeesList.DataPortal_Fetch(MyApp.Library.EmployeesList.DepartmentCriteria)': no suitable method found to override'
I haven't mentioned that the first overloaded method without parameters (DataPortal.Fetch()) works as it should.
Try this:
protected override void DataPortal_Fetch(object criteria)
{
var department = criteria as DepartmentCriteria;
if (department == null) throw new InvalidOperationException("No criteria or unknown criteria");
this.IsReadOnly = false;
RaiseListChangedEvents = false;
using (var ctx =
ContextManager<MyDatabaseDataContext>.GetManager(MyApp.DalLinq.Database.MyDatabase))
{
foreach(var data in
ctx.DataContext.GetEmployeesByDepartment(department.Department))
{
this.Add(EmployeeInfo.GetEmployeeInfo(data));
}
}
this.IsReadOnly = true;
RaiseListChangedEvents = true;
}
Not working again :)
'Invalid operation - fetch not allowed'
I must admit that this problem really puzzels me. I was 100% sure that the original code I posted here will work, because custom criteria classes are meant to be used that way. It must be some very trivial problem but I'm obviously not smart enough to figure it out :)
Just guessing:
Your EmployeeInfo.GetEmployeeInfo(data) method does call the child Data Portal??? (It should.)
You could even call it directly from within EmployeesList, making the factory method obsolete for this purpose.
Of course, GetEmployeeInfo() calls child fetch method.
I'm still trying to fix this. I'll add another LINQ2SQL class and try from there. Maybe it's something wrong with current LINQ2SQL class because i was experimenting with it a lot :) It's frustrating :)
There are some known (and unfixable) issues with passing certain arrays to the child data portal, maybe that's the issue you are encountering? The solution is to pass individual items or lists instead of arrays.
The specific behavior around arrays has changed over the past few versions of CSLA as a few of us put in many hours trying to resolve the issue. Ultimately though, there's at least one scenario where it is impossible to differentiate between an array and a list of parameters when accepting a params parameter (and that's what the child data portal accepts).
I've just investigated and I don't know if problem is with Child_Fetch.
But, EmployeesList.GetAllEmployees() method works fine. I have to mention that I've created multiple overloads for Child_Fetch method that accept results from corresponding methods in LINQ2SQL class (GetAllEmployeesResult, GetEmployeesByDepartmentResult etc...) and when i try _employeesList.GetEmployeesByDepartment("Department with no employees") it returns empty list as it should with no exception thrown. Could this be the indicator that there is a problem with Child_Fetch method?
GetAllEmployeesResult and GetEmployeesByDepartmentResult arrays are very similar. They have the same fields. The only difference is that GetAllEmployeesResult of course contains more records.
Finally, is there some other way I could implement filter on ReadOnlyListBase? :)
Finally, is there some other way I could implement filter on ReadOnlyListBase? :)
There are several ways to implement a filter.
Yes, I know about LINQ filter but I just wanted to know about some more techniques. :) This FilterBindingList looks pretty neat.
Thanks a lot Rockford and other guys!
P.S still havent fixed that Fetch error but. Guess I'll have to deal with it some time later.
FilteredBindingList is only useful for Windows Forms. And LINQ queries are not useful for Windows Forms, so you need to pick the right technique based on your UI technology.
It's Windows Forms application and I've already implemented FilteredBindingList. It works as it should.
Thanks again for useful informations :)
Copyright (c) Marimer LLC