I have a design like this:
public class Employee {
//...
}
public class Company {
private IList<Employee> _employees;
public IList<Employee> Employees {
get { return _employees; }
set {
if (_employees == value) {
return;
}
_employees = value;
//Some logic here. Eg:
//Raise PropertyChanged
//Iterate over the new values to suscribe to some events, etc.
}
}
}
when I try to do something like:
var employees = session.Query<Company>().Fetch(x => x.Employees).ToList();
it throws a LazyInitializationException:
illegal access to loading collection
The only workaround I've found is moving the logic to a method, making this method public (and virtual) and calling the method for every instance in employees, but I don't like that since I will be calling that method from my repositories.
Any ideas?
You are mixing fetching data from the database with control logic. I'd recommend fetching the data into simple value objects. Then transform it into your Company and Employee logic-laden classes afterwards. That way you separate data entities from functionality based on that data.
In Nhibernate you collection class should not be exposed to the out side world. Your typical domain would look like this
public class Company
{
public virtual String Id { get; set; }
public virtual ICollection<Employee> Employees { get; protected set; }
public Company()
{
Employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
if (Employees.Contains(employee))
return;
Employees.Add(employee);
employee.Company = this;
}
public void RemoveEmployee(Employee employee)
{
if (!Employees.Contains(employee))
return;
Employees.Remove(employee);
}
}
public class Employee
{
public virtual String Id { get; set; }
public virtual String FullName { get; set; }
public virtual Company Company { get; set; }
}
I agree with the first responder who said to user view models and INPC those, but if you want to bind directly to your domain objects, you can inject INPC directly into your domain objects.
Please see this original post from Ayende and this updated one from Ricardo
I guess you are using 'property' as collection accessor in your mapping, if so the behavior you describe is the expected one when your code tries to modify the collection.
If you want to use that pattern in your domain model, you should change collection accessor to 'field' (with the appropriate naming strategy), in order to tell NHibernate to set the backing field '_employees' and not the property 'Employees'.
This will not trigger your code that tries to access the collection anymore.
Related
I have 3 classes
public class ActivityLog
{
// The activity log affects an employee
public int EmployeeID { get; set; }
public Employee Employee { get; set; }
// The activity log affects a department
public int DepartmentID { get; set; }
public Department Department { get; set; }
}
In this example there are two different object types that could be displayed on the view, but in reality there are much more types that differ and for which it doesn't seem sensible to move it to its own inheritance model.
I would like to be able to do the below:
public class ActivityLog<T>
{
// The activity log affects an unknown type
public T ConcernedObjectID { get; set; }
public T ConcernedObject { get; set; }
}
Right now we have a lot of null checks in our view (if employee is null then use department).
Is this something that entity framework can help with somehow, or would it be best to implement a code only solution (e.g. Interfaces)?
I think you have a design problem here. The ActivityLog class tries to do too much. Its both an entry in the log for an employee and for a department. Which are completely different things. The only thing they have in common is that they can be put into an activity log.
I would either use a common interface or an abstract base class. You can then use the asp.net equivalent of data templates to visualize the data.
So something like this:
public abstract class ActivityLogEntry
{
int Id { get; }
}
public EmployeeActivityLogEntry : ActivityLogEntry
{
Employee Employee {get;}
}
public DepartmentActivityLogEntry : ActivityLogEntry
{
Department Department {get;}
}
Another thing that can help you with null checks is to make it explicit that something can be null. I use the Optional NuGet package for that. This gives you something like this
Option<Employee> Employee {get; }
public string ToString()
{
return this.Employee.Match(e => e.Name, () => "");
}
In this case you cannot directly access the Employee that is captured in the Option. Instead you have to provide a Func for what to do when there is an Employee (its not null) and for when there isn't. There are a lot more helper functions in the optional library. It makes it a lot clearer that you need to handle both cases. You can no longer be surprised by something begin null.
(Of course you should not use Option<T> for everything. Only use it on properties that can sometimes be null. Not on properties that should never be null, or you start hiding bugs from yourself).
My goal is to do TwoWay binding off a generated EntityFramework model.
What is the best way to implement NotifyPropertyChanged on properties in a generated entity model?
For example, suppose I have this entity from a database:
public partial class Survey
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Answer { get; set; }
}
I then create a ViewModel...
public class SurveyViewModel : ViewModelBase
{
private Survey _survey = new Survey();
public Survey
{
get { return _survey; }
set
{
_survey = value;
}
}
}
How could I achieve 2 way binding other than writing dependency properties for every single property in the entity model, like so...
//below the declaration of the Survey entity in the viewmodel
public string FirstName
{
get { return Survey.FirstName; }
set
{
Survey.FirstName = value;
NotifyPropertyChanged("FirstName");
}
}
//This works but is very time consuming for large models
Let me know if I'm attempting this wrong...
PropertyChanged.Fody may be what you are looking for:
// Non-auto generated partial class declaration
[ImplementPropertyChanged]
public partial class Survey
{
}
As commented by TyCobb, this question has been asked repeatedly and the result remains the same... here is a summary.
While there are ways pollute your data models with UI accommodating
features such as INotifyPropertyChanged, the MVVM mantra teaches us
that it is the View-Model's job to interact with the UI and the
Data-Model should remain as pure as possible (POCO).
So what? How do we keep to MVVM but avoid the boiler-plate codes of exposing individual properties on the View-Model?
From experience, calling a RaisePropertyChanged is not reserved only for property setters but could be used to manually raise a property changed for a model that has had its own properties modified, thus, cause the UI to update.
Here is a code example...
public class SurveyViewModel : INotifyPropertyChanged
{
private Survey _survey;
public Survey Survey
{
get { return _survey; }
set
{
_survey = value;
RaisePropertyChanged(() => Survey);
}
}
public void ModifySurvey()
{
// Modify a property of the model.
Survey.FirstName = "Modified";
// Make other modifications here...
// Notify property changed
RaisePropertyChanged(() => Survey);
}
}
I am learning C# and i have encounter the following piece of code
public class Album
{
public virtual int AlbumId { get; set; }
public virtual int GenreId { get; set; }
public virtual int ArtistId { get; set; }
public virtual string Title { get; set; }
public virtual decimal Price { get; set; }
public virtual string AlbumArtUrl { get; set; }
public virtual Genre Genre { get; set; }
public virtual Artist Artist { get; set; }
}
just wondering what's the different with the following? i mean without the get and set you can access those public property as well. what's make it important to have those get and set?
public class Album
{
public virtual int AlbumId;
public virtual int GenreId;
public virtual int ArtistId;
public virtual string Title;
public virtual decimal Price;
public virtual string AlbumArtUrl;
public virtual Genre Genre;
public virtual Artist Artist;
}
To have control over your object private fields values. for example if you don't wanna allow nulls or negative values for integers.
bool started;
public bool Started
{
get { return started; }
set
{
started = value;
if (started)
OnStarted(EventArgs.Empty);
}
}
another example
int positiveNumber;
public int PositiveNumber
{
get { return positiveNumber; }
set {
if (value < 0)
positiveNumber = 0;
else positiveNumber = value;
}
}
and also another implementation of read only properties could be as follows
int positiveNumber;
public int PositiveNumber
{
get { return positiveNumber; }
}
You can't declare a virtual field
public class Album
{
public virtual int AlbumId; // <- Syntax error
...
}
properties are, in fact, methods: get or(and) set, so
public class Album
{
public virtual int AlbumId { get; set; } // <- Both get and set methods declared as virtual ones
...
}
And you can override these get's or(and) set's in derived class if you want:
public class GreatAlbum: Album {
private Boolean m_IsGreat;
public override int AlbumId {
get {
if (m_IsGreat)
return base.AlbumId
else
return 0;
}
set {
m_IsGreat = (value != 0);
base.AlbumId = value;
}
}
...
}
With providing get(accessor) and set(mutator) methods, you can control accessing and mutating.
For example:
You have a property that you don't want to be set any value more than 15. So u make required restrictions in your set method. Unless that set method, you can't control.
But in your example, your get and set methods are default, means controlling nothing.
The main reason behind properties is to protecting and presenting private data in a controlled way.
In fact, properties show their abilties in the usage like this:
public virtual int AlbumId
{
get { // ... some magical operations ... }
set { // ... some magical operations ... }
}
And about your main question - what's the difference in this example - the main point to attention is the virtual keyword.
This keyword causes the property to be overrideable, So any other code could override the default get; method. It meens that you have the default behavior for yourself, and other codes (Extremely used in Entity Framework) implement their own logic!
Those second ones in your example aren't properties, so they don't express this magical ability...!
In the first case you are dealing with properties, in the second with fields.
Using fields has several drawbacks when compared to using properties. These drawbacks include:
You can set a breakpoint in a get or set of a property, but you can not set a breakpoint on access to the field.
Making fields public violates the information hiding principle.
The binary MSIL code for accessing fields and properties is different, so if you change a public field to a public property in the future, although the source code stays compatible, any dependant binary code breaks.
The code required to use reflection is different, hence when you move from a field to a property, your reflection code will break.
To cut a long story short: Always use public properties, NEVER use public fields.
There are a number of differences:
Properties are turned into methods by the compiler. As such, you can declare them virtual and override them in a derived class.
Using properties, you can put logic in the getter or setter (filtering, validation etc).
When you use automatically implemented properties ({ get;set;}), it may seem that you might as well just use public fields. However, using properties means you can change your getter or setter implementation at a later time, without changing the interface your class is exposing. If you had used a field and wanted to implement filtering whenever that field was read, you would have to introduce a new method, make the field private and break all existing consumers of the type.
Personally, I think the automatically implemented properties promote bad style, because they do not encourage encapsulation. Tools like ReSharper also like to generate properties with {get;set} accessors. Novice developers thus typically end up with classes with lots of {get;set;} properties exposing the type's state to the world. You should at least use {get; private set;} by default.
In my domain model I have an Entity object that looks as follows:
public class Group
{
public int idGroup { get; set; }
public string Description { get; set; }
}
I have a repository for this object:
public class GroupRepository : IGroupRepository
{
public Group LoadGroup(int idGroup)
{
//imitation of SQL data reader
Group g = new Group();
g.idGroup = Convert.ToInt32(r["idTipoGrupo"]);
g.Description = Convert.ToString(r["Descricao"]);
return g;
}
}
But now I need to get some extra information from data store about Group objects through a new function in my created repository, here are the fields I need:
public bool HasChildGroups { get; set; }
public int ChildGroupsCount { get; set; }
public bool HasDeals { get; set; }
public int DealsCount { get; set; }
These properties look to me like a "service" or "helper" properties and I don't plan to use them everywhere in my application, only few times, but I need them. The simplest thing I could think of is that I added these "service" properties to my Group object and created a method in my repository that populates them. But I consider doing this wrong, as it is the Entity and I don't need them in here. So where should I keep such "service" objects? Do I have to create a new class that inherits from Group like this:
public class GroupHelper : Group
{
public bool HasChildGroups { get; set; }
public int ChildGroupsCount { get; set; }
public bool HasDeals { get; set; }
public int DealsCount { get; set; }
}
Or should I consider using some Data Transfer Objects?
How would you solve this problem?
Any help appreciated.
The first question to ask is how the state of the proposed GroupHelper object is managed. Attributes such as HasChildGroups seems like they would be altered as a result of behaviors invoked on a Group entity. If so, then they should be first class entities in your domain model, perhaps event part of the group entity itself. If the properties are managed outside of your domain model then you can just query that data as you would any other external data source. I would have this be a standalone object, perhaps called something like GroupInfo not extending Group itself.
What seems to be the issue here is that you have query requirements that aren't in alignment with the shape of your entities. In that case you have the flexibility to decouple your read-models from your domain models. Read-models are intended to fulfill query requirements and your domain models are intended to host behavior associated with your domain.
HasChildGroups [...] look to me like a "service" or "helper" properties [...] But I consider doing this wrong, as it is the Entity and I don't need them in here.
If you concider your Group object to be a data access object and you have a separate model for, say, viewdata, you're right.
But this may also be a fat class, providing in view-specific and database-specific code. It's not plain wrong.
You could indeed create a GroupDTO class that provides the properties you require in the application but not for the data access, to separate concerns.
For example I have following domain model:
class Order {
public virtual int Id {get; protected set;}
public virtual BaseStatus Status {get; set;}
}
abstract class BaseStatus {
public virtual int Id {get; protected set;}
public abstract string Name {get;}
}
class Approved : BaseStatus {
public override string Name
{
get { return "Approved"; }
}
}
So now what I wan't to have is two tables, Orders and Statuses. Where Orders table will have StatusId column.
The question is about API of changing order status. If I do the following:
order.Status = new Approved();
That will lead to creation of new row in statuses table.
Currently I have created following helper:
class StatusesFactory {
ISession session;
public StatusesFactory(ISession session){
this.session = session;
}
public GetStatus<T> where T : BaseStatus, new() {
T status = session.QueryOver<T>.SingleOrDefault();
if(status == null){
status = new T();
session.SaveOrUpdate(status);
}
return status;
}
}
And when I want to set status I'm using such code:
order.Status = statusesFactory.GetStatus<Approved>();
It seems to work fine, but to be complex with no reason. I'm using NHibernate but I think the same question may be applied to any ORM. The reason for such a thing is easy deployment on empty data base so that it is filled on first requests.
How do you handle dictionary tables?
Does my approach have obvious down sides that I can't see?
One problem that I see here is when I need to get all possible statuses I cant use code like:
session.QueryOver().List();
because not all statuses may be created yet.
So what do you think?
good question ...
i'd think that your Approved-class should use make use of the singleton pattern, since there can be only one Approved-state ...
the list of all existing vs. all possible states is a bit more difficult ... the possible states depend on what classes inherit from BaseState... i have no idea how to find those fast, since they don't have to reside in the current assembly, or even in a loaded assembly ... you should think about a static list of all subclasses singleton objects in BaseStatus ...