Data does not get inserted: EF Code First - c#

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.

Related

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."

How to cast an object into type of another variable in C#

I'm working on an entity framework project and I'm trying to form a generic structure for adding joins to my table.
class BrowseCONTACTS_BASE : MyBrowseFrm<CONTACTS_BASE>
{
public BrowseCONTACTS_BASE()
{
MyInitialize();
}
public void MyInitialize()
{
//Here I may have more joins
MyAddJoins<ORDERS>("CONTACTS_BASE", "CB_REFNO", "ORDERS", "OR_REFNO", "OR_REFNO");
}
}
On the parent class MyBrowseFrm
partial class MyBrowseFrm<TEntity>:Form where TEntity:class
{
}
I have the following:
MyAddJoins Function that I call from the child class above
protected void MyAddJoins<TTable>(string pParent, string pParentKey, string pChild, string pChildKey,
string pDisplayField) where TTable:class, new()
{
var a = new TTable();
var item = new MyJoins<dynamic>
{
Parent = pParent,
Child = pChild,
ParentKey = pParentKey,
ChildKey = pChildKey,
DisplayField = pDisplayField,
ChildTable = a
};
MyBdJoins.Add(item);
}
//A list to store Joins added from the child table
private List<MyJoins<dynamic>> MyBdJoins;
protected struct MyJoins<TTable> where TTable : class
{
public string Parent;
public string ParentKey;
public string Child;
public string ChildKey;
public string DisplayField;
public TTable ChildTable;
}
Ok this is the part where I'm stuck, The following code will run when I press the search button.
private void MyGenerateQuery()
{
//Here I cast my Context to CONTACTS_BASE
var loContext = (DbSet<TEntity>)Context.GetPropValue(boName);
foreach (var join in MyBdJoins)
{
loContext
.Join(
(DbSet<ORDERS>)Context.GetPropValue(join.Child),
par => par.GetPropValue(join.ParentKey),
chld => chld.GetPropValue(join.ChildKey),
(par, chld) => new { GetPropValue = chld.GetPropValue(join.DisplayField) }
);
}
myGridView1.DataSource = loContext.ToList();
}
The code above at the part where it is:
(DbSet<ORDERS>)Context.GetPropValue(join.Child)
Here what I want to do is:
(DbSet<TTable>)Context.GetPropValue(join.Child)
of course, the above code gives me an error.
Note: in my code TEntity is CONTACTS_BASE and TTable is ORDERS
so how do I cast this object to type TTable
where it is in MyJoins Structure
public TTable ChildTable;
EDIT:
public partial class ORDERS
{
public int OR_REFNO { get; set; }
public string OR_PROD_CODE { get; set; }
public Nullable<DateTime> OR_DATE { get; set; }
public Nullable<int> OR_M_REFNO { get; set; }
public virtual CONTACTS_BASE CONTACTS_BASE { get; set; }
public virtual ORDER_TYPES ORDER_TYPES { get; set; }
}
public partial class CONTACTS_BASE
{
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public CONTACTS_BASE()
{
this.ORDERS = new List<ORDERS>();
}
public int CB_REFNO { get; set; }
public string CB_NAME { get; set; }
public string CB_ID_NO { get; set; }
public string CB_AGE { get; set; }
public Nullable<decimal> CB_TEL_NO { get; set; }
public string CB_EMAIL { get; set; }
public Nullable<DateTime> CB_ENROLL_DATE { get; set; }
public Nullable<DateTime> CB_START_DATE { get; set; }
public Nullable<DateTime> CB_END_DATE { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual IList<ORDERS> ORDERS { get; set; }
}

How to get data out of sqlite database by using a function?

I am making a application in Xamarin forms but whatever I try I can't get the sqlite database working. I want to select all Categories where menu_ID = 1 how can I do this? I need this code inside a other page (CategoriePage.xaml.cs) can somewann help me with this?
Here is some code that I use:
(Tables.cs):
namespace AmsterdamTheMapV3
{
public class Categories
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public int Menu_ID { get; set; }
public string Name { get; set; }
public Categories()
{
}
}
public class Places
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public int Categorie_ID { get; set; }
public string Name { get; set; }
public Boolean Featured { get; set; }
public string OpenHours { get; set; }
public string Info { get; set; }
public string Images { get; set; }
public string Phone { get; set; }
public string Website { get; set; }
public string Adress { get; set; }
public Places()
{
}
}
public class Events
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public Events()
{
}
}
}
DB helper (TheMapDB.cs):
public class TheMapDB
{
private SQLiteConnection db;
public TheMapDB()
{
//Getting conection and Creating table
db = DependencyService.Get<ISQLite>().GetConnection();
db.CreateTable<Categories>();
db.CreateTable<Places>();
db.CreateTable<Events>();
var categories = new Categories()
{
ID = 1,
Menu_ID = 1,
Name = "test"
};
db.Insert(categories); // Insert the object in the database
}
public IEnumerable<Categories> GetCategories()
{
return (from t in db.Table<Categories>() select t).ToList();
}
//Get specific Categorie
public Categories GetCategorie(int id)
{
return db.Table<Categories>().FirstOrDefault(t => t.ID == id);
}
//Delete specific Categorie
public void DeleteCategorie(int id)
{
db.Delete<Categories>(id);
}
//Add new student to Categorie
public void AddCategorie(Categories categorie)
{
db.Insert(categorie);
}
}
}
CategoriePage.xaml.cs:
public partial class CategoriePage : ContentPage
{
static TheMapDB database;
TheMapDB categorie = new TheMapDB();
public CategoriePage(String txt)
{
InitializeComponent();
var layout = new StackLayout { Padding = new Thickness(5, 10) };
this.Content = layout;
if(txt.Equals("1"))
{
txt = "this text is number 1";
//needed code can't find soluction
}
var label = new Label { Text = txt, TextColor = Color.FromHex("#77d065"), FontSize = 20 };
layout.Children.Add(label);
}
}
thank you in advance,
I suggest you make a DAO class with a function like this: (or put this function in TheMapDB.cs)
public List<Category> GetCategoryByID(int menuID)
{
return db.Table<Category>().Where(x => x.menu_ID == menuID).ToList();
}
Then you can call this function in your DAO from everywhere you want. That seems the best solution to me.
When you put this function in the class TheMapDB.cs you can say in your CategoryPage.xaml.cs:
database.GetCategoryByID(menuID);

Using Multiple Databases within a controller asp.net mvc

I have two separate VS Solutions both work fine accessing the databases associated with them.
How ever I need to look up some details from the other database to be displayed in the other solution.
Ive added the second connection string to the web.config and then added the context to my DAL:
namespace RACentral.DAL
{
public class RACentralContext : DbContext
{
public RACentralContext()
: base("RACDev")
{
}
public DbSet<RiskAssessment> RiskAssessments { get; set; }
public DbSet<Hazard> Hazards { get; set; }
public DbSet<PPE> PPEs { get; set; }
public DbSet<RiskAssessmentPPE> RiskAssessmentPPEs { get; set; }
public DbSet<PeopleExposed> PeopleExposeds { get; set; }
public DbSet<RiskAssessmentPeopleExposed> RiskAssessmentPeopleExposeds { get; set; }
public DbSet<RiskAssessmentHazard> RiskAssessmentHazards { get; set; }
public DbSet<ControlMeasure> ControlMeasures { get; set; }
public DbSet<Severity> Severitys { get; set; }
public DbSet<Likelihood> Likelihoods { get; set; }
public DbSet<AddControlMeasure> AddControlMeasures { get; set; }
public DbSet<Type> Types { get; set; }
public DbSet<SubType> SubTypes { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
public class PeopleContext : DbContext
{
public PeopleContext()
: base("PeopleContext")
{
}
public DbSet<Person> People { get; set; }
}
}
I get an error in the controller
'Not set to an instance of an object,'
Am trying to access it in my controller as follow:
public class RiskAssessmentController : Controller
{
private RACentralContext db = new RACentralContext();
private PeopleContext Peopledb = new PeopleContext();
public ViewResult StartRA()
{
var user = User.Identity.Name;
string userName = user.Substring(7);
var test = Peopled.Person.FirstOrDefault(x => x.PersonId == 1) //Error here
StartRiskAssessmentViewModel viewModel = new StartRiskAssessmentViewModel
{
RiskAssessment = new RiskAssessment(),
Assessor = userName,
};
return View(viewModel);
}
}

Display new table in the database MVC4 asp.net

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!

Categories

Resources