Entity Framework: computed field, fetched from DB only on insert... how? - entity-framework-5

EF5 (code first).
I have a field CreateDate, that has a default value GETDATE(), and value set only once - on insert. If I mark property as DatabaseGenerated(DatabaseGeneratedOption.Computed) - EF update his value on every update any other field. How I can prevent this behavior? Fetching generated value needed only after insert, but not after every update...
[Table("Users")]
public class EFUser
{
[Key]
public int ID { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreateDate { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
[StringLength(50)]
public string LoginName { get; set; }
[Required]
[StringLength(50)]
public string PasswordHash { get; set; }
}
look at example below - insert new record, and update Name field:
exec sp_executesql N'insert [dbo].[Users]([Name], [LoginName], [PasswordHash])
values (#0, #1, #2)
select [ID], [CreateDate]
from [dbo].[Users]
where ##ROWCOUNT > 0 and [ID] = scope_identity()',N'#0 nvarchar(50),#1 nvarchar(50),#2 nvarchar(50)',#0=N'6adbf8ac-8332-40a5-8e38-369f938867b1',#1=N'689950801',#2=N'291FD051'
go
exec sp_executesql N'update [dbo].[Users]
set [Name] = #0
where ([ID] = #1)
select [CreateDate]
from [dbo].[Users]
where ##ROWCOUNT > 0 and [ID] = #1',N'#0 nvarchar(50),#1 int',#0=N'6af61beb-2583-4f2d-8a7c-b3a03ca3b082',#1=29
go
First time, after insert, EF fetch back generated ID and CreateDate values - that's ok.
But after update Name... EF again fetch CreateDate, but it's not changed, never after insert.
How I can disable updating computed field value on every update?

Related

Servicestack Ormlite generates invalid SQL query for custom select

I am using version 4.5.14 of Servicestack ormlite
here "InMaintenance" Property is ignored as it is not the "Network" table column in the database. I want to set the value of the InMaintenance property based on whether the "Enddate" column in the NetworkMain table has value or not.
Following is the code
but the above code generates the following SQL query for SelectExpression
as we can see there is no space between the not null condition in the above expression.
And FromExpression is as follows
I know that I can use the SQL query in the select but how to resolve this issue?
Thanks!
Amol
4.5.14 is several years old, but this generates valid SQL in the latest version of OrmLite. Here's a live demo on Gistlyn you can run:
OrmLiteUtils.PrintSql();
public class Network
{
[PrimaryKey]
public string Id { get; set; }
public string Name { get; set; }
[Ignore]
public bool InMaintenance { get; set; }
}
public class NetworkMain
{
[PrimaryKey]
public string Id { get; set; }
[ForeignKey(typeof(Network))]
public string NetworkId { get; set; }
public DateTime? EndDate { get; set; }
}
public class NetworkDTO
{
public string Id { get; set; }
public string Name { get; set; }
public bool InMaintenance { get; set; }
}
var q = db.From<Network>()
.LeftJoin<NetworkMain>()
.Select<Network, NetworkMain>((a, m) => new
{ a,
InMaintenance = m.NetworkId == a.Id && m.EndDate.HasValue ? "1" : "0"
}).OrderBy(x=>x.Name);
var results = db.Select<NetworkDTO>(q).ToList();
Which generates:
SELECT "Network"."Id", "Network"."Name", (CASE WHEN (("NetworkMain"."NetworkId"="Network"."Id")AND("NetworkMain"."EndDate" is not null)) THEN #0 ELSE #1 END) AS InMaintenance
FROM "Network" LEFT JOIN "NetworkMain" ON
("Network"."Id" = "NetworkMain"."NetworkId")
ORDER BY "Network"."Name"

Ormlite Descending Index

Is it possible to define a descending index in OrmLite? I can only see the [Index] attribute but I have a table of over 1 million records and need a descending index.
If it's for a composite index you can specify it within its name:
[CompositeIndex("Field1", "Field2 DESC")]
public class Table
{
...
public string Field1 { get; set; }
public string Field2 { get; set; }
}
Otherwise you can use a Pre/Post Custom SQL Hooks, e.g:
[PostCreateTable("CREATE INDEX IX_NAME ON MyTable (Field1 DESC);")]
public class MyTable
{
...
public string Field1 { get; set; }
public string Field2 { get; set; }
}
Which will execute the Post SQL Hook to create the index after the table is created.

PocoDynamo (the provided key element does not match the schema)

I have created a table in Dynamo Db, with Id as the primary key and customerID as sortkey.
When i query an item by Id as shown below, I get error "the provided key element does not match the schema"
var db = new PocoDynamo(awsDb);
db.GetItem("aa4f0371-6144-4bd9-8980-5066501e37aa");
When I remove the sortkey from the dynamo DB, it works as expected.
What is the correct way to get an item by Id, which also has a sort key associated with it.
public class Notification
{
[PrimaryKey]
public Guid Id { get; set; }
[RangeKey] //Sort Key
public Guid CustomerId { get; set; }
public Guid LinkId { get; set; }
public string PreviewText { get; set; }
}
In PocoDynamo you can specify both Hash Key and Range Key with a [CompositeKey] attribute, e.g:
[CompositeKey(nameof(Id), nameof(CustomerId))]
public class Notification
{
public Guid Id { get; set; }
public Guid CustomerId { get; set; }
public Guid LinkId { get; set; }
public string PreviewText { get; set; }
}

ServiceStack OrmLite create table with [AutoIncrement] fail

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)

The cast to value type 'DateTime' failed because the materialized value is null

My project is the throwing the above error because the Ship Date in my table is null. I am using Code First, and the DateTime field is declared as nullable both in the generic set and the SQL table. I am populating a gridview with the result set. Ideally, I would like to have the gridview display "not yet shipped" when the ShipDate field is null, but at this point, I would be happy just to be able to display the record. Any help is greatly appreciated. Here is the code-behind and the context class that I am using:
public class Order
{
[Key]
public int OrderID { get; set; }
public int CustomerID { get; set; }
public string ShipAddress { get; set; }
public string ShipCity { get; set; }
public string ShipState { get; set; }
public string ShipZip { get; set; }
[ScaffoldColumn(false)]
public string PaymentTransactionID { get; set; }
[ScaffoldColumn(false)]
public System.DateTime OrderDate { get; set; }
public System.DateTime? ShipDate { get; set; }
public virtual Customers Customers { get; set; }
public List<OrderDetail> OrderDetails { get; set; }
}
The code behind is:
public List<OrderDetail> FetchByOrderID()
{
int myOrderID = CusOrderId;
ProductContext db = new ProductContext();
return db.OrderDetails.Where(
c => c.OrderID == myOrderID).ToList();
}
I was getting the above error when trying to get the max(date_column) through LINQ. The column was defined as NOT NULL and when there are no rows returned in the query its trying to assign null to the DateTime property that's representing the date column. One solution is to change the date column to being NULLable which will create the entities property as type DateTime?
I use VB.Net, but had a similar problem. I do not know if you fixed your problem.
But I declared the variable as Nullable(Of Date) and that did the trick to me. I am told that adding the "?" does the similar thing, but unfortunately did not work out for me, or I did not do it correctly. :o)
private DateTime? _settlementDate {get;set;}
I was having a similar problem, same error.
Turns out I failed to setup my ConnectionString in the configuration.

Resources