I am trying to add a foreign key manually in gorm but i get this error
db.Model(&models.Business{}).AddForeignKey undefined (type *gorm.DB has no field or method AddForeignKey)
am using postgres
i have tried
db.Model(&Business{}).AddForeignKey("cust_id", "customers(cust_id)", "CASCADE", "CASCADE")
you can do it with two solution that i know in GORM
#1
when you create model you do it like below:
type Business struct {
Name string
CustomersID int
Customers Customers `gorm:"foreignKey:CustomersID"` // use CustomersID as foreign key
}
type Customers struct {
ID int
Name string
}
#2
every time you want you can add foreign key like below
Client.Exec("ALTER TABLE business ADD FOREIGN KEY (cust_id)" +
"REFERENCES customers (id) ON DELETE CASCADE ON UPDATE CASCADE;")
Related
I have some problem. I want to add new column into my table that references to other column in other table. I do something like that:
class m161202_153033_dodanie_informacji_o_obsludze_prawnej_do_pozyczki extends CDbMigration
{
public function safeUp()
{
$this->execute("ALTER TABLE loan ADD COLUMN administrator int NOT NULL DEFAULT 15 REFERENCES person (id) ON UPDATE CASCADE ON DELETE NO ACTION;");
}
public function safeDown()
{
$this->execute("ALTER TABLE loan DROP COLUMN administrator;");
}
}
But when i try to execute this migration i have this error:
Foreign key violation: 7
DETAIL: Key (administrator)=(15) doesn't appear in table "person"..
I know that there is no suck column "administrator" in my table. But i want to add new column "administrator" into loan table. I wanted to make "administrator" foreign key from person table, column "id". Can u help me, what am i doing wrong?
The error means that there is no row in person with id equal to 15, which would be required for the constraint to be fulfilled.
When you run that ALTER TABLE statement, the table has to be rewritten, and the new column is filled with the value 15.
Often it is easier to create a new column nullable and without default value (then ALTER TABLE will not rewrite the table) and use UPDATE to populate the new column. After that you can change the column definition to NOT NULL and add a default value.
Try this
class m161202_153033_dodanie_informacji_o_obsludze_prawnej_do_pozyczki extends CDbMigration
{
public function safeUp()
{
$this->execute("INSERT INTO person (id) VALUES (15) ON CONFLICT (id) DO NOTHING;");
$this->execute("ALTER TABLE loan ADD COLUMN administrator int NOT NULL DEFAULT 15 REFERENCES person (id) ON UPDATE CASCADE ON DELETE NO ACTION;");
}
public function safeDown()
{
$this->execute("ALTER TABLE loan DROP COLUMN administrator;");
}
}
I have the following Schema:
User Table: (Primary Key)
UserId
CustomerId
Role Table: (Primary Key)
UserId
CustomerId
UserRole Table:
UserRoleId (UNIQUEIDENTIFIER (newsequentialid)) Primary Key
UserId
Customerid
RoleId
Those tables participate in many to many relationship (UserRole). I am using Entity Framework code first with mapping classes to define the database tables. So, In my mapping class for User Table, I have the following:
this.HasMany(u => u.Roles)
.WithMany()
.Map(m =>
{
m.MapLeftKey(new string[] { "CustomerID", "UserID" });
m.MapRightKey(new string[] {"CustomerID", "RoleID"});
m.ToTable("UserRoles");
}
);
Entity framework is failing with this message:
"One or more validation errors were detected during model generation:
CustomerID: Name: Each property name in a type must be unique. Property name 'CustomerID' is already defined.
UserRole: EntityType: EntitySet 'UserRole' is based on type 'UserRole' that has no keys defined.
is it possible to tell Code First that the Primary Key for my "UserRole" is UserRoleId?
The issue is when Entity Framework tries to create the UserRole Table, it would use all columns of MapLeftKey and MapRightKey to Create UserRole with PrimaryKey that has all those columns.
Any suggestions?
You need to model your classes similar to your DB, why don't you simply add the association tables? I mocked up your DB and there is no problem as long as you model all the tables.
Test it for yourself, create an EF project .edmx using code first from existing DB, I think the answer will be obvious.
I got products table
->productID - primary
->price
->Quantity
productCategory -table
->prodcatID- primary
->prodId - foreign key
->catID - foreign key
productlanguages - table
->prodID - foreign key
->langID - forein key
->Title
So I use Entity framework and I shoud somehow get all products WITH THEIR TITLE,QUANTITYI PRICE From GIVEN CATEGORY AND FROM GIVEN LANGUAGE.
SO i should somehow combine info from all these three table
so i made my first function to get all products from given category
public List<ProductCategories> GetAllProductsForCategory(int catID)
{
using (OnlineStoreDBContext db = new OnlineStoreDBContext())
{
List<ProductCategories> lst = db.ProuctCategories.Where(x => (x.CategoryID == catID)).ToList();
}
}
So now I have a list with all productID that match this category. But now how to get the data from the other two.
See Loading Related Entities: http://msdn.microsoft.com/en-au/data/jj574232.aspx
In my application users can define Parameters, and then create SlideSets based on a grouping of parameters.
I am using code-first Entity Framework 5.0 and I have the following model:
class SlideSet {
public ICollection<Parameter> Parameter
}
class Parameter {}
A parameter might be used by many slidesets or none at all. However, in my domain a parameter has no need to reference a SlideSet, they are in separate bounded contexts (both SlideSet and Parameter are Aggregate Roots). As such, I don't want to put a reference from Parameter to SlideSet.
The table model (I don't care about table/column names) that I want is
Table SlideSet
Table Param
Table SlideSetParam
FK_SlideSet
FK_Param
I know I could model this by introducing a ParameterGroup entity or a Param.SlideSets collection, but it would exist solely for ORM mapping purposes (and cause serialization issues). Is there any other way to tell EF to generate this table model from my entities?
This should make you a Parameter w/o a navigation property:
modelBuilder.Entity<SlideSet>()
.HasMany(x => x.Parameters)
.WithRequired();
EDIT:
Based on the comment - that should be all together similar. This seems to work nicely what you're trying to do....
modelBuilder.Entity<SlideSet>()
.HasMany(x => x.Parameters)
.WithMany();
...and you can use it either way:
var slideset = new SlideSet { Parameters = new []
{
new Parameter{},
new Parameter{},
new Parameter{},
new Parameter{},
}
};
var slideset2 = new SlideSet { };
db.SlideSets.Add(slideset);
db.SaveChanges();
var slidesets = db.SlideSets.ToList();
var parameters = db.Parameters.ToList();
Console.WriteLine("");
db.SlideSets.Add(slideset2);
db.SaveChanges();
slidesets = db.SlideSets.ToList();
parameters = db.Parameters.ToList();
Console.WriteLine("");
...and the SQL:
CREATE TABLE [dbo].[Parameters] (
[ParameterID] [int] NOT NULL IDENTITY,
CONSTRAINT [PK_dbo.Parameters] PRIMARY KEY ([ParameterID])
)
CREATE TABLE [dbo].[SlideSets] (
[SlideSetID] [int] NOT NULL IDENTITY,
CONSTRAINT [PK_dbo.SlideSets] PRIMARY KEY ([SlideSetID])
)
CREATE TABLE [dbo].[SlideSetParameters] (
[SlideSet_SlideSetID] [int] NOT NULL,
[Parameter_ParameterID] [int] NOT NULL,
CONSTRAINT [PK_dbo.SlideSetParameters] PRIMARY KEY ([SlideSet_SlideSetID], [Parameter_ParameterID])
)
CREATE INDEX [IX_SlideSet_SlideSetID] ON [dbo].[SlideSetParameters]([SlideSet_SlideSetID])
CREATE INDEX [IX_Parameter_ParameterID] ON [dbo].[SlideSetParameters]([Parameter_ParameterID])
ALTER TABLE [dbo].[SlideSetParameters] ADD CONSTRAINT [FK_dbo.SlideSetParameters_dbo.SlideSets_SlideSet_SlideSetID] FOREIGN KEY ([SlideSet_SlideSetID]) REFERENCES [dbo].[SlideSets] ([SlideSetID]) ON DELETE CASCADE
ALTER TABLE [dbo].[SlideSetParameters] ADD CONSTRAINT [FK_dbo.SlideSetParameters_dbo.Parameters_Parameter_ParameterID] FOREIGN KEY ([Parameter_ParameterID]) REFERENCES [dbo].[Parameters] ([ParameterID]) ON DELETE CASCADE
...this makes the original tables practically 'agnostic' of the relationships (many-to-many) - while index table is automatically generated in the background.
You can also further customize that and make your own SlideSetParam (e.g. if you'd want to add additional fields there) with pretty much the same layout - just Parameters would have to point to that instead.
I have following table structure:
Table: Plant
PlantID: Primary Key
PlantName: String
Table: Party
PartyID: Primary Key
PartyName: String
PlantID: link to Plant table
Table: Customer
PartyID: Primary Key, link to Party
CustomerCode: String
I'd like to have Customer entity object with following fields:
PartyID: Primary Key
CustomerCode: String
PartyName: String
PlantName: String
I am having trouble with PlantName field (which is brought from Plant table
I connected Customer to Party and Party to Plant with associations
However I can not connect Customer to Plant with association ( because it does not have one)
I can not add Plant table to mapping, when I do that - I am getting following error:
Error 3024: Problem in Mapping Fragment starting at line 352: Must specify mapping for all key properties (CustomerSet.PartyID) of the EntitySet CustomerSet
Removing Plant association works.
Any hints or directions very appreciated.
You can get these fields by using the reference path on the Entity Object.
To get the PartyName, use this syntax: Customer.Party.PartyName
To get the PlantName, use this syntax: Customer.Party.Plant.PlantName
You can extend the Customer entity by using the public partial class:
public partial class Customer
{
public string PartyName
{
get { return Party.PartyName; }
set { Party.PartyName = value; }
}
public string PlantName
{
get { return Party.Plant.PlantName; }
set { Party.Plant.PlantName = value; }
}
}
After some research, I came across this thread on MSDN that says you can create a read-only entity, which is enough of a downside to not use it alone, but it gets worse. You will also lose the ability to update all of the models dynamically based on the schema of the database.