Display new table in the database MVC4 asp.net - c#

I am cluless, i dont know why my database its showing in the deafult connection in the database , I am programing in C# MVC4 asp.net using razor technology,
here is my UserAccountContext
public class UserAccountContext : DbContext
{
public UserAccountContext()
: base("DefaultConnection")
{
}
public DbSet<UserAccount> UserAccounts { get; set; }
// Methods...
public DbSet<UserProfile> UserProfiles { get; set; }
// Methods...
public IQueryable<UserAccount> GetAll()
{
IQueryable<UserAccount> query = this.UserAccounts;
return query;
}
public UserAccount GetSingle(string _UserName)
{
UserAccount Query = this.GetAll().FirstOrDefault(x => x.UserName == _UserName);
return Query;
}
public void Save(UserAccount _UserAccount)
{
if (_UserAccount.ID == 0)
{
this.UserAccounts.Add(_UserAccount);
this.SaveChanges();
}
else
{
this.SaveChanges();
}
}
}
And here is my UserAccount Model
public class UserAccount
{
// Attributes turns into fields in the database
// These attributes persist in the database
[Key]
public int ID { get; set; }
public int UserId { get; set; }
public string UserName { get; set; }
public string WhoVoted { get; set; }
public double NumberOfVotes { get; set; }
// The following attributes will not persist in the DB
public string UserErrorMessage = string.Empty; // Volatile Variable
// Methods...
public UserAccount() { } //Constructor... This is needed to create the DB Table
public UserAccount(int _UserId, string _UserName) // Other Constructor
{
this.ID = 0;
this.UserId = _UserId;
this.UserName = _UserName;
this.NumberOfVotes = 0.0;
this.WhoVoted = string.Empty;
}
}
I have everything, i dont know how to deal with the database , Lookking forward for any help. Thank you in advance!

Related

How to delete records from database correctly

While I was trying to delete records from databse in wep api, occurred with error "System.InvalidOperationException: There is already an open DataReader associated with this Connection which must be closed first".
Method body:
[HttpDelete]
[Route("/DeleteUrls")]
public async Task<IActionResult> DeleteUrls(string userName)
{
var user = _dataContext.Users.FirstOrDefault(x => x.UserName == userName);
if (user==null)
{
return BadRequest("No user with such Username");
}
switch (user.IsAdmin)
{
case true:
var longUrls2Remove = _dataContext.Urls.AsQueryable();
foreach (var item in longUrls2Remove)
{
var shortUrl2Remove = _dataContext.ShortedUrls.FirstOrDefault(x => x.Url == item);
_dataContext.ShortedUrls.Remove(shortUrl2Remove);
_dataContext.Urls.Remove(item);
}
await _dataContext.SaveChangesAsync();
return Ok();
case false:
var longUrlsToRemove = _dataContext.Urls.Where(x => x.UserCreatedBy == user);
foreach (var item in longUrlsToRemove)
{
var shortUrlToRemove = _dataContext.ShortedUrls.FirstOrDefault(x => x.Url == item);
_dataContext.ShortedUrls.Remove(shortUrlToRemove);
_dataContext.Urls.Remove(item);
await _dataContext.SaveChangesAsync();
return Ok();
}
return BadRequest();
}
}
Logic is to delete all records if user is admin, and only his own if he isnt.
Database structure:
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public bool IsAdmin { get; set; }
public List<Url> Urls { get; set; }
}
public class Url
{
public int Id { get; set; }
public string OriginalUrl { get; set; }
public DateTime CreatedAt { get; set; }
public int UserId { get; set; }
public User UserCreatedBy { get; set; }
public ShortUrl ShortUrl { get; set; }
}
public class ShortUrl
{
public int Id { get; set; }
public string ShortedUrl { get; set; }
public int UrlId { get; set; }
public Url Url { get; set; }
}
Obviously the problem is with another open connetion, but I dont get any idea how to implement this method correctly.
Reason : you are executing two or more queries at the same time.
Solution : add ToList() after query.
var longUrlsToRemove = _dataContext.Urls.Where(x => x.UserCreatedBy == user).ToList()
IQueryable is not a collection of entities in memory.
ToList() stores records in memory. So you don't connect to database in every loop.

Nested Expression method call in Linq.Select()

I use .Select(i=> new T{...}) after every db hit manually to convert my entity objects into DTO object. Here are some sample entities and DTOS
User Entity;
public partial class User
{
public int Id { get; set; }
public string Username { get; set; }
public virtual UserEx UserEx { get; set; }
}
User DTO;
public class UserDTO
{
public int Id { get; set; }
public string Username { get; set; }
}
UserEx entity;
public class UserEx
{
public int UserId { get; set; }
public string MyProperty1 { get; set; }
public virtual User User { get; set; }
}
UserEx DTO;
public class UserExDTO
{
public int MyProperty1 { get; set; }
public UserDTO UserModel { get; set; }
}
My Conversion Expression Methods;
public static class ConversionExpression
{
public static Expression<Func<UserEx, UserExDTO>> GetUserExDTOConversionExpression()
{
return userEx => new UserExDTO
{
MyProperty1 = userEx.MyProperty1,
UserModel = new UserDTO
{
Id = userEx.User.Id,
Username = userEx.User.Username
}
};
}
public static Expression<Func<User, UserDTO>> GetUserDTOConversionExpression()
{
return user => new UserDTO
{
Id = user.Id,
Username = user.Username
};
}
}
And my current usage for UserDTO;
myContext.Users
.Select(ConversionExpression.GetUserDTOConversionExpression())
.ToList();
for UserExDTO;
myContext.UserExes
.Select(ConversionExpression.GetUserExDTOConversionExpression())
.ToList();
Apologize for long introduction, now here is my question ;
I need to group
new UserDTO
{
Id = userEx.User.Id,
Username = userEx.User.Username
}
due to single point of concerns. So I want something like this;
public static Expression<Func<UserEx, UserExDTO>> GetUserExDTOConversionExpression()
{
return userEx => new UserExDTO
{
MyProperty1 = userEx.MyProperty1,
//this line does not behave like the other one
UserModel = userEx.User.GetUserDTOConversionExpression()
};
}
Is there any way to do that or should I write down every expression individual and nonrelated to similar needs?
I've solved my issue and beyond only with NeinLinq. Here is my solution;
You need to remove nested declarations first.
public static Expression<Func<UserEx, UserExDTO>> GetUserExDTOConversionExpression()
{
return userEx => new UserExDTO
{
MyProperty1 = userEx.MyProperty1
//We removed other model declaration here.
};
}
Then use To method of NeinLinq to define the translation;
public static Expression<Func<UserEx, UserExDTO>> GetUserExDtOCompbinedExpression()
{
//Translate() and To() methods do all the job
return GetUserDTOConversionExpression().Translate()
.To(userEx => userEx.User, userExDTO => userExDTO.UserModel, GetUserExDTOConversionExpression());
}

Should I use custom setters in EF Core models?

I was just wondering if i should use custom setters in EF Core models. Consider this very simple example:
using System;
namespace EFTest.Models
{
public class Reservation
{
public int ReservationId { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public int ResourceId { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; }
public Resource Resource { get; set; }
}
public class Resource
{
public int ResourceId { get; set; }
public string Name { get; set; }
}
public class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
}
}
The issue being that when i have to save a model, and add an instance of a class to it, it handles getting the foreign key from said added instance just fine, like so:
public void SaveReservation()
{
var db = new Datebase();
var reservation = new Reservation(){ Start = new DateTime().Now, End = new DateTime().Now.AddDays(7)};
reservation.Resource = db.Resources.Find(2);
reservation.Customer = db.Customers.Find(4);
db.Reservations.Add(reservation);
db.SaveChanges();
}
but if i set the foreign key property for customer, but then add the instance of a resource, forexample, it is utterly unable to handle getting the foreignkey, like so:
public void SaveReservation()
{
var db = new Datebase();
var reservation = new Reservation(){ Start = new DateTime().Now, End = new DateTime().Now.AddDays(7)};
reservation.Resource = db.Resources.Find(2);
reservation.CustomerId = 4;
db.Reservations.Add(reservation);
db.SaveChanges();
}
Resulting in a sqlite exception 19, 'failing to get foreignkey' or somesuch.
The only solution i can think of is to do custom setters and getters to handle setting the property based on the key, and vice versa, e.g.:
using System;
namespace EFTest.Models
{
public class Reservation
{
public int ReservationId { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public int ResourceId
{
get
{
if(_Resource != null)
{
return _Resource.ResourceId;
}
else
{
return 0;
}
}
set
{
if(_Resource != null && !_Resource.ResourceId.Equals(value))
{
_Resource = null;
}
}
}
public int CustomerId
{
get
{
if(_Customer != null)
{
return _Customer.CustomerId;
}
else
{
return 0;
}
}
set
{
if(_Customer != null && !_Customer.CustomerId.Equals(value))
{
_Customer = null;
}
}
}
public Customer Customer
{
get
{
return _Customer;
}
set
{
_Customer = value;
if(value != null)
{
CustomerId = _Customer.CustomerId;
}
else
{
CustomerId = 0;
}
}
}
private Customer _Customer { get; set; }
public Resource Resource
{
get
{
return _Resource;
}
set
{
_Resource = value;
if(value != null)
{
ResourceId = _Resource.ResourceId;
}
else
{
ResourceId = 0;
}
}
}
private Resource _Resource { get; set; }
}
public class Resource
{
public int ResourceId { get; set; }
public string Name { get; set; }
}
public class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
}
}
But I am not at all certain this is a good way to handle the issue, can someone provide some insight on whether it is a good way to handle it? and whether there is a better one?
thank you.
A thank you to DevilSuichiro for providing the very clear and useful answer:
"But no, you shouldn't use custom getters or setters in your BO's, those should reflect your db schema pretty neatly."

Xamarin SQLite - ManyToMany relationship

I have 4 classes that i deal with in my Xamarin.Forms project: Users, User_Profiles, Medicines and Medicne_Incident.
Business rules:
Each User has 1 User_Profile (User profile is basically a detailed description of that user, User_Profile inherits from User)
There is a ManyToMany relation between Users and the medicines, and so a bridge table is created: Medicine_Incident
A user can have multiple Medicine_Incidents, but that incident is unique to the user.
I have no idea how to connect the dots (i.e., to have a stable relationship diagram for them).
Below are the class definitions for each of them:
User:
public class User
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public bool ProfileComplete { get; set; }
public User()
{
ProfileComplete = false;
Username = "";
Email = "";
Password = "";
}
public User(string email, string Password)
{
this.Email = email;
this.Password = Password;
}
}
User_Profiles:
public class User_Profiles : User
{
public string Gender { get; set; }
public string Country { get; set; }
public string Address { get; set; }
public string Province { get; set; }
public string Postal { get; set; }
public User_Profiles()
{
//Medicine = new List<Medicine>();
}
//?Do we need this?
public User_Profiles(string email, string Password)
{
//Medicine = new List<Medicine>();
this.Username = "";
//this.Dob = DateTime.Today;//Probably wrong to do
this.Gender = "";
this.Country = "";
this.Address = "";
this.Province = "";
this.Postal = "";
//Password/Email for User
this.Email = email;
this.Password = Password;
}
}
Medicine:
public class Medicine //: User_Profiles
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Medicine_Name { get; set; }
public string Medicine_Desc { get; set; }
public Medicine()
{
Medicine_Name = "";
Medicine_Desc = "";
//Medicine_Incident = new List<Medicine_Incident>();
}
}
Medicine_Incident:
public class Medicine_Incident : Medicine
{
public virtual Medicine Medicine { get; set; }
public virtual User_Profiles User_Profiles { get; set; }
public DateTime Time { get; set; }
public int Dosage { get; set; }
public Medicine_Incident()
{
// (1/1/0001 12:00:00 AM)
Dosage = 0;
}
}
I do my database querying in a file called "UserDatabase.cs":
public class UserDatabase
{
readonly SQLiteAsyncConnection database;
public UserDatabase(string dbPath)
{
database = new SQLiteAsyncConnection(dbPath);
database.CreateTableAsync<User_Profiles>().Wait();
database.CreateTableAsync<User>().Wait();
database.CreateTableAsync<Medicine>().Wait();
database.CreateTableAsync<Medicine_Incident>().Wait();
}
public void SaveProfileAsync(User_Profiles user)
{
database.InsertAsync(user);
}
public Task<User_Profiles> GetProfileAsync(string email, string pass)
{
return database.Table<User_Profiles>().Where(i => (i.Email.Equals(email)) && (i.Password.Equals(pass))).FirstOrDefaultAsync();
}
public void SaveMedicineAsync(Medicine med)
{
database.InsertAsync(med);
}
public void SaveMedicineIncidentAsync(Medicine_Incident med_inc)
{
database.InsertAsync(med_inc);
}
public Task<Medicine_Incident> GetMedicineIncidentAsync(string email, string medName, DateTime time)
{
return database.Table<Medicine_Incident>().Where(i => (i.User_Profiles.Email.Equals(email)) && (i.Medicine.Medicine_Name.Equals(medName)) && (i.Time.Equals(time))).FirstOrDefaultAsync();
}
}
Now the main thing is, i know i am doing it wrong, but how can i rectify it? Trust me when i say i spent time solving this and finding solution to this online.
NOTE:
- I am using SQLite.
- I have the SQLite extension in the project.
Sorry for the poor english
There is a lot of problems here. I guess you should read this and this article to help you learn how to model class/database in your code, but here is some tips:
 
Inheritance is used to extend a class (for example: Human inherits
from mammal that inherits from animal that inherits from living
being)
Your User_Profile class can have a public List Users (that
must be ignored by your SQLite database) and a Id [PrimaryKey]
Your User class, the IdUser_Profile (this will define which profile
each user have). It can be reffered to your UserProfile class...
I hope that it helps you.
Edit
You're right. This will not help you. I let it pass some details about your scope. Here is a more usefull information:
The only problem I see is the Medicine_Incident class. I would do so:
public class Medicine_Incident
{
[SQLite.Net.Attributes.PrimaryKey, SQLite.Net.Attributes.AutoIncrement]
public int Id { get; set; }
public int IdMedicine { get; set; }
[SQLite.Net.Attributes.Ignore]
public Medicine Medicine { get; set; }
public int IdUser_Profiles { get; set; }
[SQLite.Net.Attributes.Ignore]
public User_Profiles User_Profiles { get; set; }
public DateTime Time { get; set; }
public int Dosage { get; set; }
public Medicine_Incident()
{
// (1/1/0001 12:00:00 AM)
Dosage = 0;
}
}
And in your database query:
public class UserDatabase
{
readonly SQLiteAsyncConnection database;
public UserDatabase(string dbPath)
{
database = new SQLiteAsyncConnection(dbPath);
database.CreateTableAsync<User_Profiles>().Wait();
// Don't do that (Your User's attribute will be persisted within your User_Profiles table): database.CreateTableAsync<User>().Wait();
database.CreateTableAsync<Medicine>().Wait();
database.CreateTableAsync<Medicine_Incident>().Wait();
}
public void SaveProfileAsync(User_Profiles user)
{
database.InsertAsync(user);
}
public Task<User_Profiles> GetProfileAsync(string email, string pass)
{
return database.Table<User_Profiles>().Where(i => (i.Email.Equals(email)) && (i.Password.Equals(pass))).FirstOrDefaultAsync();
}
public void SaveMedicineAsync(Medicine med)
{
database.InsertAsync(med);
}
public void SaveMedicineIncidentAsync(Medicine_Incident med_inc)
{
database.InsertAsync(med_inc);
}
public Task<Medicine_Incident> GetMedicineIncidentAsync(string email, string medName, DateTime time)
{
var user = database.Table<User_Profiles>().Where(u => u.Email == email).FirstOrDefault();
var medicine = database.Table<Medicine>().Where(m => m.Medicine_Name == medName).FirstOrDefault();
var medInc = database.Table<Medicine_Incident>().Where(mi => mi.IdUser_Profiles == user.Id && mi.IdMedicine == medicine.Id).FirstOrDefault();
medInc.User = user;
medInc.Medicine = medicine;
return medInc;
}
}
SQLite doesn't handle relationships between classes when querying. To do this, use the SQLite Net Extensions.
I hope it helps you.

Data does not get inserted: EF Code First

I have following code to insert data into GiftCouponPayment table and Payment table. This code successfully created a database and these two tables. However there is no data inserted in one table - GiftCouponPayment table. What need to be changed in order to make it working?
CODE
static void Main(string[] args)
{
string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30";
using (var db = new NerdDinners(connectionstring))
{
var giftCouponPayment = new GiftCouponPayment();
giftCouponPayment.MyID=1;
giftCouponPayment.MyValue=250;
List<IPaymentComponent> comps = new List<IPaymentComponent>();
comps.Add(giftCouponPayment);
var payment = new Payment { PaymentComponents = comps, PaymentID = 1, PayedTime=DateTime.Now };
db.Payments.Add(payment);
int recordsAffected = db.SaveChanges();
}
}
Domain Classes
namespace LijosEF
{
public interface IPaymentComponent
{
int MyID { get; set; }
int MyValue { get; set; }
int GetEffectiveValue();
}
public partial class GiftCouponPayment : IPaymentComponent
{
private int CouponValue;
public int MyID
{
get
{
return this.GiftCouponPaymentID;
}
set
{
this.GiftCouponPaymentID = value;
}
}
public int MyValue
{
get
{
return this.CouponValue;
}
set
{
this.CouponValue = value;
}
}
public int GetEffectiveValue()
{
if (this.GiftCouponPaymentID < 2000)
{
return 0;
}
return this.CouponValue;
}
public int GiftCouponPaymentID { get; set; }
}
public partial class Payment
{
public int PaymentID { get; set; }
public List<IPaymentComponent> PaymentComponents { get; set; }
public DateTime PayedTime { get; set; }
}
//System.Data.Entity.DbContext is from EntityFramework.dll
public class NerdDinners : System.Data.Entity.DbContext
{
public NerdDinners(string connString): base(connString)
{
}
protected override void OnModelCreating(DbModelBuilder modelbuilder)
{
modelbuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
public DbSet<GiftCouponPayment> GiftCouponPayments { get; set; }
public DbSet<Payment> Payments { get; set; }
}
}
You cannot use interface in your navigation property - EF doesn't support it. You must declare your payment directly with a class:
public partial class Payment {
public int PaymentID { get; set; }
public List<GiftPaymentComponent> PaymentComponents { get; set; }
public DateTime PayedTime { get; set; }
}
If your Payment can have different PaymentComponents you must use mapped inheritance with abstract base class instead of interface.

Categories

Resources