ServiceStack OrmLite - Handle Auto increment column default seed - servicestack

How can i set a auto increment column seed from 1 to 100??
in sql server can do this use
ADD Id INT NOT NULL IDENTITY(1000,1)
but in ormlite autoincrement attribute seems like always start with 1.
tried also
db.AlterTable<MSchool>("command") // DROP ID AND ADD AUTO INCREMENT COLUMN
it works, if Id doesn't related to any table.
can i set a column autoincrement with default seed and increment?
[AutoIncrement(1000,1)]
public int Id {get;set;}
UPDATE
Resolved, but not good
public class School
{
[AutoIncrement]
public int Id {get;set;}
}
//then create table
db.CreateTable<School>();
//then update seed
db.ExecuteSql("DBCC CHECKIDENT ('School',reseed,1000)");
OR
[PostCreateTable("DBCC CHECKIDENT ('School',reseed,1000)")]
public class School : BaseModel
{
[AutoIncrement]
public int Id {get;set;}
}
Is there no easier way to do this??

Personally I don't believe this behavior belongs inside source code and would just modify the database out-of-band.
But if I were to add it in source code I'd do something like:
if (db.CreateTableIfNotExists<School>())
{
db.ExecuteSql("DBCC CHECKIDENT ('School',reseed,1000)");
}
So it only resets the seed if the table doesn't exist.
Another option is attach it to the model at runtime so it's decoupled from the class definition with:
typeof(School)
.AddAttributes(new PostCreateTableAttribute(
"DBCC CHECKIDENT ('School',reseed,1000)"));

Related

JSONB - update array value by index

How to update JSON(B) array value by index? And also to retrieve the index of each value in JSONB array?
There is ServiceStack ORMLite model:
public class Page
{
[AutoIncrement]
public long Id { get; set; }
[PgSqlJsonB]
public List<Widget> Widgets { get; set; }
}
For example, how to update the second item in Widgets list?
Here is an example of how to do select array indexes and update array value by index in raw Postgres SQL:
How to update objects inside JSONB
The idea is to select array indexes with AutoQuery and update particular JSONB array value knowing it's index in database array.
In OrmLite complex Types like List<Widget> are blobbed, so if you change the value in C# and save it, it will serialize the entire Widgets property to JSON and update the entire field.
If you want to use PostgreSQL native functions to manipulate the column contents in a server side query you'd need to use the Custom SQL APIs, e.g:
db.Execute("UPDATE page SET widgets = jsonb_set(widgets, ...) WHERE id = #id",
new { id });

Automapper mapping 2 entities to a single class

Just wondering if this is possible:
Say I have a ViewModel for comparing an old and new entity.
public class FooComparison
{
public string Name {get;set;}
public string OldName {get; set;}
public int Age {get; set;}
public int OldAge {get; set;}
...
}
I want to load 2 instances of Foo from the database and populate the FooComparison with the details from both instances.
For now, I have Mapper.CreateMap<Foo, FooComparison>() which will populate the Name, Age etc from the first entity - is there an easy way to populate the Oldxxx properties from the second entity without looping and manually updating them?
My suggestion would be to define a mapping from Tuple<Foo, Foo> to FooComparison:
Mapper.CreateMap<Tuple<Foo, Foo>, FooComparison>()
.ConvertUsing(x => new FooComparison
{
Name = x.Item2.Name,
OldName = x.Item1.Name,
Age = x.Item2.Age,
OldAge = x.Item1.Age,
...
});
Then use it like this:
Foo oldFoo = ...;
Foo newFoo = ...;
FooComparison comparison = Mapper.Map<FooComparison>(Tuple.Create(oldFoo, newFoo));
I appreciate that this loses the "auto" part of automapper, but really the big benefit you are getting by using automapper is that this mapping is defined in just one place in your software, not so much the auto part.
I have personally found this way of mapping via Tuple to work very well.

Orchard: how to persist a record without content

Allright, this should be fairly easy.
I would like to persist some records for my module in Orchard (1.7.2) without those records being also a ContentPartRecord.
In other words, I would like to be able to persist in DB the following objects:
public class LogItemRecord
{
public virtual string Message { get; set; }
}
..which is already mapped on to the db. But notice that this class is not derived from ContentPartRecord, as it is most certainly not one.
However, when I call IRepository instance's .Create method, all I get is a lousy nHibernate exception:
No persister for: MyModule.Models.LogItemRecord
...which disappears if I do declare the LogItem record as having been inherited from ContentPartRecord, but trying to persist that, apart from being hacky-tacky, runs into an exception of its own, where nHibernate again justly complains that the Id value for the record is zero, though in not so many words.
So... how do I play nicely with Orchard and use its API to persist objects of my own that are not ContentParts / ContentItems?
I'm running 1.7.3 (also tested in 1.7.2) and have successfully been able to persist the following class to the DB:
public class ContactRecord
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string JobTitle { get; set; }
public virtual string Email { get; set; }
public virtual string Phone { get; set; }
}
Here are the relevant lines from Migrations.cs
SchemaBuilder.CreateTable(
typeof(ContactRecord).Name,
table => table
.Column<int>("Id", col => col.Identity().PrimaryKey())
.Column<string>("Name")
.Column<string>("JobTitle")
.Column<string>("Email")
.Column<string>("Phone")
);
I'm going to assume that the code you've shown for LogItemRecord is the complete class definition when making the following statement...
I think that any Record class you store in the DB needs an Id property, and that property should be marked as Identity and PrimaryKey in the table definition (as I've done above).
When you create a *Record class which inherits from ContentPartRecord and setup the table like
SchemaBuilder.CreateTable(
"YourRecord",
table => table
.ContentPartRecord()
// more column definitions
);
then you get the Id property/PK "for free" by inheritance and calling .ContentPartRecord() in the Migration.
See the PersonRecord in the Orchard Training Demo Module for another example of storing a standard class as a record in the DB.

Code First EF delete with Id only and

I have the following code:
public void Remove(Guid id)
{
var symbol = new Symbol()
{
Id = id
};
_ctx.Entry(symbol).State = EntityState.Deleted;
_ctx.SaveChanges();
}
The symbol entity has a related entity called "Category". It is not set up to cascade delete since it is a value from a lookup table. I want to leave the category alone, however when this runs it throws a DbUpdateException:
Entities in 'HourlyContext.Symbols' participate in the 'Symbol_Category' relationship. 0 related 'Symbol_Category_Target' were found. 1 'Symbol_Category_Target' is expected.
I understand that EF is confused about what to do with the relationship, how can I tell it to simply discard the reference to the Category and go ahead and delete the Symbol?
Thanks.
.
EDIT
Okay so I tried making the foreign key nullable (FYI I am using code first Entity Framework) by adding a nullable CategoryId as shown here:
public class Symbol : EntityBase
{
[Required]
public string CompanyName { get; set; }
public int? CategoryId { get; set; }
[Required]
public MarketCategory Category { get; set; }
}
However, after creating a migration and updating the database, this does not resolve the exception.
.
EDIT 2
Okay so it turns out that (looking back now it's obvious) that adding the 'required' attribute prevents the column from being nullable. Now my intention was to not allow the coder (i.e. me) from accidentally setting the relationship to null in code, but allow the framework to null it out when I delete the object via Id. It appears this cannot be done. So all I needed to do was to remove the required attribute (and leave out the 'categoryId' column).
there must be a foreign key relationship being generated by EF. Easy way to check is to use SQL sever managent Studio and check for dependencies on the table
To do so, I think the foreign key column of Category table (SymbolId, whatever ...) Should be Nullable. The OndDelete action of your database table should be set null, too.
Then, EF can simply remove that symbol.

How to use AutoMapper to map a DataRow to an object in a WCF service?

I have a WCF service that calls a stored procedure and returns a DataTable. I would like to transform the DataRows to custom object before sending to the consumer but can't figure out how to do so. Lets say I retrieved a customer from a stored procedure. To keep things short here is the customer via DataRow:
string lastName = dt.Rows[0]["LastName"].ToString();
string firstName = dt.Rows[0]["FirstName"].ToString();
string age = System.Convert.ToInt32(dt.Rows[0]["Age"].ToString());
I can retrieve the customer easily. Now, I created a Customer object like so:
public Customer
{
public string LastName {get;set;}
public string FirstName {get;set;}
public int Age {get;set;}
}
I loaded AutoMapper from the package manager console. I then put a public static method on my customer like so:
public static Customer Get(DataRow dr)
{
Mapper.CreateMap<DataRow, Customer>();
return Mapper.Map<DataRow, Customer>(dr);
}
When I step through my code, every property in the customer returned from Get() is null. What am I missing here? Do I have to add a custom extension to map from a DataRow? Here is a thread that seems related but I thought AutoMapper would support this out of the box especially since the property names are identical to the column names. Thanks in advance.
This works!!
public static Customer GetSingle(DataTable dt)
{
if (dt.Rows.Count > 0) return null;
List<Customer> c = AutoMapper.Mapper.DynamicMap<IDataReader, List<Customer>>(dt.CreateDataReader());
return c[0];
}

Resources