I have the following classes
public class Person
{
public virtual int Id { get; set; }
}
public class Employee : Person
{
public virtual int EmployeeProperty { get; set; }
}
public class Customer : Person
{
public virtual int CustomerProperty { get; set; }
}
Conceptually a the same Person can be both an Employee and a Customer. Also a Person can exist without either an Employee or Customer record. Using Table Per Subclass how can I get this to work.
As it stands now I don't see a way to get NHibernate to work this way. If I create a Person, and then try to create an Employee using an existing Person Id, NHibernate still tries to insert into Person. Is there a way to get NHibernate to realize that I already have a Person and just want to add the Employee record?
I would prefer to not go to Table Per Class or Table Per Hierarchy if possible.
You model is not correct. If a Person can be both a Customer and an Employee, then you should not use inheritance (An Employee is-a Person), but composition (An Employee has-a [corresponding] Person or A Person has-a Employee [role])
This doesn't work in practice in OO. You would probably want to follow a route that says a person has the roles of being a Customer and also has the role of being an Employee.
Here is a simple example of why this can't work in general OO terms.
Person a = new Employee();
Customer b = (Customer)a; // exception
Related
I pretty want to understand how to organize my code. Let's say i have this class called "Brand" which has a "Product" object:
public class Brand {
public int ID { get; set; }
public int name { get; set; }
public Product product { get; set; }
public void add(Brand brand)
{
// Database logic
}
}
And this class called product
public class Product {
public int ID { get; set; }
public int name { get; set; }
}
What i want to know is should i have a method AddProduct inside product class or should the method be on the top class "Brand". That is my confusion.
In order to make better sense of this, think about separation of concerns and single responsiblity. The answer in this post is a nice way of putting this.
Right now you have an object called Brand that contains a method Add and some properties related to being a Brand object. This means that not only is the Brand charged with managing itself, it's also charged with managing it's own interaction with the database. You are fixing to have a similar coupling between the Product and the database as well. Then what happens when you have a collection of brands, and you realize each brand should have a collection of products, and they all have Database logic strewn throughout? Then, say you notice that each Product needs a list of ingredients, so you have to add that, so the ingredients need database logic, etc. etc. You can see this gets very confusing very quickly.
So really, you should have a third class that is responsible for managing database objects, and that class will have methods to call that take your Brand and Product objects as parameters and interact with the database internally. Now you have abstracted your database logic away from your Brand and Product logic, so the Database class can do what it's built for and no more, and the Brand and Class objects can exist as defined wrappers for related data and no more. Everything is now divided so each class represents a single simple concept. Brand class exists to represent brand data. Database class exists to interact with the database.
I'm sure you get the concept and you may have seen this a thousand times already, but thinking like this will help you spot what needs to change and find much simpler, cleaner, more maintainable solutions.
The way you declared the product is using the C# Auto Property.
First of all, you should ask yourself do you need the product to be visible as public member, or you want to encapsulate the logic of setting the product.
If the answer is that you want to want the Product to be able to set outside, then there is no need to declare any additional method:
public class Brand
{
public int Id { get; set; }
public string Name { get; set; }
public IProduct Product { get; set; }
}
public static void Main(string[] args)
{
var brand = new Brand
{
Id = 1,
Name = "Name",
Product = new Product()
};
}
However, if you want to encapsulate the way you set the product then consider using either Composition or Aggregation approaches:
public class Brand
{
private int _id;
public string _name;
private readonly IProduct _product;
public Brand(IProduct product, int id, string name )
{
_product = product;
_id = id;
_name = name;
}
}
public static void Main(string[] args)
{
var brand = new Brand(new Product(), 1, "prd");
}
Note: if you still want to be able to set the product after object declaration, consider a different name for the method, like SetProduct or something with close meaning, because AddProduct means that you are dealing with the collection of Products.
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).
I have a class Student which needs to be persisted in the database. I have methods that create and update these students (CreateStudent, UpdateStudent) and right now, the structure of this Student class is:
public class Student
{
public int ID { get; set; }
public string FirstName { get; set; }
}
Now what I am thinking is my CreateStudent accepts a Student object:
public int CreateStudent(Student newStudent);
However, since this student is new, the ID wouldn't be persisted (or shouldn't be persisted) to the database. But it seems unclear to the user of the method that this is how it works. For example, I used CreateStudent but passed a Student.ID of 6, the CreateStudent method would ignore the ID since this is creating a student. However, I am trying to find something that is clearer. What I want to try now is separating the ID to an interface which would only be available when a Student is already existing in the database. Sort of like this:
public IEntity
{
int ID { get; set; }
}
public interface IUnknownStudent
{
string FirstName { get; set; }
}
public interface IStudent : IUnknownStudent, IEntity
{
}
Then when using CreateStudent, I pass a IUnknownStudent (no ID).
Only when retrieving or updating will I use the implementation with an ID. But I am not sure if this has any problems since its the first time I'm trying it, and I was wondering if the experienced guys here can give some advice about this.
EDIT:
CreateStudent() is on a separate class, StudentLogic.
One thing I see is that you would probably want a separate class for StudentData in which you have the method
public int createStudent(Student s){
//TODO: Implement method here
}
The reason that I believe that you should have another class to house the method for createStudent is because that you shouldn't have to instantiate a Student to access the createStudent method. Think of it this way, say I create my class Student
public class Student
{
public string firstName { get; set; }
//rest of class
}
When I go to create a Student using the createStudent method inside the class, I would have to say this:
Student s = new Student();
s.createStudent(s);
And that is not really how we want to have to create things, right? That code would be hard to read and understand if you want to keep this updated.
I agree that you'd want to have the ID implemented as a separate class or interface, depending on what you need, and you might want to have a default value for "ID" in the event of an Unknown New Student being created. This way, when you return the ID of the new Student, it's always the same until the user input the new ID for the Student or the next ID was automatically selected. The main thing that I suggest is using a StudentData class to house the createStudent method and house your main function, if you have one. This way, you're using more of an MVC(Model-View-Controller) style of Development, with a Student and their ID as the Model and the View and Controller being handled by the StudentData class. It's just an easy way to structure things once you understand it.
I have my db some relations between entities. For example house-rooms:
public class House{
[Key]
public int Id{get;set;}
public string Address{get;set;}
public virtual IList<Room> Rooms{get;set;}
}
public class Room{
[Key]
public int Id{get;set;}
public string RoomName{get;set;}
[ForeignKey("House")]
public int HouseId{get;set;}
public virtual House House{get;set;}
}
Ok, now when I query for my room like this:
Room room = ctx.Room.Where(x => x.Id == myId).FirstOrDefault();
If I try to serialize it I have the room, with the house not null, which has inside a list of rooms, with a house, with a list of rooms... and so on.
I want the Room to select only non-virtual properties, so for example the HouseId but not the House itself... how can I achieve this?
EDIT:
I forgot yo say that I might need to include those nested entities sometimes. For example sometimes I might need to check a property inside the house inside the room. but sometimes not. Is there a way to choose everytimes?
I need some advice on modeling the following movies domain. I have a person entity. This person can be an Actor, Director, Producer and Writer and will often be all. I don't want to dup data in each entity so feel it best to create an abstract base class called Person that each of the Director, Actor and Writer classes inherit from. This has started to smell a when I look at the following test:
[Test] public void Can_Do_It()
{
var actor = new Actor("Clint Eastwood");
var director = //?? Can new it up as he already exists as actor }
Is it more preferable to have a Person Class and then have Classes like Writer that take in an instance of person i.e.
public class Writer(Person person,
string attribute1, string attrribute2)
{...}
A common solution would be to introduce the concept of 'role' (quite fitting in this case). A person can be an Actor in 0+ movies, and/or fill a Director Role.
That also allows you to add attributes to the role, like character-name, dates etc
Edit:
The Role class would have 2-way associations with both Person and Movie.
class Role
{
public Person Contributor { ... }
public Movie Feature { ... }
public RoleType Activity { ... }
}
class Person
{
public List<Role> Contributions { ... }
}
class Movie
{
public List<Role> Contributors { ... }
...
}
You could have a concrete class Person with all the common details of a person, and then the person class would also have a collection/list of roles. The roles would be Actor, Writer, etc. and they would have all the necessary extra attributes + behaviour.
You should look at a composition rather than inheritance based model for this. Fairly standard design pattern for this sort of thing - in fact, I suspect (don't have a copy to hand) that it's in the Gang of Four design patterns book if you want more information.
If your "roles" are finite and can be defined up-front (as seems the case in your example), you could use a bitwise enum flag on the Person class.
class Person {
[Flags]
public enum EnumRole {
None = 0,
Actor,
Director,
Producer,
Writer
}
public Person( EnumRole role ) {
Role = role;
}
public EnumRole Role { get; set; }
public bool CanDo( EnumRole role ) {
return (Role & role) != EnumRole.None;
}
}
Then create your person with the required roles:
Person p = new Person(Person.EnumRole.Actor | Person.EnumRole.Director);
... and check if they have a required role ...
bool canDoIt = p.CanDo(Person.EnumRole.Actor);