how to use datasource configs in another file? - orm

i have this code in schema.prisma:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_TEST_URL")
}
model Account {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
email String #unique #db.VarChar(100)
name String #db.VarChar(100)
password String
}
however I would like to split this file in two.
One file would be called data-source and the other would be called models for example.
Is it possible to do that?
example:
data-source
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_TEST_URL")
}
models
model Account {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
email String #unique #db.VarChar(100)
name String #db.VarChar(100)
password String
}

Related

EF Code First ApplicationUser required DateTime not added

I have a problem registering new users with my new ASP.NET Core Application (Code First).
When registering i'm using an `ApplicationUser` inheriting from `IdentityUser`.
public class ApplicationUser : IdentityUser
{
[Required]
[DefaultValue(5)]
public int ViewerRange { get; set; }
[DefaultValue(false)]
[Required]
public bool IsTACAccepted { get; set; }
public DateTime? TACAccepted { get; set; }
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime Created { get; set; }
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime Modified { get; set; }
public string Role { get; set; }
public ApplicationUser()
{
Modified = DateTime.Now;
Created = DateTime.Now;
}
}
Here´s the part of Register.cshtml.cs
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
UserName = Input.Email,
Email = Input.Email,
Role = Input.Role,
Created = DateTime.Now,
Modified = DateTime.Now,
IsTACAccepted = false,
ViewerRange = 5
};
var result = await _userManager.CreateAsync(user, Input.Password);
//[...]
When registering, the CreateAsync Method fails with the following error:
InvalidOperationException: The value for property 'ApplicationUser.Modified' cannot be set to null because its type is 'System.DateTime' which is not a nullable type.
I can't understand why this is failing.
Can someone explain in detail please?
Kind regards
The reason for the error is that [DatabaseGenerated(DatabaseGeneratedOption.Computed)] says its value is generated by the database, so any assigned value should be ignored. The error shows this isn't the case though.
This isn't the only oddity in the code. [DatabaseGenerated(DatabaseGeneratedOption.Identity)] on a DateTime makes no sense. IDENTITY is used to autoincrement numeric fields. This has no meaning for a DateTime column.
f you want to specify the values yourself, remove the DatabaseGenerated attributes and use them as normal fields. You can avoid the explicit assignment by specifying a default property value, eg
public DateTime Created { get; set; } = DateTime.Now;
public DateTime Modified { get; set; } = DateTime.Now;
It's also possible to configure the database to generate those values. This is described in the docs, in the Generated Values article. Adding Created and Modified columns is described in the Date/time generation section.
A default value constraint for the Created column can be specified with HasDefaultValueSql :
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Created)
.HasDefaultValueSql("getdate()");
}
The Modified timestamp needs a trigger though, which can't be specified in a DbContext's model. This must be created in the database, either directly :
CREATE TRIGGER [dbo].[Blogs_UPDATE] ON [dbo].[Blogs]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF ((SELECT TRIGGER_NESTLEVEL()) > 1) RETURN;
DECLARE #Id INT
SELECT #Id = INSERTED.BlogId
FROM INSERTED
UPDATE dbo.Blogs
SET LastUpdated = GETDATE()
WHERE BlogId = #Id
END
Or through a raw SQL migration that executes the same script :
migrationBuilder.Sql(
#"
EXEC ('CREATE TRIGGER [dbo].[Blogs_UPDATE] ON [dbo].[Blogs]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF ((SELECT TRIGGER_NESTLEVEL()) > 1) RETURN;
DECLARE #Id INT
SELECT #Id = INSERTED.BlogId
FROM INSERTED
UPDATE dbo.Blogs
SET LastUpdated = GETDATE()
WHERE BlogId = #Id
END')");
public DateTime? Created { get; set; }
public DateTime? Modified { get; set; }
Use this, your model needs to be told that there can be null values inside your database, otherwise it will assume there aren't.
UPDATE
**I did not actually carefully noticed your error. Now I will update my answer:-**
I see you did not use this property in your controller. so initially this property nullable. for that you found this issue. first of all, use this property to ignore nullable.
Try like this:-
public DateTime TACAccepted { get; set; } = DateTime.Now;
You can try this because your property it's null. You set this property like the above code for ignoring the nullable. or you remove this property from your model if it's don't need. I think it's will resolve your issue.
Also, make sure that column is declared as a DateTime in your SQL Database.

Api routes for multiple get methods

I have two Get methods in my api as below :
public IHttpActionResult GetCandidateProfilesByProfileID(long id)
{
......
}
and
public IHttpActionResult GetCandidatesBySearchCrietria( string FName= null,string LastName = null, Nullable<DateTime> DoB = null, string City = null,string zipCode = null, string stateID = null,string education = null,
{
...
}
How to configure routes for these? I am having issues invoking them with the default route.
Thanks,
Mahantesh
I assume you are using Web Api 2. You can use the Route attribute:
In order to make http attribute routing available you'll have to add the following line in App_Start\WebApiConfig.cs:
static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
}
}
And then add the route attribute to the method.
[HttpGet]
[Route("GetCandidateProfilesByProfileID")]
public IHttpActionResult GetCandidateProfilesByProfileID(long id)
{
......
}
[HttpGet]
[Route("GetCandidatesBySearchCrietria")]
public IHttpActionResult GetCandidatesBySearchCrietria( string FName= null,string LastName = null, Nullable<DateTime> DoB = null, string City = null,string zipCode = null, string stateID = null,string education = null)
{
...
}
Please note that certain parameters are required. If omitted this will result in Http 404 Not Found.
In asp.net Core you can use the HttpGet attribute:
[HttpGet("GetCandidateProfilesByProfileID")]
public IHttpActionResult GetCandidateProfilesByProfileID(long id)
{
......
}
[HttpGet("GetCandidatesBySearchCrietria")]
public IHttpActionResult GetCandidatesBySearchCrietria( string FName= null,string LastName = null, Nullable<DateTime> DoB = null, string City = null,string zipCode = null, string stateID = null,string education = null)
{
...
}

Assign permission for pages using Code first in asp.net MVC

Here I have created a Model Structure in asp.net mvc:
public class UserModel
{
public int UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public List<Permission> Permissions { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Permission
{
public int PermissionID { get; set; }
public bool IsPermit { get; set; }
public string Name { get; set; }
}
and setting some default values in the list and while I am adding the user in the list I assign the permission for pages to that user through the UI (by checking permission checkboxes), so that user can access only the assigned pages:
public static class Repository
{
public static List<UserModel> GetUsers()
{
List<UserModel> listUsers = new List<UserModel>
{
new UserModel
{
UserId = 1,
UserName = "abc",
Password = "abc",
Permissions = new List<Permission>
{
new Permission
{
PermissionID = 1,
IsPermit = true,
Name = "Page1"
},
new Permission
{
PermissionID = 2,
IsPermit = false,
Name = "Page2"
},
new Permission
{
PermissionID = 3,
IsPermit = false,
Name = "Page3"
},
new Permission
{
PermissionID = 4,
IsPermit = false,
Name = "Page4"
}
},
FirstName = "Rohit",
LastName = "Sharma"
},
new UserModel
{
UserId = 2,
UserName = "xyz",
Password = "xyz",
Permissions = new List<Permission>
{
new Permission
{
PermissionID = 1,
IsPermit = false,
Name = "Page1"
},
new Permission
{
PermissionID = 2,
IsPermit = true,
Name = "Page2"
},
new Permission
{
PermissionID = 3,
IsPermit = true,
Name = "Page3"
},
new Permission
{
PermissionID = 4,
IsPermit = true,
Name = "Page4"
}
},
FirstName = "Rahul",
LastName = "Sharma"
}
};
return listUsers;
}
}
Now I want to do the same by using code first approach of database with the help of DbContext class. I have a static list of page permission in a database table (Id =1, Name=Page1; Id =2, Name=Page2; Id =3, Name=Page3; Id =4, Name=Page4).
I am confused while creating model structure for database. Please guide me how to create model structure and mapping of structure with the tables.
I have a table (Permission) in my database with default rows.
ID Name
1 Page1
2 Page2
3 Page3
4 Page4
Now, when I adding user I assigning permission to that user through static checkboxes (Page1, Page2, Page3 and Page4). That’s why I created static table in a database that contains list of pages. My User table is initially blank.
User
Id int NotNull
UserName nvarchar(100) AllowNull
Password nvarchar(100) AllowNull
FirstName nvarchar(100) AllowNull
LastName nvarchar(100) AllowNull
You can use below mentioned structure when you're using code first.You have to maintain conventions when you're using code first (But can be changed when you're using Fluent API).
Model Classes
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<Permission> Permissions { get; set; }
}
public class Permission
{
public int Id { get; set; }
public bool IsPermit { get; set; }
public string Name { get; set; }
public virtual User { get; set; }
}
Tables (This will auto generate.But If you want you can create manually also)
Users
Id int NotNull
UserName nvarchar(100) AllowNull
Password nvarchar(100) AllowNull
FirstName nvarchar(100) AllowNull
LastName nvarchar(100) AllowNull
Permissions
Id int NotNull
IsPermit bit AllowNull
Name nvarchar(100) AllowNull
User_Id int NotNull
DbContext Derived Class
public class UserEntities : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Permission> Permissions { get; set; }
}
Fore more information check Code-First Development with Entity Framework
I hope this will help to you.

Castle Active Record fails to initialize

I am implementing a relatively simple model of user management using Castle Active Record with NHibernate on top of MySql, and I have ran into an issue.
Let us say, I have two tables _users and _passwords described by the following SQL create statements
CREATE TABLE _users (
id bigint(20) NOT NULL AUTO_INCREMENT,
username char(32) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY username_UQ (username),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE _passwords (
id bigint(20) NOT NULL AUTO_INCREMENT,
creation_date datetime NOT NULL,
user_id bigint(20) NOT NULL,
password_hash char(64) NOT NULL,
valid_end_date datetime NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY user_id_password_UQ (user_id,password_hash),
KEY user_passwords_FK (user_id),
CONSTRAINT user_passwords_FK FOREIGN KEY (user_id) REFERENCES _users (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The idea is to keep a primitive password history, therefore, the passwords are kept in a separate table _passwords, which has many-to-one relation with the _users table.
Now, the following C# code models this structure using Castle Active Records
namespace DataEntities
{
[ActiveRecord("_users")]
public class User : ActiveRecordBase<User>
{
[PrimaryKey(PrimaryKeyType.Identity, "id", Access = PropertyAccess.NosetterLowercase)]
public ulong Id
{
get;
set;
} // Id
[Property("username", ColumnType = "String", NotNull = true, Unique = true)]
[ValidateIsUnique]
public string Username
{
get;
set;
} // Username
[HasMany(typeof(Password))]
public IList<Password> Passwords
{
get;
set;
} // Passwords
public string ValidPasswordHash
{
get
{
DateTime l_dtNow = DateTime.Now;
if (Passwords.Count != 1 || Passwords[0].ValidFrom >= l_dtNow || Passwords[0].ValidUntil <= l_dtNow)
{
throw new Exception();
}
return Encoding.UTF8.GetString(Passwords[0].PasswordHash);
}
} // ValidPasswordHash
public static User FindByCredentials(string i_sUsername, string i_sHashedPassword)
{
return FindOne(Restrictions.Eq("Username", i_sUsername), Restrictions.Eq("ValidPasswordHash", i_sHashedPassword));
} // FindByCredentials
} // User
[ActiveRecord("_passwords")]
public class Password : ActiveRecordBase<Password>
{
[PrimaryKey(PrimaryKeyType.Identity, "id", Access = PropertyAccess.NosetterLowercase)]
public ulong Id
{
get;
set;
} // Id
[BelongsTo("user_id", NotNull = true, UniqueKey = "_passwords_UQ1")]
public ulong UserId
{
get;
set;
} // UserId
[Property("password_hash", ColumnType = "UInt64", NotNull = true, UniqueKey = "_passwords_UQ1")]
public byte[] PasswordHash
{
get;
set;
} // PasswordHash
[Property("creation_date", ColumnType = "DateTime", NotNull = true)]
public DateTime ValidFrom
{
get;
set;
} // ValidFrom
[Property("valid_end_date", ColumnType = "DateTime", NotNull = true)]
public DateTime ValidUntil
{
get;
set;
} // ValidUntil
} // Password
} // DataEntities
and on my application start the framework is initialized
try
{
ActiveRecordStarter.Initialize(ActiveRecordSectionHandler.Instance, typeof(Password),
typeof(User));
}
catch (Exception l_excpt)
{
// handle exception
}
At the end, when this code runs, it generates the following exception:
Castle.ActiveRecord.Framework.ActiveRecordException: ActiveRecord tried to infer details about the relation User.Passwords but it could not find a 'BelongsTo' mapped property in the target type DataEntities.Password
at Castle.ActiveRecord.Framework.Internal.SemanticVerifierVisitor.VisitHasMany(HasManyModel model) in c:\daten\dev\External\Castle\AR2.0\ActiveRecord\Castle.ActiveRecord\Framework\Internal\Visitors\SemanticVerifierVisitor.cs:line 544
at Castle.ActiveRecord.Framework.Internal.AbstractDepthFirstVisitor.VisitNodes(IEnumerable nodes) in c:\daten\dev\External\Castle\AR2.0\ActiveRecord\Castle.ActiveRecord\Framework\Internal\Visitors\AbstractDepthFirstVisitor.cs:line 45
at Castle.ActiveRecord.Framework.Internal.AbstractDepthFirstVisitor.VisitModel(ActiveRecordModel model) in c:\daten\dev\External\Castle\AR2.0\ActiveRecord\Castle.ActiveRecord\Framework\Internal\Visitors\AbstractDepthFirstVisitor.cs:line 59
at Castle.ActiveRecord.Framework.Internal.SemanticVerifierVisitor.VisitModel(ActiveRecordModel model) in c:\daten\dev\External\Castle\AR2.0\ActiveRecord\Castle.ActiveRecord\Framework\Internal\Visitors\SemanticVerifierVisitor.cs:line 122
at Castle.ActiveRecord.Framework.Internal.AbstractDepthFirstVisitor.VisitNodes(IEnumerable nodes) in c:\daten\dev\External\Castle\AR2.0\ActiveRecord\Castle.ActiveRecord\Framework\Internal\Visitors\AbstractDepthFirstVisitor.cs:line 45
at Castle.ActiveRecord.ActiveRecordStarter.RegisterTypes(ISessionFactoryHolder holder, IConfigurationSource source, IEnumerable`1 types, Boolean ignoreProblematicTypes) in c:\daten\dev\External\Castle\AR2.0\ActiveRecord\Castle.ActiveRecord\Framework\ActiveRecordStarter.cs:line 927
at Castle.ActiveRecord.ActiveRecordStarter.Initialize(IConfigurationSource source, Type[] types) in c:\daten\dev\External\Castle\AR2.0\ActiveRecord\Castle.ActiveRecord\Framework\ActiveRecordStarter.cs:line 202
at Global.Application_Start(Object sender, EventArgs e) in C:\Projects Code\xyz\Global.asax.cs:line 22
Well, I have stared endlessly at the UserId property of the Password class, I have googled, and now I am quite lost. So the community is my last hope... Can anybody help me understanding what causes this exception and how to fix it?
Thank you all in advance for your replies and comments.
You should have a User User { get; set; } reference property instead of a foreign key.
The official docs are a good place to start.

Help with attribute mapping my class

My class looks like:
public class User
{
public virtual int ID {get;set;}
public virtual string Username {get;set;}
}
Table:
User
-UserID INT NOT NULL,
-Username NVARCHAR(50) NOT NULL
UserID is the PK, IDENTITY.
How would I use nhibernate attribute mapping for my class?
[Class(0, Name = "User", Table = "Users")]
public class User
{
[Id(0, Name = ID", Type = "Int32", Column = "ID")]
[Generator(1, Class = "native")]
public virtual int ID {get;set;}
[Property(0, Name = "Username", Column = "Username", Type = "string", NotNull = true , Length = 50)]
public virtual string Username {get;set;}
}