Get "No persister for" Error in Fluent NHibernet - asp.net

I am new in Fluent NHibernet and i am using Fluent NHibernet in my asp.net application
this is my Poco class
public virtual int CategoryId { get; set; }
public virtual string CategoryName { get; set; }
public virtual bool IsActive { get; set; }
public virtual bool IsDeleted { get; set; }
My Mapping Class
public class clsCategoryMap : ClassMap<clsCategory>
{
public clsCategoryMap()
{
Id(x => x.CategoryId).Column("CategoryId").GeneratedBy.Assigned().Not.Nullable();
Map(x => x.CategoryName).Column("CategoryName").Not.Nullable();
Map(x => x.IsActive).Column("IsActive").Not.Nullable();
Map(x => x.IsDeleted).Column("IsDeleted").Not.Nullable();
Table("tblCategory");
}
}
Poco class and Mapping class both saprated in class Liberar like: DAL for Poco class and BLL For Mapping class.
And i create helper class it's below:
public class FNHelper
{
private static ISessionFactory _sessionfactory;
private static ISessionFactory SessionFactory
{
get
{
if (_sessionfactory == null) { InitializationSessionFactory(); }
return _sessionfactory;
}
}
private static void InitializationSessionFactory()
{
_sessionfactory = Fluently.Configure()
.Database(
MsSqlConfiguration.MsSql2008
.ConnectionString(#"Server=test\SQLEXPRESS;Database=TestDB;User ID=sa;Password=root;")
.DefaultSchema("dbo")
.ShowSql()
)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<clsCategory>())
.ExposeConfiguration((cfg => new SchemaUpdate(cfg).Execute(true, true)))
.BuildSessionFactory();
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
private static void BuildSchema(NHibernate.Cfg.Configuration configuration)
{
String SqliteRefFileName = #"D:\Projects\MeshpsDB.sql";
if (File.Exists(SqliteRefFileName))
File.Delete(SqliteRefFileName);
new SchemaExport(configuration)
.Create(true, true);
}
}
And finally i am doing in my form it's below:
protected void btnSave_Click(object sender, EventArgs e)
{
using (var session = FNHelper.OpenSession())
{
using (var tranction = session.Transaction)
{
var objCategory = new clsCategory
{
CategoryId = 0,
CategoryName = txtName.Text.Trim(),
IsActive = true,
IsDeleted = false
};
session.Save(objCategory);
tranction.Commit();
}
}
}
when i click on button then i am getting
so every one please tell me how can i solve this issue.

change m.FluentMappings.AddFromAssemblyOf<clsCategory>() to m.FluentMappings.AddFromAssemblyOf<clsCategoryMap>() because its the mappingss you want to add and these reside in another assembly.

Related

main page doesn't get updated after initialisation is finished

I am having issues with binding context, after initialisation it doesn't update. so the button is not clickable and the name label doesn't update as its stated in ctor. This is the first and only page.
Page
<Label x:Name="NamesLabels" Text="{Binding Name}"/>
<Button HorizontalOptions="FillAndExpand" Text="Show scanner" Command="{Binding ShowScannerCommand}"/>
public MainPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
BindingContext = new MainPageViewModel();
}
//also tried
protected override void OnAppearing()
{
base.OnAppearing();
var context = new MainPageViewModel();
BindingContext = context;
name.Source = context.Name;
btn.Command = context.ShowScannerCommand;
}
ViewModel
public string Name
{
get => _name;
private set
{
_name = value;
NotifyPropertyChanged("Name");
}
}
public ICommand ShowScannerCommand { get; private set; }
public MainPageViewModel()
{
Name = "rwatag";
//have tried _name = "rwatag";
ShowScannerCommand = new Command(() => ShowScanner());
}
void ShowScanner()
{
System.Diagnostics.Debug.WriteLine("result");
}
this is what I get after clicking on button and when debugging the code doesn't get fired
[InputEventReceiver] Slow Input: took 118ms in dispatching, now at finishInputEvent (MotionEvent: event_seq=0, seq=78288, action=ACTION_DOWN)
Resolved pending breakpoint at '/Users/de/Projects/Demo/Demo/View/MainPage.xaml.cs:26,1' to void Demo.MainPage.OnAppearing () [0x00014].
[zygote] Do partial code cache collection, code=61KB, data=59KB
[zygote] After code cache collection, code=61KB, data=59KB
[zygote] Increasing code cache capacity to 256KB
I use your code and it works well on my side. I just add a string _name { get; set; } property and implement the INotifyPropertyChanged interface in MainPageViewModel.
Here is the code example:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
BindingContext = new MainPageViewModel();
}
}
public class MainPageViewModel : INotifyPropertyChanged
{
string _name { get; set; }
public string Name
{
get => _name;
private set
{
_name = value;
OnPropertyChanged("Name");
}
}
public ICommand ShowScannerCommand { get; private set; }
public MainPageViewModel()
{
Name = "rwatag";
ShowScannerCommand = new Command(() => ShowScanner());
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
void ShowScanner()
{
System.Diagnostics.Debug.WriteLine("result");
}
}

Delete Child entity Record in EF core after comparing

I have a Child entity of Aggregate Entity with one-to-many relation, and in the child, there is a list containing the parent id. the data coming from the front-end is a list of object and if it is no different from what comes to back-end I will do nothing with it. otherwise, I will remove what has been removed and add what has been added to the table.
I am new at EF CORE and I am trying to apply this login in this relation.
if (child.list.SuccessorId == parent.vehicleCategoryId) => ignore;
if(!child.list.contain(parent.vehicleCategoryId)
remove(parent.vehicleCategoryId) => //delete record with vehicleCategoryId
else
add(child)
here is my entities.
public class VehicleCategory : LookupAggregateRoot<VehicleCategory>
{
#region Constructor
private VehicleCategory()
{
_successors = new List<VehicleSuccessorCategory>();
}
#endregion
#region Data
public virtual LocalizedText Name { get; set; }
public virtual long Sequence { get; set; }
private readonly List<VehicleSuccessorCategory> _successors;
public IEnumerable<VehicleSuccessorCategory> Successors
{
get => _successors.AsReadOnly();
set => throw new NotImplementedException();
}
#endregion
#region Behaviour
public void AddSuccessor(VehicleSuccessorCategory entrySuccessorCategory)
{
_successors.Add(entrySuccessorCategory);
}
public void RemoveSuccessor(VehicleSuccessorCategory entrySuccessorCategory)
{
_successors.Remove(entrySuccessorCategory);
}
}
public class VehicleSuccessorCategory : ID365Entity<int>, IEnumerable
{
#region Constructor
public int Id { get; set; }
public int SuccessorId { get; set; }
public VehicleSuccessorCategory(int order)
{
Order = order;
}
#endregion
#region Data
public int Order { get; set; }
#endregion
public bool IsTransient()
{
throw new NotImplementedException();
}
public IEnumerator GetEnumerator()
{
yield return Id;
yield return Order;
}
}
I tried
VehicleCategory vehicleCategory = _genericRepository.Get(aggregate.Id);
foreach (var successorCategory in aggregate.Successors)
{
var successorCategoryToRemove =
vehicleCategory.Successors.Where(e => e.SuccessorId == successorCategory.SuccessorId);
foreach (var vehicleSuccessorCategory in successorCategoryToRemove)
vehicleCategory.RemoveSuccessor(vehicleSuccessorCategory);
}

I can not create instace of DBContext

I have model:
public class Department
{
public int DepartmentID { get; set; }
[Required]
[UniqueDepartmentName]
public string Name { get; set; }
public List<Person> Persons { get; set; }
}
And DBcontext:
public class InstituteContext : DbContext
{
public InstituteContext (DbContextOptions<InstituteContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Department>().HasIndex(p => p.Name).IsUnique();
}
public DbSet<Institute.Models.Department> Department { get; set; }
}
As you see property "NAME" i make unique.
For validation i create My validation Attribute:
public class UniqueDepartmentName : ValidationAttribute
{
public override bool IsValid(object value)
{
var db = new InstituteContext();
}
}
But i can not create instance of InstituteContext, because constructor need parameters.
How i can create instance of InstituteContext? Or what should i pass to constructor in parameters?
Try this:
public class UniqueDepartmentName : ValidationAttribute
{
public override bool IsValid(object value)
{
var connectionString = "Your ConnectionString"
var options = new DbContextOptionsBuilder<InstituteContext>()
.UseSqlServer(new SqlConnection(connectionString)).Options;
using (var dbContext = new BloggingContext(options))
{
// Do necessary staffs here with dbContext
}
}
}
Your DbContextOptions method is in the wrong place, your constructor can be empty, and you need to add the method OnConfiguring, which receives the DbContextOptions.
Something like:
public DbSet<Department> Department { get; private set; }
protected override void OnConfiguring(DbContextOptionsBuilder options) {
// In my case I'm passing the connection string in this method below
options.UseSqlServer("Data Source=DATABASEIP;Initial Catalog=DATABASETABLE;" +
"User ID=USER;Password=PASSWORD");
}

EF Core - Many-to-Many relationship doesn't work

I'm having some problems trying to use the many-to-many relationship in EF Core 2.0. Here is me code:
Here are my entities:
User
public class User : IdentityUser
{
private User()
{
}
public String Name { get; private set; }
public ICollection<UserCourse> UserCourses { get; private set; }
public static User Create(string name, string username, string email)
{
var instance = new User
{
Id = Guid.NewGuid().ToString(),
};
instance.Update(name, username, email);
return instance;
}
public void Update(string name, string username, string email)
{
Name = name;
UserName = username;
Email = email;
}
public void Update(UserCreatingModel model)
{
this.UserName = model.Username;
this.Name = model.Name;
this.Email = model.Email;
}
public void Update(UserCourse userCourse)
{
if (UserCourses == null)
{
UserCourses = new List<UserCourse>() {userCourse};
}
else
{
UserCourses.Add(userCourse);
}
}
}
Course entity
public class Course
{
private Course() { }
public Guid Id { get; private set; }
public string Name { get; private set; }
public int Year { get; private set; }
public int Semester { get; private set; }
public List<Lesson> Lessons { get; private set; }
public ICollection<UserCourse> UserCourses { get; private set; }
public static Course Create(string name, int year, int semester, List<Lesson> lessons, List<User> professors)
{
var instance = new Course { Id = Guid.NewGuid() };
instance.Update(name, year, semester, lessons);
return instance;
}
public static Course Create(string name, int year, int semester)
{
var instance = new Course { Id = Guid.NewGuid() };
instance.Update(name, year, semester);
return instance;
}
public void Update(string name, int year, int semester, List<Lesson> lessons)
{
Name = name;
Year = year;
Semester = semester;
Lessons = lessons;
}
public void Update(string name, int year, int semester)
{
Name = name;
Year = year;
Semester = semester;
}
public void Update(UserCourse userCourse)
{
if (UserCourses == null)
{
UserCourses = new List<UserCourse>(){userCourse};
}
else
{
UserCourses.Add(userCourse);
}
}
public void Update(List<Lesson> lessons)
{
this.Lessons = lessons;
}
}
Join entity
public class UserCourse
{
private UserCourse() { }
public string UserId { get; private set; }
public User User { get; private set; }
public Guid CourseId { get; private set; }
public Course Course { get; private set; }
public static UserCourse CreateUserCourse(string userId, User user, Guid coursId, Course course)
{
var instance = new UserCourse
{
UserId = userId,
User = user,
CourseId = coursId,
Course = course
};
return instance;
}
}
This is my database context
public sealed class DatabaseContext : IdentityDbContext<User>, IDatabaseContext
{
public static readonly LoggerFactory MyLoggerFactory
= new LoggerFactory(new[] {new ConsoleLoggerProvider((_, __) => true, true)});
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
Database.EnsureCreated();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLoggerFactory(MyLoggerFactory) // Warning: Do not create a new ILoggerFactory instance each time
.EnableSensitiveDataLogging();
public new DbSet<User> Users { get; set; }
public DbSet<Course> Courses { get; set; }
public DbSet<Lesson> Lessons { get; set; }
public DbSet<UserCourse> UserCourses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Lesson>()
.HasOne(p => p.Course)
.WithMany(b => b.Lessons)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<UserCourse>()
.HasKey(uc => new {uc.UserId, uc.CourseId});
modelBuilder.Entity<UserCourse>()
.HasOne(uc => uc.User)
.WithMany(u => u.UserCourses)
.HasForeignKey(uc => uc.UserId);
modelBuilder.Entity<UserCourse>()
.HasOne(uc => uc.Course)
.WithMany(c => c.UserCourses)
.HasForeignKey(uc => uc.CourseId);
}
}
This is the repository where I try to add the 2 existing entities user and course to the joining table with the method AddCoursToProfessor
public class CoursesRepository : ACrudRepository<Course, Guid>, ICoursesRepository
{
public CoursesRepository(IDatabaseContext databaseContext) : base(databaseContext)
{
}
public override IReadOnlyList<Course> GetAll() => _databaseContext.Courses.Include(c => c.Lessons).Include(p => p.UserCourses).ToList();
public override Course GetById(Guid id)
=> _databaseContext.Courses.Include(c => c.Lessons).AsNoTracking().FirstOrDefault(c => c.Id.Equals(id));
public void AddCoursToProfessor(string profId, Guid coursId)
{
var professor = _databaseContext.Users.Include(u => u.UserCourses).FirstOrDefault(u => u.Id.Equals(profId));
var course = GetById(coursId);
var profCourse = UserCourse.CreateUserCourse(profId, professor, coursId, course);
professor.Update(profCourse);
_databaseContext.Users.Update(professor);
_databaseContext.SaveChanges();
}
}
The problem seems to be that when trying to add in the joining table, EF tries to add the course entity into it's table again and I get primary key violation error. I tried different approaches and none of them seem to work. I tried adding directly in UserCourse table but that would try to add both entities into their own tables, I tried deleting the entities before adding them to the join table, that didn't work either. I ran out of ideas, if someone has other ideas, or dealt with similar situations that would be much of help.
I forgot to mention that if I try to add a course by it self or an user, that would work, they both would be added to their tables, so I don't think that the problem is with the DB but with the configuration of the many-to-many relatonship
Ok... so I recently solved the problem. The problem was generated by the GetCourseById method because I was getting the entity AsNoTracking. The entity was not under the EF scope so it tried to create it.
As far as I know here's how I implement a MTM model.
In this instance, there are 3 parameters to take note.
CurrencyPairId is not unique. its a 2-unique parameter.
CurrencyId and IsMain is unique.
This is a trading exchange-styled composite key. i.e. EURUSD
EUR => Main Pair, USD => Counter Pair.
The class
/// <summary>
/// Partial currency pair.
/// </summary>
public class PartialCurrencyPair
{
public long CurrencyId { get; set; }
public long CurrencyPairId { get; set; }
public bool IsMain { get; set; } = false;
public CurrencyPair CurrencyPair { get; set; }
public Currency Currency { get; set; }
}
Currency
public class Currency : BaseEntityModel
{
[Key]
public long Id { get; set; }
public ICollection<PartialCurrencyPair> PartialCurrencyPairs { get; set; }
}
CurrencyPair
public class CurrencyPair : BaseEntityModel
{
[Key]
public long Id { get; set; }
// =========== RELATIONS ============ //
public ICollection<PartialCurrencyPair> PartialCurrencyPairs { get; set; }
}
Some of the mappings
in Currency;
entity.HasMany(c => c.PartialCurrencyPairs).WithOne(pcp => pcp.Currency).HasForeignKey(pcp => pcp.CurrencyId).OnDelete(DeleteBehavior.Restrict);
in CurrencyPair
entity.HasMany(cp => cp.PartialCurrencyPairs).WithOne(pcp => pcp.CurrencyPair).HasForeignKey(pcp => pcp.CurrencyPairId).OnDelete(DeleteBehavior.Restrict);
PartialCurrencyPair
builder.Entity<PartialCurrencyPair>(entity =>
{
entity.HasKey(pcp => new { pcp.CurrencyPairId, pcp.IsMain }).HasName("PartialCurrencyPair_CK_CurrencyPairId_IsMain");
});
Judging by your Course.cs, there's no Collection for UserCourse and why is it static?
Update, 2021 APR 6
EF Core has official documentation for the current practise for implementing MTM.
https://learn.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key#many-to-many

Entity Framework CTP5, code-first. Nested query error

I have the following classes:
public class Category
{
public int CategoryId { get; set; }
public string Name { get; set; }
}
public partial class CategoryMap : EntityTypeConfiguration<Category>
{
public CategoryMap()
{
this.HasKey(c => c.CategoryId);
this.Property(c => c.Name).IsRequired().HasMaxLength(400);
}
}
public class MyObjectContext : DbContext
{
public MyObjectContext(string connectionStringName)
: base(connectionStringName)
{
}
public DbSet<Category> Categories { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new CategoryMap());
base.OnModelCreating(modelBuilder);
}
}
Now when I run the following code I get an exception (GenericArguments[0], 'System.Int32', on 'System.Data.Entity.Internal.Linq.ReplacementDbQueryWrapper`1[TEntity]' violates the constraint of type 'TEntity')
DbDatabase.SetInitializer<MyObjectContext>(new DropCreateDatabaseIfModelChanges<MyObjectContext>());
using (var context = new MyObjectContext("NopSqlConnection"))
{
var query1 = from c in context.Categories
select c.CategoryId;
var test1 = query1.ToList(); //works fine
var query2 = from c in context.Categories
where query1.Contains(c.CategoryId)
orderby c.Name descending
select c;
var test2 = query2.ToList(); //throws the exception
}
Any suggestions?
It seems to work fine if you specify 'where' clause on query1

Resources