I had these classes
public class Bid : ...
{
...
[Required]
public virtual TraderUser Trader { get; set; }
}
public class TraderUser : ...
{
...
}
I then changed these classes in the following way and added a new class
public class Bid : ...
{
...
[Required]
public virtual TraderUser TraderUser { get; set; }
}
public class TraderUser : ...
{
...
public int TraderCompanyId { get; set; }
[ForeignKey("TraderCompanyId")]
public virtual TraderCompany TraderCompany { get; set; }
}
public class TraderCompany : ...
{
...
}
When I did an update-database I got the following error
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint
"FK_dbo.Bid_dbo.TraderUser_TraderUser_Id". The conflict occurred in
database "LeasePlan.Development", table "dbo.TraderUser", column 'Id'.
I can't get the database to update. Any help is much appreciated.
Do not know if it is too late, but I had same problem and maybe this could help you.
I cannot see from your post, but probably your TraderUser table has some rows already inserted. What you are trying to accomplish is to create new table TraderCompany and create foreign key relationship in TraderUser that points to TraderCompany table.
In one migration you are trying to create non nullable foreign key relationship for table that already contains data.
You could try to the following:
First migration - everything same, except this line
public int TraderCompanyId { get; set; }
should be
public int? TraderCompanyId { get; set; }
This will allow you to create nullable foreign key column.
Update your TraderCompanyId column for existing data with some row from TraderCompany table.
Second migration - Change code from
public int? TraderCompanyId { get; set; }
to
public int TraderCompanyId { get; set; }
and run your migration.
I hope this will help you.
The alternative is to add an SQL statement within the migration code to insert a row before it adds the foreign keys. Here's an example of what I did:
// Countries is a new table
CreateTable(
"dbo.Countries",
c => new
{
CountryID = c.Int(nullable: false, identity: true),
Name = c.String(),
Currency = c.Int(nullable: false),
})
.PrimaryKey(t => t.CountryID);
// Heres where i insert a row into countries
Sql("INSERT INTO Countries (Name, Currency) VALUES ('United Kingdom', 0)");
// I set the default value to 1 on the ID fields
AddColumn("dbo.Brokers", "CountryID", c => c.Int(nullable: false, defaultValue: 1));
AddColumn("dbo.Products", "CountryID", c => c.Int(nullable: false, defaultValue: 1));
AddForeignKey("dbo.Brokers", "CountryID", "dbo.Countries", "CountryID", cascadeDelete: false);
AddForeignKey("dbo.Products", "CountryID", "dbo.Countries", "CountryID", cascadeDelete: false);
// Migrations then creates index's
CreateIndex("dbo.Brokers", "CountryID");
CreateIndex("dbo.Products", "CountryID");
Related
I'm looking for a way to map several POCO objects into single table in the ServiceStack.
Is it possible to do this in a clean way, without "hacking" table creation process?
As a general rule, In OrmLite: 1 Class = 1 Table.
But I'm not clear what you mean my "map several POCO objects into single table", it sounds like using Auto Mapping to populate a table with multiple POCO instances, e.g:
var row = db.SingleById<Table>(id);
row.PopulateWithNonDefaultValues(instance1);
row.PopulateWithNonDefaultValues(instance2);
db.Update(row);
If you need to maintain a single table and have other "sub" classes that maintain different table in the universal table you can use [Alias] so all Update/Select/Insert's reference the same table, e.g:
public class Poco
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
[Alias(nameof(Poco))]
public class PocoName
{
public int Id { get; set; }
public string Name { get; set; }
}
[Alias(nameof(Poco))]
public class PocoAge
{
public int Id { get; set; }
public int Age { get; set; }
}
Although I don't really see the benefit over having a single table that you use AutoMapping to map your other classes to before using that in OrmLite.
Currently I have a part that has 3 fields (Name, Value1, Value2). I have everything working where I can do a Create/Edit/Delete on the part.
What I want to do now is have a grid with 3 columns (Name, Value1, Value2) and can have multiple rows (up to the user how many there will be). The save won't happen until the user done (save all rows in a single post back).
I haven't figured what is needed so a collection of items will get saved on post back.
Any suggestions on how to do this?
Thanks!
What you could have is to have, in the part, a collection of the records corresponding to (Name, Value1, Value2) by having your dbms create and manage a 1-to-n relationship.
For example, you would have
public class ThisIsYourPart : ContentPart<ThisIsYourPartRecord> {
// You can access the list of your records as
// yourPart.Record.YourRecords
}
public class ThisIsYourPartRecord : ContentPartRecord {
public ThisIsYourPartRecord () {
YourRecords= new List<YourRecordWithValues>();
}
public virtual IList<YourRecordWithValues> YourRecords{ get; set; }
}
public class YourRecordWithValues {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Value1 { get; set; } // use your actual type
public virtual ThisIsYourPartRecord ThisIsYourPartRecord { get; set; }
}
public class YourMigration : DataMigrationImpl {
public int Create() {
SchemaBuilder.CreateTable("YourRecordWithValues ", table => table
.Column<int>("Id", col => col.Identity().PrimaryKey())
.Column<string>("Name", col => col.NotNull().Unlimited())
.Column<string>("Value1", col => col.NotNull().Unlimited())
.Column<int>("ThisIsYourPartRecord_Id"));
SchemaBuilder.CreateTable("ThisIsYourPartRecord", table => table
.ContentPartRecord());
}
}
Code like that should do it.
We used this kind of relations a lot in https://github.com/bleroy/Nwazet.Commerce
*edit:
of course, have all the code in the proper files and folders.
I don't know how to store collection (Comments) in separate table.
By default comments are serialized and stored in SomeClass table as column Comments.
[{Id:0,CreateDate:2013-09-12T14:28:37.0456202+02:00,,SomeClassID:1,CommentText:"coment text",}]
Is there any way to save it in separate tables?
public class SomeClass {
[AutoIncrement]
public int Id { get; set; }
public string Title { get; set; }
List<Comment> comments = new List<Comment>();
public List<Comment> Comments {
get { return comments; }
set { comments = value; }
}
}
public class Comment {
[AutoIncrement]
public int Id { get; set; }
[References(typeof(SomeClass))]
public int SomeClassID { get; set; }
[StringLength(4000)]
public string CommentText { get; set; }
}
I don't think ORMLite supports serializing to multiple tables. 1 table = 1 class so the comments will be stored as a Blob field in the SomeClass table.
If you need to store them in separate tables you will have to save the comments separately and have a foreign key reference back to the id of the SomeClass table.
I am using ServiceStack version="3.9.54" targetFramework="net40" with PostgreSQL.\
When i create table with
public class test
{
[AutoIncrement]
public int id { get; set; }
public string test_name { get; set; }
}
dbConn.CreateTable<test>(true);
CREATE TABLE test
(
id serial NOT NULL,
test_name text,
CONSTRAINT test_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE);
But when i create with
public class test
{
public string test_name { get; set; }
[AutoIncrement]
public int id { get; set; }
}
dbConn.CreateTable<test>(true);
Here is table on Postgres
CREATE TABLE test
(
test_name text NOT NULL,
id integer NOT NULL,
CONSTRAINT test_pkey PRIMARY KEY (test_name)
)
WITH (
OIDS=FALSE
);
What happen with my id columns. Is it bug ?
Thanks for your help
Tuan Hoang Anh
I think there are some conventions and case-sensitivity at play here. If you change id to Id it should work
public class test
{
public string test_name { get; set; }
[AutoIncrement]
public int Id { get; set; }
}
dbConn.CreateTable<test>(true);
OrmLite expects an 'Id' property to be present and to be the primary key. You can attribute a property with [PrimaryKey] if you don't want to use Id. However, in this case attributing id with [PrimaryKey] will attempt to create 2 primary keys since OrmLite can't find an Id field and (I think) defaults the first property it finds to be the primary key (can't find docs/proof to back this up, though)
I have three entities:
public class MainEntity()
{
public long Id { get; set; }
public long EntityAId { get; set; }
public EntityA OptionalEntityA { get; set; }
public long EntityBId { get; set; }
public EntityB OptionalEntityB { get; set; }
public string SProp { get; set; }
}
public class EntityA()
{
public long Id { get; set; }
public long MainEntityId { get; set; }
public MainEntity RequiredEntity { get; set; }
}
public class EntityB()
{
public long Id { get; set; }
public long MainEntityId { get; set; }
public MainEntity RequiredEntity { get; set; }
}
All three entities have there own Id generated by database:
Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
How can I define the Relationship between MainEntity and EntityA and EntityB in order to have:
MainEntity may have zero or one EntityA
MainEntity may have zero or one EntityB
EntityA must have one MainEntity
EntityB must have one MainEntity
In my MainEntityConfigurationMap I have defined relation like this:
HasOptional(m => m.OptionalEntityA).WithRequired(ea => ea.RequiredEntity);
HasOptional(m => m.OptionalEntityB).WithRequired(eb => eb.RequiredEntity);
Looking at the generated migration I have this for EntityA:
CreateTable(
"dbo.EntityA",
c => new
{
Id = c.Long(nullable: false, identity: true),
MainEntityId = c.Long(nullable: false),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.MainEntity", t => t.Id)
.Index(t => t.Id);
Entity Framework is defining a shared primary key here, is there a way to avoid that and make MainEntityId poiting to MainEntity.Id?
Entity framework supports one-to-one relation only on top of shared primary key (PK in dependent table is also FK to principal table). The reason is that FK in dependent table must be unique to enforce one-to-one relation but EF currently doesn't support unique constraint (except PK).
And to add on what #Ladislav Mrmka said...
Here is a full study on the various one-to-one modalities - and particularly how to make it using FK-s instead of tying up PK-s (but don't raise your hopes up too high).
Create a Unique Constraint To Enforce the Relationship as a One to One
It boils down to executing a SQL manually (during Seed-ing or similar Db initialization) - which adds a UNIQUE CONSTRAINT...
However, even in that case it won't work for you - or not w/o changes.
If I'm not mistaking - you'd have to give up one navigation property - and most likely the OptionEntityA/B - as unique column cannot support NULL.