Entity Framework 4 not respecting database constraints for numeric fields - entity-framework-4

Say, I have a table in the DB defined as follows
Table: Foo
PkId - int, primary, autoincrement
Bar - int, allow null=false, no default
Now when generating the EF model from the database the 'Bar' field is correctly defined as Nullable=false, Type=Int32.
Now when I do the following
var foo = new Foo();
context.AddToFoos(foo);
context.SaveChanges();
The row is inserted into the database and 'Bar' has a value of 0? I would have expected an exception because Bar hasn't been set. I realise that 0 isn't null but its also not a value that I've set.
Is this by design or have I misunderstood something?

It's not nullable and thus an int. The default of int is 0. So the DB is happy and the framework is fine as well.

Related

Odoo 8 - Compute Field with "store=True" can't store in database

I'm using Odoo 8 and I have a problem with compute field with type is Many2One.
Here, I declared department_id:
department_id = fields.Text(
string="Department", store=True,
comodel_name="hr.department",
compute="_get_department_id"
)
And fuction of this compute field:
#api.depends('employee_id')
def _get_department_id(self):
if self.employee_id.department_id:
self.department_id = self.employee_id.department_id.name
It seems to work right now, but it's not. In view, I can see the value of department_id. But in the database, the table has no column department_id and has no value of this column.
My question is: how can I store the department_id in database?
Notes:
In the declaration of department_id, I set store=True, but it did NOT store the value of this field in database.
I did a test. I add compute_field with type Text, It works, I don't know why compute field doesn't work with type Many2One.
#api.depends('employee_id')
def _get_compute_field(self):
if self.employee_id.department_id:
self.compute_field = self.employee_id.department_id.name
compute_field = fields.Text(
string="Compute Field", store=True,
compute="_get_compute_field"
)
The store=True works.
It may be that you added the computation to the field after it was created on the database. In this case the initial computation is not triggered.
A work around is to drop the column from the table and then upgrade your module. When the field is recreated the initial values should be computed.

Persist column order from Grails domain to database

When Grails creates a table from a domain object, is it possible to specify the column order? I'd like it to preserve the column order as specified in the domain. Instead, it seems to be mostly alphabetical. I could not find anything in the documentation. I've found this article that details specifying constraints, but that did not appear to fix the issue for database columns.
Example:
class Foo {
Long id
String zee
Integer baz
Integer bar
}
I'd like the database columns to then be ordered as:
id | zee | baz | bar
Instead I get something closer to:
id | bar | baz | zee
You can always create the DB outside of Grails and put the columns in whatever order you wish and Grails will happily use the schema you provide (assuming only the column ordering is different from what it wants to create by default)
An even better option, as #Burt pointed out, is to use the database migration plugin to create (and manage) the database. It lets you have fine-grained control over the database in a database-agnostic way and also has the massive advantage of making your DB schema and schema changes versioned along with your code, for both upgrades and rollbacks.
This is the only way to do it as I know. Use static constraints and write them with your order
class Foo {
Long id
String zee
Integer baz
Integer bar
}
static constraints = {
id()
zee()
baz()
bar()
}

How to define what DatabaseGenerated.Computed should compute?

I am just doing my first steps with EF CodeFirst, especially with dataAnnotations.
Now I'm doing my best to understand the "DatabaseGenerated" attribute.
What I know so far:
using this attribute gives me three options to handle creation of a property value: Computed, Id and None.
using this attribute means, that the property can not be updated manually - it is done by the database
So - as I can imagine what happens when using th "Id" option, I have no idea what happens when using "Computed" option. I red that this should tell the db to compute the field value.
For example: field "sum" = field "price" + field "shipping".
But how can I use that in that way? I looked around and did not find any examples. Could you please help me?
You can't use EF to tell the database how to compute the column -- you can only tell EF that the column is database generated so it should be retrieved from the database for your use in code.
To control how the database computes the column you have to manually instruct it either outside of EF or in your database initialization logic.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
context.Database.ExecuteSqlCommand("RAW SQL HERE");
}
Your SQL (MS T-SQL) might look like this (more here):
CREATE TABLE t2 (a int, b int, c int, x float,
y AS CASE x
WHEN 0 THEN a
WHEN 1 THEN b
ELSE c
END)
For SQL here's some info about Computed Colums:
http://msdn.microsoft.com/en-us/library/ms191250(v=sql.105).aspx
Also for reference:
http://msdn.microsoft.com/en-us/library/gg193958.aspx

Grails alters my table using not null instead of null

I'm developing a personal project with grails in order to learn this powerful tool.
I have encountered this problem when adding two new fields (x,y) to my domain class "Post":
class Post {
long id;
Date creationDate;
String text;
byte[] image;
Style style;
long likeCount;
long dislikeCount;
User owner;
//coordinates on the wall
int x;
int y;
//this is probably to remove
static hasMany = [judgment : Judgment];
static constraints = {
text(nullable:true, maxSize:5000);
image(nullable:true, maxSize:1000000);
creationDate(nullable:true);
x(nullable:true);
y(nullable:true);
}
}
I added x and y after I create some data (Post records) on my postgres database.
But when I run-app in grails console this error comes up:
| Error 2012-03-04 12:04:23,670 [pool-5-thread-1] ERROR hbm2ddl.SchemaUpdate - Unsuccessful: alter table post add column x int4 not null
| Error 2012-03-04 12:04:23,672 [pool-5-thread-1] ERROR hbm2ddl.SchemaUpdate - ERROR: column "x" contains null values
this is very strange because i declared in constraint x,y to be nullable.. so why grails try to alter my table declaring x and y to be not null?
They're primitive int fields, so nullable doesn't make sense. You can't store a null value in the class instance, and if you have a null value in the database there's no sensible default conversion to an int value. You may consider 0 a sensible value for null, but 0 and null aren't equivalent in general.
If you want to allow null values for primitive numbers (int, long, etc.) or for boolean use the non-primitive Object classes Integer, Long, Boolean, etc. Another problem with primitive types is validation. Since they default to 0 (or false for boolean) you can't know whether the user chose 0 or false or if they didn't make a choice at all and you just have the default values from the constructor. So making them non-primitive leaves them null and you can know whether they made a choice or not.
Also, unrelated - you don't need to declare the id field, since Grails adds one for you anyway. And lose the semicolons ;)

How can I Alias Data in a WebGrid

I have an existing database that I can't change. I have a column of type int that has various numbers that mean something.
This something would be a string. For example, 1="dog", 2="cat", 3="bird". There are a dozen or so integers to deal with.
I'm using ASP.NET MVC 3 with EF 4.1 and have a WebGrid binding to the Model. Is there a way to alias the data for these integers listed in the WebGrid to display the string value that mean something to the user?
Any help on this would be greatly appreciated!
Add an enum to your Model:
public enum foo
{
dog = 1, cat, bird //etc
}
Hopefully, you are using ViewModels. If you are, add a property for the enum:
public foo thing {get;set;}
And set the value of thing based on the integer value you get from the database:
Model m = new Model{number = 3};
m.thing = (foo) m.number;
Or you could create a helper and use that within the format parameter to set a value based on the integer, or you could use JavaScript/jQuery to alter the values from ints to strings once they have been rendered to the browser.

Resources