I’m developing an application with a model similar to Stack Overflow (question / answer etc...)
Modelling a NoSQL Forum Application with C# / ASP.net MVC
The model looks something like this (simplified)
class Question
{
public string Title { get; set; }
public string Body { get; set; }
public DateTime DateCreated { get; set; }
public string UserName { get; set; }
public List<Answer> Replies { get; set; }
}
class Answer
{
public string Body { get; set; }
public DateTime DateCreated { get; set; }
public string UserName { get; set; }
}
So my documents are just one document, with the "answers" embedded in them
I’m trying to design my repositories for this approach.
Should I have 2 separate repositories? For example:
interface IQuestionRepository
{
void PutQuestion(Question question);
Question GetQuestion(string questionID);
}
interface IAnswerRepository
{
void PutAnswer(string questionID, Answer Answer);
Answer GetAnswer(string answerID);
}
Or something like this:
interface IPostRepository
{
void PutQuestion(Question question);
Question GetQuestion(string questionID);
void PutAnswer(string questionID, Answer Answer);
Answer GetAnswer(string answerID);
}
Your model is inherently flawed.
Question should be a root document.
Answer should be a root document.
While written in regards to RavenDB the document modeling information is mostly directly usable by you: http://codeofrob.com/archive/2010/12/21/ravendb-document-design-with-collections.aspx
Edit: FWIW the reason why your model is flawed is with document databases you want your documents to model transaction boundaries. Think of the editing scenario with stack overflow and how much of a nightmare it would be to maintain consistency with multiple people adding and updating answers which all alter the root document, and the poster is updating the question. The amount of contention on the single object will very problematic.
RavenDB provides what they call "patching" that lets you manipulate part of a document structure instead of the entire document exactly to solve problems like this but this design is best avoided up front instead of trying to make it work by greatly increasing the complexity of your persistence model having to do partial updates and handle elaborate concurrency situations.
And to answer the specific question after this, then you would have an AnswersRepository and a QuestsionsRepository
I think that it will be better to create repository for each aggregate rute(only for Question Document)
You don't need an Answer's repository. From a domain point of view, you should just add the answer to your Question object. The question repository should do the job, as Question looks like an aggregate root and you should have a repository per aggregate root (not per entity).
You should be careful not to create a Anemic Domain Model.
Related
I have a good understanding of EF, and generated my database successfully. Now, I am struggling with adding dynamic properties to one of the entity classes. For example, I have a Post class, and other users can make comments to the posts. When I list the existing posts, I want to display the number of comments made to corresponding post.
One solution might be having a property called CommentCount, and updating the Post by increasing the (int) value of the CommentCount property by 1 when a new comment is made.
The other solution, and I think it is a better solution, is that when retrieving the post from the DB, the number of comments associated with the post can be computed and retrieved at the same time and assigned to CommentCount property of the post instance. However, I do not know how to achieve this with EF.
Which approach is highly recommended? Or, is there any other ways of doing this? If it is the second one, how can I achieve this with EF?
1) You should simply consider not putting the property called CommentCount into your model. When you develop for example a WPF Windows application, you should consider using MVVM pattern and the CommentCount would belong to your ViewModel class and not to your Model class. There you implement INotifyPropertyChanged and you can use it from your frontend Views. Analogically there is MVC pattern for ASP.NET etc.
There are other design patterns like Repository pattern. Using this pattern you can create the CommentCount in your repository class and not in your
model class. This would be similar to your second solution.
2) I assume from your question that you are using code-first approach:
generated my database successfully
If you do so and you wish to include CommentCount directly in your Model class, you can do it this by adding partial class file to your project like this:
namespace DBModel.Models
{
public partial class Post
{
public int CommentsCount
{
get { return this.Comments.Count; }
}
...
But I cannot see why to create extra property in your model just for that.
On the other hand adding this field as a computed field into your SQL database could make sense and then it would be part of your EF model.
If you calculation is very complex you should try creating a View in your DB and then add it to your Model?
But if your Model have something simple like
class Post {
public int postid { get; set; }
public virtual ICollection<comment> comment { get; set; }
}
In your controller you can do
db.post(x => x.postid == yourid).comments.count()
to get total of comment
or in your view
#foreach (var item in Model)
{
<li>item.postid;</li>
<li>item.comment.Count();</li>
}
Or update your class
class Post {
public int postid { get; set; }
public virtual ICollection<comment> comment { get; set; }
public int CommentCount
{
get
{
return comment.Count();
}
}
}
Just remember bring related data in your query.
In my case POI have properties parish_id, sector_id, city_id and parish have municipality, and municipality have state.
Using this query I can get Poi with all the related data.
filter = db.poi
.Include("parish")
.Include("sector")
.Include("city")
.Include("parish.municipality")
.Include("parish.municipality.state")
.Where(x => x.sector_id == SectorID);
I'm trying to get a grasp of using the EF for an upcoming project.
Currently I have this code first code:
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public virtual List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
This created the database and tables and I've been able to add blogs / post no problem. But I am confused about how to structure around EF code first approach.
Should both Blog and Post have a reference to BloggingContext and then have their own get / add / update methods ?
Should I create separate BlogManager / PostManager classes that actually do the getting / adding / updating of data and simply return the entity objects?
Should I create separate classes that inherit from Blog / Post that contain the get / add / update methods?
Should both Blog and Post have a reference to BloggingContext
No - the classes themselves should not be tied to a particular source. They should just represent an entity and be independent of where the data comes from. That allows for easier unit testing since you can create a blog that is completely independent of your data source.
Should I create separate BlogManager / PostManager classes that actually do the getting / adding / updating of data and simply return the entity objects?
Yes - this is typically called a repository, so BlogRepository and PostRepository might be better names.
Since the two will be inter-dependent it would also be good to create IBLogRepository and IPostRepository interfaces that the repositories implement so you don't tightly couple the repositories. Then when you query for a blog and want it's post as well the BlogRepository can chain the request to the IPostRepository.
Should I create separate classes that inherit from Blog / Post that contain the get / add / update methods?
No - because inheritance implies an "is a" relationship - and a class that saves a blog it not necessarily a blog itself.
The DbContext class can handle everything data-related on its own. You don't need to include a reference to them in your entity classes (nor should you, since DbContext classes open up a database connection). DbContext will also handle your basic CRUD operations on its own (through the use of the DbSets<T> on it, which are easy ways to access all of the data in a specific table.
If you want, you could also do what #Sergey mentioned above in the comments and implement a repository interface on top of it. I have written a blog post about doing that which you can find here. Basically, you set it up as a generic repository with a background reference to the DbContext class, and in that way you can put up a nice layer in between your application code and your database logic.
After watching NDC12 presentation "Crafting Wicked Domain Models" from Jimmy Bogard (http://ndcoslo.oktaset.com/Agenda), I was wandering how to persist that kind of domain model.
This is sample class from presentation:
public class Member
{
List<Offer> _offers;
public Member(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
_offers = new List<Offer>();
}
public string FirstName { get; set; }
public string LastName { get; set; }
public IEnumerable<Offer> AssignedOffers {
get { return _offers; }
}
public int NumberOfOffers { get; private set; }
public Offer AssignOffer(OfferType offerType, IOfferValueCalc valueCalc)
{
var value = valueCalc.CalculateValue(this, offerType);
var expiration = offerType.CalculateExpiration();
var offer = new Offer(this, offerType, expiration, value);
_offers.Add(offer);
NumberOfOffers++;
return offer;
}
}
so there are some rules contained in this domain model:
- Member must have first and last name
- Number of offers can't be changed outside
- Member is responsible for creating new offer, calculating its value and assignment
If if try to map this to some ORM like Entity Framework or NHibernate, it will not work.
So, what's best approach for mapping this kind of model to database with ORM?
For example, how do I load AssignedOffers from DB if there's no setter?
Only thing that does make sense for me is using command/query architecture: queries are always done with DTO as result, not domain entities, and commands are done on domain models. Also, event sourcing is perfect fit for behaviours on domain model. But this kind of CQS architecture isn't maybe suitable for every project, specially brownfield. Or not?
I'm aware of similar questions here, but couldn't find concrete example and solution.
This is actually a very good question and something I have contemplated. It is potentially difficult to create proper domain objects that are fully encapsulated (i.e. no property setters) and use an ORM to build the domain objects directly.
In my experience there are 3 ways of solving this issue:
As already mention by Luka, NHibernate supports mapping to private fields, rather than property setters.
If using EF (which I don't think supports the above) you could use the memento pattern to restore state to your domain objects. e.g. you use entity framework to populate 'memento' objects which your domain entities accept to set their private fields.
As you have pointed out, using CQRS with event sourcing eliminates this problem. This is my preferred method of crafting perfectly encapsulated domain objects, that also have all the added benefits of event sourcing.
Old thread. But there's a more recent post (late 2014) by Vaughn Vernon that addresses just this scenario, with particular reference to Entity Framework. Given that I somehow struggled to find such information, maybe it can be helpful to post it here as well.
Basically the post advocates for the Product domain (aggregate) object to wrap the ProductState EF POCO data object for what concerns the "data bag" side of things. Of course the domain object would still add all its rich domain behaviour through domain-specific methods/accessors, but it would resort to inner data object when it has to get/set its properties.
Copying snippet straight from post:
public class Product
{
public Product(
TenantId tenantId,
ProductId productId,
ProductOwnerId productOwnerId,
string name,
string description)
{
State = new ProductState();
State.ProductKey = tenantId.Id + ":" + productId.Id;
State.ProductOwnerId = productOwnerId;
State.Name = name;
State.Description = description;
State.BacklogItems = new List<ProductBacklogItem>();
}
internal Product(ProductState state)
{
State = state;
}
//...
private readonly ProductState State;
}
public class ProductState
{
[Key]
public string ProductKey { get; set; }
public ProductOwnerId ProductOwnerId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<ProductBacklogItemState> BacklogItems { get; set; }
...
}
Repository would use internal constructor in order to instantiate (load) an entity instance from its DB-persisted version.
The one bit I can add myself, is that probably Product domain object should be dirtied with one more accessor just for the purpose of persistence through EF: in the same was as new Product(productState) allows a domain entity to be loaded from database, the opposite way should be allowed through something like:
public class Product
{
// ...
internal ProductState State
{
get
{
// return this.State as is, if you trust the caller (repository),
// or deep clone it and return it
}
}
}
// inside repository.Add(Product product):
dbContext.Add(product.State);
For AssignedOffers : if you look at the code you'll see that AssignedOffers returns value from a field. NHibernate can populate that field like this: Map(x => x.AssignedOffers).Access.Field().
Agree with using CQS.
When doing DDD first thing, you ignore the persistence concerns. THe ORM is tighlty coupled to a RDBMS so it's a persistence concern.
An ORM models persistence structure NOT the domain. Basically the repository must 'convert' the received Aggregate Root to one or many persistence entities. The Bounded Context matters a lot since the Aggregate Root changes according to what are you trying to accomplish as well.
Let's say you want to save the Member in the context of a new offer assigned. Then you'll have something like this (of course this is only one possible scenario)
public interface IAssignOffer
{
int OwnerId {get;}
Offer AssignOffer(OfferType offerType, IOfferValueCalc valueCalc);
IEnumerable<Offer> NewOffers {get; }
}
public class Member:IAssignOffer
{
/* implementation */
}
public interface IDomainRepository
{
void Save(IAssignOffer member);
}
Next the repo will get only the data required in order to change the NH entities and that's all.
About EVent Sourcing, I think that you have to see if it fits your domain and I don't see any problem with using Event Sourcing only for storing domain Aggregate Roots while the rest (mainly infrastructure) can be stored in the ordinary way (relational tables). I think CQRS gives you great flexibility in this matter.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Everytime I'm looking for AutoMapper stuff on StackOverflow, I'm reading something about ValueInjecter.
Can somebody tell me the pros and cons between them (performance, features, API usage, extensibility, testing) ?
as the creator of ValueInjecter, I can tell you that I did it because I wanted something simple and very flexible
I really don't like writing much or writing lots of monkey code like:
Prop1.Ignore, Prop2.Ignore etc.
CreateMap<Foo,Bar>(); CreateMap<Tomato, Potato>(); etc.
ValueInjecter is something like mozilla with it's plugins, you create ValueInjections and use them
there are built-in injections for flattening, unflattening, and some that are intended to be inherited
and it works more in an aspect type of way, you don't have to specify all properties 1-to-1, instead you do something like:
take all the int properties from source which name ends with "Id", transform the value and set each to a property in the source object with same name without the Id suffix and it's type is inherited from Entity, stuff like that
so one obvious difference, ValueInjecter is used even in windows forms with flattening and unflattening, that's how flexible it is
(mapping from object to form controls and back)
Automapper, not usable in windows forms, no unflatenning, but it has good stuff like collections mapping, so in case you need it with ValueInjecter you just do something like:
foos.Select(o => new Bar().InjectFrom(o));
you can also use ValueInjecter to map from anonymous and dynamic objects
differences:
automapper create configuration for each mapping possibility CreateMap()
valueinjecter inject from any object to any object (there are also cases when you inject from object to valuetype)
automapper has flattening built it, and only for simple types or from same type, and it doesn't has unflattening
valueinjecter only if you need it you do target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection>
and if you want from Foo.Bar.Name of type String to FooBarName of type Class1 you inherit FlatLoopValueInjection and specify this
automapper maps properties with same name by default and for the rest you have to specify one by one, and do stuff like Prop1.Ignore(), Prop2.Ignore() etc.
valueinjecter has a default injection .InjectFrom() that does the properties with the same name and type; for everything else you create your custom valueinjections with individual mapping logic/rules, more like aspects, e.g. from all props of Type Foo to all props of type Bar
Since I've never used any of the other tools, I can only talk about AutoMapper. I had a few goals in mind for building AutoMapper:
Support flattening to dumb DTO objects
Support obvious scenarios out of the box (collections, enumerations etc.)
Be able to easily verify mappings in a test
Allow for edge cases for resolving values from other places (custom type->type mapping, individual member mapping, and some really crazy edge cases).
If you want to do these things, AutoMapper works very well for you. Things AutoMapper doesn't do well are:
Filling existing objects
Unflattening
The reason being I've never needed to do these things. For the most part, our entities don't have setters, don't expose collections, etc. so that's why it's not there. We use AutoMapper to flatten to DTOs and map from UI models to command messages and the like. That's where it works really, really well for us.
I tried both and prefer ValueInjecter because it's so simple:
myObject.InjectFrom(otherObject);
That's all there is to know for the vast majority of my injection needs. It can't possibly get more simple and elegant than this.
This is a question I've been researching too, and for my use case, it seems to be valueinjecter hands down. It requires no prior setup to use (may hit performance I guess, although if smartly implemented it could cache the mappings for future invocations rather than reflecting each time), so you don't need to predefine any mappings before using them.
Most importantly however, it allows reverse mapping. Now I may be missing something here as Jimmy mentions that he sees no use case where its necessary, so maybe I have the pattern wrong, but my use case is that I'm creating a ViewModel object from my ORM. I then display this on my webpage. Once the user finishes I get the ViewModel back in as a httppost, how does this get converted back to the original ORM classes? I'd love to know the pattern with automapper. With ValueInjector it is trivial, and it will even unflatten. e.g Creating a new entity
The model created by the entityframework (model first):
public partial class Family
{
public int Id { get; set; }
public string FamilyName { get; set; }
public virtual Address Address { get; set; }
}
public partial class Address
{
public int Id { get; set; }
public string Line1 { get; set; }
public string Line2 { get; set; }
public string TownCity { get; set; }
public string County { get; set; }
public string Postcode { get; set; }
public virtual Family Family { get; set; }
}
The ViewModel (which I can decorate with validators):
public class FamilyViewModel
{
public int Id { get; set; }
public string FamilyName { get; set; }
public int AddressId { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressTownCity { get; set; }
public string AddressCounty { get; set; }
public string AddressPostcode { get; set; }
}
The ViewController:
//
// GET: /Family/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Family/Create
[HttpPost]
public ActionResult Create(FamilyViewModel familyViewModel)
{
try
{
Family family = new Family();
family.InjectFrom<UnflatLoopValueInjection>(familyViewModel);
db.Families.Add(family);
db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
To my mind, it doesn't get much simpler than that?
(So this begs the question, whats wrong with the pattern that I run into this (and it seems many others do to), that its not seen as of value to AutoMapper?)
However, if this pattern as decscribed, is one you want to use, then my vote is valueinjecter by a country mile.
I'm in the process of writing a BSD licensed mini-ORM targeted at embedded databases (with support for ese, sqlite and sqlce out of the box)
After working lots with Rails in the last year I have been thinking of implementing an Active Record pattern in C#.
I have come up with some demo code and was wondering if the interface design is sound.
Here you go:
// first param is the class, second is the primary key
public class Order : ActiveRecord<Order,int> {
BelongsTo<Customer> Customer { get; set; }
[PrimaryKey(AutoIncrement=true)]
public int Id { get; set; }
public string Details { get; set; }
}
[Index("FirstName", "LastName")]
[Index("LastName", "FirstName")]
public class Customer : ActiveRecord<Customer,int>
{
public HasMany<Order> Orders { get; set; }
[PrimaryKey(AutoIncrement=true)]
public int Id { get; set; }
[ColumnInfo(MinLength=4, MaxLength=255, Nullable=false)]
public string FirstName { get; set; }
[ColumnInfo(MinLength=4, MaxLength=255, Nullable=false)]
public string LastName { get; set; }
public string Comments { get; set; }
}
[TestClass]
public class TestActiveRecord {
public void Demo()
{
var customer = Customer.Build();
customer.FirstName = "bob";
customer.LastName = "doe";
var order = customer.Orders.Build();
order.Details = "This is the first order";
customer.Save();
var customer2 = Customer.Find(customer.Id);
Assert.AreEqual(1, customer2.Orders.Count);
}
}
Sorry about this being a multiple questions in one question ...
Can you think of any changes to this API? Are there any fatal flaws? Are there any open source ORMs that define similar interfaces?
The Castle Active Record Project.
Although it's not a strict implementation of the Active Record pattern, it works very well. Bonus is you will get some experience with NHibernate in the process.
As someone who has written his own, very simple, OR/M only to find it lacking when scenarios got more complex, I would strongly urge you to take a hard look at Caste ActiveRecord and NHibernate, unless you are doing this as a learning experience.
ActiveRecordMediator
Create a repository class that inherits from this AR class. Then you don't break your hierarchy and you implement a repository pattern along with your AR pattern!
Could someone possibly provide code to a very simple activerecord class that I could use to learn with? Looking at the source on projects like Castle and SubSonic is a bit overwhelming. I'd like to learn the active record pattern to get an idea of how it works. I know whatever I build would be nothing compared to Castle or SubSonic, but I think the learning experience would be great.
I looked at Hayden ActiveRecord, but I can't seem to find the source. Most of the active record related postings on his site are quite old.
Thanks.
Edit:
Sorry, I should have created a new question for this...