RavenDB polymorphic Index - c#

I'm working with RavenDB, and I'm trying to do something. I have a base type, Principal, from which two classes are derived: User and ApplicationInstance. In my application, instances of User and ApplicationInstance must be created and stored frequently. The thing is, though, that I need to also be able to query all of the Principal objects stored in the database at once, determine whether a given Principal is a User or an ApplicationInstance, and then query for the entire User or ApplicationInstance object.
How can I do this?

You can define a Multi Map Index that uses as source both the User and ApplicationInstance collections.
If you define your index using C# code (by implementing AbstractMultiMapIndexCreationTask<>), you'll have to call AddMap twice to achieve that (as illustrated in the blog post link above)
If you define the index using Raven Studio, simply click the Add Map button and you'll get a new text area which allows you to define an additional Map.
Note, however, that the output structure of both maps must have the same properties (pretty much as you would do with UNION in SQL).

What are you trying to do? If the end result is to query all Principals, then load the entire User or AppInstance, why not just go straight for querying all Users or all AppInstances?
Raven won't store base classes; it will only store the most derived type (User or AppInstance, in your case). So you'll have a collection of Users and a collection of AppInstances.
If you really need to query both at once, you can use Multi Map indexes. You can also change the entity name and store both in a single Principal collection.
But it's difficult to recommend a solution without knowing what you're trying to do. Explain what you're trying to do and we'll tell you the proper way to get there.

Related

Dynamic table name EF CORE 2.2

I want to make a universal method for working with tables. Studied links
Dynamically Instantiate Model object in Entity Framework DB first by passing type as parameter
Dynamically access table in EF Core 2.0
As an example, the ASP.NET CORE controller for one of the SQL tables is shown below. There are many tables. You have to implement such (DEL,ADD,CHANGE) methods for each table :
[Authorize(Roles = "Administrator")]
[HttpPost]
public ActionResult DeleteToDB(string id)
{
webtm_mng_16Context db = new webtm_mng_16Context();
var Obj_item1 = (from o1 in db.IT_bar
where o1.id == int.Parse(id)
select o1).SingleOrDefault();
if ((Obj_item1 != null))
{
db.IT_bar.Remove(Obj_item1);
db.SaveChanges();
}
var Result = "ok";
return Json(Result);
}
I want to get a universal method for all such operations with the ability to change the name of the table dynamically. Ideally, set the table name as a string. I know that this can be done using SQL inserts, but is there really no simple method to implement this in EF CORE
Sorry, but you need to rework your model.
It is possible to do something generic as long as you have one table per type - you can go into the configuration and change the database table. OpenIddict allows that. You can overwrite the constructors of the DbContext and play whatever you want with the object model, and that includes changing table names.
What you can also do is a generic base class taking the classes you deal with as parameters. I have those - taking (a) the db entity type and (b) the api side dto type and then using some generic functions and Automapper to map between them.
But the moment you need to grab the table name dynamically you are in a world of pain. EF standard architecture assumes that an object type is mapped to a database entity. As such, an ID is unique within a table - the whole relational model depends on that. Id 44 has to be unique, for a specific object, not for an object and the table it was at this moment loaded from.
You also miss up significantly on acutally logic, i.e. for delete. I hate to tell you, but while you can implement security on other layers for reading, every single one of my write/update methods are handwritten. Now, it may seem that "Authorize" works - but no, it does not. Or - it does if your application is "Hello world" complex. I run sometimes pages of testing code whether an operation is allowed in a specific business context and this IS specific, whether the user has set an override switch (which may or may not be valid depending on who he is) do bypass certain business rules. All that is anyway specific.
Oh, what you can also do... because you seem to have a lot of tables: do NOT use one class, generate them. Scaffolding is not that complex. I hardly remember when I did generate the last EF core database classes - they nowadays all come out of Entity Developer (tool from Devart), while the db is handled with change scripts (I work db first - i actually want to USE The database and that means filtered indices, triggers, some sp's and views with specific SQL), so migrations do not really work at all.
But now, overwriting the table name dynamically - while keeping the same object in the background - will bite you quite fast. It likely only works for extremely simplistic things - you know, "hello world" example - and breaks apart the moment you actually have logic.

How to reorder ids (from 1 to n) in C# Entity framework

I'm quite new to C# MVC so what i'm asking might be bad practice, but is there a way (or should I attempt), to reorder the Ids of the objects in a collection so that the first element always remains with and Id of 1. If it gets deleted and replaced by the second element, this element should then get a new Id of 1.
I'm using Ids to order the displayed elements on a page, and I guess I could manage to create a new property that would serve this purpose, but I'm wondering if reordering the actual Ids would be a good/bad idea.
I'm using Code First, and I let entity manage the Ids automatically for now.
Any advice on the matter will be very welcome!
Thanks in advance!
Yes, you're right in your assumption. Firstly, you should not be using the IDs for sorting. The purpose of the IDs is to identify the records and you should not use them for other purposes. More importantly, it is a very bad idea to change the IDs except in very special cases. When you modify an ID, all related records with foreign IDs referencing the modified IDs need to be changed too.
You are also right that the best way is to add another column called something like "SortingOrder" and use that for your ordering. I do it all the time, and most my tables that need ordering that is decided by the admin have a column called "SortingOrder" (or "sorting_order" in SQL).

Mapping object hierarchies with Simple.Data

Has anyone figured out the best way to return an object hierarchy with
a multiple record set stored procedure?
At the moment I am pulling out each of the record sets and mapping
them individually into their types and then constructing the main
type.
Example: an account object with roles and phone numbers, a stored proc
returns 3 record sets, one with the account, one with the phone
numbers for the account and the last with the accounts roles.
Is there a better way of combining the record set into one so that I can cast
directly?
The next feature in line (for version 0.14, planned release in the next couple of weeks) is the With clause for queries, which will populate an object hierarchy. Having seen this question, I will think about how to expose enough of the implementation to make it usable in a stored procedure scenario.

NHibernate / Fluent NHibernate Dynamic Column Mapping

I have a table that, some of its columns are unknown at compile time. Such columns could either be of an integer value, or some Enum value. There is a table that holds all the names of such dynamic columns and also holds the column's type. This "metatable" has the following columns:
DynamicColumnId (Pk)
Name
TypeId (Integer / Enum, as Fk from a separate table)
Integer columns have the Name from this table, whereas Enum columns are Fk columns from a table that has that Name, with some modification (e.g. a "DynamicTable" prefix).
The only solution I could think of for this situation is using Reflection.Emit to dynamically create an Entity class and a corresponding Mapping class. Admittedly, I'm new to NHybernate / Fluent NHybernate and it seems like a relatively simple hierarchy between the tables, and so I wanted to verify my solution isn't as ugly as it initially appears...
I would also welcome solutions that completely disregard my table hierarchy, in order to effectively acheive the same results (that is, to enumerate the rows on the dynamic table, going over all the columns, with knowledge of whether they are Enums and, if they are, their possible values as well).
(Edit: Additional information re problem domain)
I initially included minimal details, as to avoid Too-Much-Info related confusion.
This description is much more complex, but it unravels the motives behind this design.
The application involved is designed to automate log/dump analysis. Analysis-scenarios are frequently provided by the log/dump experts and so, in order to streamline the typical process of requirements=>implementation=>verification cycle, such analysis-scenarios are implemented by the experts directly as an Iron Python code snippet, with some domain-specific constructs injected into the snippets' scope. Each snippet has a "context" for which it is relevant. An example of "context" could be "product," "version," etc... So, the snippet itself is only invoked in certain contexts - this helps simplifying the Python code by eliminating branching (you could view it as Aspect Oriented Programming, to some extent). A non-expert could use the application, with a given code-context database, to analyze a log/dump, after choosing values for the various contexts.
When an expert decides that a new context is required for cataloging a certain code snippet, he could add a context, indicating the possible values it could have. Once a new context is added to the database, a non-expert that runs an analysis will be given the option to choose a value for the newly-added context.
The "dynamic table" is the table that associates a code snippet with values of the various contexts (columns) that existed when the snippet was issued, plus default values for the columns that did not exist at that time.
I won't claim to fully understand your scenario, but it seems to me that you'd be better off using a key-value store such as Redis or a schema-less database like CouchDB instead of SQL. This doesn't seem to be a problem for a relational database, but if you really need to use a RDBMS I'd map NHibernate as closely as possible to the real schema (DynamicColumnId, Name, TypeId) then build whatever data structure you need on top of that.

ORM - Saving/Restoring default values for a DB object with C#

In order to assist users with repetitve data entry, I am trying to implement a system where many of the previous properties are remembered when adding new data.
Is it possible to use the Properties.Settings.Default.MySetting functionality or is there a better method for doing this kind of thing?
Couldn't you just make a (deep) copy of the previous object, and use that as the next object, allowing users to overwrite any fields that changed? This way, the fields would be what the user last entered, individualized per user, and updated as they chnaged those fields.
If you have a way of remembering the last thing entered per user, you cold even preserve this between sessions.
The OP comments:
Unfortunately, making a deep copy of an object messes up the objectcontext when relationships are involved. A new object with relationships either needs to have new relational objects created or existing objects queried from the database.
So? If the relation is to an another entity (a foreign key in the database), it's a uses-a relationship, and you just retain it. If it's an attribute, you copy it.
For example, lets say your form is data entry about employees, and ithas a drop down for, I dunno, employeeType, that's either "Exempt" (no overtime) or "Non-exempt" (gets overtime). You pulled the values for employeeType from the database, and you want the next employee entered to have the same values as the last entered employee, to save the data entry people keystrokes. So your deep copy would just associate the copied employee with the same database employeeType.
But for attribute data (like name), you'd make a copy.
It depends on what you're trying to achieve. The good thing about using the MySetting functionality is that the "Most Recent" properties can be persisted the next time the application is closed.
I'm assuming this is a winforms application so I'd possibly keep a cached instance of the last save of each of the backing objects in a hashtable somewhere and then when you create a new form, look up the backing object in the hashtable and bind the required properties to the new instance of the form.
You can then serialize and persist the entire hashtable to the MySettings object if you like so it can be used each time the user accesses the application.

Categories

Resources