ASP.NET Boilerplate - Entity Task Requires Primary Key [duplicate] - c#

I'm training following aspnetboilerplate.com tutorials about developing using their frameworks. I'm stuck at the very first coding point where I have to create a basic table "Task" as stated in the code below.
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Abp.Domain.Entities;
using Abp.Domain.Entities.Auditing;
using Abp.Timing;
namespace WebApp.Tasks
{
[Table("AppTasks")]
public class Task : Entity, IHasCreationTime
{
public const int MaxTitleLength = 256;
public const int MaxDescriptionLength = 64 * 1024; //64KB
[Required]
[StringLength(MaxTitleLength)]
public string Title { get; set; }
[StringLength(MaxDescriptionLength)]
public string Description { get; set; }
public DateTime CreationTime { get; set; }
public TaskState State { get; set; }
public Task()
{
CreationTime = Clock.Now;
State = TaskState.Open;
}
public Task(string title, string description = null)
: this()
{
Title = title;
Description = description;
}
}
public enum TaskState: byte
{
Open = 0,
Completed = 1
}
}
I added the following code in my WebApp DBContext, too.
public class WebAppDbContext : AbpDbContext
{
public DbSet<Task> Tasks { get; set; } //<- This line
public WebAppDbContext(DbContextOptions<WebAppDbContext> options)
: base(options)
{
}
}
The tutorial does not mention any error regarding this code, but every time I make the command
Add-migration "Initial"
in the package manager console, I get this error.
The entity type "Task" requires a primary key to be defined.
I surfed the web for similar errors and each solution I've found does not work for me...
Update #1: I edited the code to this, but the error still remains.
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Abp.Domain.Entities;
using Abp.Domain.Entities.Auditing;
using Abp.Timing;
namespace WebApp.Tasks
{
[Table("AppTasks")]
public class Task : Entity, IHasCreationTime
{
public const int MaxTitleLength = 256;
public const int MaxDescriptionLength = 64 * 1024; //64KB
[Key]
public int Id { get; set; }
[Required]
[StringLength(MaxTitleLength)]
public string Title { get; set; }
[StringLength(MaxDescriptionLength)]
public string Description { get; set; }
public DateTime CreationTime { get; set; }
public TaskState State { get; set; }
public Task()
{
CreationTime = Clock.Now;
State = TaskState.Open;
}
public Task(int id, string title, string description = null)
: this()
{
Id = id;
Title = title;
Description = description;
}
}
public enum TaskState: byte
{
Open = 0,
Completed = 1
}
}
Tutorial link: https://aspnetboilerplate.com/Pages/Documents/Articles/Introduction-With-AspNet-Core-And-Entity-Framework-Core-Part-1/index.html
Update #2: This is the code of WebAppDbContext.cs
using Abp.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
namespace WebApp.EntityFrameworkCore
{
public class WebAppDbContext : AbpDbContext
{
//Add DbSet properties for your entities...
public DbSet<Task> Tasks { get; set; }
public WebAppDbContext(DbContextOptions<WebAppDbContext> options)
: base(options)
{
}
}
}

I've tried to reproduce your codes on my end and I noticed that the problem that you're dealing with is due to the wrong namespaces in the context WebAppDbContext.
using Abp.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
//using System.Threading.Tasks;//<------------ this line causes the error
using WebApp.Tasks; //<----------- You need to add this namespace.
namespace WebApp.EntityFrameworkCore
{
public class WebAppDbContext : AbpDbContext
{
//Add DbSet properties for your entities...
public DbSet<Task> Tasks { get; set; }
public WebAppDbContext(DbContextOptions<WebAppDbContext> options)
: base(options)
{
}
}
}
The problem is due to a conflict in the naming convention. I would recommend changing the name of the entity to something else to prevent further conflicts in the future.

Related

Problems saving to the database

Good morning everyone, I'm learning to use asp.net core in version 6 and I'm having problems saving a record to the database it shows the following error:
SqlException: Invalid object name 'VehiclePerson'.
From what I know, it is actually because it does not find the table in "VehiclePerson" although the connection is made, so I used Scaffolding to obtain the DB from Microsoft SSMS and I created the models and the Context file, so I don't think there are problems with the connection.
This is my VehiclePerson.cs file
using System.Collections.Generic;
namespace APITDCON.Models.QQGUAR01;
public partial class VehiclePerson
{
public string? EmpNumber { get; set; }
public string? Lastname { get; set; }
public string? Firstname { get; set; }
public string? Costcenter { get; set; }
public string? Department { get; set; }
public string? CredentNumber { get; set; }
public string? FromDate { get; set; }
public string? ToDate { get; set; }
public string? Rights { get; set; }
public int Id { get; set; }
}
This is my VehiclePerson.cs file
using Microsoft.EntityFrameworkCore;
using APITDCON.Models.QQGUAR01;
using Microsoft.IdentityModel.Tokens;
using System.Reflection;
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
namespace APITDCON.Data
{
public class APITDCONContext : DbContext
{
public APITDCONContext(DbContextOptions<APITDCONContext> options) : base(options)
{
}
public DbSet<VehiclePerson> VehiclePerson { get; set; }
}
}
This is my VehiclePerson.cs file
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using APITDCON.Models.TANKFARM;
using APITDCON.Models;
using APITDCON.Data;
using System.Collections;
namespace APITDCON.Controllers
{
public class VehiclePersonController1 : Controller
{
private readonly APITDCONContext _apiTDCONContext;
public VehiclePersonController1(APITDCONContext apiTDCONContext)
{
_apiTDCONContext = apiTDCONContext;
}
[HttpGet]
public async Task<IActionResult> Index()
{
List<VehiclePerson> lista = new List<VehiclePerson>();
lista = GetAllDataDrivers();
return View(lista);
}
[HttpGet]
public IActionResult Add()
{
return View();
}
[HttpPost]
public IActionResult Add(VehiclePerson vehiclePersonRequest)
{
string mensaje = "";
var vehicleperson = new VehiclePerson()
{
EmpNumber = vehiclePersonRequest.EmpNumber,
Lastname = vehiclePersonRequest.Lastname,
Firstname = vehiclePersonRequest.Firstname,
Costcenter = vehiclePersonRequest.Costcenter,
Department = vehiclePersonRequest.Department,
CredentNumber = vehiclePersonRequest.CredentNumber,
FromDate = vehiclePersonRequest.FromDate,
ToDate = vehiclePersonRequest.ToDate,
Rights = vehiclePersonRequest.Rights
};
using (var db = new Models.QQGUAR01.Qqguar01Context())
{
var result = new List<VehiclePerson>();
result = (from data in db.VehiclePerson
select new VehiclePerson
{
EmpNumber = data.EmpNumber,
Lastname = data.Lastname,
Firstname = data.Firstname
}).ToList();
}
_apiTDCONContext.VehiclePerson.Add(vehicleperson);
_apiTDCONContext.SaveChanges();
return RedirectToAction("Add");
}
}
}
Database and table
Error
The table name defined in your database context is VehiclePerson, but your table name in the database is VEHICLE_PERSON, the two names do not match.
The easiest way is to change the name of the table VEHICLE_PERSON in the database to VehiclePerson, or change public DbSet<VehiclePerson> VehiclePerson { get; set; } to public DbSet<VehiclePerson> VEHICLE_PERSON { get; set; } in your context.
If you want to avoid similar situations in the future, you can use the following commands to migrate and update the database after adding Scaffolding:
Add-Migration InitialCreate
Update-Database
For more details on scaffolding and connecting to the database, you can refer to this official document.
By default EF will use entity name as table name so you can override it in multiple ways, for example using Table attribute:
[Table("VEHICLE_PERSON")]
public partial class VehiclePerson
{
}

I keep on getting the error that my .NET model needs to have a constructor with 0 args or only optional args?

I am going through a .NET REST API tutorial which does CRUD for command line commands in .NET through a sql server backend. I am using postman to send requests to my endpoints, and if I send a post request to my endpoint it with just a object with all the req for the CommandCreateDTO, it comes up with this error: System.ArgumentException: Commander.Models.Command needs to have a constructor with 0 args or only optional args. (Parameter 'type'). Thoughts?
Controllers
//POST api/commands
[HttpPost]
public ActionResult<CommandCreateDto> CreateCommand(CommandCreateDto commandCreateDto)
{
var commandModel = _mapper.Map<Command>(commandCreateDto);
_repository.CreateCommand(commandModel);
_repository.SaveChanges();
return Ok(commandModel);
}
CommandReadDto
namespace Commander.Dtos
{
public class CommandReadDto
{
public int Id { get; set; }
public string HowTo { get; set; }
public string Line { get; set; }
public CommandReadDto(int Id, string HowTo, string Line)
{
this.Id = Id;
this.HowTo = HowTo;
this.Line = Line;
}
}
}
CommandCreateDto
namespace Commander.Dtos
{
public class CommandCreateDto
{
public string HowTo { get; set; }
public string Line { get; set; }
public string Platform { get; set; }
public CommandCreateDto(string HowTo, string Line, string Platform)
{
this.HowTo = HowTo;
this.Line = Line;
this.Platform = Platform;
}
}
}
Command Model
using System.ComponentModel.DataAnnotations;
namespace Commander.Models
{
public class Command
{
[Key]
public int Id { get; set; }
[Required]
[MaxLength(250)]
public string HowTo { get; set; }
[Required]
public string Line { get; set; }
[Required]
public string Platform { get; set; }
public Command(int Id, string HowTo, string Line, string Platform)
{
this.Id = Id;
this.HowTo = HowTo;
this.Line = Line;
this.Platform = Platform;
}
}
}
CommandsProfile
using AutoMapper;
using Commander.Dtos;
using Commander.Models;
namespace Commander.Profiles
{
public class CommandsProfile : Profile
{
public CommandsProfile()
{
//Source - Target
CreateMap<Command, CommandReadDto>();
CreateMap<CommandCreateDto, Command>();
}
}
}
Your Automapper CreateMap() is trying to map Command class with CommandReadDto. To do that it is expecting default constructor(Constructor without any parameter) in your Command model.
To solve your problem add new default constructor to your Command.Model class.
using System.ComponentModel.DataAnnotations;
namespace Commander.Models
{
public class Command
{
...
public Command(){} //This is missing in your code.
public Command(int Id, string HowTo, string Line, string Platform)
{
this.Id = Id;
this.HowTo = HowTo;
this.Line = Line;
this.Platform = Platform;
}
}
}

How to use FIND() for a MongoDB query on a MVC .net C# project

I'm connecting a MongoDB (Azure) with a MVC .NET C# project. The connection and object definition are working very good so far. My problem is when I try to add the method FIND() to return all the data in the object USER.
My Model:
using System;
using System.Collections.Generic;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
namespace backendnet.Models
{
public class MongoCore
{
public class DB
{
static MongoClient Client = new MongoClient("mongodb://mydbconnect");
static public IMongoDatabase Database = Client.GetDatabase("mydb");
static public IMongoCollection<User> Users = Database.GetCollection<User>("users");
}
public class User
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("email")]
public string Email { get; set; }
[BsonElement("password")]
public string Password { get; set; }
[BsonElement("name")]
public List<DimensionName> Name { get; set; }
[BsonElement("address")]
public List<DimensionAddress> Address { get; set; }
[BsonElement("permissions")]
public List<DimensionPermissions> Permissions { get; set; }
[BsonElement("status")]
public string Status { get; set; }
[BsonElement("created")]
public string Created { get; set; }
[BsonElement("updated")]
public string Updated { get; set; }
}
public class DimensionName
{
[BsonElement("first")]
public string First { get; set; }
[BsonElement("last")]
public string Last { get; set; }
}
public class DimensionAddress
{
[BsonElement("stree")]
public string Stree { get; set; }
[BsonElement("number")]
public string Number { get; set; }
[BsonElement("city")]
public string City { get; set; }
[BsonElement("state")]
public string State { get; set; }
[BsonElement("zipcode")]
public string Zipcode { get; set; }
[BsonElement("type")]
public string Type { get; set; }
}
public class DimensionPermissions
{
[BsonElement("list")]
public string List { get; set; }
[BsonElement("create")]
public string Create { get; set; }
[BsonElement("edit")]
public string Edit { get; set; }
[BsonElement("delete")]
public string Delete { get; set; }
}
}
}
My Controller:
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using backendnet.Models;
using MongoDB.Bson;
namespace backendnet.Controllers
{
public class DashboardController : Controller
{
private string _viewFolder = "../Admin/Dashboard";
public ActionResult Index()
{
var results = new MongoCore.DB();
ViewData["ListPost"] = results.ToJson();
return View (_viewFolder);
}
}
}
My View partial:
<p>HERE: #ViewData["ListPost"]</p>
I get this:
HERE: { }
So I tried adding in the Model -> DB the method Find:
MongoCursor<User> cursor = Users.Find("Email" != "");
But always show an error:
Expression is always 'true' ["Email" != ""]
May anyone show me what I'm missing here?
I Don't See you calling MongoDB.Find()? I have pasted below my code I use for MongoDB C# driver in order to attain a record based on a key:value pair in my MongoDB database.
The Find or FindAsync method both require a BsonDocument Argument, which can be created using the Builders as seen below. Your filter can be empty, which would get all records since you are not filtering out anything.
Once you call the find method, you will be able to access the information using Lambda, or other query methods. You can see in my query i just need one record so i ask for FirstOrDefault. Hope this helps.
async Task<Document> IDal.GetRecordAsync(string key, string value)
{
try
{
if (Database == null) ((IDal)this).StartConnection();
var filter = Builders<BsonDocument>.Filter.Eq(key, value);
var cursor = await Collection.FindAsync(filter);
var bsondocument = cursor.FirstOrDefault();
return bsondocument == null ? null : _converter.ConvertBsonDocumentToDocument(bsondocument);
}
catch (Exception ex)
{
Console.WriteLine(ex);
return null;
}
}
public ActionResult GetUsers()
{
MongoServer objServer = MongoServer.Create("Server=localhost:27017");
MongoDatabase objDatabse = objServer.GetDatabase("DBName");
List UserDetails = objDatabse.GetCollection("Colletion_Name").FindAll().ToList();
return View(UserDetails);
}

Entity Framework Migrations Error : Sequence contains no elements - Timestamp

I have been create a project in VS2015 with entity framework 6 - Code First with
EntityFramework [6.0.0.0]
mysql.data.entity.EF6 [6.8.3.0]
I am try Migrations
command: Add-Migration Initial
error: Sequence contains no matching element
I've been trying a bunch of things, and get the cause of this
[Timestamp]
public byte[] RowVersion { get; set; }
this is the sample model-code first
using MySql.Data.Entity;
using System.Data.Common;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace TokoBersama.Model
{
// Code-Based Configuration and Dependency resolution
[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class MySqlDatabaseConnection : DbContext
{
#region Tabels
public DbSet<returnpenjualan> ReturnPenjualan { get; set; }
#endregion
#region member Event
public MySqlDatabaseConnection()
: base("name=myConnectionString")
{
}
public MySqlDatabaseConnection(DbConnection existingConnection, bool contextOwnsConnection)
: base(existingConnection, contextOwnsConnection)
{
}
//protected override void OnModelCreating(DbModelBuilder modelBuilder)
//{
// base.OnModelCreating(modelBuilder);
//
// Map entity to table
// modelBuilder.Entity<jenis>().MapToStoredProcedures();
//}
#endregion
}
#region tabels
public class returnpenjualan
{
[Key]
[StringLength(12)]
public string frjb { get; set; }
[Required]
[StringLength(12)]
public string fjb { get; set; }
//THE CAUSE OF ERROR
[Timestamp]
public byte[] RowVersion { get; set; }
[Required]
[StringLength(15)]
public string kepada { get; set; }
[Required]
[StringLength(45)]
public string alamat { get; set; }
[StringLength(45)]
public string ktp { get; set; }
[Required]
public double jumlahreturnpenjualan { get; set; }
[Required]
[StringLength(45)]
public string username { get; set; }
}
#endregion
}
ASK
I've search tutorial and the like for using Timestamp in DataAnnotation and get the same answer for using "Timestamp", is there something iam missing to use "Timestamp"???
I have been search "mysql ef6: timestamp" and using this code for the time being, i don't know this the best solution for my question, is there some another solution, please reply
[Column(TypeName = "timestamp")]
public DateTime RowVersion { get; set; }

Working with the DbContext in a non-extended class

I'm getting the following exception when running the code bellow:
The entity type DomainUser is not part of the model for the current context.
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
namespace EFTest
{
class Program
{
static void Main(string[] args)
{
var dbContext = new DbContext(#"Data Source=...\sqlexpress;Initial Catalog=...;Integrated Security=True");
var entities = dbContext.Set<DomainUser>().ToList();
}
}
[Table("DomainUsers")]
public class DomainUser
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
}
}
UPDATE1
It works fine if I do specify the query, so what I'm a missing so that EF generates the query itself. I'm coming from an HNibernate+Fluent background.
class Program
{
static void Main(string[] args)
{
using (var dbContext = new DbContext(#"Data Source=...;Initial Catalog=...;Integrated Security=True"))
{
var entities = dbContext.Database.SqlQuery<DomainUser>("select * from DomainUsers;").ToList();
}
}
}
[Table("DomainUsers")]
public class DomainUser
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
}
UPDATE 2
I got it working with the code bellow, which I had already tested, the thing is, the SomeContext class does not provide any information that I can't provide when I'm using the generic DbContext directly and creating another dummy class just to have some dull properties is really a strange thing to me. They do a lot of type checking anyway, so why not have just one context and if the type used in the Set method is not contained in the context, just do some reflection and add it. I still find it strange that I really need to define a context all the time, let's see what other say
class Program
{
static void Main(string[] args)
{
using (var dbContext = new SomeContext(#"Data Source=...;Initial Catalog=...;Integrated Security=True"))
{
var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
var entities = dbContext.Set<DomainUser>().ToList();
}
}
}
[Table("DomainUsers")]
public class DomainUser
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
}
public class SomeContext : DbContext
{
public SomeContext(string conn) : base(conn) { }
public DbSet<DomainUser> DomainUsers { get; set; }
}
Any ideas of what is going on.
You need to add a property to the DbContext
public DbSet<DomainUser> DomainUsers { get; set; }
Once you have done that you should be able to do
dbContext.DomainUsers.ToList();
Update
I'd say it's always best practice to extend the context as follow
public class FunkyContext : DbContext
{
public DbSet<DomainUser> DomainUsers { get; set; }
}

Categories