Ignore property to the IdentityUser in UI - c#

i'm using abp 4.4.2 with razor and i want to ignore the PhoneNumber,i was do this in my EntityExtensionMapping:
OneTimeRunner.Run(() =>
{
ObjectExtensionManager.Instance.MapEfCoreEntity<IdentityUser>(i => i.Ignore("PhoneNumber"));
});
after the adding Migration i have this generated code
public partial class IdentityUpdate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "PhoneNumber",
table: "AbpUsers");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "PhoneNumber",
table: "AbpUsers",
type: "nvarchar(16)",
maxLength: 16,
nullable: true);
}
}
after the update database, the AbpUsers Table not have the PhoneNumber, However when i want to ignore the field into the user interface in the ModuleExtensionConfigurator,
ObjectExtensionManager.Instance.Modules()
.ConfigureIdentity(identity =>
{
identity.ConfigureUser(user =>
{
user.AddOrUpdateProperty<string>(
"PhoneNumber",
property =>
{
property.UI.OnTable.IsVisible = false;
property.UI.OnCreateForm.IsVisible = false;
property.UI.OnEditForm.IsVisible = false;
});
});
});
The /Identity/Users page and Create/Edit pop-up display again the PhoneNumber.
How can i do ?
Thank you in advance

You need to override the /Identity/Users/index.js file to ignore the PhoneNumber column.
For this create a folder structure like Identity -> Users -> index.js under your Pages folder. Copy and paste the original content of the index.js (that defined in Identity module) file to your index.js file and remove the PhoneNumber column related lines from it.
Check the UI Customization document for more info.
File Structure:
Your index.js file:

Related

Entity Framework Apply Migrations Programatically

I am trying to apply migrations through c# code using entity framework.
I want to drop certain tables(not all of them) and recreate programatically.
I have something like this:
try
{
await dbContext.Database.ExecuteSqlRawAsync("drop table if exists results");
await dbContext.GetInfrastructure().GetService<IMigrator().MigrateAsync("20230104163600_AfterSync");
}
catch (Exception e)
{
throw;
}
I try to run specific custom migration which contains only some of the entities of the DbContext.
Here's the migration:
[DbContext(typeof(TempDbContext))]
[Migration("20230104163600_AfterSync")]
public partial class AfterSync : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "results",
columns: table => new
{
id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
groupId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
},
constraints: table =>
{
table.PrimaryKey("pK_results", x => x.id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "results");
}
}
If I remove the line
await dbContext.Database.ExecuteSqlRawAsync("drop table if exists results");
It says:
Microsoft.Data.SqlClient.SqlException: 'There is already an object named 'results' in the database.'
If I remove the override of Down method in the migration and leave the previous line, the application just crashes.
Can someone help how I can drop and recreate only certain tables not all of them withtout using the database.Migrate() method. Thanks

EF-Core: Table "name" already exists - when trying to update database

ASP Core 3.1 - API. I'm using the latest version of Entity Framework Core.
I have created a table ToDoItem and a ToDoItemContext. After creating the initial migration, and running update-database. I now have that table in my database. I now added a new model called: ToDoItemDescription.
When I try to update the database after creating a new migration, I get the error:
Table 'todoitems' already exists
Further details: I have two contexts, and this is the command I ran:
update-database -context todoitemscontext
I also tried:
update-database -context todoitemscontext -migration AddDescription
Here is my full code:
Models:
public class TodoItem : IEntity
{
public long Id { get; set; }
public string Name { get; set; }
bool IsComplete { get; set; }
}
public class ToDoItemDescription
{
public int id { get; set; }
public string Description { get; set; }
//public int ToDoItemId { get; set; }
public TodoItem TodoItem { get; set; }
}
Context:
public class TodoItemsContext : DbContext
{
public TodoItemsContext(DbContextOptions<TodoItemsContext> options) : base(options) { }
public DbSet<TodoItem> TodoItems { get; set; }
public DbSet<ToDoItemDescription> TodoItemsDescription { get; set; }
}
Migrations:
[DbContext(typeof(TodoItemsContext))]
partial class TodoItemsContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder) {
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.9")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("project.Models.ToDoItemDescription", b => {
b.Property<int>("id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Description")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<long?>("TodoItemId")
.HasColumnType("bigint");
b.HasKey("id");
b.HasIndex("TodoItemId");
b.ToTable("TodoItemsDescription");
});
modelBuilder.Entity("project.Models.TodoItem", b => {
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("IsComplete")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.HasKey("Id");
b.ToTable("TodoItems");
});
modelBuilder.Entity("project.Models.ToDoItemDescription", b =>
{
b.HasOne("project.Models.TodoItem", "TodoItem")
.WithMany()
.HasForeignKey("TodoItemId");
});
#pragma warning restore 612, 618
}
public partial class TodoItems_Initial : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "TodoItems",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(nullable: true),
IsComplete = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TodoItems", x => x.Id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "TodoItems");
}
}
public partial class AddDescription : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "TodoItemsDescription",
columns: table => new
{
id = table.Column<int>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Description = table.Column<string>(nullable: true),
TodoItemId = table.Column<long>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_TodoItemsDescription", x => x.id);
table.ForeignKey(
name: "FK_TodoItemsDescription_TodoItems_TodoItemId",
column: x => x.TodoItemId,
principalTable: "TodoItems",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_TodoItemsDescription_TodoItemId",
table: "TodoItemsDescription",
column: "TodoItemId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "TodoItemsDescription");
}
}
Thank you.
This happens if you have created the database upfront without migrations, for example by using DbContext.Database.EnsureCreated();.
This usually happens when you have a migration that creates a table and the required table is already present in your database so, when you update the database from classes in Migration, it will try to create a table and will fail because the Create command will not be executed as it already has that specific table.
So, in order to avoid the error, you might want to remove the migration class or comment the code in Up() method of that class so it doesn't execute that specific create command.
It could possible help people working with MySQL databases either on Linux and Windows
TL;DR;
I had to rename the table
__efmigrationshistory (note the lowercase) to
__EFMigrationsHistory (note the case)
so the command-line dotnet-ef database update managed to verify all the migrations present on the table __EFMigrationsHistory, and therefore, creating the new field on the table, say Tenant
More
I have to work on Linux, Windows, MacOs boxes. Primarily using Visual Studio code and .net core 3.1.xxx
I use the code-first approach. The MySQL database was firstly, create on the Windows box, where all the tables were created lower cased
Switching to the Linux box, I realized the case was important, so, say, table "tenant" was renamed to "Tenant", by hand.
Once I had to create a new field on the Tenant's c# class, I ran:
dotnet-ef migrations add new-ftpSettings-field and dotnet-ef database update, I got table "Order" already exists. Note I was trying to insert a new field to the "Tenant" table
After a lot of investigation and search, I decided to refresh the database again, and I saw "two suspicious tables" __efmigrationshistory and __EFMigrationsHistory.
I renamed the empty table __EFMigrationsHistory to like Table1 (as a backup), and thus renamed the table __efmigrationshistory to __EFMigrationsHistory
I ran the dotnet-ef database update and the field was properly added to the MySQL database.
*** Like you might have figured this out, running the command-line dotnet-ef database update on Linux was creating a new (and) empty table __EFMigrationsHistory to MySQL database while it had already, a lower cased table on __efmigrationshistory (the good one, created on my Windows box, with all the migrations).
*** This is my first contribution. Any advice is welcome!
Keep safe! Tchau/Au revoir!
I was working through the migration tutorial and had made a mistake sometimes around these steps
dotnet ef migrations add AddBlogCreatedTimestamp
dotnet ef database update
I did the following
deleted the files AddBlogCreatedTimestamp.Designer.cs and AddBlogCreatedTimestamp.cs
inside blogging.db in the table __EFMigrationsHistory i deleted the row that contains 2023__***__AddBlogCreatedTimestamp this was the migration step that failed.
I repeated the migration step dotnet ef migrations add ...
then manually added DropTable(...) to AddBlogCreatedTimestamp.Up()
only then i ran dotnet ef database update
This made sure that in an up-migration the tables would be deleted
Code manually changed
public partial class AddBlogCreatedTimestamp : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
// manually added
migrationBuilder.DropTable(name: "Posts");
migrationBuilder.DropTable(name: "Blogs");
// ... other lines that were created
}
// more other code ...
}
What i still not get is why this is needed. I am not aware to have used anything like EnsureCreated

EFCore AlterColumn MaxLength in Code First Migration

Using Visual Studio 2019 C#.
I'm very new to a code first development approach.
I've made a working ToDo.cs data model and ApplicationDbContext.cs. I ran PM>add-migration to auto-generate the data migration below and then PM>database-update to commit the table to my SQL Server successfully.
FILENAME: 20200815211807_AddedToDoTable.cs
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace BlazorApp.Data.Migrations
{
public partial class AddedToDoTable : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ToDoList",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(maxLength: 15, nullable: false),
Status = table.Column<string>(nullable: false),
DueDate = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ToDoList", x => x.Id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ToDoList");
}
}
}
Now I need to change the string length of the [Name] column from 15 to 25. So, I created a new migration like this:
using Microsoft.EntityFrameworkCore.Migrations;
namespace BlazorApp.Data.Migrations
{
public partial class ChangeNameLength : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("ALTER TABLE ToDoList ALTER COLUMN Name nvarchar(25);");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}
But the Package Manager says: "Object reference not set to an instance of an object." And doesn't make any changes.
What am I doing wrong? Can you help me understand this simple change?
Thanks, Jason
I think my problem had to do with my usage of the Package Manager Console.
I started over using the same migration script and everything worked fine!
PM> add-migration "ChangedNameLength"
Build started...
Build succeeded.
To undo this action, use Remove-Migration.
PM> update-database
Build started...
Build succeeded.
Done.
PM>
Why don't you use the correct migration syntax:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "ToDoList",
maxLength: 25);
}

Ignore schema attribute for SQLite during migration?

I have a shared model that will be used to create both SqlServer and SQLite databases. I added the Table attribute onto each one of my model classes and supplied a schema:
[Table("Sites", Schema = "Common")]
When I migrate the SQLite database using context.Database.Migrate(), I get a NotSupportedException error. I know that SQLite doesn't support schemas, so I was wondering if there was an easy way to ignore the schema attribute during migrate?
Set the schema in code rather than by attribute. That way you can use some method/config to determine the schema, for example:
public class MyContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
if(UsingSqlLite)
{
modelBuilder.Entity<Site>().ToTable("Sites");
}
else
{
modelBuilder.Entity<Site>().ToTable("Sites", "Common");
}
}
//snip
}
Since you are using the same migration on both SQL Server and SQLite, you probably need to ignore the schema inside the migration.
protected override void Up(MigrationBuilder migrationBuilder)
{
if (migrationBuilder.ActiveProvider == "Microsoft.EntityFrameworkCore.Sqlite")
{
migrationBuilder.CreateTable(
name: "Sites",
...);
}
else
{
migrationBuilder.CreateTable(
name: "Sites",
schema: "Common",
...);
}
}

Entity Framework Code first making a column non-nullable

I am using EF code first for my project. I have following code in my DataModel
[HiddenInput(DisplayValue = false)]
public DateTime? PasswordDate { get; set; }
To make this non-nullable I removed '?' and ran Add-Migration command from Package manager console. following migration file was generated.
public partial class PasswordDate : DbMigration
{
public override void Up()
{
AlterColumn("dbo.CertificateInfoes", "PasswordDate", c => c.DateTime(nullable: false));
}
public override void Down()
{
AlterColumn("dbo.CertificateInfoes", "PasswordDate", c => c.DateTime());
}
}
But when I run Update-Database command:
Update-Database -SourceMigration 201309020721215_PasswordDate
I get following error: Cannot insert the value NULL into column 'PasswordDate', table ''; column does not allow nulls. UPDATE fails.
The statement has been terminated.
Kindly suggest the solutions.
That's because you allowed NULL values in that column, then tried to make it non-nullable. It will subsequently try to migrate your existing data into that newly non-nullable column, which will break because you already have NULL values in there.
Two solutions:
1) Change it back to nullable
2) Give it a default value for items that don't have a value.
It's not possible to directly add a non-nullable column to a table that has historical data in the table if no default value is provided for that column.
What I do is
add the column as nullable.
provide an sql script to populate this newly added column.
alter the column to make is as non-nullable.
Code example(with postgres database):
public override void Up()
{
AddColumn("public.YourTableName", "YourColumnName", c => c.Int(nullable: true));
Sql(#"UPDATE ""public"".""YourTableName""
SET ""YourColumnName"" = Value you want to set
");
AlterColumn("public.YourTableName", "YourColumnName", c => c.Int(nullable: false));
}
Another way in EF core 6 would be to alter the migration script where the add column specifies a default value. You can then later drop this default value again.
public partial class AddOrderSource : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
// Add the column with a default value, then drop the default value.
// This creates a non-nullable column without the migration failing because of existing data.
migrationBuilder.AddColumn<int>(
name: "OrderSource",
table: "Orders",
type: "int",
nullable: false,
defaultValue: 1); // Sample default value
migrationBuilder.AlterColumn<int>(
name: "OrderSource",
table: "Orders",
oldDefaultValue: 1,
defaultValue: null
);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "OrderSource",
table: "Orders");
}
}

Categories