Help with SubSonic 2.2 binding - subsonic2.2

I have the following tables
TUser (user_id,firstname,lastname) PK
user_id
TGroup (group_id,name) PK group_id
TUsersGroups (user_id,group_id) PK
(user_id,group_id) FK (user_id) FK
(group_id)
I need to bind to a DataGrid the TUsers, showing the following columns firstname,lastname and groupname (the NAME taken from the TGroup.
I know I can accomplish this via the Subsonic Query, but is there a way to get the list of type TUserCollection showing the Group Name?

Not like you want. However, if your list is small, you can just access the associated TGroup object from each of the TUser objects. But of course that causes another query each time you access one of them.
What I have done in the past is either add a column to the result set of a Subsonic Query (before the query is executed), but that means you don't have a strongly typed collection of TUser objects.
Also, you could create a view with all the columns you want and regen Subsonic.
Finally, you could pull back all users into a collection (that match your criteria) and all groups that match your criteria, into their own collections, then "find" the group you want out of the new Group collection whenever you need it for an associated TUser.

Related

Multi tenancy ASP.NET core

I'm trying to build ASP.NET core api where I have a few group of users. These groups have a common database, but from there they can only see the records assigned to them.
For example the user XYZ calling the controller returning the values from the Products table sees only those that were assigned to his group. And the same when he adds a new Product, only the users of his group see it, and other groups do not know about the existence of this Product.
I would like to ask you to explain to me how to do it in ASP.NET core, what libraries I could use, because unfortunately I don't know how to do it.
Thank you in advance for your help.
I don't think you need to search for a library or a framework to build this out, you can do the implementation as follows,
Create a table that reads as ProductPermissions
Make an entry for recordid, groupid, roleid in this table
After a user is assigned a group, the relevant tables should have the values like UserDetails, UserGroups, UserRoles etc
When I want to see the list of products that are accessible to me, I make a request to the GetProducts API.
The API gets my userid from the authentication process, roles and group ids
Now, you have to join the products table and the ProductPermissions table with the keys and filter by the groupid that I have been assigned.
The same logic applies for all the entity operations that I do, any action will be validated against the ProductPermissions table.
Note
In order to get a generic table than redundant ProductPermissions, you can have the table as EntityPermissions and then have the entityId (ex: Product, Category etc) as a column and that will be used a filter during joining so that you have a single table for all entities.

Access Customer Attributes from Generic Inquiry

I need to leverage Customer Attributes in a Generic Inquiry. I devise most of my Generic Inquiries starting with raw SQL in Server Management Studio. I find it much easier to locate the data I need this way. However, I am having a terrible time figuring out how Attributes are tied to Customers. Attributes are added to a Customer Class, and then a customer is associated with a Customer Class. This allows any attributes available for that Customer Class to be modifiable for the Customer.
Using the database, I have found the following:
Individual Attribute objects are stored in the CSAttribute table
Options for the Attributes (such as combobox) are stored in the CSAttributeDetail table
Individual instances of each attribute are stored in the CSAnswers table
There is also a CSAttributeGroup table, which I believe relates CSAttributeDetail records to CSAttribute records.
So, one would expect the CSAnswers table to have a reference to the customer the answer is attached to... but it does not. This table is defined as:
CompanyID (PK, int, not null)
RefNoteID (PK, uniqueidentifier, not null)
AttributeID (PK, nvarchar(10), not null)
Value (nvarchar(255), null)
To add insult to injury, table names in the database do not always align 1-to-1 to what is available in a Generic Inquiry. For example, many fields that are available to ARInvoice in a GI are actually stored in the ARRegister table in the database. I suspect something very similar is going on for Attributes.
Can anyone point me in the right direction of locating how Attributes are associated to Customers at both the database level, and at the GI level?
Attributes are linked to the record with the RefNoteID field; it will match the NoteID of the other record (note that in your case it wouldn't be in the Customers table but in BAccount, which is a 1:1 join with Customers). You should rarely, if ever, need to directly reference the CSAnswers table. Internally, Acumatica will generate a set of virtual fields in the primary table that match the name of the attribute, suffixed with _Attributes:
Please note that you won't be able to reference the attribute in the "Conditions" tab, however you can filter by this column in the grid and create predefined filters.
I've made a number of GIs using Customer Attributes, the RefNoteID uniqueidentifier in the CSAnswers table relates to the NoteID uniqueidentifier on the Customer table, and the AttributeID is the specific Attribute. To get All attributes for a customer on multiple Rows join on just the RefNoteID, if you want specific attribute(s) add additional join conditions for each AttributeID.

Multiple record types and how to split them amongst tables

I'm working on a database structure and trying to imagine the best way to split up a host of related records into tables. Records all have the same base type they inherit from, but each then expands on it for their particular use.
These 4 properties are present for every type.
id, name, groupid, userid
Here are the types that expand off those 4 properties.
"Static": value
"Increment": currentValue, maxValue, overMaxAllowed, underNegativeAllowed
"Target": targetValue, result, lastResult
What I tried initially was to create a "records" table with the 4 base properties in it. I then created 3 other tables named "records_static/increment/target", each with their specific properties as columns. I then forged relationships between a "rowID" column in each of these secondary tables with the main table's "id".
Populating the tables with dummy data, I am now having some major problems attempting to extract the data with a query. The only parameter is the userid, beyond that what I need is a table with all of the columns and data associated with the userid.
I am unsure if I should abandon that table design, or if I just am going about the query incorrectly.
I hope I explained that well enough, please let me know if you need additional detail.
Make the design as simple as possible.
First I'd try a single table that contains all attributes that might apply to a record. Irrelevant attributes can be null. You can enforce null values for a specific type with a check constraint.
If that doesn't work out, you can create three tables for each record type, without a common table.
If that doesn't work out, you can create a base table with 1:1 extension tables. Be aware that querying that is much harder, requiring join for every operation:
select *
from fruit f
left join
apple a
on a.fruit_id = f.id
left join
pear p
on p.fruit_id = f.id
left join
...
The more complex the design, the more room for an inconsistent database state. The second option you could have a pear and an apple with the same id. In the third option you can have missing rows in either the base or the extension table. Or the tables can contradict each other, for example a base row saying "pear" with an extension row in the Apple table. I fully trust end users to find a way to get that into your database :)
Throw out the complex design and start with the simplest one. Your first attempt was not a failure: you now know the cost of adding relations between tables. Which can look deceptively trivial (or even "right") at design time.
This is a typical "object-oriented to relational" mapping problem. You can find books about this. Also a lot of google hits like
http://www.ibm.com/developerworks/library/ws-mapping-to-rdb/
The easiest for you to implement is to have one table containing all columns necessary to store all your types. Make sure you define them as nullable. Only the common columns can be not null if necessary.
Just because object share some of the same properties does not mean you need to have one table for both objects. That leads to unnecessary right outer joins that have a 1 to 1 relationship which is not what I think of as good database design.
but...
If you want to continue in your fashion I think all you need is a primary key in the table with common columns "id, name, groupid, userid" (I assume ID) then that would be the foreign key to your table with currentValue, maxValue, overMaxAllowed, underNegativeAllowed

NHibernate How to make Criteria inner join without hydrating objects?

Some quick nhibernate problem:
I have sql tables:
Item { Id, Name }
ItemRange { Id, Name }
ItemHasItemRange { Id, ItemId, ItemRangeId }
Mappings are simple, so I will not paste them, the ItemId and ItemRangeId are foreign keys, Item class has ItemHasItemRanges collection mapped as lazy bag.
I want all items which are in particular ItemRange, but I do not want to retrieve associated ItemRangeObjects, I just want to do inner join to narrow results.
When I do it like that:
c.CreateCriteria("Item", "i")
.CreateAlias("ItemHasItemRanges", "ihpr", JoinType.InnerJoin)
.Add(Restrictions.Eq("ihpr.ItemRange.Id", I18nHelper.CurrentItemRange.Id));
It works fine, but all ItemHasItemRange objects are fetched as well to the Item.ItemHasItemRanges collections (which is mapped as lazy)
I do not want to fetch Item.ItemHasItemRanges, because it takes time. I just want to do inner join to limit result set. It is possible in NHibernate?
So I think that you just want to retrieve those objects in order to show an overview / list, and you are not going to actually 'do' something with those objects (unless perhaps loading one of them) ?
In that case, I think that it is better for you to work with 'projections'.
Here's the scenario:
You'll have to create a (simple) class that just contains the properties that you want to show (where you're interested in).
You'll have to 'import' that class into NHibernate, so that NHibernate knows of its existence.
Next, you can create your Criteria statement like you have it now. (Working with your domain classes).
Then, you should specify how the projection should look like. That is, how the properties of your Item entity map to the properties of your 'DTO'/View class (= the simple class you just created).
Specify that an AliasToBean ResultTransformer should be used.
Then, execute your Criteria query. NHibernate will be able to produce the simplest possible query that is needed in order to retrieve all the data that is necessary.
I've explained something similar here
I find out the problem was somewhere else. ItemHasItemRange table did not have multiple index on ItemId and ItemRangeId - id only had separate indexes on each field. Thats why performance was so poor.
But NHibernate question is still valid - is it possible to create inner join for criteria only to narrow results and not to fetch all joined objects which normally are lazy.

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.