I'm trying to get my mysql data in ASP.net MVC3.
The mysql Database Name is supply_db and table name is xcart_orders.
ASP.net code is like below,
(Im just following my book, and just switch to my DB info but it does not work :( )
(I will omit using and namespace)
Web.Config File,
<add name="EFMysqlContext" connectionString="server=XXX.XXX.XXX.XX;User Id=root;pwd=xxx;Persist Security Info=True;database=supply_db"
providerName="Mysql.Data.MySqlClient" />
Abstract/IXcartOrdersRepository.cs
public interface IXcartOrdersRepository
{
IQueryable<XcartOrder> xcart_orders { get; }
}
/Concrete/EFXcartOrderRepository.cs
public class EFXcartOrdersRepository : IXcartOrdersRepository
{
private EFMysqlContext context = new EFMysqlContext();
public IQueryable<XcartOrder> xcart_orders
{
get { return context.xcart_orders; } // I thought the 'xcart_orders' should be match with db table name, isn't it?
}
}
/Entities/XcartOrder.cs
public class XcartOrder
{
[Key]
public int orderid { get; set; }
public string login { get; set; }
public string membership { get; set; }
public decimal subtotal { get; set; }
}
and In my controller,
IXcartOrdersRepository XcartOrdersRepository = new EFXcartOrdersRepository();
int orderCnt = XcartOrdersRepository.xcart_orders.Count();
then error occur, the error message say "{"Table 'supply_db.XcartOrders' doesn't exist"}"
I think I could connect to db, but couldn't get the table.
anybody know which part do I need to change?
Thank you!
can you decorate your Xcartorder class with the Table attribute to explicitly specify the desired name?
[Table("xcart_orders")]
public class XcartOrder
{
...
edit: attribute syntax
Related
These are my classes:
public class Post : IPost
{
public int Id { get; set; }
public virtual int[] DuplicateOf { get; set; }
public virtual ICommentInfo[] Comments { get; set; }
}
public class CommentInfo : ICommentInfo
{
public virtual string Author { get; set; }
public virtual int Id { get; set; }
public virtual string Text { get; set; }
public virtual int PostId{ get; set; }
[ForeignKey("PostId")]
public virtual Post Post { get; set; }
}
With this CommentConfiguration added to OnModelCreate():
HasRequired(c => c.Post)
.WithMany(b=>(ICollection<CommentInfo>) b.Comments)
.HasForeignKey(b=>b.PostId)
.WillCascadeOnDelete(true);
I really cannot understand why the property Comments is always null, and why EF doesn't initialize it since it's virtual.
I tried disabling lazy loading too, but when i try loading the navigation property with context.Post.Include("Comments") an error tells me that "There is not a navigation property called Comments".
So I tried using Entity Framework Power Tools Beta 3 to see the Entity Data Model, and I discovered that there is not a navigation end for table "Post" even if there is the relationship between the two tables and there's the Comment table end too.
I sincerly don't know which way to turn, could be a problem of Array?? Should I use an Icollection property??
Though I cannot change the type of that property because Post is implementing an Interface.
Every sample I look at is clear and easy to make work. Please help me.. Thank you in advance.
EDIT:
This is what I changed after looking at the link I posted yesterday.
public class Post : IPost
{
public int Id { get; set; }
public virtual int[] DuplicateOf { get; set; }
public virtual ICollection<CommentInfo> Comments { get; set; }
ICommentInfo[] IPost.Comments {
get { return Comments ; }
set { Comments = (CommentInfo[])value; } }
}
The exception is: System.ObjectDisposedException :The ObjectContext instance has been disposed and can no longer be used for operations that require a connection and raises when the application tries to get the Comments.
If I remove the virtual key the exception disappear but the property remain always null and the values don't persist in any way.
EDITv2
I've solved my problem adding a new property and map my old property to it.
public class Post : IPost
{
public int Id { get; set; }
public virtual int[] DuplicateOf { get; set; }
public ICommentInfo[] Comments
{
get { return ListComments.ToArray(); }
}
public List<CommentInfo> ListComments {get;set;}
}
In my PostConfiguration OnModelCreate() I used the ListComments property as a navigation property like this:
HasMany(b => b.ListComments)
.WithRequired(c=>c.Post)
.HasForeignKey(c=>c.PostId)
.WillCascadeOnDelete(true);
Now it perfectly works, it was simpler than I expected and when I try to receive the Comments Collection, if I include the "ListComments" property, I get the array of Post.
Thank you for your help!
I can't access the link in your comment, but I assume you changed
public virtual ICommentInfo[] Comments { get; set; }
into the common way to define navigation properties:
public virtual ICollection<CommentInfo> Comments { get; set; }
because entity framework does not support interfaces in its conceptual model.
The exception about the disposed context means that you access this property after fetching Post objects from the database and disposing the context. This triggers lazy loading while the connection to the database is lost. The solution is to use Include:
var posts = context.Posts.Include(p => p.Comments).Where(...)
Now posts and comments are fetched in one go.
I am currently working on a Web API project with a Database-First method using Entity Framework (which I know is not the most stable of platforms yet), but I am running into something very strange.
When the GET method within my APIController tries to return all records in a DbSet with a LINQ Include() method involved such as this, it will return a 500 error:
// GET api/Casinos
public IEnumerable<casino> Getcasinos()
{
var casinos = db.casinos.Include(c => c.city).Include(c => c.state);
return casinos.AsEnumerable();
}
Yet, this method works fine, and returns my data from within my database:
// GET api/States
public IEnumerable<state> Getstates()
{
return db.states.AsEnumerable();
}
So I have proved in other instances that if it returns the entities without LINQ queries, it works great, yet when there is an Include method used upon the DbContext, it fails.
Of course, trying to find this error is impossible, even with Fiddler, Chrome/Firefox dev tools, and adding in GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
If anyone has resolved this, it would be nice to know a nice resolution so I can start returning my data! Thanks!:)
P.S. I am using SQL Server 2012
This is happening due to error in serialization (Json/XML). The problem is you are directly trying to transmit your Models over the wire. As an example, see this:
public class Casino
{
public int ID { get; set; }
public string Name { get; set; }
public virtual City City { get; set; }
}
public class State
{
public int ID { get; set; }
public string Name { get; set; }
[XmlIgnore]
[IgnoreDataMember]
public virtual ICollection<City> Cities { get; set; }
}
public class City
{
public int ID { get; set; }
public string Name { get; set; }
public virtual State State { get; set; }
[XmlIgnore]
[IgnoreDataMember]
public virtual ICollection<Casino> Casinos { get; set; }
}
public class Context : DbContext
{
public Context()
: base("Casino")
{
}
public DbSet<Casino> Casinos { get; set; }
public DbSet<State> States { get; set; }
public DbSet<City> Cities { get; set; }
}
Pay attention to the XmlIgnore and IgnoreDataMember. You need to restrict avoiding serialization so it doesn't happen in circular manner. Further, the above model will still not work because it has virtual. Remove virtual from everywhere namely City, Cities, Casinos and State and then it would work but that would be inefficient.
To sum up: Use DTOs and only send data that you really want to send instead of directly sending your models.
Hope this helps!
I had same problem in ASP.Net Core Web Api and made it working with this solution:
Add Microsoft.AspNetCore.Mvc.NewtonsoftJson nuget package to web api project.
and in Startup.cs class in ConfigureServices method add this code:
services.AddControllersWithViews().AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
We are using EF Code First 4.3.1.
We are developing an ASP.NET Web Role referring to multiple class libraries.
There are two class libraries each containing classes and an individual DBcontext.
Lets say the Library1 has classes A and B.
DBcon1: DbSet and DbSet
Lets say the Library2 has classes C and D.
Class C{
[Key]
public int CId{ get; set;}
[Required]
public virtual A referencedA {get; set;}
}
DBcon2: DbSet<C> and DbSet<D>
When I try to use the DBcon2 as such:
using (var con = new DBcon2())
{
C vr = new C();
vr.CId= 1;
vr.referencedA = DBCon1.As.First();
con.Cs.Add(vr);
con.SaveChanges();
}
I get an exception as:
"The member with identity does not exist in the metadata collection.
Parameter name: identity"
Both DBCon1 and DBcon2 are using the sane SQL Server Database "SampleDB".
Please point me in the right direction.
I got this error and fixed it by not trying to set the navigation property in the related table, just set the foreign key id instead
eg
public class Student()
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public int CourseId { get; set; }
public virtual Course Course { get; set; }
}
public class Course()
{
public int CourseId { get; set; }
public string CourseName { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
Main code:
var myCourse = new Course();
var myCourseId = 1;
var student = new Student() {
CourseId = myCourseId
// Course = myCourse <-- this would cause the error
}
Might not be your issue but maybe it will point you in the right direction and hopefully will help someone else.
The exception is a bit cryptic, but pretty clear if you realise that a context needs information about entities (metadata) to be able to write sql statements. Thus, your DBcon2 context has no clue where to find the primary key of an A, because it has no metadata about A.
You could however set an integer property A_Id (or the like), but then you'll have to write custom code to resolve it to an A.
Another option is to merge (parts of) the contexts, if possible.
I've got my EF Code First working exactly as expected aside from one small bit. I'm not sure how to name my Database File.
I'm using SQL CE, but I'm sure this applies to all forms of EF Code First.
Here's my DbContext
namespace MyApp.Domain.EntityFramework
{
public class DataContext : DbContext
{
//...
}
}
And when the database is created it's created as
MyApp.Domain.EntityFramework.DataContext.sdf
I'd prefer to just have it named
MyApp.sdf
Now I'm sure this is simple, but my Googling skills keep turning up examples where the database name is auto generated like mine.
http://www.hanselman.com/blog/SimpleCodeFirstWithEntityFramework4MagicUnicornFeatureCTP4.aspx
You need to specify a connection string (for example by creating a connection string named DataContext (your class name) in your config file, and set the desired name there.
I was looking to do the same. Managed to end up with this:
public class ShopDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<Feature> Features { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Subcategory> Subcategories { get; set; }
public DbSet<Information> OrderInformation { get; set; }
public ShopDbContext() : base("Shop")
{
}
}
It will name your database "Shop" so just replace what is in the base("Shop") with whatever you want to call your database. Hope this helps.
I'm having some troubles with validation on my application.
Let's say I've the following models:
public class Company
{
public int id { get; set; }
[Required]
public String Name { get; set; }
public String Location { get; set; }
public List<Contacts> Contacts { get; set; }
}
public class Contact
{
public int id { get; set; }
[Required]
public String Name { get; set; }
[DataType(DataType.EmailAddress)]
public String Email { get; set; }
public String Telephone { get; set; }
public String Mobile { get; set; }
}
Now in my company create view I've two buttons, one to add contacts to the company, and another one to create the new company.
I detected which button was used in my controller like this (both buttons are named "button"):
[HttpPost]
public ActionResult Create(String button, FormCollection collection)
{
if(button == "AddContact")
{
AddContact(collection);
}
else
{
CreateCompany(collection);
}
}
While it's being created the object that represents the company that it's being create is stored in the session (for example HttpContext.Session["company"] = company;)
Now the problem is that if, for example, I try to add a contact without first specifying the company name, i get a validation error because the company name is required, which shouldn't happen because the user might want to add the contacts before adding the company info. Or if I try to save the company, I also get a validation error, because usually when saving the "add contact" form is empty, which means that the contact name (which is required as well) was not specified.
What I want to know is that if it's possible to validate the contact properties only when the addContact button is used, and validate the company properties only when the createCompany button is pressed.
For now i only need to do this serve-side, but if anyone has a solution to do this client-side as well i would appreciate the help.
You could trigger your own validation on the individual objects using
Validator.TryValidateObject(Object, ValidationContext, ICollection)
You can provide conditional validation using the Entity Framework by overriding DbEntityValidationResult in the DbContext. When this validation occurs in the DbContext you can access other entities. When validating a contact you can check the company too. For example:
protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
{
var result = base.ValidateEntity(entityEntry, items);
ValidateContact(result);
return result;
}
private void ValidateContact(DbEntityValidationResult result)
{
var contact= result.Entry.Entity as Contact;
if (contact!= null && contact.ContactId != 0)
{
// Add validation code here, such as:
if(!string.IsNullOrEmpty(contact.Company.Name){
result.ValidationErrors.Add(
new DbValidationError(
"Contact",
"Company name cannot be null or empty when validating contacts.")
);
}
}
}
See Julia Lerman's Programming Entity Framework: DbContext http://www.amazon.com/Programming-Entity-Framework-Julia-Lerman/dp/1449312969 for more details.