neo4jclient: Creating properties/fields at runtime, no fixed schema application - c#

I’m creating an ecommerce with products having their own fields (Id, Name):
This is the object I have in c#
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
This is my code to generate a product in C# to neo4j
Console.WriteLine("Generate node: ");
var newProduct = new Product{Id=666, Name="Banana"};
client.Cypher
.Create("(product:Product {newProduct})")
.WithParams(new { newProduct })
.ExecuteWithoutResults();
Supposing a user or I need to add some other attributes, such as price to the product node, the first thing is to add a new Product attribute to the class
..
public int price { get; set; }
..
And then modify the cypher code to add the product with the net attribute/property.
Clearly this is a hardcoded approach, not good for a dynamic db/site.
Since I’ve been used to RDBMS this type of problem could only be solved with EAV and numerous pivots, I was hoping that Nosql (ie Neo4J) could have helped me in dealing with variable attributes fileds without EAV.
Code that generates code could be a solution?
What comes in my mind is using Dynamic code/variable or codeDom, is this the way to go? are there other elegant solutions?
Please provide some explanations or topic to study.
NoSql should be schema-less but it’s schema-less application is not so easy am I correct?

In a schema-free database the schema lives in the applications that use it.
You can make schema changes at least in the database with a tool like Liquigraph
If you change your objects you will have code that uses these new properties, so you have to adapt your code anyway, or?
You can write some code (or use the library if it supports it) to consume and hydrate arbitrary objects.

Related

What is the best way to write data via MVC into database?

I am working on a homework project using MVC with EF Core.
I am looking for the best way to write data into the database. (I am beginner)
There are two tables. Predbilježba(Enrollment) and Seminari(Seminars)
public class Predbilježba
{
[Key]
public int PredbilježbeID { get; set; }
public string Ime { get; set; }
public string Prezime { get; set; }
public string Adresa { get; set; }
public string Email { get; set; }
public string Telefon { get; set; }
public bool Status { get; set; }
[DataType(DataType.Date)]
public DateTime DatumUpisa { get; set; }
public int SeminarID { get; set; }
public Seminar Seminar { get; set; }
}
public class Seminar
{
public int SeminarID { get; set; }
public string Naziv { get; set; }
public string Opis { get; set; }
[DataType(DataType.Date)]
public DateTime Datum { get; set; }
public bool Popunjen { get; set; }
public ICollection<Predbilježba> Predbilježba { get; set; }
}
I need to insert a sort of Enrollment (Named: Predbilježba) into the database.
Enrollment is connected to a table called Seminars (Named: Seminari).
So when a person is "enrolling" into a "seminar", he/she needs to insert basic data into form (name, phone number, etc.) and they need to choose a "seminar" from a list of given seminars which are in "Seminar" table.
So when they click "Save", their basic data is written into Predbilježba / (eng. Enrollment)" along with chosen "seminar"
So I already have controllers for these 2 models, and appropriate views to create, edit, and so on..
My question is: Do I create a separate controller/model/view to insert data into tables? Can someone give me some example of how it is done?
To clarify further, I need to make user side page where user can "enroll" to "seminar" by writing name, last name, etc.. and by choosing the desired seminar. For now I have functional database, Identity (which will be used later in project), controllers of both models, and appropriate views where I can edit Prebilježbe(eng. Enrollments) and Seminars.
Images of page follow:
So when user clicks Upiši se (eng. enroll) as shown in image number 3. , that selected Seminar, along with basic info that opens after the click (image 4 ) needs to be written into database "Predbilježbe" (eng Enrollments)
This "Upis" page would be a user input page, and "Seminari" and "Predbilježbe" would be admin pages..
If I understand your question correctly, you are asking about good architectural design. Aren't you? (if not please let me know to edit the answer).
You have many architectural choices and possibilities. The easiest one for you to start with is the Service-Repository architectural pattern. I would omit the Repository word here because EF is already (in my opinion) a Repository pattern implementation (at least partially).
So to keep it simple, you would like to start with Service architectural pattern. Which is about creating a class, which injects the DbContext in its construction (let's name it PredbilježbaService). And in this class, you handle all operations of your logic (including database EF queries).
Then you inject this class to your controller and call the required functions from that service class (which deals with the database) in your controller.
The same process can be applied to the other entity Seminar.
P.S. by injecting I mean using any IoC design pattern (in ASP.Net Core, dependency injection is already built-in).
So after these brief words, to answer your question directly, yes, a good software design would be by creating a separate class which handles database operations (adding rows, editing rows, etc.)
It all depends on what your application is supposed to do.
If this is nothing more than a few views around a few tables, then it is perfectly fine to save these objects directly from the controller. The best design is usually the simplest one and there is no need to overcomplicate things with layers, architectural patterns and so on. These are relevant when the size of the project is much larger than in your case.
Good design is all about communication. If someone else is supposed to maintain your project, will it be clear to them where to find the functionality?
I would expect two controllers: one for seminars (called SeminarController) and one for enrollments (called EnrollmentController). These will have methods for viewing, inserting, modifying and deleting data. I would be able to extend your project easily because I know where (and how) to find the code. So your suggestion seems like a good fit.
Response to comment
In the list of seminars has a link pointing to the screen where someone can register for a seminar. That action needs to know which seminar has been selected. The way to do it is to pass the id of the seminar with the request, e.g. /Enrollment/Register/{seminar id}. This results in a GET-request. The form in the enrollment view will POST the inputted data back to the controller.
In the EnrollmentController you would have something like this:
private readonly MyDbContext context;
// Constructor and other methods omitted
[HttpGet]
public ActionResult Register(int seminarId)
{
var seminar = context.Seminars.Single(x => x.Id == seminarId);
return View(seminar);
}
[HttpPost]
public ActionResult Register(Enrollment enrollment)
{
context.Enrollment.Add(enrollment);
return RedirectToAction("index", "Seminar");
}
Depending on the requirements, you might need to insert some validation etc.
You need to study about software architectures a bit to clarify this. Try reading about Layered Architecture for basic structures, and I am assuming you already understand how the MVC architecture works. These will clarify where to perform which task. One of my favorites is the Onion architecture. So basically when you implement an architecture in your code, it becomes much more easy to read, control and track all activities performed within the code.
At the simplest, it is better to split the tasks as below:
1. You define your model classes
2. You create a database class/layer, where you will implement the logic to perform data base queries into your database with respect to the models and return the formatted data (This is where you perform the EF core queries).
3. You create your controllers, where you handle tasks by sending appropriate requests to the database layer and fetch the formatted data.
4. You create your views based on the expected model, and setup the controllers to send the formatted model data to the appropriate view.
A good place to start is here: Tutorial on EF core with MVC
The best way to achieve this in MVC is tu use the nuget package EntityFrameworkCore
Here is a step by step documentation: https://learn.microsoft.com/en-us/ef/core/get-started/
For any further questions, feel free to ask.

How to access data when a viewModel depends on several models

I'm a novice trying to wrap my head around MVVM. I'm trying to build something and have not found an answer on how to deal with this:
I have several models/entities, some of which have logical connections and I am wondering where/when to bring it all together nicely.
Assume we have a PersonModel:
public class PersonModel
{
public int Id { get; set; }
public string Name { get; set; }
...
}
And a ClubModel:
public class ClubModel
{
public int Id { get; set; }
public string Name { get; set; }
...
}
And we have MembershipModel (a Person can have several Club memberships):
public class MembershipModel
{
public int Id { get; set; }
public PersonId { get; set; }
public ClubId { get; set; }
}
All these models are stored somewhere, and the models are persisted "as in" in that data storage.
Assume we have separate repositories in place for each of these models that supplies the standard CRUD operations.
Now I want to create a view model to manage all Persons, e.g. renaming, adding memberships, etc. -> PersonMangementViewModel.
In order to nicely bind a Person with all its properties and memberships, I would also create a PersonView(?)Model that can be used in the PersonManagementViewModel. It could contain e.g. view relevant properties and also the memberships:
public class PersonViewModel : PersonModel
{
public Color BkgnColor { get return SomeLogic(); }
public IEnumerable<MembershipModel> { get; set; }
...
}
My question here is, how would I smartly go about getting the Membership info into the PersionViewModel? I could of course create an instance of the MemberShipRepo directly in the PersionViewModel but that seems not nice, especially if you have a lot of Persons. I could also create all repositories in the PersonManagementViewModel and then pass references into the PersonViewModel.
Or does it make more sense to create another layer (e.g. "service" layer) that returns primarily the PersonViewModel, therefore uses the individual repositories and is called from the PersonManagementViewModel (thus removing the burden from it and allowing for re-use of the service elsewhere)?
Happy to have pointed out conceptional mistakes or some further reading.
Thanks
You are creating separate model for each table I guess. Does not matter, but your models are fragmented. You can consider putting related data together using Aggregate Root and Repository per Aggregate root instead of per model. This concept is discussed under DDD. But as you said you are new to MVVM, there is already lot much to learn. Involving DDD at this stage will only complicate the things.
If you decide to keep the things as is, best and quick thing I can guess is what you are doing now. Get instance of model from data store in View Model (or whatever your location) and map somehow. Tools like Automapper are good but they does not fit each situation. Do not hesitate to map by hand if needed. You can also use mix approach (Automapper + map by hand) to simplify the things.
About service layer, sure... why not. Totally depends on you. If used, this layer typically contain your business logic, mapping, formatting of data, validations etc. Again, each of that thing is up to you.
My suggestions:
Focus on your business objectives first.
Design patterns are good and helpful. Those are extract of many exceptionally capable developers to solve specific problem. Do use them. But, do not unnecessarily stick to it. Read above suggestion. In short, avoid over-engineering. Design patterns are created to solve specific problem. If you do not have that problem, then do not mess-up your code with unnecessary pattern.
Read about Aggregate Root, DDD, Repository etc.
Try your best to avoid Generic Repository.

Exporting EF Entity to Excel/PDF and How to Exclude Attributes without violating SRP?

I am working with Entity Framework as my ORM for a project at work, and I need to be able to write only some of the values of each entity to an existing Excel template.
The data is required to be formatted as Excel Tables so that the end user can reference the information by using formulas like "=AVG(People_Table[Age])". (note, this is just a contrived example for a simplicity). There is also a requirement to export the values to PDF as well.
I've decide that reflection is the way to go to export the information in the least painful manner possible. The problem now, however, is I want to exclude certain properties from being written to the spreadsheet. And I also might want to write the properties in a certain order and specify a display format.
One way I could do this is with defining specific Data Attributes on the properties. I liked this answer on ignoring specific attributes: Exclude property from getType().GetProperties(). So a possible solution could be:
// class I want to export
public class PersonEntity {
[SkipAttribute] // per solution in the referenced answer
public int PersonId { get; set; }
[SkipAttribute]
public int ForeignKeyId { get; set; }
[Display(Order = 3)]
public int Age { get; set; }
[Display(Name="First Name", Order = 1)]
public string FirstName { get; set; }
[Display(Name="Last Name", Order = 2)]
public string LastName { get; set; }
/* additional properties remove for brevity */
}
The Problem I see with the above solution is that this entity class is now doing two things: One, proving a mapping between EF and the Database which is it's primary function, and two providing information on how to consume the class for exporting to Excel. I see this as getting messy and leading to confusion because it (possibly?) violates SRP. And, also, I only need the SkipAttribute when exporting to Excel, most of the time I will just ignore this attribute.
An alternative solution that I see could be to create a separate set of classes that only contains the needed properties and to use this for exporting to Excel, and then using a tool like AutoMapper to map from EF Person to this class.
So, the export class would be:
public class PersonExportModel {
[Display(Name="First Name")]
public string FirstName { get; set; }
[Display(Name="Last Name")]
public string LastName { get; set; }
public int Age { get; set; }
/* additional properties removed for brevity */
}
And I would just use reflection to dump the values out to the specified format using ClosedXML or a PDF rendering library like ITextSharp.
Concern with the above solution is that this is going to end up with a lot of extra code just to ignore a few unwanted properties (mostly PK's, FK's, and some complex relationship properties). I am also at the issue any updates to the EF class, like removing a property, will require me to also go through the other classes and remove the corresponding properties. But I like this solution because there is less confusion to me about what data is needed for exporting to Excel.
So I'm stuck between either bloating my EF class to tell how it should be exported or creating other ExportModels that are tightly coupled to the EF class and would be a pain to update if the underlying model changes. And the whole mapping between classes is a real pain, which can be alleviated with AutoMapper. This comes with, however, it's own set of problems with obfuscated mapping and performance penalties. I could live with these "problems" if it means I do not have to manually map between the two classes.
I've thought about farming the work out to a SSRS but I need to ability to write the data to specific existing workbooks which I understand is not possible. I'd also need the ability to create named tables which also I understand is not possible out of the box with SSRS. I'd also need to create two reports because the Excel output would look much different than the PDF format. So even the SSRS would cause a lot of extra work.
Any suggestions on which solution might be best, or perhaps an alternative approach? The requirement of this project is in flux so I'm looking for a solution that will be as painless as possible to updates.

MongoDB: How to define a dynamic entity in my own domain class?

New to MongoDB. Set up a C# web project in VS 2013.
Need to insert data as document into MongoDB. The number of Key-Value pair every time could be different.
For example,
document 1: Id is "1", data is one pair key-value: "order":"shoes"
document 2: Id is "2", data is a 3-pair key-value: "order":"shoes", "package":"big", "country":"Norway"
In this "Getting Started" says because it is so much easier to work with your own domain classes this quick-start will assume that you are going to do that. suggests make our own class like:
public class Entity
{
public ObjectId Id { get; set; }
public string Name { get; set; }
}
then use it like:
var entity = new Entity { Name = "Tom" };
...
entity.Name = "Dick";
collection.Save(entity);
Well, it defeats the idea of no-fixed columns, right?
So, I guess BsonDocument is the the model to use and is there any good samples for beginners?
I'm amazed how often this topic comes up... Essentially, this is more of a 'statically typed language limitation' than a MongoDB issue:
Schemaless doesn't mean you don't have any schema per se, it basically means you don't have to tell the database up front what you're going to store. It's basically "code first" - the code just writes to the database like it would to RAM, with all the flexibility involved.
Of course, the typical application will have some sort of reoccurring data structure, some classes, some object-oriented paradigm in one way or another. That is also true for the indexes: indexes are (usually) 'static' in the sense that you do have to tell mongodb about which field to index up front.
However, there is also the use case where you don't know what to store. If your data is really that unforeseeable, it makes sense to think "code first": what would you do in C#? Would you use the BsonDocument? Probably not. Maybe an embedded Dictionary does the trick, e.g.
public class Product {
public ObjectId Id {get;set;}
public decimal Price {get;set;}
public Dictionary<string, string> Attributes {get;set;}
// ...
}
This solution can also work with multikeys to simulate a large number of indexes to make queries on the attributes reasonably fast (though the lack of static typing makes range queries tricky). See
It really depends on your needs. If you want to have nested objects and static typing, things get a lot more complicated than this. Then again, the consumer of such a data structure (i.e. the frontend or client application) often needs to make assumptions that make it easy to digest this information, so it's often not possible to make this type safe anyway.
Other options include indeed using the BsonDocument, which I find too invasive in the sense that you make your business models depend on the database driver implementation; or using a common base class like ProductAttributes that can be extended by classes such as ProductAttributesShoes, etc. This question really revolves around the whole system design - do you know the properties at compile time? Do you have dropdowns for the property values in your frontend? Where do they come from?
If you want something reusable and flexible, you could simply use a JSON library, serialize the object to string and store that to the database. In any case, the interaction with such objects will be ugly from the C# side because they're not statically typed.

Dynamic class creation

we have a data-layer which contains classes generated by outputs (tables/views/procs/functions) from database. The tables in database are normalized and are designed similar to OOP design ( table for "invoice" has 1:1 relation to table for "document", table for "invoice-item" has 1:1 relation to table for "document-item", etc...". All access to/from databaes is by stored procedures (for simple tables too).
Typical clas looks like (shortly):
public class DocumentItem {
public Guid? ItemID { get; set; }
public Guid? IDDocument { get; set; }
public DateTime? LastChange { get; set; }
}
public class InvoiceItem : DocumentItem {
public Guid? IDProduct { get; set; }
public decimal? Price { get; set; }
}
The problem is, the database tables has relations similar to multiple inheritance in OOP. Now we do a new class for every database output. But every database outputs are combination of "pure" tables in database.
The ideal solution would be (IMHO) tranform classes to interface, use the multiple implementation of interfaces, and then automaticly implement the members (this "table-classes" has only properties, and body of properties are always same).
For example:
public interface IItem {
Guid? ItemID { get; set; }
DateTime? LastChange { get; set; }
}
public interface IDocumentItem : IItem {
Guid? IDDocument { get; set; }
}
public interface IItemWithProduct : IItem {
Guid? IDProduct { get; set; }
}
public interface IItemWithRank : IItem {
string Rank { get; set; }
}
public interface IItemWithPrice : IItem {
decimal? Price { get; set; }
}
// example of "final" item interface
public interface IStorageItem : IDocumentItem, IItemWithProduct, IItemWithRank { }
// example of "final" item interface
public interface IInvoiceItem : IDocumentItem, IItemWithProduct, IItemWithPrice { }
// the result should be a object of class which implements "IInvoiceItem"
object myInvoiceItem = SomeMagicClass.CreateClassFromInterface( typeof( IInvoiceItem ) );
The database contains hunderts of tables and the whole solution is composed from dynamicly loaded modules (100+ modules).
What do you think, is the best way, how to deal with it?
EDIT:
Using partial classes is good tip, bud in our solution can not be used, because "IDocumentItem" and "IItemWithPrice" (for example) are in different assemblies.
Now, if we make change in "DocumentItem" table, we must go and re-generate source code in all dependent assemblies. There is almost no reuse (because can not use multiple inheritance). Its quite time consuming, if there are dozens of dependent assemblies.
I think it is a bad idea to automatically generate your domain model from your database schema.
So, you're really looking for some kind of mix-in technology. Of course, I have to ask why you aren't using LINQ to Entity Framework or NHibernate. O/RMs handle these problems by mapping the relational model into usable data structures that have APIs to support all of the transactions that you'll need to manipulate data in the database. But I digress.
If you are really looking for a mix-in technology to do dynamic code generation, check out Cecil at the Mono Project. It's a way better place to start than trying to use Reflection.Emit to build dynamic classes. There are other dynamic code generators out there but you may want to start with Cecil since the documentation is pretty good.
If you wish to continue auto-generating from the database and want to model multiple inheritance, then I think you have the right idea: Alter the tool to spit out interfaces with multiple inheritance, plus X num implementations.
You indicated elsewhere that a convention for inheritance vs. aggregation is enforced, and (as I understand) you know exactly how the resulting interfaces and classes should look. I understand that business rules are implemented elsewhere (maybe in a business rules engine?), so regenerating the classes should not require changes to dependent code, unless you want to take advantage of those changes, or existing properties have been altered or removed.
But you won't be done. Your classes will still have id's of related entities. If you want to make things easier for client code, you should have references to related entities (not caring about the related entity's ID), like this:
public class Person{
public Guid? PersonID { get; set; }
public Person Parent { get; set; }
}
That would make things easier on the client. When you think about it, going from ID's to references is work you have to do anyway; it's better to do it once in the middle tier than to let the client do it N number of times. Plus this makes your code less database-dependent.
So above all else, I recommend writing an OO wrapper for the auto-generated classes. You would program against this OO wrapper for almost everything; let only the data access layer interact with the auto-generated classes. Sure, you can't reuse inheritance metadata in the database (specified via conventions, I assume?), but at least you won't be carving a new path.
By contrast, what you have now looks like an anemic data model or worse.
The scenario is unclear to me.
If the code is generated, you don't need any magic: add some metadata to your database objects (e.g. Extended Properties in SQL Server) that flags the "basic" interfaces, and modify your generating template/tool to consider the flags.
If the question is about multiple inheritance, you are out of luck with .Net.
If the code is generated, you may also take advantage of partial classes and methods (are you using .Net 3.5?) to produce code in different source files.
If you need to generate code at run-time there are many techniques, not least ORM tools.
Now may you be a bit more explicit of your design context?

Categories

Resources