EF Code First How to specify DateTime as timestampz - npgsql

With Code First database creation, how a can one specify a DateTime property to take the postgres timestampz datatype instead of the default timestamp?.
I am storing all dates as UTC, however have an issue with linq queries where the DateTime.Kind is Unspecified. I believe the timestampz should resolve this.
The below code examples attempt to use the 'Column' attribute, this results in an error (DateTime not compatible).
I am using npgsql v3.1.7 and EntityFramework6.Npgsql v 3.1.1
[Column(TypeName="timestampz")]
public DateTime CreatedByDate { get; set; }
[Column(TypeName="NpgsqlDateTime")]
public DateTime CreatedByDate { get; set; }

You can use the TimeStamp attribute in the namespace System.ComponentModel.DataAnnotations to have .NET create a non-nullable Timestamp column in the database table that your entity represents.
[Timestamp]
public Byte[] TimeStamp { get; set; }
Code first allows only one Timestamp property per entity.

Related

In Entity Framework Core, how can my EF entities return a value from another table that is not an entity as a lookup?

I'm using EF Core 6 on a project. Most of my tables have a field like CreatedBy/UpdatedBy that includes a user id. There are only a few occasions where I need to show the full name associated with the user id, but that value is in another table in a different database, but on the same server.
Is creating a view that joins to the needed table only way to handle this? Could I create function in the database where my EF Core entities are modeled? How would that work code wise?
As EF context does not support cross database queries. Therefore, workaround can be a SQL view.
Is creating a view that joins to the needed table only way to handle this?
Yes you can do that. While creating view you should consider below way:
SELECT {Your 1st Table Column} [YourFirstDatabase].[dbo].[Your1stDbTable] WHERE UserId = (SELECT {Your 2nd Table Column} FROM [YourSecondDatabase].[dbo].[Your2ndDbTable] WHERE Category = 'Cat')
Could I create function in the database where my EF Core entities are modeled?
You could create function, stored procedure and view to achieve that. Afterwards, you should define that within a POCO Class finally call that on your context. For instance, here I am showing the example using a SQL view:
SQL view:
USE [DatabaseName_Where_You_Want_to_Create_View]
CREATE VIEW [ExecuteQueryFromOneDbToAnother]
AS
SELECT UserId, UserType,CreatedDate
FROM [RentalDb].[dbo].[Users]
WHERE UserId = (SELECT AnimalId
FROM [PetAnalyticsDb].[dbo].[Animal]
WHERE Category = 'Cat')
Note: I am simulating the example where I have two database from that I have two table where these columns, I would use in first database table UserId, UserType, CreatedDate and in second database from Animal table from the AnimalId I will search the user
How would that work code wise?
Following example would guided you how the implementation in the code should be.
Database context:
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext (DbContextOptions<ApplicationDbContext > options) : base(options)
{
}
    public DbSet<MultipleDBQueryExecutionModel> multipleDBQueryExecutionModels { get; set; }
            
    override void OnModelCreating(ModelBuilder modelBuilder)
{
        modelBuilder.Entity<MultipleDBQueryExecutionModel>().ToTable("ExecuteQueryFromOneDbToAnother");
    }
}
Note: put your view name while map in DbContext to table ToTable("ExecuteQueryFromOneDbToAnother");. Here ExecuteQueryFromOneDbToAnother is the view name.
POCO class:
public class MultipleDBQueryExecutionModel
{
[Key]
public Int UserId { get; set; }
public string UserType { get; set; }
public DateTime CreatedDate { get; set; }
}
Controller:
[HttpGet]
public ActionResult GetDataFromDifferentDatabase()
{
var data = _context.multipleDBQueryExecutionModels.ToList();
return Ok(data);
}
Output:

Query SQL Server table using EF Core convert varchar to Unicode in Where clause [duplicate]

I have this setting in my model:
[StringLength(250)]
public string Comment { get; set; }
to set the maximum length to 250 in the database which is great.
However it's set as nvarchar(250) when the database person was expecting varchar(250).
Can somebody please tell me how to set it as a varchar from the model as opposed to an nvarchar?
Use ColumnAttribute to give the datatype
[Column(TypeName = "VARCHAR")]
[StringLength(250)]
public string Comment { get; set; }
Or use fluent API
modelBuilder.Entity<MyEntity>()
.Property(e => e.Comment).HasColumnType("VARCHAR").HasMaxLength(250);
For some reason this older post keeps coming up in my search... so just FYI, using EF6 Core it's combined. The above answer errors out for me.
[Column(TypeName = "VARCHAR(250)")]
public string Comment {get;set;}
Visual Studio 2022 using Net 6 and EF Core 6, database first using the -DataAnnotations parameter creates the following attributes
/* Nullable column */
[StringLength(250)]
[Unicode(false)]
public string? Comment { get; set; }
/* Non-Nullable column */
[StringLength(250)]
[Unicode(false)]
public string Comment { get; set; } = null!;

Update-Database fails in EF Core when creating database generated integer

I'm using EF Core 3.0. I have an AppUser, which extends Microsoft's IdentityUser.
I have to integrate with another API, which forces me to represent
my AppUser with an integer ID. My AppUser PK however, is a string.
I've come up with an idea, that my AppUser will also contain a property
named ShortId, which will be an integer generated by the database when
inserting.
My class declaration therefore looks like this:
public class AppUser : IdentityUser
{
public string Name { get; set; }
public string Surname { get; set; }
...
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ShortId { get; set; }
}
However, after adding migration and running Update-Database there's an error saying
Could not create IDENTITY attribute on nullable column 'ShortId', table 'AspNetUsers'.
I've clearly marked my column with [Required] attribute, therefore it should be clear that this column is not nullable. However, SQL insert statement still looks like this, which seems to produce an error:
CREATE TABLE ... (
...
[ShortId] int NULL IDENTITY,
... )

How to add time part in database (sqlserver) asp.net core

In a asp.net core MVC application, we got a DateTime field LastUpdated. In sqlserver the type of the field is a datetime. If we set the time (and date) in the database, the information is showed correctly, but after an upate the time part is always set to zeros. Code looks like:
[DataType(DataType.DateTime)]
public DateTime LastUpdated { get; set; }
object.LastUpdated = DateTime.UtcNow;
context.Update(object);
Thanks for any help!
The database type was Date, is changed to DataTime, BUT changes were made by hand, and we missed:
entity.Property(e => e.LastUpdated).HasColumnType("date");
which should be:
entity.Property(e => e.LastUpdated).HasColumnType("datetime");
ChrisPratt, and others, thanks!
reading your c# code, I believe that the problem is basically the use of the UTC function, because in your table the datatype is datetime and not datetimeoffset, otherwise, in C# you are trying to send it UTC data, only to test my recomendation is to change it to
[DataType(DataType.DateTime)]
public DateTime LastUpdated { get; set; }
object.LastUpdated = DateTime.Now;
context.Update(object);

How can I remove a Column that has a Constraint with a migration from the DB (ASP.NET MVC5)

Each time I try dropping a column with the following migration:
public partial class RemoveProject_Id1InAspNetUsers2 : DbMigration
{
public override void Up()
{
DropColumn("dbo.AspNetUsers", "Project_Id1");
}
public override void Down()
{
}
}
I get the following error after I Update-Database in PMC:
The index 'IX_Project_Id1' is dependent on column 'Project_Id1'.
The object 'FK_dbo.AspNetUsers_dbo.Projects_Project_Id1' is dependent on column 'Project_Id1'.
ALTER TABLE DROP COLUMN Project_Id1 failed because one or more objects access this column.
This is my AspNetUser Table:
dbo.AspNetUser DB Image
This is my Project Class:
public class Project
{
public int Id { get; set; }
[DisplayName("Project Manager")]
public string ProjectManagerId { get; set; }
// [ForeignKey("ProjectManagerId")]
// public ApplicationUser ProjectManager { get; set; }
//public string ProjectMembersId { get; set; }
//public List<ApplicationUser> ProjectMembers { get; set; }
public virtual ICollection<ProjectResource> OurProjectResources { get; set; }
}
I have tried removing removing all references of ApplicationUser from my Project Class.
PS: I've tried running a Migration of this SQL statement:
Sql("ALTER TABLE AspNetUsers DROP CONSTRAINT FK_AspNetUsers_Projects_Project_Id1"); and it gives an error that :
'FK_AspNetUsers_Projects_Project_Id1' is not a constraint.
Could not drop constraint. See previous errors.
I'm using EF6 Code First Workflow.
This post explains what the problem is, but I will like to understand how to write the migration to remove the column from the DB.
First, you need to specify the constraint name as it is in the error:
'FK_AspNetUsers_Projects_Project_Id1' is not a constraint. Could not
drop constraint. See previous errors.
So, to drop the constraint, we can use:
Sql("ALTER TABLE AspNetUsers DROP CONSTRAINT [FK_dbo.AspNetUsers_dbo.Projects_Project_Id1]");
Then, you get error, that there is an index created on the field:
The index 'IX_Project_Id1' is dependent on column 'Project_Id1'. ALTER
TABLE DROP COLUMN Project_Id1 failed because one or more objects
access this column.
We need to drop the index, too.
Sql("DROP INDEX [IX_Project_Id1] ON dbo.AspNetUsers ");

Resources