I want to use last inserted id from database, but that Id is in string format. Is there any way I can get last inserted string ID?
Every time I am using
p.UserId = db.AspNetUsers.Max(m => m.Id);
but it is returning wrong results. I think it is string so max won't work. Can anyone please suggest how to solve this problem?
Table structure:
Patient: ID (PK), UID (fk of UserLogin), Name
AspNetUsers table:
CREATE TABLE [dbo].[AspNetUsers]
(
[Id] NVARCHAR(128) NOT NULL,
[Email] NVARCHAR (256) NULL,
)
Patient table:
CREATE TABLE Patient
(
PatientId INT IDENTITY(1,1) PRIMARY KEY,
PId AS 'P' + RIGHT('00000' + CAST(PatientId AS NVARCHAR(10)), 10) PERSISTED,
UserId NVARCHAR(128) FOREIGN KEY REFERENCES AspNetUsers(Id)
)
Example ID is in format like this : 62d8d072-5261-4aaf-b552-d75453cc3421
This is the code , first I am getting value from view in AspNetUsers table , therefore it will generate id in table and I want to use that Id for my Patient table.
[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
public async Task<ActionResult> SignUp(Patientview pv)
{
ClinicDbContext db = new ClinicDbContext();
if (ModelState.IsValid)
{
try
{
var user = new ApplicationUser { UserName = pv.Email, Email = pv.Email };
var result = await UserManager.CreateAsync(user, pv.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
else
{
return View(pv);
}
Patient p = new Patient();
p.FirstName = pv.FirstName;
p.LastName = pv.LastName;
p.DateOfBirth = pv.DateOfBirth;
p.Email = pv.Email;
p.PhoneNumber = pv.PhoneNumber.ToString();
p.StreetAddress = pv.StreetAddress.ToString();
p.City = pv.City;
p.State = pv.State;
p.ZipCode = pv.ZipCode;
p.UserId = db.AspNetUsers.Max(m => m.Id);
_context.Patients.Add(p);
_context.SaveChanges();
return RedirectToAction("Index", "Admin");
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
System.Diagnostics.Debug.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
System.Diagnostics.Debug.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
}
else
{
return View(pv);
}
}
Normally with EF you would map the relationship between entities with the FKs and let EF manage the assignment of the FK when the primary record and associated records are saved. However, in your case the relationship is relatively loosely coupled.
Are all Patient records going to be associated to ASP.Net authenticated users? If so you can look at changing the PK type on Patient to match the ASPNet table then set up the Patient as a 1-to-1 relationship to ASPNetUser.
Alternatively, if Patients can be ASPNetUsers (but can also be dissociated) then I would look at adding a PatientId column as an autoincrementing integer or sequential GUID (newsequentialId())to ASPNetUser and mapping that to the PatientId in patient as either optional or required a many-to-1. This gets around the ugliness of the string PK on ASPNetUser and allows you to use a FK type that is more suited to your application. (Int or GUID)
A third option you can use to get that newly inserted PK; The PK will only be created after the DbContext SaveChanges so this leaves you with calling SaveChanges twice to get that first id:
//...
var user = new ApplicationUser { UserName = pv.Email, Email = pv.Email };
var result = await UserManager.CreateAsync(user, pv.Password);
if (result.Succeeded)
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
else
return View(pv);
_context.SaveChanges();
Patient p = new Patient();
p.PatientId = Guid.Parse(user.UserId); // User ID will be populated after the above SaveChanges call.
p.FirstName = pv.FirstName;
//...
_context.SaveChanges(); //Save the Patient.
Typically though this isn't ideal as you can get the situation where the first SaveChanges succeeds, but the second fails. These records should likely go through together, so this can be achieved with a tranasaction scope, or a unit or work such as DbContextScope.
Using a TransactionScope:
using (var tx = new TransactionScope())
{
var user = new ApplicationUser { UserName = pv.Email, Email = pv.Email };
var result = await UserManager.CreateAsync(user, pv.Password);
if (result.Succeeded)
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
else
return View(pv);
_context.SaveChanges();
Patient p = new Patient();
p.PatientId = Guid.Parse(user.UserId); // User ID will be populated after the above SaveChanges call.
p.FirstName = pv.FirstName;
//...
_context.SaveChanges(); //Save the Patient.
tx.Complete()
}
In general though, mapping the relationship between entities would be a better option because then the FK constraints can be set up to manage things like cascade deletes.
I understand that you want to get the the last inserted field in the database.
Why don't you use Last() function. :)
p.UserId = db.AspNetUsers.Select(X=>x.id).Last();
Will give you the Userid from the last row of the table.
Max is selecting the maximum value which may or may not yield you the last value.
Related
I have multiple tables that has 1:1 relations
I need to separate the fields to another tables because some of it are rarely used. The "main" table has a Primary Key that is auto number (Identity in SQL Server)
Now I need to insert multiple records from XML using Entity Framework
XDocument xDoc = XDocument.Load(Server.MapPath("~/xml/xmlFile.xml"));
List<MainTable> allListings = xDoc.Descendants("listing")
.Select(listing => new MainTable
{
listingCategory = listing.Element("listCategory").Value,
listingStatus = listing.Element("listStatus").Value
}).ToList();
using (DemoEntities db = new DemoEntities())
{
foreach (var i in allListings)
{
db.Main.Add(i);
}
db.SaveChanges();
}
The following code is not possible because I need [id] field auto assigned by SQL Server to the [MainTable].
List<SecondTable> allListingsTableTwo = xDoc.Descendants("listing")
.Select(listing => new SecondTable
{
anotherField = listing.Element("fieldfromXML").Value
}).ToList();
foreach (var i in allListingsTableTwo)
{
db.SecondTable.Add(i);
}
you can get the primary key by:
db.Main.Add(i);
context.SaveChanges();
int id = i.Id; // Yes it's here
What I am trying to do is create a record in 2 tables, Communities and CommunityTeams. Each of these have a primary key ID which is set as a Identity 1.1 in SQL Server. Now, I would like to capture the key of Communities as a foreign key in CommunityTeams, but I have no way of knowing what that ID is.
Here is my code in ASP.NET MVC and Entity Framework:
if (ModelState.IsValid)
{
// Community Info
model.CommunityType = Convert.ToInt32(fc["communityType"]);
model.ComunityName = fc["communityName"];
model.CommunityCity = fc["communityCity"];
model.CommunityState = fc["communityState"];
model.CommunityCounty = fc["communityCounty"];
model.Population = Convert.ToInt32(fc["communityPop"]);
// Save to Database
model.Active = true;
model.DateCreated = DateTime.Now;
model.CreatedBy = User.Identity.Name;
model.Application_Complete = true;
model.Application_Date = DateTime.Now;
model.Payment_Complete = true;
model.Payment_Date = DateTime.Now;
model.Renewal = true;
model.Renewal_Date = DateTime.Now;
team.TeamLeader = true;
team.Admin = true;
var user = User.Identity.Name;
team.UserName = user.ToString();
team.CommunityId = 1;
db.CommunityTeams.Add(team);
db.Communities.Add(model);
db.SaveChanges();
return RedirectToAction("Index", "Habitats");
}
I will admit that you have a navigation property to Community in your CommunityTeam entity.
Replace team.CommunityId = 1; by team.Community = model;. Then simply add the team entity, EF will create both model and team.
db.CommunityTeams.Add(team);
db.SaveChanges();
You can also split the save in two parts by calling db.SaveChanges(); between the two Add call.
The first save will create the Community entity, EF will fill your primary key automatically so you can use it in Team entity for the second save.
I'm a bit confused on how to create a "Key" object to select exactly 1 row of my Entity ("Customer").
My code :
Query query = new Query("Customer");
// **** how do I have to create this key ???
Key key = KeyFactory.createKey("Customer", 1);
// ****
FilterPredicate keyFilter = new FilterPredicate(Entity.KEY_RESERVED_PROPERTY, FilterOperator.EQUAL, key);
query.setFilter(keyFilter);
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
PreparedQuery pq = datastore.prepare(query);
Entity customer = pq.asSingleEntity();
if (! (customer == null)) {
log.info("OK !");
}
else {
log.info("no customer found");
}
My result is always : "no customer found".
With the datastore viewer (I'm working locally) I can see 3 rows :
id/name = 1 email = "your email" name = "your name"
id/name = 2 email = "your email" name = "your name"
id/name = 3 email = "your email" name = "your name"
I want to select customer with id/name=1.
I've tried :
KeyFactory.createKey("Customer", 1);
and
KeyFactory.createKey("Customer", "your name");
but with no success.
When I do programmatically a search (asList) on "Customer" and I print the keys' values I see :
row 1 key = Customer("your name")/Customer(1)
row 2 key = Customer("your name")/Customer(2)
row 3 key = Customer("your name")/Customer(3)
The printable values of the keys are in the format : "Entity(name)/Entity(id/name)"
How can I create such key values in my code ?
On the javadoc I see only :
createKey("kind", id)
createKey("kind", "name")
The other methods require an ancestor, I've not created an ancestor ....
This is the code that I've executed to created the 3 rows (it has been executed 3 times) :
Key customerKey = KeyFactory.createKey("Customer", "your name");
Entity customer = new Entity("Customer", customerKey);
customer.setProperty("name", "your name");
customer.setProperty("email", "your email");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
datastore.put(customer);
Thanks in advance !
Regards
Max
In other words, how do create a Key whose "toString" gives the following result ?
Code : log.info("customer KeyFactory.keyToString = "+KeyFactory.keyToString(key));
Output : INFO: customer KeyFactory.keyToString = Customer("your name")/Customer(1)
The creation of the Entities is not correct.
You dont have to create a key on your own.
If you create a Entity with a kind and keyname or ID parameter, a key will be created automaticlly out of the kind and the keyname or ID.
Entity customer = new Entity("Customer", "your name");
customer.setProperty("email", "your email");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
datastore.put(customer);
That is all you need to create the Entity you want.
When you give a kind and a key, a child Entity will be created.
So you had created a Customer with "your name" who is a Customer with the ID 1.
To get the Entity with a key you just have to take the same parameters to create a key.
Key key = KeyFactory.createKey("Customer", "your name");
I would prefer to use get(), but i dont know what you want to do.
For Example to get the email of a Customer:
Entity e;
try {
e = datastore.get(key);
String myEmail= (String) e.getProperty("your email");
I think you want to use get() not query() when you have a Key.
https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/DatastoreService#get(com.google.appengine.api.datastore.Key)
Let us assume that you have a Java entity class called Product and you wish to retrieve a unique record given its key i.e. ID
The method would look something like this:
public Product getProduct(Long id) {
//Get Persistence Manager
PersistenceManager pm = ...;
Key k = KeyFactory.createKey(Product.class.getSimpleName(), id);
Product product = null;
try {
product = pm.getObjectById(Product.class, k);
}
finally {
pm.close();
}
return product;
}
So in your example, I think you can replace Product with your class name. I guess your class name is Customer
Hi all the below solution works in that it creates a record in the MeetingRoomRequest table and also adds the associated amenities to that request into the MeetingRoomRequestAmenityLink table. However it just feels a bit clunky, so I was wondering if there is a nicer solution out there (i.e. not having to create 2 context instances) using MVC 3 and Entity Framework??
Please note i've set up the necessary relationships (one to many) in SQL Server and Entity Framework.
Also please note AmenityList is an array of id's (e.g. [1,2,4])
private readonly IDataRepository<MeetingRoomRequest> _meetingRoomRequestRepository = new DataRepository<MeetingRoomRequest>();
private readonly IDataRepository<MeetingRoomRequestAmenityLink> _meetingRoomRequestAmenityLinkRepository = new DataRepository<MeetingRoomRequestAmenityLink>();
var meetingRoomRequestToAdd = new MeetingRoomRequest
{
User = meetingRoomRequestViewModel.User,
UserEmail = meetingRoomRequestViewModel.UserEmail,
Title = meetingRoomRequestViewModel.Title,
Comments = meetingRoomRequestViewModel.Comments,
StartDateTime = meetingRoomRequestViewModel.StartTime,
EndDateTime = meetingRoomRequestViewModel.EndTime,
RequestStatusID = (int)Enums.RequestStatus.New,
AttendeeCount = meetingRoomRequestViewModel.AttendeeCount,
AttendeeType = meetingRoomRequestViewModel.AttendeeType,
OfficeID = meetingRoomRequestViewModel.OfficeId,
LocationID = meetingRoomRequestViewModel.LocationId,
};
_meetingRoomRequestRepository.Add(meetingRoomRequestToAdd);
_meetingRoomRequestRepository.SaveChanges();
var meetingRoomRequestAdded = meetingRoomRequestToAdd;
foreach (var item in meetingRoomRequestViewModel.AmenityList)
{
var meetingRoomRequestAmenityLinkToAdd = new MeetingRoomRequestAmenityLink
{
AmenityID = item,
MeetingRoomRequestID = meetingRoomRequestAdded.MeetingRoomRequestID
};
_meetingRoomRequestAmenityLinkRepository.Add(meetingRoomRequestAmenityLinkToAdd);
_meetingRoomRequestAmenityLinkRepository.SaveChanges();
}
The way you are going about it looks right, but there are some improvements that could be made in efficiency of processing the request.
Since these are a child/parent relationship, you can create the parent entity and then attached the childern in the foreach loop before you call save changes on the parent entity. EF will automatically populate the foreign key value on the child object with the primary (or associated key) from the parent.
You can continue to use your Entity without having to save it back out to a variable. EF's object tracking will continue to track this throughout your function.
By moving the savechanges outside of the foreach loop, you are reducing the number of calls. I believe the same amount of SQL will be sent on the one final call, but you may see increases of not having the connection open/close. There may be other built in efficiencies as well from EF
The Code
var meetingRoomRequestToAdd = new MeetingRoomRequest
{
User = meetingRoomRequestViewModel.User,
UserEmail = meetingRoomRequestViewModel.UserEmail,
Title = meetingRoomRequestViewModel.Title,
Comments = meetingRoomRequestViewModel.Comments,
StartDateTime = meetingRoomRequestViewModel.StartTime,
EndDateTime = meetingRoomRequestViewModel.EndTime,
RequestStatusID = (int)Enums.RequestStatus.New,
AttendeeCount = meetingRoomRequestViewModel.AttendeeCount,
AttendeeType = meetingRoomRequestViewModel.AttendeeType,
OfficeID = meetingRoomRequestViewModel.OfficeId,
LocationID = meetingRoomRequestViewModel.LocationId,
};
_meetingRoomRequestRepository.Add(meetingRoomRequestToAdd);
foreach (var item in meetingRoomRequestViewModel.AmenityList)
{
meetingRoomRequestToAdd.MeetingRoomRequestAmenityLinks.Add(new MeetingRoomRequestAmenityLink
{
AmenityID = item
});
}
_meetingRoomRequestRepository.SaveChanges();
I have a trigger which copies the billing street address from the related Account to the other streets address on the related Contact. I wrote this trigger from reading materials online is this correct? Is there better way to write it?
Public class iTestClass {
public static testmethod void test()
{
Contact objContact1;
Contact objContact2;
objContact1 = New Contact();
objContact1.OtherStreet = '123 lane';
objContact1.OtherCity = 'Washington';
objContact1.OtherState = 'OR';
objContact1.OtherCountry = 'USA';
objContact1.OtherPostalCode = '12122';
objContact2 = New Contact();
objContact2.OtherStreet = '232 st.';
objContact2.OtherCity = 'cleveland';
objContact2.OtherState = 'OH';
objContact2.OtherCountry = 'USA';
objContact2.OtherPostalCode = '166030';
}
}
You're on the right lines, but a) you're not inserting the contact records, and b) you need to insert an account first, then set the account ID on those contacts before you insert them.
// before creating the contacts create an account
Account sAcct = new Account();
sAcct.Name = 'Test Account';
sAcct.BillingStreet = '1 Some Street'; // I forget the name of the field!
// etc.
insert sAcct;
// then on your contacts do this:
objContact1.Account = sAcct.Id;
// then insert them at the end to fire the trigger
insert objContact1;