Save same class structure in two sets of tables with NHibernate - nhibernate

I've got a scenario something like this mock class heirachy
Order
OrderLine
Product
Customer
OrderNotes
which creates some tables like
Customer
Product
CustomerOrderNotes (CustomerId, OrderId)
Order (CustomerId)
OrderLines (OrderId, ProductId)
I've got this mapped to NHibernate and everything is working fine.
So now I want to create an in edit version of this object heirachy, and persist it to the database as well.
I'm using asp.net and want to save the in edit changes to separate rows, and then only when publish is pushed to commit the changes to the live row. (I'm planning on doing the copying from the edit data to the live data)
Using the same object model is it possible to store the in edit data in separate tables?
If not I could create an EditOrder class that derives from Order, but then EditOrder would still point to OrderLine, and Customer. So any changes from OrderLine and Customer would get saved to the live rows.
For NHibernate it appears I would need to create a separate heirachy
EditOrder
EditOrderLine
EditProduct
EditCustomer
EditCustomerNotes
without creating a generic behemoth that let you defined each class used in this heirachy I'm not sure which route to take.
I really want to use one class heirachy, rather than maintain two class heirachies.
The other option is to serialize the object heirachy for in edit onto the user class. But then if one of the class changes I'll have to wipe out the data, rather than run a database migration script.
Another solution is to use another database/session factory with different mapping files.
What is the recommended way of handling a scenario like this?

The two sets of tables are there to support two different states (published/awaiting approval (or the like)).
If possible, I recommend making this state explicit in your model, and save everything in the same table.
The client of the published objects will then somehow have to exclude the non-published objects.

Related

How To Override Default LINQ to SQL Association Name

I am working on a pretty straight forward C# application that uses LINQ to SQL for database access. The application is a non-web (i.e. thick client) application.
The problem that I have recently run into is with the default association name that LINQ to SQL is creating for fields that are foreign keys to another table. More specifically, I have provided an example below:
Example of Problem
The majority of my combo boxes are filled using values from a reference data table (i.e. RefData) that stores a type, description, and a few other fields. When the form initially loads, it fills the combo boxes with values based on a query by type. For example, I have a form that allows the user to add customers. On this form, there is a combo box for state. The stateComboBox is filled by running a query against the RefData table where type = stateType. Then, when the user saves the customer with a selected state the id of the RefData column for the selected state is stored in the state column of the customer table. All of this works as expected. However, if my customer table has more than one column that is a foreign key to the RefData table it quickly becomes very confusing because the association name(s) created by LINQ are Customer.RefData, Customer.RefData1, Customer.RefData2, etc... It would be much easier if I could override the name of the association so that accessing the reference data would be more like Customer.State, Customer.Country, Customer.Type, etc...
I have looked into changing this information in the DBML that is generated by VS but, my database schema is still very immature and constantly requires changes. Right now, I have been deleting the DBML every day or two to regenerate the LINQ to SQL files after making changes to the database. Is there an easy way to create these associations with meaningful names that will not be lost while I frequently re-create the DBML?
I am not sure LINQ to SQL is the best method of accessing data, period, but I find it even more problematic in your case.
Your real issue is you have the concept of your domain objects fairly static (you know what the program needs to use to get work done), but you are not sure how you are persisting the data, as your schema is in flux. This is not a good scenario for automagic updates.
If it were me, I would code the domain models so they do not change except when you desire change. I would then determine how to link to the persistent schema (database in this case). If you like a bit more automagic, then I would consider Entity Framework, as you can use code first and map to the schema as it changes.
If you find this still does not help, because your database schema changes are incompatible with the domain models, you need to get away from coding and go into a deeper planning mode. Otherwise, you are going to continue to beat your head against the proverbial wall of change.
Create a partial class definition for your Customer table and add more meaningful getter properties for the LINQ to SQL generated member names:
public partial class Customer
{
public string Name { get; set; }
[JsonIgnore]
public RefData State => this.RefData;
[JsonIgnore]
public RefData Country => this.RefData1;
}
I blogged about this here

Access 2003 - Create and Delete Many-To-Many associations

I need to develop a front end to a MSSQL database just to modify a few tables. I decided to use Access 2003 simply because of time restraints.
I used Linked Tables over ODBC to get them into Access, I'm designing the forms but I'm having problems creating an interface to allow users to create and delete new association between entities.
My Database structure is:
product
# productcode
- name
product_part
* productcode
* partnumber
- position
part
# partnumber
- comment
There is a many-to-many relationship between product and part (a product can have many parts and a part can belong to many products) except I can't find any easy way to allow a user to just associate a new part to product, only view the existing ones.
I've defined the relationships in Access except the options for cardinality and referential integrity are greyed out, I'm assuming this is because they're linked tables? Not sure if this would affect anything.
I created a form for product with an embedded subform which lists all the associated parts and their position (position is an attribute of the relationship since it's contextual but I can spin this out into it's own table if it'll make things easier).
Basically I need to make an user interface mechanism which will associate a selected part from a list to the shown product or any other way to create new and delete existing associations flexibly. I would have thought Access would have something in some wizard somewhere to do this, but if it does I can't find it.
Any help would be appreciated.
Judging on what noted so far, then this should be a simple matter to have the main form based on your topmost table (product). The continues sub form should then be based on ONLY the product part table.
If you think about this, the third table is really only a lookup table there for your convenience to allow you to not have to type in manually type in the part number.
So, base the child sub form as a continuous form, and make that column for part number a combo box that looks up the part numbers from the third table (part). So this combo boss can search and display by description, but will in fact automatically store the part number in that colum for you.
So while there's no need for any types of wizards, you certainly do not have to write any type of code whatsoever. Just ensure that the master child link settings for the sub form are set up correctly, and access will thus insert and maintain The product code columns used to link back to the main product table. You can most certainly use the combo box wizard to create the combo box in the continuous sub form that you're going to use to Select what part and set the part number column from the parts table.
The result will be a form that allows you to add new part assemblies or edit existing. While access will maintain the product code column for you, if you delete a main record, you'll need to have setup referential integrity and cascade deletes on the back end database part. So as you correctly note, all the integrity features will be set up in the database back end, not in the access front end part.
I've discovered what I wanted to do isn't easily possible using Linked Tables, I was able to do what I wanted to do easily if I used native access tables (since it let me properly define the relationships) but I couldn't do that with linked tables.

Nhiberate, multiple tables, same class

It's been asked a million times, its like this.
Say Invoice is the base class and InvoiceHistory is the class that simply inherits from Invoice.
When I do something like
invoiceList = session.CreateCriteria(typeof(Invoice)).List();
I get everything from Invoice (that I want, plus everything from InvoiceHistory).
Do I need to have an InvoiceBase and create derived versions for Invoice and InvoiceHistory?
I think this has to do with polymorphism in NHibernate. Try specifying polymorphism="explicit" on the mapping for your base-class (Invoice).
If you don't want to retrieve the invoicehistory for an invoice inheritance wouldn't do the trick. Even creating an InvoiceBase would not help. If you are using inheritance nhibernate will always return the most complex object that exists in database. So if there is a foreign key in the invoicehistory pointing to an invoice you will alway get the invoicehistory object instead of a simple invoice. This is a fundamental feature of nhibernate.
You could excplicitly fetch only the properties of invoice and map them by hand using a ResultTransformer (see Reference for more infos) or create and map a SimpleInvoice object also referencing the invoice table, but with the latter you may face some stales-state issues is you mix Invoice and SimpleInvoice within the same session.
Hope this helps.

NHibernate: Dynamic Table Mapping

I have a scenario where I want to persist document info record to a table specific to the typo of document, rather than a generic table for all records.
For example, records for Invoices will be stored in dbo.Doc_1000 and records for Receipts will be stored in dbo.Doc_2000 where 1000 and 2000 are id autogenerate and store in well-known table (dbo.TypeOfDoc.
Furthermore each dbo.Doc.xxx table have a group of system column (always the same) and could have a group of dynamic column (metadata).
Tables dbo.Doc.xxx and eventually dynamic column are clearly created at runtime.
If this is possible with NHibernate???
Thanks.
hope that I got your point. I am currently looking for a solution for a problem that looks similar. I want to integrate a feature in my application where the admin user can design an entity at runtime.
As far as I know, once the SessionFactory is configured and ready to use, there is no way to modify the mapping used by nhibernate. If you want to use a customized table structure that is configured, created and modified at runtime, you should have a place where a corresponding mapping lives, e.g. as a nhibernate mapping xml file and you have to set up a new SessionFactory each time you change the database model to reflect these changes.

using NHibernate on a table without a primary key

I am (hopefully) just about to start on my first NHibernate project and have come across a stumbling block. Would appreciate any advice.
I am working on a project where my new code will run side-by-side with legacy code and I cannot change the data model at all. I have come across a situation where one of the main tables has no primary key. It is something like this:
Say there is an order table and a product table, and a line_item table which lists the products in each order (i.e. consits of order_id, product_id, and quantity). In this data model it is quite possible to have 2 line items for the same product in the same order. What happens in the existing code is that whenever the user updates a line item, all line items for that order are deleted and re-inserted. Since even a compound key of all the fields in the line_item table would not necessarily be unique, that is the only possible way to update a line item in this data model.
I am prepared to guarantee that I will never attempt to update or delete an indivdual line item. Can I make my NHibernate code work in the same way as the existing code? If not, does this mean I (a) I cannot use NHibernate at all; (b) I cannot use NHibernate to map the line_item table; or (c) I can still map this table but not its relationships
Thanks in advance for any advice
I think if you map it as a bag collection on the Order (with inverse="false") it would work.
Collection Mapping
Note: Large NHibernate bags mapped
with inverse="false" are inefficient
and should be avoided; NHibernate
can't create, delete or update rows
individually, because there is no key
that may be used to identify an
individual row.
They warn against it but it sounds like what you want.