Error loading association from controller in cakephp - join

I can't get this simple query right. I need to join my adresses table to my annonces table.
I supose this should be farly strait forward but I simply can't get it to work.
I firstly made my adresse table object like this
class AdressesTable extends Table
{
public function initialize(array $config)
{
$this->belongsTo('Annonces', [
'foreignKey' => 'annonceId',
'joinType' => 'INNER',
]);
}
}
Then in my annonces controller I tryed to join the adresses like this
public function view($id = null)
{
if (!$id) {
throw new NotFoundException(__('Annonce invalide!'));
}
$query = $this->Annonces->find('all', ['contain' => ['Adresses']])->where(['id' => $id]);
$annonce = $query->firstOrFail();
$this->set(compact('annonce'));
}
But then I got this error :
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Adresses.annonce_id' in 'where clause'
Witch I don't understand why I got it since I have defined my foreign key in the AdressesTable class.
The query I would like to have at the end would look like this
SELECT *
FROM annonces
INNER JOIN adresses ON adresses.annonceId = annonces.id
WHERE annonces.id = #param
*PS. I know it wont be select * but rather select [all my column]*
EDIT : My table schema are as following
CREATE TABLE annonces(
id INT NOT NULL AUTO_INCREMENT, #PK
startDate DATE NOT NULL,
endDate DATE NOT NULL,
title VARCHAR(128) NOT NULL,
descript TEXT NOT NULL,
infoSupplementaire TEXT NULL,
premium BIT NOT NULL,
clientId INT NOT NULL, #FK
categorieId INT NOT NULL, #FK
CONSTRAINT pk_annonces_id PRIMARY KEY (id),
CONSTRAINT fk_annonces_clientId FOREIGN KEY (clientId) REFERENCES clients(id),
CONSTRAINT fk_annonces_categorieId FOREIGN KEY (categorieId) REFERENCES categories(id)
);
CREATE TABLE adresses(
id INT NOT NULL AUTO_INCREMENT, #PK
latitude DECIMAL(11,7),
longitude DECIMAL(11,7),
adresse VARCHAR(512),
annonceId INT NOT NULL, #FK
CONSTRAINT pk_adresses_id PRIMARY KEY (id),
CONSTRAINT fk_adresses_annonceId FOREIGN KEY (annonceId) REFERENCES annonces(id)
)
I solved my problem by renaming my column folowing cakephp convention and using any of the code from this answer

You can try
$query = $this->Annonces->find('all', ['contain' => ['Adresses']])->where(['Annonces.id' => $id]);
$annonce = $query->firstOrFail();
OR
public function view($id = null)
{
if (!$id) {
throw new NotFoundException(__('Annonce invalide!'));
}
$annonceEntity = $this->Annonces->get($id);
$query = $this->Annonces->find('all', ['contain' => ['Adresses']])->where(['Annonces.id' => $annonceEntity->id]);
$annonce = $query->firstOrFail();
$this->set(compact('annonce'));
}

Related

Search database depending on chosen search criteria

I'm following a YouTube series which teachs ASP.NET MVC. In the tutorial the teacher shows how to make a simple search functionality however in my case it's different.
I have search criteria: Studies (Dropdown), Country (Dropdown), Status (Dropdown) and Keyword (Input).
My question is how do I query the database to show the results depending on the search criteria that was chosen?
To be more clear:
If the User has chosen Studies and Country only then the code should use values from Studies and Country to search the respective database column.
Click here for the UI Design
Table: Students
[StudentID] INT IDENTITY (1, 1) NOT NULL,
[StudentName] VARCHAR (50) NOT NULL,
[StudentStudiesID] INT NOT NULL,
[StudentCountry] VARCHAR (50) NOT NULL,
[StudentCity] VARCHAR (50) NOT NULL,
[StudentStatus] VARCHAR (50) NOT NULL,
CONSTRAINT [PK_Students] PRIMARY KEY CLUSTERED ([StudentID] ASC),
CONSTRAINT [FK_Students_Studies] FOREIGN KEY ([StudentStudiesID]) REFERENCES [dbo].[Studies] ([StudiesID])
SearchController.cs
public class SearchController : Controller
{
public ActionResult Index()
{
DatabaseEntitiesModel db = new DatabaseEntitiesModel();
int Studies;
int.TryParse(Request.QueryString["Studies"], out Studies);
var Country = Request.QueryString["Country"];
var Status = Request.QueryString["Status"];
var Keyword = Request.QueryString["Keyword"];
IQueryable <Student> SearchQuery = db.Students;
List<SearchViewModel> SVM = SearchQuery.Select(x => new SearchViewModel
{
StudentID = x.StudentID,
StudentName = x.StudentName,
StudentCountry = x.StudentCountry,
StudentCity = x.StudentCity,
StudiesName = x.Study.StudiesName,
StudentStatus = x.StudentStatus
}).OrderByDescending(x => x.StudentID).ToList();
return View( SVM );
}
}
Reuse SearchQuery (items are lazy-loaded, until you call ToList()) and add as many specific Where() clauses/calls as you need:
// the type (IQueryable<Student>) should be defined explicitly
// details: https://stackoverflow.com/questions/21969154/cannot-implicitly-convert-type-system-linq-iqueryable-to-system-data-entity-d
IQueryable<Student> query = db.Students;
if(viewModel.Filter1 != null) {
query = query.Where(i => i.SomeStudentProperty1 == viewModel.Filter1);
}
if(viewModel.Filter2 != null) {
query = query.Where(i => i.SomeStudentProperty2 == viewModel.Filter2);
}
var result = query.ToList();
The easiest way to do this would be to test each condition and if it meets what you want, add a Where clause. Something like this:
int.TryParse(Request.QueryString["Studies"], out Studies);
var Country = Request.QueryString["Country"];
var Status = Request.QueryString["Status"];
var Keyword = Request.QueryString["Keyword"];
IQueryable<Student> SearchQuery = db.Students;
if(Studies > 0)
{
SearchQuery = SearchQuery.Where(s => s.StudiesID == Studies);
}
if(!string.IsNullOrEmpty(Country))
{
SearchQuery = SearchQuery.Where(s => s.StudentCountry == Country);
}
...More conditions can go here
Because of Lazy Loading, the actual query isn't executed until you call .ToList(), or iterate over the collection. Hopefully, this gets you started on the right track.
Edit
In my haste, I changed your IQueryable to a var. Fixed.
Also, as Erik pointed out, using Request.QueryString is not the way to go. You'll instead want to pass these values in to the action method. So, something like:
public ActionResult Index(int studies, string status, string country, string keyword)

Entity Framework 6 - SQL Server and Oracle (SaveChanges)

I have an application which uses below (Employee) domain model for SQL Server and Oracle data provider. This model works fine for Oracle data provider, however the same gives error for SQL Server. And when I change the field "ID" from decimal to Int it works fine for SQL Server but gives error in Oracle.
On application configuration I am changing the data provider from i.e. from SQL Server to Oracle or vice-versa.
Cannot insert explicit value for identity column in table 'Employee' when IDENTITY_INSERT is set to OFF.*
ORA-01400: cannot insert NULL into ("Emp"."Employee"."ID")
public class Employee
{
[Key, Column(Order = 0)]
public decimal ID { get; set; }
public string NAME { get; set; }
}
if (ID == null || ID == 0)
{
Model.Employee obj = new Model.Employee();
obj.NAME = Name;
if (Convert.ToInt32(ConfigurationSettings.AppSettings["DataProviderType"]) == "Oracle")
obj.ID = GetNextId();
DbContext.Employees.Add(obj);
DbContext.SaveChanges();
}
SQL Server table script
CREATE TABLE [dbo].[Employee](
[ID] [int] IDENTITY(1,1) NOT NULL,
[NAME] [varchar](256) NULL,
CONSTRAINT [Employee_PK] PRIMARY KEY CLUSTERED
(
[ID] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Oracle table script
CREATE TABLE Employee
(
"ID" NUMBER NOT NULL ENABLE,
"NAME" VARCHAR2(256)
);
CREATE UNIQUE INDEX "PK_Employee" ON "Employee" ("ID");
ALTER TABLE "Employee" ADD CONSTRAINT "Employee_PK" PRIMARY KEY ("ID") ENABLE;
How can I handle this in my application i.e. in DOTNET Side?
With suggestion from #IvanStoev, I have change datatype from int to numeric IDENTITY(1,1) NOT NULL. in sql server. And also handled IDENTITY_INSERT error with below code,
modelBuilder.Entity<Employee>().Property(i => i.ID).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);
Hope this will help someone with similar issue.

user post count for a specific table

I am attempting to count the user posts for a specific table. I have referenced the following codex: https://codex.wordpress.org/Function_Reference/count_user_posts
but I keep outputting a value of zero for my user count. My function is
function count_user_posts_ship_to_you( $userid, $post_type = 'post', $public_only = false ) {
global $wpdb;
$NumPosts = $wpdb->get_var( "SELECT COUNT(*) FROM `ship_to_us` WHERE `user_id` = $userid" );
return $NumPosts; }
The process part that inputs into my table is referenced below:
$x_fields = 'ip, NumPosts';
$x_values = f_getIP() . "', '" . count_user_posts_ship_to_you($_POST['user_id']);
/*Check to see if the table exists and if it doesn't create it.*/
if ( !f_tableExists($table, DB_NAME) ) {
$sql = "CREATE TABLE $table (
ID int NOT NULL AUTO_INCREMENT,
PRIMARY KEY(ID),
ip int NOT NULL,
NumPosts int NOT NULL
)";
/*Insert out values into the database.*/
$sql="INSERT INTO $table ($x_fields) VALUES ('$x_values')";
I have also tried other solutions from other similar posts of this question but have not helped me resolve the problem. Any assistance would be appreciated!

error 1452: Foreign Key error

I am new to mysql and I am trying create a gradebook db to keep track of grades for a certain class. I am using Mysql workbench and here is my code:
SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='TRADITIONAL';
DROP SCHEMA IF EXISTS nj1368843 ;
CREATE SCHEMA IF NOT EXISTS nj1368843 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
USE nj1368843 ;
-- Table nj1368843.Users
DROP TABLE IF EXISTS nj1368843.Users ;
CREATE TABLE IF NOT EXISTS nj1368843.Users (
idUsers INT NOT NULL AUTO_INCREMENT ,
UserName VARCHAR(45) NOT NULL ,
pw VARCHAR(45) NOT NULL ,
PRIMARY KEY (idUsers, UserName, pw) )
ENGINE = InnoDB;
INSERT INTO nj1368843.Users (UserName, pw) VALUES ('njack2', '123');
-- Table nj1368843.Teachers
DROP TABLE IF EXISTS nj1368843.Teachers ;
CREATE TABLE IF NOT EXISTS nj1368843.Teachers (
idTeachers INT NOT NULL ,
Lname VARCHAR(45) NULL ,
Fname VARCHAR(45) NULL ,
Users_idUsers INT NOT NULL ,
Users_pw VARCHAR(45) NOT NULL ,
PRIMARY KEY (idTeachers) ,
INDEX fk_Teachers_Users1 (Users_idUsers ASC, Users_pw ASC) ,
CONSTRAINT fk_Teachers_Users1
FOREIGN KEY (`Users_idUsers` , `Users_pw` )
REFERENCES `nj1368843`.`Users` (`idUsers` , `UserName` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
INSERT INTO nj1368843.Teachers (idTeachers, Lname, Fname, Users_idUsers, Users_pw) VALUES (105, 'Stacey', 'Sheila', '1', '123');
-- Table nj1368843.Schedule
DROP TABLE IF EXISTS nj1368843.Schedule ;
CREATE TABLE IF NOT EXISTS nj1368843.Schedule (
course_id INT NOT NULL ,
Semester VARCHAR(45) NULL ,
Year YEAR NULL ,
Teachers_idTeachers INT NOT NULL ,
PRIMARY KEY (course_id) ,
INDEX fk_Grades_Teachers1 (Teachers_idTeachers ASC) ,
CONSTRAINT fk_Grades_Teachers1
FOREIGN KEY (`Teachers_idTeachers` )
REFERENCES `nj1368843`.`Teachers` (`idTeachers` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- Table nj1368843.Assignments
DROP TABLE IF EXISTS nj1368843.Assignments ;
CREATE TABLE IF NOT EXISTS nj1368843.Assignments (
idAssignments INT NOT NULL ,
Assignment 1 INT NULL ,
AVG_Grade INT(11) NULL ,
Schedule_course_id INT NOT NULL ,
PRIMARY KEY (idAssignments) ,
INDEX fk_Assignments_Schedule1 (Schedule_course_id ASC) ,
CONSTRAINT fk_Assignments_Schedule1
FOREIGN KEY (`Schedule_course_id` )
REFERENCES `nj1368843`.`Schedule` (`course_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- Table nj1368843.Student
DROP TABLE IF EXISTS nj1368843.Student ;
CREATE TABLE IF NOT EXISTS nj1368843.Student (
idStudent INT NOT NULL ,
lname VARCHAR(45) NULL ,
fname VARCHAR(45) NULL ,
Schedule_course_id INT NOT NULL ,
Users_idUsers INT NOT NULL ,
Users_pw VARCHAR(45) NOT NULL ,
Assignments_idAssignments INT NOT NULL ,
PRIMARY KEY (idStudent) ,
INDEX fk_Student_Schedule1 (Schedule_course_id ASC) ,
INDEX fk_Student_Users1 (Users_idUsers ASC, Users_pw ASC) ,
INDEX fk_Student_Assignments1 (Assignments_idAssignments ASC) ,
CONSTRAINT fk_Student_Schedule1
FOREIGN KEY (`Schedule_course_id` )
REFERENCES `nj1368843`.`Schedule` (`course_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT fk_Student_Users1
FOREIGN KEY (`Users_idUsers` , `Users_pw` )
REFERENCES `nj1368843`.`Users` (`idUsers` , `UserName` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT fk_Student_Assignments1
FOREIGN KEY (`Assignments_idAssignments` )
REFERENCES `nj1368843`.`Assignments` (`idAssignments` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- Table nj1368843.Classes
DROP TABLE IF EXISTS nj1368843.Classes ;
CREATE TABLE IF NOT EXISTS nj1368843.Classes (
cid INT NOT NULL ,
Name VARCHAR(45) NULL ,
Schedule_course_id INT NOT NULL ,
PRIMARY KEY (cid) ,
INDEX fk_Classes_Schedule1 (Schedule_course_id ASC) ,
CONSTRAINT fk_Classes_Schedule1
FOREIGN KEY (`Schedule_course_id` )
REFERENCES `nj1368843`.`Schedule` (`course_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- Table nj1368843.Teachers
DROP TABLE IF EXISTS nj1368843.Teachers ;
CREATE TABLE IF NOT EXISTS nj1368843.Teachers (
idTeachers INT NOT NULL ,
Lname VARCHAR(45) NULL ,
Fname VARCHAR(45) NULL ,
Users_idUsers INT NOT NULL ,
Users_pw VARCHAR(45) NOT NULL ,
PRIMARY KEY (idTeachers) ,
INDEX fk_Teachers_Users1 (Users_idUsers ASC, Users_pw ASC) ,
CONSTRAINT fk_Teachers_Users1
FOREIGN KEY (`Users_idUsers` , `Users_pw` )
REFERENCES `nj1368843`.`Users` (`idUsers` , `UserName` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
SET SQL_MODE=#OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS;
I generated this out of an erd diagram and I can't insert any information in the database because I get:
ERROR 1452: Cannot add or update a child row: a foreign key constraint fails (nj1368843.Teachers, CONSTRAINT fk_Teachers_Users1 FOREIGN KEY (Users_idUsers, Users_pw) REFERENCES Users (idUsers, UserName) ON DELETE NO ACTION ON UPDATE NO ACTION)
SQL Statement:
INSERT INTO nj1368843.Teachers (idTeachers, Lname, Fname, Users_idUsers, Users_pw) VALUES (105, 'Stacey', 'Sheila', 1, '123')
I tried everyone's ideas and looked over the code a million times and still can't find the problem. I can't insert into none of the tables for this db.help.

Elegant linq solution for left joins with unique data

I woud like to inquire if my Linq solution below is a good solution or if there is a better way. I am new to using Linq, and am most familiar with MySQL. So I've been converting one of my past projects from PHP to .NET MVC and am trying to learn Linq. I would like to find out if there is a better solution than the one I came up with.
I have the following table structures:
CREATE TABLE maplocations (
ID int NOT NULL AUTO_INCREMENT,
name varchar(35) NOT NULL,
Lat double NOT NULL,
Lng double NOT NULL,
PRIMARY KEY (ID),
UNIQUE KEY name (name)
);
CREATE TABLE reservations (
ID INT NOT NULL AUTO_INCREMENT,
loc_ID INT NOT NULL,
resDate DATE NOT NULL,
user_ID INT NOT NULL,
PRIMARY KEY (ID),
UNIQUE KEY one_per (loc_ID, resDate),
FOREIGN KEY (user_ID) REFERENCES Users (ID),
FOREIGN KEY (loc_ID) REFERENCES MapLocations (ID)
);
CREATE TABLE Users (
ID INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
email VARCHAR(50) NOT NULL,
pass VARCHAR(128) NOT NULL,
salt VARCHAR(5) NOT NULL,
PRIMARY KEY (ID),
UNIQUE KEY unique_names (name),
UNIQUE KEY unique_email (email)
);
In MySQL, I use the following query to get the ealiest reservation at each maplocation with a non null date for any locations that don't have a reservation.
SELECT locs.*, if(res.resDate,res.resDate,'0001-01-01') as resDate, res.Name as User
FROM MapLocations locs
LEFT JOIN (
SELECT loc_ID, resDate, Name
FROM Reservations, Users
WHERE resDate >= Date(Now())
AND user_ID = Users.ID
ORDER BY resDate
) res on locs.ID = res.loc_ID
group by locs.ID
ORDER BY locs.Name;
In Linq, with Visual studio automatically creating much of the structure after connecting to the database, I have come up with the following equivalent to that SQL Query
var resList = (from res in Reservations
where res.ResDate >= DateTime.Today
select res);
var locAndRes =
(from loc in Maplocations
join res in resList on loc.ID equals res.Loc_ID into join1
from res2 in join1.DefaultIfEmpty()
join usr in Users on res2.User_ID equals usr.ID into join2
from usr2 in join2.DefaultIfEmpty()
orderby loc.ID,res2.ResDate
select new {
ID = (int)loc.ID,
Name = (string)loc.Name,
Lat = (double)loc.Lat,
Lng = (double)loc.Lng,
resDate = res2 != null ?(DateTime)res2.ResDate : DateTime.MinValue,
user = usr2 != null ? usr2.Name : null
}).GroupBy(a => a.ID).Select(b => b.FirstOrDefault());
So, I'm wondering is there a better way to perform this query?
Are these equivalent?
Are there any good practices I should be following?
Also, one more question, I'm having trouble getting this from the var to a List. doing something like this doesn't work
List<locAndResModel> locList = locAndRes.AsQueryable().ToList<locAndResModel>();
In the above snippet locAndResModel is just a class which has variables to match the int, string, double double, DateTime, string results of the query. Is there an easy way to get a list without having to do a foreach and passing the results to a constructor override? Or should I just add it to ViewData and return the View?
You'll want to take advantage of the automatic joins performed by the Entity Framework. Give this a try and let me know if it does what you want:
var locAndRes = from maplocation in MapLocations
let earliestReservationDate = maplocation.Reservations.Min(res => res.resDate)
let earliestReservation = (from reservation in mapLocation.Reservations
where reservation.resDate == earliestReservationDate && reservation.resDate >= DateTime.Today
select reservation).FirstOrDefault()
select new locAndResModel( maplocation.ID, maplocation.name, maplocation.Lat, maplocation.Lng, earliestReservation != null ? earliestReservation.resDate : DateTime.MinValue, earliestReservation != null ?earliestReservation.User.name : null)

Resources