Moving to a specific item in CollectionViewSource? - c#

I'm new at WPF and I'm trying to use MVVM. I'm using CollectionViewSource in my view-model against a SQL database using Entity Framework.
So let's say I have this class:
public class People
{
public int Id { get; set; }
public string name { get; set; }
}
And lets say this is what I have in the database:
ID: Name:
Bugs Bunny
Mick Jagger
Mickey Mouse
Donald Duck
Goofy
Elmer Fudd
Daffy Duck
Porky Pig
Now using CollectionViewSource.View, I know how to use the methods MoveCurrentToNext(), MoveCurrentToPrevious(), etc. and that works fine, but I need to move to a specific name, for example Donald Duck. So if I do this:
dbContext.Peoples.Find(4);
Or if I do this
dbContext.Peoples.Where(p => p.Name == "Donald Duck").FirstOrDefault();
That will get me the right object from the database using Entity Framework. However, if I do this:
CollectionViewSource.View.MoveCurrentTo(dbContext.Peoples.Find(4));
It will not move, and CollectionViewSource.View.CurrentItem is null.
So then how would someone move to the correct item?

I guess this is because the reference that you get when calling dbContext.Peoples.Find(4) is not the same as the one you have in your CollectionView source collection.
The CollectionViewSource.View.MoveCurrentTo (an others 'MoveTo' methods of the collectionView) requires an argument that is the same reference as the one in your source collection.
Then, if your dbContext methods to retreive an object returns a new instance or an instance different than the one in your CollectionView, this won't work.
So either use an intermediate collection as the source of the collection view to keep a unique reference to the objects (and update these references when the object in in data access context change) or try to implement equality members in your People class (never tried the later solution but should work).
Also, try to add in your question some complete piece of code rather than code fragments about which we can't realy see exactly where is the problem.

Related

Generate a unique ID to a body property of an object that's CONSISTENT through runtime and presents no overhead to the developer on implementation

This problem is a bit hard to expose via the title so I hope the following clarifies my intentions a bit.
Suppose you have the following data classes:
class abstract Employee {
string ID;
}
class FullTimeEmployee : Employee {
string schedule;
}
class PartTimeEmployee : Employee{
string schedulePartTime;
}
class WheelsSpecialist : Employee{ }
class InteriorsSpecialist : Employee{ }
class Workshop {
WheelsSpecialist wheely_guy;
InteriorsSpecialist interiors_guy;
}
Now, suppose that I instantiate my workshop as follows:
var Workshop = new Workshop{
wheely_guy = new PartTimeEmployee(),
interiors_guy = new FullTimeEmployee();
}
Please assume that the structure / inheritance and instantiations here provided are immutable.
What I'd like is to generate an ID set on Employee.ID that survives the runtime and is consist and independent from class properties / developer implementation.
Understand also that: The path of each object property in the workshop instantiation is guaranteed to be UNIQUE.
As so, a good ID for the WheelsSpecialist in Workshop.wheely_guy would be "Workshop.wheely_guy". (for example) because no path will ever be the same when I'm instantiating the workshop.
When I access the object "Workshop.wheely_guy.ID" I'd like to have "Workshop.wheely_guy" there or something analogous.
I imagine something like this would work (non valid C#, logic intact):
class PartTimeEmployee {
//instantiationPath is for example, "Workshop.wheely_guy"
onCreate(string instantiationPath){
this.ID = instantionPath;
}
}
I've tried this with StackTrace and whatnot, but couldn't find a way of doing it right.
Whether this instantiationPath method is used or not, the solution requires that:
I get to keep my structure as is in the example EXCEPT for properties. Those can change.
When I want to add a new dimension to my workshop variable I CAN'T, as a developer, be responsible for awarding a class it's own unique property.
As so, doing something like "this.ID = wheels" manually is not an option (also, depending this ID on properties that the developer must implement is also not viable).
Can this be done some way that meets my demands?
Thank you!
The provided code does not compile, and the object design/inheritance used seems a bit off. You probably want to work on the abstractions themselves. But that is not what you asked (mainly). It's kind of hard to figure out what exactly you asked, but I will do my best to answer what I think you asked (mostly):
"I want a field of an object instance to contain an automatically calculated navigation path by which it is accessible in some collection or composite object unrelated to the object itself" -> while close to impossible in C#, this might be entirely/easily possible in other languages. Still, the concept itself seems a little off.
The premise here is that the Employee object does not and should not know about the Workshop object Think about part-time employees trying to work separate shifts in separate workshops at the same time, and other possible changes in the business logic regarding Employees and Workshops.
Let's walk through some of the possibilities, ordered by viability:
Doing some magic at constructor/instantiation time in the abstract constructor code (Stack Frame walking, callerMember tricks, Reflection?, AST parsing?)
At instantiation, in a constructor, the stack trace does not contain information about which property/field it is about to be assigned to (if at all for that matter, it might just need to be instantiated, not assigned to anything). So there is no way to set such an id at constructor time.
Doing some magic in the Id property getter
There is no way to pass in parameters to a property getter, so we run into the same type of problem as with option 1: the stack trace contains no useful information by the time the getter is accessed.
Make the Employee object know about Workshop
No, just no.
Some weird runtime/weaving magic to "calculate" these paths when they are accessed?
Maybe, but how much effort to put in and to what purpose?
Expression parsing in a separate method:
//Left out the non-compiling code.
public static void Main(string[] args)
{
var Workshop = new Workshop
{
WheelsGuy = new PartTimeEmployee(),
InteriorsGuy = new FullTimeEmployee()
};
Console.WriteLine(GetObjectAccessPath((_) => Workshop.WheelsGuy));
}
public static string GetObjectAccessPath(Expression<Func<Workshop, Employee>> member)
{
string body = member.Body.Reduce().ToString();
// the line below might take some tweaking depending on your needs
return body.Substring(body.IndexOf($"{nameof(Workshop)}"));
}
// Output: Workshop.WheelsGuy
Use Reflection in a separate method to "get" a list of properties that are of any type derived from Employee and based on that Generate a list of ids with something like properties.Select(p => $"Workshop_{p.Name}");
Most viable: Re-design the object model:
(This is my opinion, and the requirements of your project might be different. Even if I am speculating here, the same principles presented here would apply in many other ways).
Extract more abstractions, like Position, Role, and Schedule. Part-time would be a schedule. Wheels guy would be a role. Position would be "an employee that fulfills the role of wheels guy at a workshop." There might be more examples (pay by hour/week/month, tax exemption, etc.).
As a rule, holding too many concerns in one class is a code smell and will get you in trouble quick. You can choose to carve up the classes however you want, but for what you "seem" to want, this part is important: have a class that represents the relationship between employee and workshop.
For example, instead of the Workshop holding instances of Employees: the Position class would hold/know about an Employee, his Role, his Schedule, and the Workshop he works at. The Position's Id could then easily be Id => $"Workshop_{Role}"; or Id => $"{WorkShop}_{Role}", etc. As a bonus, you get the design bonus of the Workshop being free from knowing which types of employees it might hold.
In general, I'd suggest you look into SOLID principles, it's an eye opener.

How should aggregate expose info from child entity?

[ Follow up from this question Should entity have methods and if so how to prevent them from being called outside aggregate ]
I am trying to understand in full details how aggregate root exposes data from its child entities to outer world; in particular, at least repository will need that info in order to be able to save it.
So, for the sake of the argument, lets consider these rules:
Person have a few channels of communication: phone, email, facebook account (might as well be a collection of each of those but for simplicity lets say its just one of each).
Person can choose to make any of those channels public so that other Persons can contact him or make any of those private so that he can't be pinged through that particular channel.
Person can choose global setting of not being contacted at all. In that case, its forbidden to switch any of the phone, email, facebook to public.
[ Note: the model i'll show now might not be the best one but lets leave remodeling aside for now and focus on exposing child entity infos ]
lets say we have aggregate root Person (c# code), only with example for Phone entity as others are the same logic:
class Person {
...
private Phone Phone { get; set;}
public bool WantsToBeContactedAtAll { get; }
public void ExposePhoneNumberPublic() {
if(!this.WantsToBeContactedAtAll)
throw new SomeError("Not allowed.");
this.Phone.PublishPhoneNumber(true);
}
public void HidePhoneNumber() {
this.Phone.PublishPhoneNumber(false)
}
}
class Phone {
//this is identifier
public readonly string PhoneNumber { get; private set; }
public string Description { get; private set; }
public boolean ShouldBePublished { get; private set; }
public Phone(string phoneNumber, string description, bool shouldBePublished) {
//set values
}
public void PublishPhoneNumber(bool preference){
this.ShouldBePublished = preference;
}
So, what we want to prevent is someone doing:
Person Adam = new Person(...);
Adam.Phone.PublishPhoneNumber(true);
But now, we still need info from Adam.Phone if for nothing else, then for the repository to access it when saving aggregate:
_personRepository.Add(Adam);
Questions:
How to expose Person.Phone info?
Should we expose some copy of the Phone property as a struct (value object)?
Have Phone as private type within Person aggregate and expose another PhoneReadOnly type what would be just a class with properties and getters.
Another way of asking those all question is: how can at least repository read Person.Phone information that it needs in order to be able to save Person?
Please treat me as a complete idiot and explain in details.
Thanks
How shoud aggregate expose info from child entity?
In a way that doesn't allow the caller to change the state of the aggregate.
Pass a primitive value
Pass a reference to an immutable object
Pass a copy of an object
Copies of information are fine, because you can't change my state by changing your copy of my data. References to immutable objects are fine, because you can't change them at all, therefore you can't change my state. But giving you a reference to my mutable state increases the odds of a programmer error.
Let's consider the repository example for a moment -- repositories, remember, are used to give the application the illusion that all of the aggregates are just members of some vast, in memory collection. To support this illusion, the repository needs two functions -- one that takes a representation from our stable data store and creates from it the domain model entities that make up the aggregate, and another that takes the aggregate and constructs from it the representation to put in the data store.
Let's pretend that we had some really naive aggregate that was just an array of integers
class Aggregate {
int [] State;
}
And then we imagine the functions that a repository might need to load and store this aggregate
Aggregate a = Aggregate.from(state)
int [] state = a.state
Now, what happens if we try to cheat?
int [] state = a.state;
state[0] = 12345;
Did a change? Since we want the domain model to be the authority for the state of the world, the answer had better be "no". Which in turn means that the aggregate doesn't yield a reference to its own array, but instead a copy of that array.
The same principle applies if we think about an aggregate with an array of child entities.
class Aggregate {
Child [] children;
}
So what does this aggregate yield? Not it's own array, because that would allow the client to change the aggregate by replacing a Child. But it can't just copy the array either, because we could call methods on one of the child array elements to change itself, which would indirectly change the state of the aggregate.
So we don't return an array of children, we return an array of descriptions of children. It's a sort of "deep copy". The descriptions contain copies of data, but no references -- nothing that links back to the internals of the entity itself -- and so it is safe to yield the description to a caller, who can do what they like with it (including sticking the description into a document store for later recovery).
I tend to think that making your child entities (immutable) value objects simplifies this issue a lot.
A rule of thumb is that you never modify a value object, you replace it. Unlike controlling what people do with the inside of your sub-entities, assigning a value to a direct property of the AR is something you can easily restrict from the root. You can just mark the setter as private and only allow changing it by going through the adequate AR method:
class Person {
public Phone Phone { get; private set; }
public void ExposePhoneNumberPublic() {
if(!this.WantsToBeContactedAtAll)
throw new SomeError("Not allowed.");
Phone = new Phone(Phone.Number, Phone.Description, shouldBePublished: true);
}
}
Note that the part where you take the existing Phone and new up a slightly different one could be done more elegantly - see the "with" keyword here.
Another way of asking those all question is: how can at least
repository read Person.Phone information that it needs in order to be
able to save Person?
I believe that's actually a totally different question. Usually, reading is not the hardest part - if you want any client code to be able to read the Phone, there's no reason that a Repository won't. Writing can be more tricky, as a well-encapsulated aggregate root doesn't necessarily let you change it like that. With ORMs, making the setters protected will work most of the time. An alternative is to use internal with InternalsVisibleTo the concrete repository's assembly, or work with a fully mutable backing state object.

Class Design - Load list in the class or can it be done in any other way?

I am currently designing a class "User"
public class User
{
...
public int LocationId {get; set;}
public string LocationName
{
get
{
//Get name from the LocationList based on the LocationId
}
}
public List<SelectListItem> LocationList
{
get
{
//Retrieve the location as list from DB
}
}
....
}
My concern is that each time a new object is created, the DB will be accessed and the location list will be retrieved.
Can a class be created this way? Or is there a better way of doing it? Any help would be highly appreciated. Thanks.
The database would only be hit when LocationList was accessed, not when the class is newed up. However, no, this is not the best way. Entity classes / view models should not interact with your context directly. The biggest reason for this is that you should really only have one and only one instance of your context and it's not always possible to properly inject it into these classes.
Instead, you should use a repository or service class to abstract away the query and then simply set the list property directly in your controller action by calling some method on your repository or service.
There is one point in addition to what Chris mentioned, take a look on this rule:
CA1002: Do not expose generic lists.
So in general, the class shouldn't expose any property returning a generic list. Try to use one of these:
System.Collections.ObjectModel.Collection
System.Collections.ObjectModel.ReadOnlyCollection
System.Collections.ObjectModel.KeyedCollection
It's almost always a good idea to make a repository whenever an external system/source should be communicated with.
In that way you have all logic that interacts with a given source in one place and can debug and edit it in that one specific place. Plus you should only have a single database context in use at any given time anyway as Chris Pratt mentions.

How to move/copy all the objects from one IList to other

I am working on ASP.NET MVC 4 project. I have ViewModel which is :
public class SectionModel
{
public Menu Menu { get; set; }
public IList<Document> Documents { get; set;}
}
then in my action I have :
Menu menu = unitOfWork.MenuRepository.GetById(Id);
IList<Document> docs = unitOfWork.DocumentRepository.GetBy(x => x.MenuID == menu.MenuID).ToList();
SectionModel model = new SectionModel();
model.Menu = menu;//???
model.Documents = docs;//???
So menu and docs are fetched from the database. The when I create new instance of SectionModel I want to pass the values but I'm not sure what's the proper way. In fact what is the way to assign the single object menu and the IList<Document> docs?
I was thinking of model.Menu.Add(menu) and then some foreach like:
foreach (var doc in docs)
{
model.Documents.Add(doc);
}
but I'm not sure that's the proper way to do this.
There's a common thread of thought I see all the time, about using interfaces to declare lists (or some other collection type) when declaring properties. I understand the motivation to do this, should you ever decide to throw the standard .NET List<> class in favour of your home-grown.
I've yet to see a decent reason for this. You're falling foul of the "let's abstract everything away in all circumstances, even if they are not particularly relevant" idiom. (And let us not forget that interfaces on POCOs are not particularly ORM-friendly.)
If I were designing an API, I might use IList, even if everything worked with a List internally. Truth is, it's a bit of a misnomer. I've never had cause to use an IList<> because that's all it is... a programmatic misnomer.
As Julie says, swap out that interface and put a decent class in there (List<>, for example).. not only is it concrete, but you can then use it as it should be used. People love to band about the terms of interfaces always in case I change my mind but that just stinks of bad design.
Don't be afraid to use a real, concrete class.
I recommend interfaces if your code should inter-operate with others projects but underneath you are using always List<T>
you have to change this
public class SectionModel
{
public Menu Menu { get; set; }
public List<Document> Documents { get; set;}
}
and use
model.Documents.AddRange(docs);
If you consider to use AutoMapper, here's the code:
First, make sure you have AutoMapper installed. Use package-manager and type command package-install AutoMapper.
var anonymous = new {
Menu = unitOfWork.MenuRepository.GetById(Id);,
Documents = unitOfWork.DocumentRepository.GetBy(x => x.MenuID == menu.MenuID).ToList();
};
var sectionModel = AutoMapper.Mapper.DynamicMap<SectionModel>(anonymous);
Any why I suggest to use this ?
Point 1: IList is fine here. Somebody (or you) had put there during design and it's just fine. According to me, changing to List is unnecessary. Your model object is just there to put the information and IList is fine because your sectionmodel class is not going to change or delete any entry from it. Since its just there for enumeration its fine.
Point 2: You can do the manual mapping. But, AutoMapper just maintains code readable.

C# CSLA business object dilemma: read-only vs read/write

I'm part of a team tasked to revamping our old VB6 UI/COBOL database application to modern times. Before I was hired, the decision was made (largely on sales, I'm sure) to redo the UI before the database. So, now we're using WPF and MVVM to great effect, it's been amazing so far, especially using CSLA as our Model layer.
However, because our development is side-by-side with the next version of the old product, we're constrained a bit. We can't make any changes (or minimal changes) to the calls made to the COBOL database. This has been fine so far, albeit pining back to the glory days of SQL Server if you can believe it.
Where I've hit a particularly nasty roadblock regarding our BO design is in dealing with "light" business objects returned in lists and their "full" counterparts. Let me try and construct an example:
Let's say we have a person object in the DB with a bunch of fields. When we do a search on that table, we don't return all the fields, so we populate our lite object with these. These fields may or may not be a subset of the full person. We may have done a join or two to retrieve some other information specific to the search. But, if we want to edit our person object, we have to make another call to get the full version to populate the UI. This leaves us with two objects and attempting to juggle their state in 1 VM, all the while trying to keep the person list in sync on whatever parent object it sits after delete, edit, and add. Originally, I made our lite person object derive from ReadOnlyBase<>. But now that I'm dealing with the same list behavior you'd have with a list of full BOs except with half full, half lite, I'm thinking I should've just made both the lite and full versions derive from BusinessBase<> and simply made the lite version setter properties private.
Has anyone else out there come across and found a solution for this? After sleeping on it, I've come up with this potential solution. What if we wrap the full and lite version of our BO in another BO, like this:
public class PersonFull : BusinessBase<PersonFull>
{
...
}
public class PersonLite : BusinessBase<PersonLite>
{
...
}
public class Person : BusinessBase<Person>
{
public PersonFull PersonFull;
public PersonLite PersonLite;
}
public class PersonList : BusinessListBase<PersonList, Person>
{
}
Obviously everything would be CSLA registered properties and such, but for the sake of brevity they're fields there. In this case Person and PersonList would hold all the factory methods. After a search operation PersonList would be populated by Person objects whose PersonLite members were all populated and the PersonFull objects were all null. If we needed to get the full version, we simply tell the Person object to do so, and now we have our PersonFull object so we can populate the edit UI. If the Person object is to be deleted, we can easily do this with the CSLA delete procedures in place, while still maintaining the integrity of our lists across all the VMs that are listening to it.
So, I hope this made sense to everyone, and if anyone has a different solution they've successfully employed or criticism of this one, by all means!
Thanks!
(Reposted from: http://forums.lhotka.net/forums/thread/35576.aspx)
public class PersonLite : ReadOnlyBase<PersonLite>
{
public void Update(PersonFull person) { }
}
public class PersonFull : BusinessBase<PersonFull>
{
// blah blah
}
I would update the "lite" object with the changes made to the "full" object, and leave it as ReadOnlyBase. It's important to remember that the "ReadOnly" in ReadOnlyBase means an object that is only read from the database, and never saved to it. A less elegant, but more accurate name would be NotSavableBase, because such objects lack the DataPortal_XYZ machinery for anything but fetches. For obvious reasons, such objects usually have immutable properties, but they don't have to. ReadOnlyBase derives from Core.BindableBase and implements INotifyPropertyChanged, so changing the values of its properties will work just fine with binding.
When you save your "full" object, you pass the newly saved instance to the Update(PersonFull) method of the instance that sits in your list, and update the properties of the "lite" object from the "full" object.
I've used this technique many times and it works just fine.
If you look over Rocky's examples that come with the CSLA framework, you'll notice that he always separates the read only objects from the read/write objects. I think this is done for good reason, because the behaviors are going to be drastically different. Read only objects will be more performance based, their validation will be very different, and usually have less information altogether. The read/write objects will not be as perfomance based and rely heavily on validation, authorization, etc.
However, that leaves you with the dilemma you currently find yourself in. What I would do is overload the constructor of each class so you can pass them between each other and "copy" what you need out of each other.
Something like this:
public class PersonLite : BusinessBase<PersonLite>
{
public PersonLite(PersonFull fullPerson)
{
//copy from fullPerson's properties or whatever
}
}
public class PersonFull : BusinessBase<PersonFull>
{
public PersonFull(PersonLite litePerson)
{
//copy from litePerson's properties or whatever
}
}
You could do this with a factory pattern as well, which is Rocky's preference I believe.

Categories