Errors relating to #relation - database

I'm having issue related to database as shown in picture: enter image description here:
When I try to save this schema VsCode automatically creates duplicates of User Department and Class fields In User table.
enum UserRole {
GUEST
ADMIN
INSTRUCTOR
EMPLOYEE
STUDENT
}
model User {
id String #id #unique #default(cuid())
createdAt DateTime? #default(now())
updatedAt DateTime? #updatedAt
deletedAt DateTime?
firstName String
lastName String
email String #unique
password String
emailVerified DateTime?
photo String?
role UserRole #default(GUEST)
jobTitle String?
hireDate DateTime?
enrollmentID String? #unique
enrollmentDate DateTime?
instructors User[] #relation("Instructors")
students User[] #relation("Students")
department Department? #relation(fields: [departmentId], references: [id])
departmentId String?
classes Class[] #relation(fields: [classId], references: [id])
classId String?
##index([departmentId])
##index([classId])
}
model Department {
id String #id #unique #default(cuid())
name String? #unique
employees User[] #relation("Employees")
}
model Class {
id String #id #unique #default(cuid())
name String? #unique
startDate DateTime?
members User[] #relation("Members")
instructor User? #relation(fields: [instructorId], references: [id])
instructorId String?
##index([instructorId])
}

Related

All containing foreign keys must be removed or redefined before the property can be removed [EF CORE]

I am currently working on my Uni project - .net MVC app. Basic requirement was to create a table of Users containing columns such as id, name, surname etc. which I've done properly. Here is my Model class User.cs:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ProjektPRP.Models
{
public class User
{
public int Id { get; set; }
[RegularExpression(#"^[A-Z]+[a-zA-Z\s]*$")]
[Required]
[StringLength(50)]
public string? Name { get; set; }
[RegularExpression(#"^[A-Z]+[a-zA-Z\s]*$")]
[Required]
[StringLength(50)]
public string? Surname { get; set; }
[Display(Name = "Date of birth")]
[DataType(DataType.Date)]
public DateTime DateOfBirth { get; set; }
[DataType(DataType.EmailAddress)]
[Required]
public string? Login { get; set; }
public virtual Role RoleId { get; set; } // used to be "public int RoleId"
public bool IsDeleted { get; set; }
}
}
I used Add-Migration and User table appeared in database.
Then I had to create another table Roles containing roleID and name (admin, moderator, user). I created Role class, same as I did before with User.cs and after adding a migration everything was fine.
Then I wanted User.RoleId to be a foreign key referencing Role.Id (primary key of Role table), so I changed int RoleId to virtual Role RoleId and in Role.cs I created a collection of users.
Here is Role class:
using System.ComponentModel.DataAnnotations;
namespace ProjektPRP.Models
{
public class Role
{
public int Id { get; set; }
[RegularExpression(#"a-z")]
public string? Name { get; set; }
public virtual ICollection<User> Users {get; set; } = new List<User>();
}
}
While trying to migrate once more, the following error occurred:
The property 'RoleId' cannot be removed from entity type 'ProjektPRP.Models.User (Dictionary<string, object>)' because it is being used in the foreign key {'RoleId'} on 'ProjektPRP.Models.User (Dictionary<string, object>)'. All containing foreign keys must be removed or redefined before the property can be removed.
I don't really know how can I fix that issue. As I mentioned before - at that phase of writing my project I need two tables:
Users with their personal/account data and RoleID being a foreign key referring to:
Roles with ID and name.

How can I combine two props into a third prop when adding to database?

I'm creating my first project using ASP.NET Core 3.0 using EF Core. When creating a user (Patient) I want them to be able to enter their first and last names separately in the create view, these will be saved in my database in a FirstName and LastName column respectively. However, I'm wanting to have both of these fields combined and stored in another column called FullName so I can use it for searching for users. Is there a straightforward way of doing this?
I've tried with the below code but I'm getting an unhandled exception -
"SqlException: Cannot insert the value NULL into column 'FullName',
table 'WebPMR.dbo.Patient'; column does not allow nulls. INSERT fails.
The statement has been terminated"
Model:
public class Patient
{
public int Id { get; set; }
[Display(Name = "Title")]
public int TitleId { get; set; }
[Required]
[Display(Name = "First Name")]
[StringLength(25, MinimumLength = 1, ErrorMessage = "First Name must be 1-25 characters long")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name")]
[StringLength(50, MinimumLength = 1, ErrorMessage = "Last Name must be 1-50 characters long")]
public string LastName { get; set; }
private string _fullName;
public string FullName
{
get => _fullName;
set => _fullName = FirstName + " " + LastName;
}
}
Controller:
// GET: Create
public IActionResult Create()
{
return View();
}
// POST:Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,FirstName,LastName")] Patient patient)
{
if (ModelState.IsValid)
{
_context.Add(patient);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["TitleId"] = new SelectList(_context.Title, "Id", "Description", patient.TitleId);
return View(patient);
}
You can use a computed column
Table (
FirstName VARCHAR(128),
LastName VARCHAR(128),
FullName AS FirstName + ' ' + LastName
)
Then you can make it persisted so you can create an index on it.
https://learn.microsoft.com/en-us/sql/relational-databases/tables/specify-computed-columns-in-a-table?view=sql-server-ver15
You can add:
[NotMapped]
attribute to mean you don't have such a field.
Also, instead of a property you could have it as FullName method, or ToString() override.
In searching such data however, you would likely would want to have them separate. It is less common to search by a full name, and in an hospital data probably a receptionist would appreciate to get a list of patients by last name.

Dapper... Must declare the scalar variable

I'm starting with Dapper in a C# application (I currently use Entity in most places) and i'm having an issue with a simple query.
I keep getting back "Must declare scalar variable '#ReportId'" but I am declaring it!
db.Execute(#"INSERT INTO cdr_Requests (ReportId, ReportName, StartTime, EndTime, Status, ReportUrl, CreatedAt, UpdatedAt, Timezone, CdrReportRead) VALUES (#ReportId, #ReportName, #StartTime, #EndTime, #Status, #ReportUrl, #CreatedAt, #UpdatedAt, #Timezone, #CdrReportRead)", new { data.id, data.report_name, data.start_time, data.end_time, data.status, data.report_url, data.created_at, data.updated_at, data.timezone, data.cdrreportread });
Here is my class:
public class cdr_Request
{
public int ID { get; set; }
public string ReportId { get; set; }
public string ReportName { get; set; }
}
I'm just having trouble figuring out what is going on!
Ok apparently I had a complete brain fart and was looking at the wrong line. I changed to this and it works:
db.Execute(#"INSERT INTO cdr_Requests (ReportId, ReportName, StartTime, EndTime, Status, ReportUrl, CreatedAt, UpdatedAt, Timezone, CdrReportRead)
VALUES (#ReportId, #ReportName, #StartTime, #EndTime, #Status, #ReportUrl, #CreatedAt, #UpdatedAt, #Timezone, #CdrReportRead)", new {
ReportId = data.id,
ReportName = data.report_name,
StartTime = data.start_time,
EndTime = data.end_time,
Status = data.status,
ReportUrl = data.report_url,
CreatedAt = data.created_at,
UpdatedAt = data.updated_at,
Timezone = data.timezone,
CdrReportRead = 0
});
Just in case any of ma F# peeps come across the 'must declare the scalar variable issue' - often the cause is that you declared your parameters record in a private module. E.g.
module private MyStuff =
type Params = { MyParam : int }
You'll just have to move the type or de-private the module.

how to use hibernate annotations OnetoOne in springMvc?

I'm working with spring MVC``Spring security hibernate
I've created 2 tables in the database , this the schema:
create table user(
id int(10),
name VARCHAR(30) NOT NULL,
address VARCHAR(30) NOT NULL,
PRIMARY KEY (id)
);
create table compte(
id int(10),
login VARCHAR(30) NOT NULL,
password VARCHAR(30) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES user( id)
);
I'm developing a web application for users managements, the administrator add user's informations and submit (data from the first form is inserted into the userdatabase) and then in an other jsp he adds the authentication data for this user and submit ( here data is inserted into the second database compte )
the form in the jsp page that inserts into user's table is done correctly when it's not joined to any other table .
But when I tried to use hibernate annotations in my application and join the two tables user and compte I have errors :
Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: com.package.domain.User.compte, referenced property unknown: com.package.domain.Compte.User
user.java :
#Entity
#Table(name = "user")
public class User {
#Id
#Column(name="id")
private int id;
#Column(name="name")
private String name;
#Column(name="address")
private String address;
#OneToOne(mappedBy="User", cascade=CascadeType.ALL)
private Compte compte;
//getters and setters
compte.java :
#Entity
#Table(name = "COMPTE")
public class Compte {
#Id
#GeneratedValue
#Column(name = "id")
private int id;
#Column(name = "login")
private String login;
#Column(name = "password")
private String password;
#OneToOne
#PrimaryKeyJoinColumn
private User user;
//getters and setters
I don't know how should I insert comptedata into the second table ? how it will recognize that the login and the password correspond to the user's id just inserted.
PS : i've created 2 tables in the database to use the second for authentication in spring security if my database design is incorrect please tell me :)
Firstly, you need to specify not a class name (User), but a property name (user) in the mappedBy
#OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private Compte compte;
In my opinion It will be better to associate Compte to the User by an additional foreign key and I would like to have login and password in the User table.
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue
#Column(name = "f_id")
private int id;
#Column(name = "f_login")
private String login;
#Column(name = "f_password")
private String password;
#OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private Compte compte;
}
#Entity
#Table(name = "comptes")
public class Compte {
#Id
#GeneratedValue
#Column(name = "f_id")
private int id;
#OneToOne
#JoinColumn(name = "fk_user")
private User user;
#Column(name = "f_name")
private String name;
}

Apex code-how to get the data of campaign Members from Subquery

I am trying to display four fields on my VF page Name, Status from (Campaign Members) and Subject and Last Modified Date from (Activity History) Object.I am not able to fetch the Name and Status fields from Campaign Members.
Can anyone please tell me How to get the Name and Status fields from Campaign Members.Below is my Controller code.
public with sharing class CampaignView {
public Campaign camp {get; set; }
public List<MemberWrapper> lMemberWrappers {get; set;}
public DateTime startDate {get; set;}
public CampaignView(ApexPages.StandardController controller) {
camp = (Campaign)controller.getRecord();
lMemberWrappers = new List<MemberWrapper>();
getCampaignMembers();
startDate = null;
for (Campaign c : [Select ID, (SELECT Id, CampaignId, Status FROM CampaignMembers where CampaignId = :camp.Id) FROM campaign WHERE id = :camp.Id ]) {
for (Lead ld : CampaignMembers) {
for (ActivityHistory ah : ld.getSObjects('ActivityHistories')) {
lMemberWrappers.add(new MemberWrapper(ld.Name, ah.Subject, ah.LastModifiedDate, ld.CampaignMembers.get(0).Status));
}
}
}
}
private List<Lead> CampaignMembers;
public List<Lead> getCampaignMembers() {
CampaignMembers = [Select Id, Name, Phone, MobilePhone, Email, LastModifiedDate, (Select id, Campaign.Name, Contact.Phone, Lead.FirstName, Lead.LastName, Lead.Name, LeadID, ContactID, Lead.Phone, Lead.Email, Lastmodifieddate, Lead.LastmodifiedDate, Status, CampaignId, Campign_ID__c, Lead.MobilePhone From CampaignMembers where CampaignId = :camp.Id ),
(Select Subject, Id, lastModifiedDate From ActivityHistories order by LastModifiedDate DESC LIMIT 1 )
From Lead where Id IN(select LeadId from campaignMember where campaignId = :camp.Id ) ];
return CampaignMembers;
}
public class MemberWrapper {
public Object Status {get; set;}
public String Name {get; set;}
public String Subject {get; set;}
public Datetime LastActivityHistory {get; set;}
public MemberWrapper(String Name, String Subject, Datetime LastActivityHistory, Object Status ) {
this.Name = Name;
this.Subject = Subject;
this.LastActivityHistory = LastActivityHistory;
this.Status = Status;
}
}
}
This will take you more than one query because of the ActivityHistory requirement. There are four levels of relationships in play here: Campaign -> CampaignMember -> Lead -> ActivityHistory, so you cannot perform this using just sub-queries.
The following code should get you the info you need:
Set<Id> leadIds = new Set<Id>();
List<Campaign> campaignList = [Select ID, (SELECT Id, Status, LeadId FROM CampaignMembers) FROM campaign WHERE id = :camp.Id ];
for (Campaign c : campaignList) {
for (CampaignMember cm : c.CampaignMembers) {
leadIds.add(cm.LeadId);
}
}
Map<Id, Lead> leadMap = new Map<Id, Lead>([Select Id, Name, (Select Subject, LastModifiedDate from ActivityHistories Order By LastModifiedDate DESC limit 1) From Lead Where Id IN :leadIds]);
for (Campaign c : campaignList) {
for (CampaignMember cm : c.CampaignMembers) {
Lead ld = leadMap.get(cm.LeadId);
if (ld.ActivityHistories.size() > 0) {
ActivityHistory ah = ld.ActivityHistories[0];
lMemberWrappers.add(new MemberWrapper(ld.Name, ah.Subject, ah.LastModifiedDate, cm.Status));
}
}
}
I just skipped creating the MemberWrapper if there were no activities, but you could change it to just put blank values if you wish.

Resources