Linq2Sql Insert Records To Related Tables - asp.net-mvc

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.

Related

MVC Database Model Dynamic Properties

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.

Supplying the model with varying amounts of data from database

Supposed I have an online store and a model User, which contains a whole bunch of parameters (First Name, Last Name, an Address object, ProductCategoryAccess object etc.)
The way it's currently set up is the constructor accepts an Id and populates the entire class with data from the database.
But what if I don't need all that data? For example, if I have a view that just lists users, I'd have to create a list of Users, with each of them needlessly querying the database for information that I don't need (Address, ProductCategoryAccess, etc).
What's the best way of handling this? Do I create a bunch of different classes, with only the parameters I need for various situations? Do I create one User class, but with different "setter" methods, which will use different queries to populate only certain parameters?
Are you using any ORM tools to get the data? If yes, then you could use lazy binding to retrieve only elements that you need.
If you are directly querying the db, then dividing it across different methods with queries should do the trick.
What are the different situations you need to account for?
If you only wish to select certain properties from your user database record then you can use projections to bind the records into a data transfer object that contains only the properties you need for any given page.
For instance, if you needed properties for an edit user page then your query (I assume you're using Entity Framework?) would look something like this:
this.userContext.Users.Where(y => y.UserId == userId).Select(x => new UserEditDto {
FirstName = x.FirstName,
Surname = x.Surname,
EmailAddress = x.EmailAddress
}).FirstOrDefault();
What this will do is build a LINQ query against the database that selects only the properties specified within the select part of the LINQ statements. In fact, if you were to remove the FirstOfDefault() method and stick a breakpoint in you'd be able to see the SQL generated by that statement would look a little something like:
SELECT FirstName, Surname, EmailAddress FROM users WHERE userId = 1;
It's only when you call .FirstOrDefault() does the LINQ provider execute the query against the database and return the result.
From here you're able to return your DTO to your service layer or your controller to send it to a view within a view model. You can then rinse and repeat this same type of query for other possible data transfer objects and views that require certain data.

Performance implications : Entity table reference vs List of that table reference

I am using entity framework and developing an architecture for application with remote data access. Coming back to point, i query the database for one record (say on the basis of itemcode). Now the resultset i will get whether i should return it as List or collection or simple as an object of entity. I am using entity object but my boss is saying i should use List. He thought , returning result as an entity with return whole table structure also. Quick suggestion would be appreciated.
List<Employee> lstemployee = GetRecordByCode(itemCode)
or
Employee emp = GetRecordByCode(itemCode)
What's the difference? If itemCode is a unique key you will either get one Employee object or a list containing the same one Employee object. You will never return the whole table. That will only happen if within GetRecordByCode you do something like context.Employees.ToList() without any Where filter before the ToList().
If itemCode is not unique you even have to use a list.

How do I determine the ID of an aggregate root added to a repository?

Say I have a generic repository interface as follows:
public interface IRepository<T>
{
Add(T item);
Delete(int itemId);
Update(T item);
}
Typically the new ID of an item added through IRepository.Add() would be determined by some back-end database, but only once the overall transaction/unit of work has been submitted. So I'm fairly certain that it would be wrong for IRepository.Add() to return the new ID of the added item. The repository really shouldn't know anything about how ID are created. Is this correct?
If this is a case how else can one determine the new ID of an item added to a repository, or should I even be doing this? I know an ORM like NHibernate is able to automagically replace objects in memory with new objects with the correct ID, but I'm trying to design my repository with out any specific ORM implementation in mind.
For example say I have a website where customers can make orders. A new customer chooses to check out and is sent to a form to fill out their details. This information is used to create a Customer object which is stored in a CustomerRepository. Now their order information needs to be created but an Order needs to reference a Customer by their ID?
Customer newCustomer = new Customer(first, last, address, phone dateOfBirth);
customerRepository.Add(newCustomer);
//How would I determine customerId??
Order newOrder = new Order(customerId, shippingAddress, billingAddress);
newOrder.AddOrderItem("widget");
newOrder.AddOrderItem("doohicky");
newOrder.AddOrderItem("stuff");
In the example you give, I would create the Customer and Order in one step, and pass domain objects to domain objects, instead of passing Ids:
Customer newCustomer = new Customer(first, last, address, phone dateOfBirth);
// Pass the customer rather than the CustomerId:
Order newOrder = new Order(newCustomer , shippingAddress, billingAddress);
newOrder.AddOrderItem("widget");
newOrder.AddOrderItem("doohicky");
newOrder.AddOrderItem("stuff");
customerRepository.Add(newCustomer);
orderRepository.Add(newOrder);
// SaveChanges()
...when the changes are saved, the framework automatically populates the Ids of both Customer and Order, and fills in Customer.Id, Order.customerId, (etc.) by virtue of the Customer object having been assigned to the Order.
Eric,
In the scenario you mention, I don't see any CommitChanges() going on. I would wrap everything in a transactionscope and then hit customerRepository.CommitChanges() before you add the orderlines. you should then be able to grab the id from the newly created customer object and use it as follows:
Order newOrder = new Order(newCustomer.Id, shippingAddress, billingAddress);
then, if the order(s) fails, you can roll everything back and keep it atomic by not hitting scope.Complete().
hope this helps..
I generate id on a client (a la CombGuid.NewGuid()) and then pass it to constructor. Approach when you are using database identity has serious disadvantages
Whether or not you use NHibernate, I feel that the approach it takes is the right one. Your goal with any domain objects is to only ever have one instance of that object in memory at any one time, i.e. you should never have two objects that represent the same database record. It follows that if the database has updated the record with a new id, the domain object in memory should also be updated with that ID since that is the "one" true representation of that record.
After calling Add, the object's ID is set and you could then make further changes to that object and call Update without having to know too much about your implementation.
Your interface is more DAO than Repository according to DDD:
http://codebetter.com/iancooper/2011/04/12/repository-saveupdate-is-a-smell/
Like Steve Wilkes mentioned, you should keep reference of Customer in Order and not Customer Id so when Unit of Work is processed, it will create correct link those Entities in Persistence Storage (SQL DB, Web Service etc)
For more on DAO here: http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
Domain entities should have their own ID strategy regardless database IDs, so preferably generate your id in the domain layer, or if you really need to generate id in database, then add another domain identifier generated at domain layer beside the database auto generated id.
In domain driven design where you apply repository pattern you should not tie your domain with database so relying on database for id creation is not a good idea.
Another point is that you may want to make customer associated in order not just putting the customer id, this makes the domain layer rich and solid.

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.

Resources