I try to load from the already found user a list of friends and from the list of friends and load for each list of messages.
dont work
Load only frends, do not load messages in each frend
_context.Entry(ldetails).Collection(p=>p.ListFriends).Query().
Include(r=>r.MessagesDetails).Load();
My data struct
public class RegistrationUser
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PMId { get; set; }
[Required]
[Column(TypeName ="varchar(16)")]
public string UserName { get; set; }
[Required]
[Column(TypeName = "varchar(16)")]
public string Password { get; set; }
[Column(TypeName = "varchar(480)")]
public string Token { get; set; }
public ICollection<ListFriend> ListFriends { get; set; }
public RegistrationUser()
{
ListFriends = new List<ListFriend>();
}
}
public class ListFriend
{
[Key,Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
[Required]
[Column(TypeName ="varchar(16)")]
public string UserFriendName { get; set; }
public ICollection<MessagesDetail> MessagesDetails { get; set; }
public ListFriend()
{
MessagesDetails = new List<MessagesDetail>();
}
}
public class MessagesDetail
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key,Column(Order = 0)]
public int PMIdMes { get; set; }
[Required]
[Column(TypeName ="nvarchar(240)")]
public string TextMessage{ get; set; }
[Required]
[Column(TypeName = "varchar(16)")]
public string SenderUser { get; set; }
[Required]
[Column(TypeName = "varchar(16)")]
public string CatcherUser { get; set; }
}
It my method not work
[HttpPost("EnterUserDetail")]
public async Task<ActionResult<RegistrationUser>> postUserDetail( RegistrationUser registrationUser )
{
var ldetails = _context.RegistrationUsers.SingleOrDefault(c=>c.UserName==registrationUser.UserName);
var pdetails = _context.RegistrationUsers.SingleOrDefault(c=>c.Password==registrationUser.Password);
if (ldetails == null && pdetails == null)
{
return NotFound();
}
//_context.Entry(ldetails).Collection("ListFriends").Load();
_context.Entry(ldetails).Collection(p=>p.ListFriends).Query().Include(r=>r.MessagesDetails).Load();
//_context.Entry(ldetails).Collection("ListFriends").IsLoaded = true;
//await _context.SaveChangesAsync();
return ldetails;
}
You are actually making 3 requests to the database to get the desired result. A better, optimized way to achieve this could be as
[HttpPost("EnterUserDetail")]
public async Task<ActionResult<RegistrationUser>> postUserDetail( RegistrationUser registrationUser)
{
// send one query to database to get the result and include here.
var ldetails = _context.RegistrationUsers.Include(i => i.ListFriends).SingleOrDefault(c => c.UserName == registrationUser.UserName && c.Password == registrationUser.Password);
if (ldetails == null && pdetails == null)
{
return NotFound();
}
return ldetails;
}
Related
When I want to call a property of my object property Trip from TripApplicationUser model class its values are null. So I do not know how to initialize the Trip object to get its property values later on and to now have problem with indexing in database. I have pasted here the most important parts of code.
[Authorize]
public async Task<ActionResult> Enroll(int id)
{
if (id == null)
{
return NotFound();
}
var currentTrip = await _context.Trip.FindAsync(id);
var currentUser = await _userManager.GetUserAsync(User);
var isAlreadyEnrolled = _context.TripApplicationUsers.Where(tu => tu.ApplicationUserId.Equals(currentUser.Id) && tu.TripId == id);
var UserTrips = isAlreadyEnrolled.ToList();
if (currentTrip.TripSeats > 0 && !UserTrips.Any())
{
ViewBag.process = "done";
currentTrip.TripSeats--;
_context.Update(currentTrip);
var rowToSave = new TripApplicationUser
{
TripId = currentTrip.TripId,
ApplicationUserId = currentUser.Id,
Trip = currentTrip //HOW SHOULD I INITIALIZE IT ACTUALLY?
};
_context.Add(rowToSave);
await _context.SaveChangesAsync();
} else if (UserTrips.Any())
{
ViewBag.process = "already done";
} else if(currentTrip.TripSeats <= 0)
{
ViewBag.process = "not done";
}
var UsersTrips = _context.TripApplicationUsers.Where(t => t.ApplicationUserId.Equals(currentUser.Id)).ToList();
return View(UsersTrips);
}
public class ApplicationUser : IdentityUser
{
[PersonalData]
[Column(TypeName = "nvarchar(MAX)")]
public string FirstName { get; set; }
[PersonalData]
[Column(TypeName = "nvarchar(MAX)")]
public string Surname { get; set; }
[PersonalData]
[Column(TypeName = "nvarchar(MAX)")]
public string BirthDate { get; set; }
public ICollection<TripApplicationUser> TripApplicationUsers { get; set; }
}
public class Trip
{
public int TripId { get; set; }
public string TripDate { get; set; }
public int TripDuration { get; set; }
public int TripLength { get; set; }
public int TripSeats { get; set; }
public int TrailId { get; set; }
public Trail Trail { get; set; }
public ICollection<TripApplicationUser> TripApplicationUsers { get; set; }
}
public class TripApplicationUser
{
public int TripId { get; set; }
public Trip Trip { get; set; }
public string ApplicationUserId { get; set; }
public ApplicationUser ApplicationUser { get; set; }
}
If you want your Trip object to contain data from Navigational properties you have to include them in the request.
var currentTrip = await _context.Trip.Include(trip=> trip.TripApplicationUsers).FirstOrDefaultAsync(trip => trip.TripId == id);
I have table clientcontactcompany table and checking for if combination of email Address and clientcompanyId exist. I have set a unique constraint on both the fields. I am trying to write logic in my repository layer
Client company contact class
public partial class ClientCompanyContact
{
public ClientCompanyContact()
{
FxforwardTrade = new HashSet<FxforwardTrade>();
Fxoption = new HashSet<Fxoption>();
}
public int Id { get; set; }
public int ClientCompanyId { get; set; }
public string Title { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string Email { get; set; }
public string TelephoneDirect { get; set; }
public string TelephoneMobile { get; set; }
public string TelephoneOther { get; set; }
public DateTime? Birthday { get; set; }
public bool Authorized { get; set; }
public byte[] UpdateTimeStamp { get; set; }
public int UpdatedByAuthUserId { get; set; }
public DateTime UpdatedDateTime { get; set; }
public string Notes { get; set; }
public string Fullname { get; set; }
public bool RecNotifications { get; set; }
public bool RecAmreport { get; set; }
public int? AuthUserId { get; set; }
public string Position { get; set; }
public bool? PrimaryContact { get; set; }
public bool RecActivityReport { get; set; }
public bool IsDeleted { get; set; }
public string Aspnumber { get; set; }
public DateTime? AspcreationDate { get; set; }
public DateTime? LastTelephoneChangeDate { get; set; }
public DateTime? LastEmailChangeDate { get; set; }
public string BloombergGpi { get; set; }
public string NiNumber { get; set; }
public AuthUser AuthUser { get; set; }
public ClientCompany ClientCompany { get; set; }
public AuthUser UpdatedByAuthUser { get; set; }
public ICollection<FxforwardTrade> FxforwardTrade { get; set; }
public ICollection<Fxoption> Fxoption { get; set; }
}
Client contact repository
public IGenericRepo<ClientCompanyContact> ClientCompanyContactRepository =>
_clientCompanyContactRepository = _clientCompanyContactRepository ?? new GenericRepo<ClientCompanyContact>(Context);
This is what I tried snd not compiling . What’s the right of doing it
public async Task<bool> UniqueEmail(string email, string ClientCompanyId)
{
return await ClientCompanyContactRepository.Get().Where(x => x.Email == email && x.ClientCompanyId = ClientCompanyId);
}
Firstly, pass the ClientCompanyID in as an int, then you're missing an equal sign, should be:
x => x.Email == email && x.ClientCompanyId == ClientCompanyId
You have few small but deadly mistakes in your code.
The method should look more like this.
public async Task<bool> UniqueEmail(string email, int clientCompanyId)
{
var count = await ClientCompanyContactRepository.Get()
.Count(x => x.Email == email && x.ClientCompanyId == clientCompanyId);
return count < 2;
}
Please note that .Count(x => ...) could be .Where( x => ...).Count().
Changes:
Pass clientCompanyId as int, so 'int ClientCompanyId'
You need to return a bool not a list objects, so 'bool anyMatching = x.Any(...); return !anyMatching'.
Parameter names should start with common letter, so 'int clientCompanyId'
Comparison uses ==, not = so '== ClientCompanyId'
If Get is async it should be GetAsync, or even GetAllAsync.
Update: it seems that Get is not async. Let's drop all async parts.
public bool UniqueEmail(string email, int clientCompanyId)
{
var count = ClientCompanyContactRepository.Get()
.Count(x => x.Email == email && x.ClientCompanyId == clientCompanyId);
return count < 2;
}
Please note we don't know what Get() returns so we don't know if the filtering will happen in memory or in the database.
I suspect that Get() may return all records so the filtering will happen in memory. You may want to move UniqueEmail into the repository.*
I first loaded all the messages from the database. Then I chose what I need.
But it's not correctly loading all messages.
var ldetails = _context.RegistrationUsers.Include(i => i.ListFriends).ThenInclude(z=>z.MessagesDetails).SingleOrDefault(c => c.UserName == Context.User.Identity.Name);
I wanted to load only one message by criterion but I constantly get an error.
Please show me a ways to do it.
I have tried:
var ldetails = _context.RegistrationUsers.Include(i => i.ListFriends).ThenInclude(z=>z.MessagesDetails.SingleOrDefault(g=>g.TextMessage == messagesDetail.TextMessage)).SingleOrDefault(c => c.UserName == Context.User.Identity.Name);
But I get an error. My code looks like:
public class RegistrationUser
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PMId { get; set; }
[Required]
[Column(TypeName ="varchar(16)")]
public string UserName { get; set; }
[Required]
[Column(TypeName = "varchar(16)")]
public string Password { get; set; }
[Column(TypeName = "varchar(480)")]
public string Token { get; set; }
public ICollection<ListFriend> ListFriends { get; set; }
public RegistrationUser()
{
ListFriends = new List<ListFriend>();
}
}
public class ListFriend
{
[Key,Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
[Required]
[Column(TypeName ="varchar(16)")]
public string UserFriendName { get; set; }
public ICollection<MessagesDetail> MessagesDetails { get; set;
}
public ListFriend()
{
MessagesDetails = new List<MessagesDetail>();
}
}
public class MessagesDetail
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key,Column(Order = 0)]
public int PMIdMes { get; set; }
[Required]
[Column(TypeName ="nvarchar(240)")]
public string TextMessage{ get; set; }
[Required]
[Column(TypeName = "varchar(16)")]
public string SenderUser { get; set; }
[Required]
[Column(TypeName = "varchar(16)")]
public string CatcherUser { get; set; }
}
//My method
[Authorize]
public async Task DeleteMessage(string frend ,MessagesDetail
messagesDetail)
{
var ldetails = _context.RegistrationUsers.Include(i =>
i.ListFriends).ThenInclude(z=>z.MessagesDetails.
SingleOrDefault(g=>g.TextMessage == messagesDetail.TextMessage)).
SingleOrDefault(c => c.UserName == Context.User.Identity.Name);
//.....
}
I expect to receive a message for the condition:
g=>g.TextMessage == messagesDetail.TextMessage;
You are probably trying to filter in Include or IncludeThen which is not supported. You would have to create a projection by using Select:
var ldetails = _context.RegistrationUsers.Select(x=>new RegistrationUser
{
PMId=x.PMId,
UserName=x.UserName,
Password=x.Password,
Token=x.Token,
ListFriends=x.ListFriends.Select(q => new ListFriend
{
UserId=q.UserId,
UserFriendName=q.UserFriendName,
MessagesDetails=q.Where(a => a.TextMessage == messagesDetail.TextMessage).ToList()
}).ToList()
}).SingleOrDefault(c => c.UserName == Context.User.Identity.Name);
Take a look at this issue for more information.
var pdetails = _context.RegistrationUsers.SingleOrDefault(c=>c.Password==Context.User.Identity.Name);
var nlk = _context.Entry(pdetails).Collection(n => n.ListFriends).Query().SelectMany(n => n.MessagesDetails).Where(z => z.TextMessage == messagesDetail.TextMessage).ToList();
IT work!
I have the following code:
internal static bool SaveUOSChangeLog(List<Contracts.DataContracts.UOSChangeLog> values, string user)
{
try
{
using(var ctx = new StradaDataReviewContext2())
{
values.ForEach(u => { u.Username = user; u.Changed = DateTime.Now; });
var test = ctx.UOSChangeLog.Add(values);
ctx.SaveChanges();
return true;
}
}
The thing I want to do Is to save values to the database. However, I get a the following error message:
Here is my Contracts.DataContracts.UOSChangeLog:
public int? Id { get; set; }
public int Accident_nr { get; set; }
public int Refnr { get; set; }
public int Action { get; set; }
public string Old_data { get; set; }
public string New_data { get; set; }
public DateTime SearchedFromDate { get; set; }
public DateTime SearchedToDate { get; set; }
public DateTime Changed { get; set; }
public string Username { get; set; }
public string Comment { get; set; }
And here Is my Services.StradaDataReview2Model.UOSChangeLog that are used as a DbSet
[Table("UOSChangeLog")]
public partial class UOSChangeLog
{
[Required]
public int? Id { get; set; }
public int Accident_nr { get; set; }
[Required]
public int Refnr { get; set; }
[Required]
public int Action { get; set; }
[Required]
public string Old_data { get; set; }
[Required]
public string New_data { get; set; }
[Required]
public DateTime SearchedFromDate { get; set; }
[Required]
public DateTime SearchedToDate { get; set; }
[Required]
public DateTime Changed { get; set; }
[Required]
public string Username { get; set; }
[Required]
public string Comment { get; set; }
}
You're trying to add a list with the Add method which takes a single object, just keep it simple and use a foreach:
using(var ctx = new StradaDataReviewContext2())
{
foreach(var value in values)
{
value.Username = user;
value.Changed = DateTime.Now;
ctx.UOSChangeLog.Add(value);
}
ctx.SaveChanges();
return true;
}
Just use a simple foreach, linq is a querying language, not a modifying language.
Please use addrange method.
db.TheTable.AddRange(TheList)
db.SaveChanges();
You can use Entity Framework's .AddRange method to add a collection of objects to your Db.
MSDN
It will look like:
using(var ctx = new StradaDataReviewContext2())
{
values.ForEach(u => { u.Username = user; u.Changed = DateTime.Now; });
var test = ctx.UOSChangeLog.AddRange(values);
ctx.SaveChanges();
return true;
}
Im trying to get the last record submitted in the db using the repository pattern and MVC. I am attaching the interface and class.And the controller where you can put the code. Please let me know if you need more details. Thanks.
public interface IRequestRepository
{
tblRequest GetCaseId(int caseId);
}
public class RequestRepository: IRequestRepository
{
helpdeskEntities context = null;
public RequestRepository()
{
context = new helpdeskEntities();
}
public string GetCaseId(Ticket ticket)
{
string caseId = string.Empty;
tblRequest tr = context.tblRequests.Where(u => u.CaseID == ticket.CaseID && u.UEmailAddress == ticket.UEmailAddress).SingleOrDefault();
if (tr != null)
{
caseId = tr.CaseID;
}
return caseId;
}
}
public class Ticket
{
public int CaseID { get; set; }
public string Title { get; set; }
[Required]
public string UFirstName { get; set; }
[Required]
public string ULastName { get; set; }
//public string UDisplayName { get; set; }
[Required]
public string UDep_Location { get; set; }
[Required]
public string UEmailAddress { get; set; }
//public string UComputerName { get; set; }
//public string UIPAddress { get; set; }
[Required]
public string UPhoneNumber { get; set; }
[Required]
public string Priority { get; set; }
[Required]
public string ProbCat { get; set; }
//public string IniDateTime { get; set; }
//public string UpdateProbDetails { get; set; }
//public string UpdatedBy { get; set; }
public string InitiatedBy_tech { get; set; }
public string AssignedBy { get; set; }
public string TechAssigned { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public string ProbDetails { get; set; }
}
Controller
public ActionResult CreateTicket(tblRequest td)
{
}
First, you need to upgrade your IRequestRepository and add that method:
(I am assuming you're using EntityFramework for that)
public IRequestRepository
{
Request Latest(Ticket ticket);
}
Next, you need to implement that method in your RequestRepository:
public class RequestRepository : IRequestRepository
{
/* other code here */
public Request Latest(Ticket ticket)
{
// I'm also assuming you're using an auto incremented CaseId
return this.context.tblRequests.OrderByDescending(p => p.CaseId).FirstOrDefault(p => p.UEmailAddress == ticket.UEmailAddress);
}
}
And another thing:
Your IRequestRepository.GetCaseId implementation returns a string while it should return a tblRequest (one would also expect it to return an int Id...)
Anyway, I hope this helps!