Here is my object:
public class CMSContentItemFolder
{
int Id {get; set; }
public Guid InstanceId { get; set; }
public List<CMSContentItemFolder> ContentItemFolders { get; set; }
public List<CMSContentItem> ContentItems { get; set; }
}
So the folder can have infinite levels of subfolders, just like a system folder on your c drive.
In order for me to performs CRUD on a folder and it's children, I have to write recursive methods, which works but is a bit of a pain. I know the Patching API would be better, but I haven't seen examples of it working for recursive objects.
Whats the best way to do this in RavenDb?
Thanks!
You should model with encapsulation or referencing, not both. In your object, what is the purpose of an Id on nested CMSContentItemFolder? You should probably reference instead. And the same would apply for content items. They are probably each in their own document.
public List<int> ContentItemFolderIds { get; set; }
public List<int> ContentItemIds { get; set; }
Then you don't have any recursion to contend with when patching.
Related
I'm using entity framework and I figured out that it ain't able to serialize the output of
EDM Objects. For now I'm using Northwind Products-table. SO thereforth I'm forced to cast the Object to another and are using the .Cast but it doesn't work.
The only solution I have is to property by property do it manually in my code, but I'm thinking - there must be a better way!
For god's sake - it is 2013! And this Entity seems like a good idea in the beginning but it has so many gotchas and constraints that it actually hinders more than it helps, but anyway the EDMX diagrams are nice!
Anybody who has a better solution to casting the objects?
POCO
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
//public Nullable<int> SupplierID { get; set; }
//public Nullable<int> CategoryID { get; set; }
public string QuantityPerUnit { get; set; }
public Nullable<decimal> UnitPrice { get; set; }
public Nullable<short> UnitsInStock { get; set; }
public Nullable<short> UnitsOnOrder { get; set; }
public Nullable<short> ReorderLevel { get; set; }
//public bool Discontinued { get; set; }
public Category Category { get; set; }
//public ICollection<Order_Detail> Order_Details { get; set; }
//public Supplier Supplier { get; set; }
}
View Model
public class ProductsViewModel
{
public List<POCO.Product> Products { get; set; }
public ProductsViewModel()
{
using (NorthwindEntities dNorthwindEntities = new NorthwindEntities())
{
this.Products = dNorthwindEntities.Products.Cast<POCO.Product>().ToList();
Web api controller:
public class ProductsController : ApiController
{
public List<Product> GetAllProducts()
{
var viewmodel = new ProductsViewModel();
return viewmodel.Products;
}
1.
You can use frameworks like AutoMapper to handle Entities to ViewModel / DTO mapping automatically.
2.
Using Entities in the View (even in their POCO form) is not recommended for couple of reasons:
Security: Sending entities back to the client/view may expose more data than you intended.
Serialization: Since your entities usually contain reference to another entities and those entities may contain a reference back to the (parent) entity, you have to configure your serializer to handle this situation otherwise you'll get Circular Dependency Exception.
Incompatibility: The structure of your entity may not be compatible with what your view/client needs to render itself. Sometimes your view just needs a simple string while the entity holds this data in a much complex way hence the view needs to 'extract' it and you end up with a view full of unnecessary entity-drill-down code.
Fluent Nhibernate Many to Many association to multiple classes
We use Nhibernate and up to now we have been able use the auto mapping. But I think this is about to change.
We have a Code class that has a many to many relation with several other classes.
I’m thinking something along these lines:
public class Code
{
public virtual Guid Id { get; set; }
public virtual ICollection<CodeUsage> Usage { get; set; }
}
class CodeUsage
{
public virtual Guid Id { get; set; }
public virtual Code Code { get; set; }
// Class, [Property,] Id for "ANY" mapping to A & B
}
class A
{
public virtual Guid Id { get; set; }
public virtual ICollection<CodeUsage> Codes { get; set; }
}
class B
{
public virtual Guid Id { get; set; }
public virtual ICollection<CodeUsage> Codes { get; set; }
}
Many to Many will lead to the creation of a linking table, in the linking table their needs come a mapping to the classes using codes. In the documentation it is referred to as a “Any” mapping.
But I have no idea how get fluent to create one.
Thoughts anyone? or even better: a solution <);o)}{
You can't map <many-to-any> in Fluent NHibernate - it's not supported.
I think it may be a good reason to move to mapping-by-code, that supports it well.
I have a datamodel like
ModelA which contains a Collection.
ModelB contains a Collection as a backreference. That is failing because of cyclic references if I query with Include("ModelB"). Not good but I solved that via setting ModelB.List=null for each element.
The problem now is submitting a changed ModelA tree: I am adding ModelB-entities to ModelA.ModelB[]. Now the UpdateEntity function is complaining the it could not add elements of type ModelB which are declared static. The JSON deserializer is creating static arrays.
How is it possible with the combination of upshot/MVC4 to submit datamodels which are not completely flat? As it is not possible right now to create your own DTO objects where you might figure out something I am stuck now...
After investigating the error a bit better, I think the problem is the cyclic backreference:
The ModelA->ModelB->ModelA is breaking the storage of the data. "Could not add data of type ModelA to type ModelB".
As I mentioned the backreference was set to Null because the cyclic ref serialisation problem...
I hope the will be some easier way on doing more manually with DTO objects where I have mroe control.
Please see also: MVC 4, Upshot entities cyclic references for the beginning of the journey...
To solve the cyclic backreference, you can use the ignoreDataMember attribute:
public class Customer
{
[Key]
public int CustomerId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public virtual ICollection<Delivery> Deliveries { get; set; }
}
public class Delivery
{
[Key]
public int DeliveryId { get; set; }
public string Description { get; set; }
public bool IsDelivered { get; set; }
[IgnoreDataMember]
public virtual Customer Customer { get; set; }
public virtual int CustomerId { get; set; }
}
I posted a working solution to your problem in a different question: https://stackoverflow.com/a/10010695/1226140
I am revisiting RavenDB after a brief experiment quite a while ago. At the moment I'm considering document design which is nested 3 levels deep, i.e.
public class UserEvent
{
public UserEvent()
{
Shows = new List<Show>();
}
public readonly string IdPrefix = "Events/";
public string Id { get; set; }
public string Title { get; set; }
public List<Show> Shows { get; set; }
}
public class Show
{
public Show()
{
Entries = new List<ShowEntry>();
}
public readonly string IdPrefix = "Shows/";
public string Id { get; set; }
public string EventId { get; set; }
public string Name { get; set; }
public DateTime Date { get; set; }
public List<ShowEntry> Entries { get; set; }
}
public class ShowEntry
{
public readonly string IdPrefix = "ShowEntries/";
public string Id { get; set; }
public string DogId { get; set; }
public string OwnerName { get; set; }
public EntryClass Class { get; set; }
}
First of all, is this a sensible design? A UserEvent generally has a few (less than 6) Show, but a Show can have between tens to hundreds of ShowEntry. I have included DogId in ShowEntry but maybe later I will change it to a property of Dog type. A Dog is of a particular Breed, and a Breed belongs to a Group. The Dog side of the story will have to be another question but for now I'm interested in the UserEvent side.
If my documents are designed this way can I use the Patching API to add items into the Entries collection within a Show? I would like to have an index which will summarise Entries based on Dog properties. Will indexes get processed if an a document is patched?
Your design certainly looks sensible from an outside perspective. The big question you need to ask yourself is, "What do you plan on querying a majority of the time?"
For instance, Show seems to be a fairly common object that would benefit from being an Aggregate Root (from Domain Driven Design). I find that when organizing my documents, the most important question is, "how often do you plan on querying the object."
To answer your last question, Patching should definitely causing re-indexing.
I'm having some trouble figuring out the appropriate FluentNHibernate mapping syntax for the following data model and domain objects. Here's the data model I'm working against:
And I'm trying to map the following domain objects to that model:
namespace FluentNHibernateSandbox.Entities
{
public abstract class EntityBase
{
public virtual long Id { get; set; }
}
}
namespace FluentNHibernateSandbox.Entities
{
public class Attribute : EntityBase
{
public virtual string Name { get; set; }
public virtual string Label { get; set; }
public virtual string Description { get; set; }
public virtual int SortOrder { get; set; }
public virtual Group Group { get; set; }
public virtual Editor Editor { get; set; }
}
}
namespace FluentNHibernateSandbox.Entities
{
public class Group : EntityBase
{
public virtual string Name { get; set; }
public virtual string Label { get; set; }
public virtual string Description { get; set; }
public virtual int SortOrder { get; set; }
public virtual IList<Attribute> Attributes { get; set; }
}
}
namespace FluentNHibernateSandbox.Entities
{
public class Editor : EntityBase
{
public virtual string ViewName { get; set; }
public virtual string WorkerClassName { get; set; }
}
}
In general, what I ultimately want doesn't seem like it should be all that hard to do, but I after having tried just about every combination of mappings I can think of, I still can't seem to get it right. I just need my Attribute to have a reference to the Group that it belongs to and a reference to the Editor assigned to it, and each Group should have a collection of the Attributes that are part of it. The couple of many-to-many join tables are what seem to be giving me fits. Particularly the APPLICATION_ATTRIBUTE table. Ultimately I only want the Attributes that my application is concerned with, in this case, those with an APPLICATION_ID of 4.
Any help would be greatly appreciated. Thanks.
Really kinda surprised nobody responded to this at all, but anyway. The answer/solution for this mapping situation that we came up with, which I was trying to avoid to start with, but turned out to really be the best way to go, was to create some custom views in the database that joined together all of the application-specific data I needed, and then just mapped my application's domain objects to those views. This worked at least partially because the information I needed from these tables is going to be read-only for this application, but even if I needed to write to the tables, I'm pretty sure (though haven't verified as I didn't really have need in this case) that I could have setup my views to be writeable and that would've worked too.
Hat tip to #robconery.