Using TransformResults to select hierarical data from RavenDB? - ravendb

I have a simple class hierarchy looking like this:
public class Top
{
public string Id { get; set; }
public string Description { get; set; }
public List<Middle> Middles { get; set; }
}
public class Middle
{
public string Id { get; set; }
public string Description { get; set; }
public List<Bottom> Bottoms { get; set; }
}
public class Bottom
{
public string Id { get; set; }
public string Description { get; set; }
}
The whole thing is saved as entity of type 'Top'. Document is designed to preserve and reflect relationships/hierarchy but half but at time I will, for example, care only about an 'Id' and 'Description' of a given relationship. So, the types of queries I'd want to run are
select all Top,
select all Middle,
select Middle where Top.Id=somevalue
select Bottom where Top.Id=somevalue and Middle.Id=somevalue
I would like the results to be transformed and returned to me like this:
public class Result
{
public int Id { get; set; }
public string Description { get; set; }
}
How can I implement TransformResults (I presume that that's the feature that can be used) to achieve this? I've read quite a few examples but all of the sudden I see parameters/values, which were not declared anywhere and as a result I don't understand what's happening.

TransformResults doesn't have access to the outside world, you can't execute logic based on the query that you run.
You can flatten this structure, sure, but unless you will create multiple indexes with different TransformResults, you can't do this.
Note that this is a strange thing to do in the first place, because it doesn't matches the standard modeling of documents as a transaction boundary.

Related

What's the best way to go about implementing hashtag functionality in EF Core/Razor Pages?

I'm trying to implement hasthags into an application. I've configured the database already and even have a layout for how I'd like the form to look, however I'm not sure if it's possible to do what I want to do with Razor pages. I have the below classes:
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName{ get; set; }
public IList<PersonTag> PersonTags { get; set; }
}
public class Tag
{
public int TagId { get; set; }
public string TagName { get; set; }
public IList<PersonTag> PersonTags { get; set; }
}
public class PersonTag
{
public int PersonTagId { get; set; }
public int PersonId { get; set; }
public Person Person { get; set; }
public int TagId { get; set; }
public Tag Tag { get; set; }
}
And would like the form to look like this, where you see this input while editing a Person. You'd add a new hashtag by typing in the input box--hitting enter there (or pressing a button--not pictured) would create the tag in the Tag table and also create a new PersonTag relationship with the Person being edited, which would be saved on form submission. I guess the Tag could also get created on form submission if that's simpler. Clicking the "x" on one of the tags should also remove the PersonTag relationship
Is this something that's possible with razor pages? To this point I've only ever done simpler inputs (either single values or select lists), but in this case I need the user to have the option to enter free text multiple times. What kind of input would I need for these? Or would I need to do entirely special handling to pull the data on form submit, and just populate the tags with Javascript when the user adds them?

ASP.NET MVC 4 database scaffolding self referential model

I have a constructed a model using code first in C#. The model literally represents a container element for a website building application, in other words, the model defines a Div tag or some such HTML element. Like a Div tag which can contain multiple child elements, I have tried to represent this in my model, but the scaffolding to the DB, does not give me what I'd expect.
I should get a new many to many joins table, but instead I only get a single column in the DB which expects a single int data type.
Here is the model:
public class ElementContainer
{
public int ElementContainerID { get; set; }
public int PageId { get; set; }
public int? ParentElementContainerID { get; set; }
public string ElementContainerName { get; set; }
public ElementType ElementType { get; set; }
public string ElementClass { get; set; }
public PageAsset PageAsset { get; set; } // content of container
public List<ElementContainer> NestedContainers { get; set; }
}
The last line is the self-referential attribute which just appears as a column called ElementContainer_ElementContainerID
Thanks in advance!
I agree with Bahman, DB first is easier.
While I haven't tried to do what you are trying, your code looks like a self-Join that would do exactly what you describe.
This is a One-to-Many relationship. EF Navigation will pull a List of all nested children containers.
If you want to create a many-to-many relationship with EF Code-First, you should create another Entity
public class ContainerChildren
{
public int ElementContainerID { get; set; }
public List<ElementContainer> NestedContainers { get; set; }
}
this reference should help you to get the exact idea http://blogs.msdn.com/b/wriju/archive/2011/05/14/code-first-ef-4-1-building-many-to-many-relationship.aspx

RavenDB document design, patching, and index creation

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.

PetaPoco to return self-referencing hierarchy

How would one write a query/method to return a POCO that is from a self-referencing database as shown in this question
Firstly you would map it a flat class. eg. db.Fetch<CategoryDb>("select * from categories");
public class CategoryDb {
public int Id { get; set; }
public string Name { get; set; }
public int ParentCategoryId { get; set; }
}
From here I would then create a new Object that self referenced itself. (You could use the existing object with the ParentCategory having the [Result] attribute on it.)
public class Category {
public int Id { get; set; }
public string Name { get; set; }
public Category ParentCategory { get; set; }
}
You could then take this and convert your flat list into a nested list.
I do have code somewhere that can do this, and for which it also provides searching methods etc, but its not on this computer. I will update tomorrow with a link to the code.

FluentNHibernate mapping syntax help needed

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.