Choose between one-to-one and component in NHibernate - nhibernate

I am trying to map classes User and Profile, just as the following:
public class User
{
public long ID { get; set; }
public string LoginName { get; set; }
public Profile Profile { get; set; }
}
public class Profile
{
//the ID is the same with User's ID
public long ID { get; protected set; }
public string NickName { get; set; }
public Gender Gender { get; set; }
}
So, they can be mapped as both one-to-one and componenet relationship. And I find some people appraise the component and think one-to-one is a bad practise, why? For performance reason? But they are designed as two separate tables in many scenarios(asp.net2.0 Membership, for example).
How should I choose? Which aspects should I consider? I know component means "value object" but not an enitity, but does this mean some further things?
ps: And what confused me more is the opinion that the many-to-one should be used even it's one-to-one relationship in real world!

The key should be in your use cases for this class. Don't take ASP.NET Membership as an example, because its design is terrible.
You need to answer these questions:
Does a Profile make sense as an entity of its own?
Do you have references to the Profile anywhere else in your domain?
Can you have a User without a Profile?
Does it have a behavior of its own?
Would you extend (inherit) Profile for some reason?
Do most use cases just deal with the user (and its LoginName, not just the ID) but not the profile?
If most questions are true, you have a good case for using one-to-one (I disagree with #Falcon; this is actually one of the legitimate uses for one-to-one)
Otherwise, a Component will work fine. It doesn't have an ID, so you can remove that property.

You should use neither.
One-To-One
You have the user and the profile in different database tables but both share a mutually exclusive PK:
See http://jagregory.com/writings/i-think-you-mean-a-many-to-one-sir/
Pretty bad design practice for relational databases, it's messy and does not necessarily enforce constraints for the relationship.
Component
You can use component to get a clean Object-Model from a messy relational database, profile and user data are both stored in the same database table but they should be separated in your object model (like you want it, judging from your code). Lazy loading probably isn't supported, which will cause high database traffic.
Reference
Imho, you should use a Reference. It's conceptual kinda like one-to-one but a user references a profile. The profiles can be stored in their own table, can be loaded lazily (performance) and are not dependent on a user.
Regarding your confusion:
Just read the link I supplied. Technically, you need a many to one for a properly designed database-scheme, as that is what is technically possible and will be mapped. I know it's confusing. If you just need to map one-side, think of a reference instead of a one-to-one.

Related

ASP.NET Boilerplate misleading naming convention and files structure

ASP.NET Boilerplate creators claim their framework uses already familiar tools and implements best practices around them to provide you a SOLID development experience.
But I can't understand what the basis of some part of their naming convention and files structure.
For example, this is a part of their official SimpleTaskApp example:
[AutoMapFrom(typeof(Task))]
public class TaskListDto : EntityDto, IHasCreationTime
{
public string Title { get; set; }
public string Description { get; set; }
public DateTime CreationTime { get; set; }
public TaskState State { get; set; }
}
TaskListDto is very misleading! Isn't TaskDto more understandable?
Or why folders containing entities should be plural: Tasks/Task.cs or People/Person.cs.
Why are they kept apart at all? Is it not better to put all entities into one Entites folder in the Domain layer?
I Do not have any experience with this framework but there is a concept in DDD called Domain Aggregates. It defines that entites with the same concept should be kept close together. For example we have a concept called people that some entities carry the same concept. We take Person as an aggregate root and all the other entities with the same concept are accessible via that aggregate root. So we keep the entites with the same concept under the same folder.
As of the TaskListDto I think the name should serve the purpose of the Class. And thus here we want to have a list of Tasks not a single task.
reading further about Domain Aggregates: https://www.jamesmichaelhickey.com/domain-driven-design-aggregates/

Using different models for one view for GET and POST

I've seen multiple answers on this so I'm really confused.
Using one single view, can you use one model for the GET action and a different model for the POST? As an example, here's what I've got--here's an example of a ViewModel I have:
public class ModelAViewModel {
public ModelB modB { get; set; }
public ModelC modC { get; set; }
}
I currently use ModelAViewModel to do a GET to display data from ModelB and ModelC. I was wondering if I could also do a POST of just ModelB and then make a new object of ModelC in the POST function.
Might be bad coding standards, but a new requirement of a feature came in to display ModelC's data, and I was wondering if this was possible without refactoring.
In general, always just go for it. If it doesn't work, then you can ask for advice, but just try it and see what happens.
Since you're here already, though, I can tell you that this is fine. If you don't post anything for modC, it will just be null on POST. Also, the model validator doesn't validate null instance properties, so you can still have required properties and such on ModelC and as long as you don't post anything at all related to it, you won't get errors.

Proper design technique

I am creating an asp.net mvc4 application that will ask the user a set of questions based on a particular criteria that they enter. Each question is stored in a table and only those questions that meet the criteria will be displayed to the end user.
I am using a viewmodel that combines information from a couple of different tables. Basically it has a list of Questions and an inspection id to tie all the test together. My question is what is the proper oo design technique for populating the viewmodel.
Should the method / methods for populating the viewmodel reside within the viewmodel class itself? Basically passing the entities into the viewmodel and allow it to populate itself.
Should there be a new class that you send in the entities in and it returns the viewmodel?
Or is there a better way to do this.
yes, your approach is valid.
Consider the following example in your model:
public List<Questions> Questions
{
get {
QuestionRepository Rep = new QuestionRepository();
return Rep.ObtainQuestions(ClientAge,ClientType)
}
}
public int ClientAge { get; set; }
public ClientTypeEnum ClientType { get; set; }
the getter in the Questions property includes all the logic. as long as the clientAge and the ClientType properties have valid values, the question list will be populated. this avoids having to set the data in every action method where you need to populate the property.
in the example I am getting the data from a repository but you could get it from an ORM like entity framework, or any other source.
you can google the term skinny controllers and read up more on the recomendations and best practices.

should my POCO classes communicate with repositories, and if so- how to do it?

I'm writing an ASP.Net webforms app using nHibernate. Currently I'm not using any IoC framework.
Firstly- my scenarios:
I don't want to allow two Employees with the same name. I would like to enable the Employee class to search for other Employee with the same name and issue an error.
A Department may have 1000s of Employees. I need to know exactly how many Employees each Department has. I don't want to load them all into memory, so I use a calculated property- EmployeesCount. However, this property is initialized the first time the Department object is loaded. If I add / remove employees the changes are not reflected in that property. (especially since I'm using 2nd level cache, so my object persists over multiple Session scopes)
My idea of solving these problems is to have my domain objects hold reference to the appropriate Repository objects.
I think the best solution is to have my repositories implement interfaces and use some sort of IoC container / DI mechanism.
So, in Employee I'll have:
if (_empRepository.GetEmployeeByName(newEmployeeName) != null) //...
and in Department:
public int EmployeesCount
{
get
{
return _departmentRepository.GetCurrentEmployeesCount(this);
}
}
my questions:
Which is prefferable- c'tor DI
public Employee(IEmployeeRepository repository)
or using an IoC container?
public Employee()
{
_empRepository = container.Resolve<IEmployeeRepository>();
}
How to implement the desired solution? I understand that Interceptors / tuplizers is the way to go, but I couldn't really get my head around the whole thing. Is this a good example? Also- in which namespace should I define the Interfaces, the IoC container etc.?
The POC0-to-persistence relationship is usually uni-directional: The persistence tier knows about POCOs, but not the other way around.
The moment you make the POCO responsible for things like searching for other Employees with the same name, you make it bi-directional. I'd be concerned about growing cycles between modules in your design.
Putting that activity in the POCO might sound like a good idea, because it helps to avoid the "anemic domain model" label, but I wouldn't do it. I'd put those methods on persistence interfaces and let them handle it. It's also more likely that the service in charge of fulfilling the use case would want to know about duplicate Employee names; let it do the asking and leave POCO out of the conversation.
This approach will make your testing life easier. You'll know how painful module cycles can be when you go to test. You'll have to drag too much machinery into the test to get it to work.
i also think Pocos shouldn't know about persistance. Have you considered alternatives like
class Department
{
public int Id { get; set; }
public IList<Employee> ActiveEmployees { get; set; }
}
public DepartmentMap()
{
...
HasMany(d => d.ActiveEmployees)
.KeyColumn("department_id")
.Where("stillactiveindepartment = true") // for example
.ExtraLazyLoad(); // will issue an Count(*) instead of initializing collection, also other methods like Contains() issue an sql
}
For Employee with unique names:
1) in the service/controler: before saving a new employee issue a query which checks if an employee with same name already exists.
2) Unique Constraint in database will give an exception on save.
3) Custom interceptor in the session which hooks the save/flush event. it can throw if there is already a customer
The other answer mostly addresses the questions you asked, and I agree with the advice there.
For your question about accessing employee counts, look into using projections with NHibernate. I'd put a query in your service layer (for whatever web service operation needs to get the employee count) that uses a count projection.
EDIT: Forgot you're using Services/Repositories/POCOs. In that case, create an employee count query in the repository and invoke it from the service.

Patterns for building social network type applications?

I need to design / architect / develop a web based social network type application.
Basic functionality:
- users create accounts on the system
- users agree to "friend" each other
- users create content within system
- users specifies which friends may view/edit content that they created
Surely this core functionality has been created many times before? Are there any best practice patterns out there for how to implement this sort of thing?
I'm most interested in how the database for this would look.
What would this look like from a SQL perspective (any database)?
What would this look like from a NOSQL perspective (any NOSQL database)?
The thing I am most interested in, is how is the question of "content visibility" solved within the database? i.e. how does the database/application ensure that only approved friends may see the user created content?
Thanks
First thing to get out the way is the database, an SQL one would just look like a normalised sql database. What else could it look like? A nosql database would look like a bunch of name value pair files.
Three approaches to building a social web site after and only after you do a shed load of research on existing popular and unpopular ones to ascertain their architecture and the markets that that they are aimed at, and the particular services that they offer to these markets.
Roll your own from scratch (and or use a framework). Like Facebook, Beebo, Myspace et al. This is obviously the longest route to getting there but it does mean you have something to sell when you do. Both the platform and the membership and the USP are yours to sell to Rupert Murdoch or whomever.
Use a CMS that lends itself to social site and use the basic functionality, plus the plug-ins plus your own inspiration to hit your target market. In this area Drupal is often used (i have used it successfully as well) but Joomla, Xaraya and many other both free and paid for can be used. Yep more research. Less to sell here when Rupert gives you a bell as the base tool is probably GPL'd
Use one of the provided system where you sign up and then use the tools to build your own but all the goodies are provided, These are known as white label sites. Start looking here. Here you have little to sell on if someone wants to take you over.
How is "content visibility" handled. Initially of course the site builder makes a decision on who can see content. Owners only, friends, registered users, the general public? etc. But this decision must fir in with the aims and policies of the site. The best way then to handle this is through Role Based Access RBAC see here for details
When you say you "need to design / architect / develop" is this because of an overwhelming inner urge or because someone is paying you?
Either way remember the social web space is very very crowded. If you are just building another YouTube, or FaceBook then you are unlikely to be able to generate the critical mass of number required to make such a site commercially successful.
If it is for a niche market not already catered for, e.g. "The Peckham and Brockley Exotic Bird Fanciers Club" then you know what you market is and what features will be required so any of the above options you deem the easiest and cheapest can be used but that is up to you to analyse and execute.
You may of course have an idea for a social site that is mainstream and is not covered by the other, i.e. you have spotted the mythological "gap in the market". In this case go for it but prepare to be disappointed. Or not.
Your design should be maintenable. This is what I have in my project.
1.) Application.Infrastructure
Base classes for all businessobjects, busines object collection, data-access classes and my custom attributes and utilities as extension methods, Generic validation framework. This determines overall behavior organization of my final .net application.
2.) Application.DataModel
Typed Dataset for the Database.
TableAdapters extended to incorporate Transactions and other features I may need.
3.) Application.DataAccess
Data access classes.
Actual place where Database actions are queried using underlying Typed Dataset.
4.) Application.DomainObjects
Business objects and Business object collections.
Enums.
5.) Application.BusinessLayer
Provides manager classes accessible from Presentation layer.
HttpHandlers.
My own Page base class.
More things go here..
6.) Application.WebClient or Application.WindowsClient
My presentation layer
Takes references from Application.BusinessLayer and Application.BusinessObjects.
Application.BusinessObjects are used across the application and they travel across all layers whenever neeeded [except Application.DataModel and Application.Infrastructure]
All my queries are defined only Application.DataModel.
Application.DataAccess returns or takes Business objects as part of any data-access operation. Business objects are created with the help of reflection attributes. Each business object is marked with an attribute mapping to target table in database and properties within the business object are marked with attributes mapping to target coloumn in respective data-base table.
My validation framework lets me validate each field with the help of designated ValidationAttribute.
My framrwork heavily uses Attributes to automate most of the tedious tasks like mapping and validation. I can also new feature as new aspect in the framework.
A sample business object would look like this in my application.
User.cs
[TableMapping("Users")]
public class User : EntityBase
{
#region Constructor(s)
public AppUser()
{
BookCollection = new BookCollection();
}
#endregion
#region Properties
#region Default Properties - Direct Field Mapping using DataFieldMappingAttribute
private System.Int32 _UserId;
private System.String _FirstName;
private System.String _LastName;
private System.String _UserName;
private System.Boolean _IsActive;
[DataFieldMapping("UserID")]
[DataObjectFieldAttribute(true, true, false)]
[NotNullOrEmpty(Message = "UserID From Users Table Is Required.")]
public override int Id
{
get
{
return _UserId;
}
set
{
_UserId = value;
}
}
[DataFieldMapping("UserName")]
[Searchable]
[NotNullOrEmpty(Message = "Username Is Required.")]
public string UserName
{
get
{
return _UserName;
}
set
{
_UserName = value;
}
}
[DataFieldMapping("FirstName")]
[Searchable]
public string FirstName
{
get
{
return _FirstName;
}
set
{
_FirstName = value;
}
}
[DataFieldMapping("LastName")]
[Searchable]
public string LastName
{
get
{
return _LastName;
}
set
{
_LastName = value;
}
}
[DataFieldMapping("IsActive")]
public bool IsActive
{
get
{
return _IsActive;
}
set
{
_IsActive = value;
}
}
#region One-To-Many Mappings
public BookCollection Books { get; set; }
#endregion
#region Derived Properties
public string FullName { get { return this.FirstName + " " + this.LastName; } }
#endregion
#endregion
public override bool Validate()
{
bool baseValid = base.Validate();
bool localValid = Books.Validate();
return baseValid && localValid;
}
}
BookCollection.cs
/// <summary>
/// The BookCollection class is designed to work with lists of instances of Book.
/// </summary>
public class BookCollection : EntityCollectionBase<Book>
{
/// <summary>
/// Initializes a new instance of the BookCollection class.
/// </summary>
public BookCollection()
{
}
/// <summary>
/// Initializes a new instance of the BookCollection class.
/// </summary>
public BookCollection (IList<Book> initialList)
: base(initialList)
{
}
}
a Graph Database like http://www.neo4j.org is a choice to look at. It lends itself very well to both the social network (e.g. http://blog.neo4j.org/2009/09/social-networks-in-database-using-graph.html) and the ACL-based security (e.g. http://wiki.neo4j.org/content/ACL ).
You should first study the existing social networks out there (Facebook, Myspace, etc). There is a fair amount of information available about how they are implemented.
The key to success for social networks is not the technology on which it is based but the problems they solve for the users. If the users like it, you're doomed for success even if your technology is crap.
[EDIT] How is it implemented? Check any SQL-based user role system. In this case, every user is also a role which can be added as "allowed to access" to any object. Depending on how many objects you have and how fine grained the control should be, that can mean that you have a table with three columns: OBJECT, USER, ACCESS_TYPE where ACCESS_TYPE can be one of OWNER, READ (friend), WRITE (close friend).
This table will become pretty large but a few 100 million rows is not uncommon for todays databases anymore.
As Aaroon pointed out, you should first ask youself what problem you want to solve.
What content do you want people to share? Should it really be visible only to friends? It is much easier and scalable if you make content publicly visible, because what content is displayed is not dependent on who is watching the page and you can cache it easily. Publicly available user-generated content attracts new users.
If you want to restrict access and give to the user the opportunity to attach groups of friends to a resource I would go with a simple group-based access control. Let each resource have a group of users which can edit the resource and a group of users who can see it.
That way each resource has two single value attributes, and each user belons to a finite number of group. You can attach the view-group and edit-group attributes to a document stored in a NOSQL database, a search engine like Lucene/Sphinx or a row in a SQL database. When querying for content available for the user, pass all groups the user belongs to (in SQL you would use IN clause, in Sphinx setFilter('view-group', array(2,3,4)). The database would return only content available for the user. Because you are attaching only 2 integer values (view-group and edit-group) to a document, you can store them in memory which makes the search fast and scalable.
In the end it looks like Elgg or Dolphin might meet our requirements. These appear to be PHP frameworks for rolling your own social network. I looked at the Facebook platform but nowhere did it clearly explain just what it is - it appears to be the facebook code but perhaps it is only the code for an addon API or something.