Book Store Model - oop

I am developing a solution. I want to model following structure
Collection 1
Category 1
Sub Category 1.1
Book 1
Book 2
Book 3
Sub Category 1.2
Book 1
Category 2
Sub Category 2.1
Book 2
Sub Category 2.2
Book 3
Sub Category 2.3
Book 4
Category 3
Sub Category 3.1
Book 4
)
What it the best possible way to model it so that it can be traversed in both the direction
1) From collection to Book (i.e. if collection is selected find all the categories, sub categories, and books under that.)
2) From book to collection (i.e. if book is selected should be able to find which sub category, category and collection it belongs to)

Here's a basic model for your application.
alt text http://ruchitsurati.net/myfiles/bookstore.png
public class Book
{
public Category ParentCategory { get; set; }
public Book() { }
}
public class Category
{
public CategorySet SubCategories { get; set; }
public BookSet Books { get; set; }
public Category()
{
SubCategories = new CategorySet();
Books = new BookSet();
}
}
public class Collection
{
public CategorySet Categories { get; set; }
public Collection() {
Categories = new CategorySet();
}
}
public class BookSet : System.Collections.ObjectModel.Collection<Book>
{
public BookSet() { }
}
public class CategorySet : System.Collections.ObjectModel.Collection<Category>
{
public CategorySet() { }
}
public class CollectionSet : System.Collections.ObjectModel.Collection<Collection>
{
public CollectionSet() { }
}

It sounds like what you need is a threaded tree. Alternatively, just use almost any halfway reasonable relational database.

Related

Entity Framework dbcontext crashing during foreach loop

I have an asp.net core mvc project. I'm trying to get over 300+ records from a table(s) using entity framework. Here are the models I have:
public partial class Movies
{
public int Id { get; set; }
public string Title { get; set; }
public virtual MovieInfoes MovieInfoes { get; set; }
}
public partial class MovieInfoes
{
public int Id { get; set; }
public string Actors { get; set; }
public string Director { get; set; }
public virtual Movies IdNavigation { get; set; }
}
In the controller section, I have an action that is suppose to list the title, actors, and director data.
public IActionResult ListAllMovies()
{
var movies = context.Movies.Include("MovieInfoes").ToList();
foreach (var movie in movies)
{
string x = movie.MovieInfoes.Actors;
}
return View(movies);
}
For some reason, it is crashing after it iterates 19 records (I'm trying to iterate thru 300+ records). I get an error saying "NullReferenceException: Object reference not set to an instance of an object".
Note: I've tried with lazy loading and eager loading, and both ways result in same error.
You're likely attempting to access movie.MovieInfoes.Actors with an instance of movie that has a null MovieInfoes reference.
Try accessing Actors with a null-conditional operator by changing string x = movie.MovieInfoes.Actors; to string x = movie?.MovieInfoes?.Actors;

DDD shared entity between two aggregate roots

I'm working with two different aggregate roots: Post and Question. Both of them have a Category.
So far I have implemented it as a shared entity (which I'm not sure if is a correct design in DDD).
public class Post
{
public Guid Id { get; private set; }
public Category Category { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
}
public class Question
{
public Guid Id { get; private set; }
public Category Category { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
}
public class Category
{
public int Id { get; private set; }
public string Name { get; private set; }
public string Key { get; private set; }
}
Note: I'm aware I'm falling into primitive obsession anti-pattern, and I have plans on refactor the primitives into ValueObjects.
After read this post DDD: Share entity with multiple aggregate roots I'm thinking that maybe I should convert the Category in a ValueObject (with multiple fields).
In theory Category could be an Entity with its own lifecycle, but reality is that I don't really add/remove/update categories.
Is it possible to use a shared Entity on DDD? Or I better rather use a ValueObject?
Lets deal with one aggregate first: Post
Now to answer your question:
Is it possible to use a shared Entity on DDD? Or I better rather use a ValueObject?
It depends on what you will do with Category.
Scenario 1:
You have a feature(or page) in your application to show all posts of a category. I would go with the following design:
public class Category
{
public int Id { get; set; }
//this is my in-memory database. Use repository and service to adjust yours
public static List<Post> Posts;
public Category()
{
Posts = new List<Post>();
}
public void AddPost(Guid id, string title, string body)
{
var post = new Post(id, title, body, this.Id);
//saving the post into in-memory. Perhaps you can check some business logic inside Post entity
Posts.Add(post);
}
// You can retrieve all posts of a single category
public IEnumerable<Post> GetAllPosts()
{
return Posts.Where(x => x.CategoryId == this.Id);
}
}
public class Post
{
public Guid Id { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
public int CategoryId { get; private set; }
public Post(Guid id)
{
Id = id;
}
public Post(Guid id, string title, string body, int categoryId)
{
//I prefer to pass guid into domain from external services.
//Using this way, your service will have the id to return to upper layers.
//Alternatively you can create new guid here on your own
Id = id;
Title = title;
Body = body;
CategoryId = categoryId;
}
// you can retrieve a post detail
public Post GetPost()
{
return Category.Posts.FirstOrDefault(x => x.Id == this.Id);
}
}
I can see only one aggregate root in this scenario: Category.
Scenario 2:
You have posts page, from there users can view detail post. Additionally, every post has a category which will be shown somewhere on that detailed page. You can have following simple design:
public class Post
{
public Guid Id { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
public string CatKey { get; private set; }
public Post(Guid id)
{
Id = id;
}
public Post(Guid id, string title, string body, string catKey)
{
//I prefer to pass guid into domain from external services.
//Using this way, your service will have the id to return to upper layers.
//Alternatively you can create new guid here on your own
Id = id;
Title = title;
Body = body;
//I don't even bother with category id. This is a simple value object, you can store all of your categories
//into a hashtable of key-value
CatKey = catKey;
}
// you can retrieve a post detail
public Post GetPost()
{
//get your post detail from repo
}
}
Hope you can make your decision now.
The main question of Entity vs ValueObject is would two instances of the Category with the same values need to be tracked differently? The classic example is a dollar bill - in most instances, the serial number (ID) doesn't matter, and one dollar is the same as another (ValueObject). If your domain is collecting rare bills, though, that would change.
I'd suspect not in your case, since it appears Category is really just comprised of the name and key. If the Category of a Post changes, do you need to track what the Category previous was?

nhibernate map a category contains top n product

I have a question, that is "category class" contains many product class. but now, i have a CategoryService class that will implement find IList at the same sutiation every category only contain the top n of products, not all of products, what should i do? Give me a choice,thanks!
the code list:
public class category
{
public int Id{get;set;}
public int Categoryname{get;set;}
public IList<Product> Products{get;set;}
}
public class Product
{
public int Id{get;set;}
public string ProductName{get;set;}
public Category Category{get;set;}
etc...
}
then have a domain service:
public class CategoryService
{
private ICategoryRepository categoryRepository;
public CategoryService(ICategoryRepository categoryRepository)
{
this.categoryRepository=categoryRepository;
}
public IList<Category> FindAll()
{
IList<Category> categories;
categories=categoryRepository.FindAll();
//and now i need categoryRepository find all category ,and every category contains top n product, what should i do;
return categories;
}
}
var count = // it's your top
session.QueryOver<Category>
.Fetch(category => category.Product).Eager
.Take(count)
.TransformUsing(Transformers.DistinctRootEntity)
.List();

How do i map this in NHibernate

I Have two classes, Survey and Poll classes. Also I have Question and Question Choice classes. How do I map these so I come out with particular table formats. Here are the classes involved.
public class Survey
{
public IList<Question> Questions { get; private set; }
}
public class Poll
{
public Question Question { get; set; }
}
public class Question
{
public string Text { get; set; }
public IList<QuestionChocie> Choices { get; private set; }
}
public class QuestionChoice
{
public string Text { get; set; }
}
The resulting tables that I'm shooting for include the following
Surveys- a table of survey information.
Polls - a table of polls information.
SurveyQuestions -a table of survey questions.
PollQuestions - a table of poll questions.
SurveyChoices - a table of the question choices for the surveys.
PollChoices - a table of the question choices for the survey.
Preferably, I really want to know for Fluent NHibernate, or just mapping xml is fine too.
You haven't defined relationships between the tables so I'm going to assume one-to-many.
The general mapping would be:
public class SurveyMap : ClassMap<Survey>
{
public SurveyMap()
{
HasMany<SurveyQuestion>(x => x.Questions).Inverse();
// Rest of mapping
}
}
public class SurveyQuestionMap : ClassMap<Question>
{
public QuestionMap()
{
References<Survey>(x => x.Survey);
HasMany<SurveyChoice>(x => x.Choices).Inverse();
// Rest of mapping
}
}
public class SurveyChoiceMap : ClassMap<SurveyChoice>
{
public SurveyChoiceMap()
{
References<SurveyQuestion>(x => x.Question);
// Rest of mapping
}
}

Recursively get all children from a self referencing many to many object with ef-core

My first post on Stackoverflow. So Apologies in advance if I do not understand something here :)
I have a abstract class called ElementEntity.
Inside this class i have 2 many to many relations, ChildRelations and ParentRelations.
I need a list with id's from all the Children and grandchildren etc.. form a certain ElementEntity.
We don't know how deep this tree is so somthing like:
Context.Hospitals().Include(b => b.ChildRelations).ThenInclude(c => c.child).ThenInclude etc.. is not an option. ( Hospital is a derived ElementEntity )
What would be the best (most inexpensive) approach?
As indication a certain element could have hundreds of thousands of offspring objects.
public abstract class ElementEntity
{
public long Id {get; set;}
public virtual ICollection<BaseGroupParentChildRelation> ParentRelations { get; } = new List<BaseGroupParentChildRelation>();
public virtual ICollection<BaseGroupParentChildRelation> ChildRelations { get; } = new List<BaseGroupParentChildRelation>();
}
public class BaseGroupParentChildRelation
{
public long ParentId { get; set; }
public virtual ElementEntity Parent { get; set; }
public long ChildId { get; set; }
public virtual ElementEntity Child { get; set; }
}
Possible fix:
await projectDbContext.Set<BaseGroupParentChildRelation>().ToListAsync();
var Hotels = await projectDbContext.Hotels.Include(b =>
b.ChildRelations).ThenInclude(b => b.Child).ToListAsync();
Hotels now include children, grandchildren, great-grandchildren etc.. etc..