How to handle entity versions in SQL Server? - entity-framework

I have a SQL Server 2008 R2 database that contains a table that holds my entities from an ad.
It looks something like this :
Title
Price
CreatedDate
UpdatedDate
Description
EndDate
PublishedDate
StateOfProduct
Id
UserId
UserLocationId
Visits
CategoryId
TypeOfAd
AdminComment
ReviewedDate
AmountOfImages
UserPostCode
UserEmail
UserPhoneNr
UserPassword
OwnerType
AdminUserId
InactivatedDate
OldPrice
PriceLastChange
An Ad entity can have the following stages : Published, Waiting for review, Outdated.
Say that the ad is published and the customer decides to edit the ad, this means that the settings on the ad above will change. A change like this demands a new review and that means that the ad will go from Published to Waiting for review.
The problem with this is that when a ad is changed and is waiting for review it is not published anymore.
What I need is to let the ad be published with the old (reviewed) data and when the review is done of the updated ad it will switch places but keep the old id.
The question is how to handle this the right way?
I Suppose that I could have two identical tables to keep record count down and to make it simpler to find published ads but it will be a lot more work to use Entity Framework against two identical tables at the same time.
Another solution might be to add two extra columns in the Ads table that holds the version of the ad and the original adId. The flow will in this case be something like this :
Create Ad(id=1), originalId = null, version = null.
Review Ad(id=1)
Publish Ad(id=1), version = 1
Customer Updates Ad, new Ad(id=2) is created with version set to null(=waiting for review) and originalId = 1
Reviewed Ad(id=2) done, Ad(id=1) will be copied to a new records (id = 3 (or2)), originalId set to 1. Ad(id=2) will be moved/copied to Ad(id1), originalId = null, version = 2.
The ad table might however be vary large with this but it will be a lot easier to trace ads history.

I believe this could be done using many approaches, it's just a matter of preference. What I would do is make a new table named, say, ReviewedAds with int Id, int AdId, bit Reviewed. 1:many relationship with Ads table so AdId from this table is a foreign key and matches Id from Ads table. Then I would display only those ads whose Reviewed bit is set to '1'. Two records in ReviewedAds couldn't have the same AdId and Reviewed bit set to '1'.

Related

Nest TypeORM Postgres update user's column('number of posts') based on the userId in the Posts Table

I'm wondering if it's possible to auto update the User's column('number of posts') if the Posts table updates. The Post entity has a ManyToOne relation with User('userId'). Is there a way to make the User Table "listen" to the Post Table and automatically updates the number of post column, or i need to write it in the post service create function to do so. I'm new to sql so i'm just trying new stuff. I'm using NestJS,typeORM, Postgres and Graphql
#Kendle's answer does work and has the advantage of pushing the computation and complexity down onto your DB server. Alternatively, you can keep that logic in the application by leveraging TypeORM's Subscribers functionality. Documentation can be found here.
In your specific use case, you could register a subscriber for your Post entity implementing afterInsert and afterRemove (or afterSoftRemove if you soft delete posts) to increment and the decrement the counter respectively.
You don't want to duplicate that data. That's the whole idea of a relational database that different data is kept in different tables.
You can create a view if you want to avoid typing a query with a JOIN each time.
For example you might create the view below:
CREATE VIEW userPosts AS
SELECT
user.id,
user.name,
COUNT(posts.id)
FROM users
LEFT JOIN posts ON user.id = posts.user_id
ORDER BY user.id;
Once you have created the view your can query it as if it were a table.
SELECT * FROM userDate WHERE id = '0001';
Of course I don't have your table definitions and data so you will need to adapt this code to your tables.

Database optimization for subscriptions and activation codes

I wonder about the structure of the database and how it should be designed optimally.
Problem:
An application for publishing books, books is added by the administrator. There is a Cooperator module, when publishing a book to the platform, you can add a Cooperator. Cooperator has activation codes. The activation code allows the user to access content that has been tagged with a given Cooperator. You can purchase a subscription, a subscription gives you the opportunity to access books without the specified Cooperator. I do not know how to solve it correctly from the database side, to make it as optimal as possible, in addition, if the user does not activate the Cooperator code, he should not see these books at all.
Actual Database:
Book Entity:
Date Created
Date Updated
Id
Name
Categories
Cooperator
Cooperator Entity
Date Created
Date Updated
Id
Name
CodeBatches (One to Many)
Code Batche Entity:
Date Created
Date Updated
Id
Name
Access In Months
Cooperator (Many to One)
CodesActivation (One to Many)
Code Activation Entity
Date Created
Date Updated
Id
Status
Activation Code(Unique)

One view, multiple nested forms, multiple tables

Background
I was given the task of writing a Small Business online database. This database is to include a lot of info as well as info on their directors and branches. Since any business can have an unlimited amount of directors and branches, I need to create a database that is not limited to just one director and/or branch.
What do I have
Currently I have 3 tables.
smmes [id, company_name, trading_name, business_address, registration_number, tax_reference, vat_number, bbbee_status, employees, awards, created, modified]
ownerships [id, smme_id, name, surname, gender, age, race, disability, qualification, created, modified]
branches [id, smme_id, location, contact_number, contact_person, created, modified]
Note: smme_id is the id of the company in smmes that the branch or director belongs to.
And I have a view for the SMME's.
What is my question
I'm VERY new to cakePHP (in fact, this is my first app I'm creating with cakePHP). I want to know how I can make one form where a user can enter all this detail and then add the details for all directors and branches from one view. I would prefer that they do not have various views to go through to create all the details. Add to that, this one view should then save all the data to the correct tables with the correct smme_id.
Is this possible or should I rather leave cakePHP and write it manually.
You can load model on demand in your controller and then pass model specific data(received from posted form) to loaded model's save method.
public function detail(){
if($this->request->is('post')): // update only when form is posted
$this->loadModel('ownerships');
$owner_name= $this->request->data['Ownername'];
$ownerships_data = array('Ownership' = > array(
'name' = > $owner_name
//add other keys from posted form
)
);
$this->Ownership->saveAll($ownerships_data);
// load other models for saving posted data in related tables
endif;
}
Similarly load other models and pass fields from posted form as array to it's save method.
Suppose URL format is http://example.com/director/detail.So you would like to put above method(termed as action in MVC terminology) in app/controllers/directors_controller.php
Generally if URL format is http://somesite.com/abc/xyz it will look for xyz action in
app/controllers/abcs_controller.php
You can read more about cake conventions here

Entity Framework code first aspnet_Users mapping / joins

I was wondering with Entity Framework 4.1 code first how do you guys handle queries that involve an existing aspnet_Users table?
Basically I have a requirement for a query that involves the aspnet_Users so that I can return the username:
SELECT t.Prop1, u.Username
FROM Table1 t
INNER JOIN aspnet_User u ON t.UserId = u.UserId
Where t.Prop2 = true
Ideally in linq I would like:
from t in context.Table1
join u in context.aspnet_Users on t.UserId equals u.UserId
where t.Prop2 = true
But I'm not sure how to get aspnet_Users mapping to a class User? how do I make aspnet_Users part of my dbset ?
Any help would be appreciated, thanks in advance
Don't map aspnet_Users table or any other table related to aspnet. These tables have their own data access and their own logic for accessing. Mapping these tables will introduce code duplication, possible problems and breaks separation of concerns. If you need users for queries, create view with only needed information like id, user name, email and map the view. The point is that view will be read only, it will contain only allowed data and your application will not accidentally modify these data without using ASP.NET API.
First read Ladislav's answer. If you still want to go ahead : to do what you want would involve mapping the users and roles and members tables into the codefirst domain - which means writing a membership provider in code-first.
Luckily there is a project for that http://codefirstmembership.codeplex.com/ although its not a perfect implementation. The original is VB, look in the Discussion tab for my work on getting it running in c# MVC.
I'm working with the author on a better implementation that protects the membership data (password, last logged on date, all of the non-allowed data) but allow you to map and extend the user table. But its not ready yet!
You don't really need to use Entity Framework to access aspnet_membership provider accounts. You really just need to create an instance of the membership object, pass in a unique user identifier and a Boolean value indicating whether to update the LastActivityDate value for the user and the method returns a MembershipUser object populated with current values from the data source for the specified user.
You can then access the username by using the property of "Username".
Example:
private MembershipUser user =
Membership.GetUser(7578ec40-9e91-4458-b3d6-0a69dee82c6e, True);
Response.Write(user.UserName);
In case you have additional questions about MembershipProvider, you can read up on it on the MSDN website under the title of "Managing Users by Using Membership".
Hope this helps you some with your requirement.

FileMaker - Finding Primary Key of First Related Record

I'm using a script to create a new Invoice record. I'd like to automatically set the invoice's fClient fContactID column to the ID of the client's first contact.
In my script, how would I find/compute the ID of the client's first contact? SetField with a calculated result of Min(Contact_Invoice Contact::ContactID) didn't work.
Tables:
Client - primary key: ClientID
Contact - has foreign key: fClientID (a client can have many contacts)
Invoice - has foreign keys: fClientID & fContactID (an invoice is associated with one client and with one of that client's contacts)
Thank you,
Ben
You say you want to set the "fClientID", but from your description it sound more like you're wanting to set the fContactID. Is that right?
If that's the case, then you have an Invoice, related to a Client, which is directly related to a Contact. What you're doing is right, but if it's not working then your context isn't right. Your context at the time is the Invoice table, so the related Contact needs to be accessible from there.
You could also use an auto enter calc instead of a script to set this. Extra bonus is that this will only let you select a valid context and related table.