MVC Database Model Dynamic Properties - asp.net-mvc

He guys, so I need a little help with my database model for an mvc project I am working on.
Here is the situation:
I have a table called dbo.Clients that has the columns ClientName, PlanName, PlanPrice, PlanStartDate, PlanEndDate, and IsArchived.
For the fields ClientName, and IsArchived are only going to have one value in them that is subject to change. However, each client will have multiple PlanName, PlanPrice, PlanStartDate, and PlanEndDate values.
I have a ClientModel, ClientViewModel, ClientRepository, ClientService, and ClientController set up that successfully puts values into the database from the view.
The problem:
The way that I have done this is that I can only use one value for PlanName, PlanPrice, PlanStartDate, and PlanEndDate. For example lets say a client has bought Plan 1 and Plan 2 but I cannot store more than 1 plan.
What I want to do is make another table called Plans but I'm not quite sure how to use that in the MVC way to storing multiple values per client.

You need two tables. One will be a client master named something like Clients with the Columns Id, ClientName and IsArchived.
The other table will be something like ClientPlans with the columns ClientId, PlanName, PlanPrice, PlanStartDate, PlanEndDate
Ensure there's a Foreign Key relation between the Id in the Clients table and the ClientId in the ClientPlans table.
This can be refactored further to have a separate table for Plans (Id,PlanName, PlanPrice, PlanStartDate, PlanEndDate) and a transaction table called ClientPlans containing ClientId and PlanId with the appropriate relationships set.

Related

Entity framework multiple DbContext in single execution

I have one master & detail in my 'db1' and there is one column named 'EntryByUserId' in master table.
User table is available in 'db2'.
When all the tables are available in one single database we can directly get user detail by using include function. But here my reference table is in another database so in my case user object will return null value. So anyone please help me to achieve this.
I have created multiple dbcontext in my project but don't know how to get this.
Below is the code we use when all tables are available in single database.
dbcontext1.tbl_Master.Include(m => m.tbl_Detail).Include(m => m.tbl_user)
.AsNoTracking().FirstOrDefault();
One option to accommodate this cleanly, especially for something as frequently accessed as a "User" reference for something like reporting on CreatedBy or ModifiedBy tracking on rows would be to implement a view within Db2 that lists the users from Db1. Then in your main application context you can map a User entity to the view rather than a table. I would put guards in your DbContext and entities to discourage/prevent modifications to this User entity, and leave maintenance of users to a DbContext overseeing the Db1 tables.
If this is something like a multi-tenant system with a system database for authentication and separate DBs per tenant which are tracking things like CreatedBy against records, I would recommend considering a system to inspect and replicate users between the auth database and the respective tenant databases. The reason for this would be to help enforce referential integrity for the data and the user references. The issue with the view approach is that there is no constraint available to ensure that a UserId reference actually corresponds with a row in the Users table over in the other database. It can be indexed, but not constrained so you have to handle the possibility of invalid data.

How to join two tables in cakephp 3.x with a custom fieldname?

I have one table called countries which has a field i.e ID with primary key and the other table is customers which has a field called primary_country. I want to join both the tables in cakephp way, but always it is taking customers.country_id which is not present in the table. I am using primary_country because the table also has alternate_country field. so i can't use country_id. Please provide me any solution so that I can fetch the country names on the basis of primary_country and alternate_country.
You'll need to modify your table object with the foreign key, as mentionned here:
https://book.cakephp.org/3.0/en/orm/associations.html
It could be something like that, in your case :
class CustomersTable extends Table
{
public function initialize(array $config)
{
$this->belongsTo('Countries')
->setForeignKey('primary_country');
}
}
But i must say that if your model is still under conception, you may want to make an third table customer_countries and make an 'hasMany' relation between 'customers' and 'countries'. Limiting records for one customer to only two countries, and ordering them between 'primary' and 'alternate' is part of you business logic.

Asp.net mvc5 Identity?

Asp.net mvc 5 Identity 2.0 will create 5 tables automatically when run the mvc project.
Here, my question is why some tables like AspnetUser, it's item 'Id' type defined to string.
The String seems like GUID, but why it doesn't define to guid type instead of using string.
Is it transfer data type from string or do something when quering data ?
I can't figure out why it define to string, but look like guid ?
another table have same problem like AspnetRole, it's item 'UserId', 'RoleId' defined to string too.
Have any idea ?
I'm guessing this is having different reasons.
One reason is the insert performance for Guids, which will get slower and slower after an amount of data (Clustered indexes).
Another reason is the difference of handling Guid in different databases. Microsoft Sql Server has an UniqueIdentifier type that is a Guid, MySql will store them as strings, Oracle stores the raw bytes of a Guid...
I hope this explains a part of your queustion, as not fully :)...
Identity framework not only created for code first approach to be generate database tables with given fields or datatypes. Identity framework can be used against existing database or migrate old asp.net membership provider, or we can use our own table names with extra database fields to store more data on identity tables.
Further more, the Id of the aspnetUser table (that is the User table) used as string because, we can use Guid, integer, long etc. for this field depending on the requirement.
E.g. : If you decided to use integer as Id of the aspnetUser table (User table), then the database field will be auto increment int (or bigInt or etc.) field. But you need to do model binding in order to fulfill entity framework migration requirements.
By default we get Guid inserted into this field when we use out of the box asp.net Identity framework.
When you have defined roles for the registered user, there will be record added into AspnetRole table, this is also completely depending on the fields we defined on the tables as I discussed before. If we decided to use integer as Id of the aspnetUser table, then AspnetRole table fields updated according to the relationship with aspnetUser table fields.
Hope this helps.

What am I missing with my Entity Framework?

I have asp.net membership and I use the built in Create user method since it is convenient now after this depending on the user I want to add 2 more fields to the aspnet_UserTable.
In my aspnet_user Table I have like this
// All Standard Fields that come with this table
ClubID<nullable)
ClubName <nullable)
I have a table that relates this
Club Table
ClubID<PK>
ClubName
So this relationship forms that one club can have many users. But one user can only have 1 club.
So now I been trying to figure out how to add the ClubID to the aspnet Usertable since it does not show up in the Entity Framework Diagram since it does not show FK.
// Note in this case I am just using EF made to create but in reality I will use the Membership.Create.
aspnet_Users test = aspnet_Users.Createaspnet_Users(Guid.NewGuid(), Guid.NewGuid(), "myTest5", "mytest5", false, DateTime.Now);
test.Club = Club.CreateClub("One224", "Two224");
test.ClubName = "go";
MyEntities.AddToaspnet_Users(test);
MyrEntities.SaveChanges();
So what I have works but it just makes no sense and I hope there is a better way. Like I try to create the club and then stick it in the test.club.
This add's the ClubID primary key but does not add the clubName.
So then I have to add the club name separately. Like why? Is there not a better way?
I also prefer linq method syntax so if it is needed and you know this syntax can you please write it in that.
I would recommend a few things.
One: Strongly consider not adding columns to the aspnet_* tables. If you ever want to change your authentication method down the road you'll be stuck lugging those tables around with you even though you won't need them anymore. Also, there may be a new, better version of the membership provider one day that you won't be able to upgrade because you have customized the membership schema.
Two: Instead, why not create a new table called User (or something of your liking) that has your own primary key but links back to the ASP.NET Membership unique key (the guid).
Your table might look like
User
UserId (PK)
AuthenticationUserId (FK back to aspnet_User table)
ClubId (FK back to your club table)
Three: I don't understand why you've repeated ClubName both in your user table and in your Club table. You really only need to define the ClubName once, right? Keep your Club table how it is but remove the ClubName column from the user table.
Your code above for associating the club with the user is correct and works because that's how the Entity Framework works. You're associating entities with each other and are abstracted from some of the relational aspects of your data schema. It's a little strange to get used to it first but it does work.

Linq2Sql Insert Records To Related Tables

Similar situation to : How to add several dependent records with LINQ2SQL
(this seems logical, but it doesn't work for me)
ASP.NET MVC + Linq2SQL
I have 2 tables called Challenges and Participants.
Challenge { challengeId,
ChallengeDesc, applicantId,
respondantId }
Participants { participantId, FirstName, LastName }
There are 1-many relationships between participants and Challenges - 1 for each key (applicantId, RespondantId).
I have an input form that collects all fields to create a new applicant and respondant and the challenge. The Databinder binds all the fields to Challenge and it's child participants correctly, however, the participant objects' names don't match the key names in the challenge object when browsing the structure created by Linq2Sql (applicantId matches with Participant object and respondantId matches with Participant1 object).
So when i try to SubmitChanges() after InsertOnSubmit(aChallenge) i get a foreign_key constraint validation message back from Linq2Sql. In SQL Server Profiler, I can see that the participants are being created properly, but when the challenge is being saved, the IDs of these newly inserted participants are not being set to the challenge object so the system is throwing a foreign key violation message.
How do i get past this?
You have to write it this way I think (assuming you have classes Participant and Challenge):
Participant applicant = new Participant();
Participant respondant = new Participant();
//update your participants here
Challenge insertedChallenge = new Challenge();
//update your challenge values here
applicant.Challenges.add(insertedChallenge);
respondant.Challenges1.add(insertedChallenge);
submitChanges();
Linq-to-SQL should automatically assign these properties (Challenges and Challenges) so it can set the key values for you.
Hope it helps.
You might want to edit you data objects (normally by using the DBML designer) and rename the Participant-typed properties to Applicant and Respondent respectively. It'll be easier to work with than having Participant and Participant1. You can do this in the association properties (the lines that connect the tables).
When you want to assign the foreign keys in Challenge, you have two choices. If you have the Participant objects themselves, you can assign them to the (newly renamed) Applicant and Respondent properties (and LINQ to SQL will update ApplicantID or RespondentID accordingly). Or if you have the ParticipantIDs, you can assign them to ApplicantID or RespondentID directly.

Resources